-
Notifications
You must be signed in to change notification settings - Fork 2.1k
/
InetLayer.h
326 lines (258 loc) · 11.1 KB
/
InetLayer.h
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
/*
*
* Copyright (c) 2020-2021 Project CHIP Authors
* Copyright (c) 2013-2017 Nest Labs, Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
/**
* @file
* This file defines classes for abstracting access to and
* interactions with a platform- and system-specific Internet
* Protocol stack which, as of this implementation, may be either
* BSD/POSIX Sockets, LwIP or Network.framework.
*
* Major abstractions provided are:
*
* * Timers
* * Domain Name System (DNS) resolution
* * TCP network transport
* * UDP network transport
* * Raw network transport
*
* For BSD/POSIX Sockets, event readiness notification is handled
* via file descriptors and a traditional poll / select
* implementation on the platform adaptation.
*
* For LwIP, event readiness notification is handled via events /
* messages and platform- and system-specific hooks for the event
* / message system.
*
*/
#pragma once
#ifndef __STDC_LIMIT_MACROS
#define __STDC_LIMIT_MACROS
#endif
#include <inet/InetConfig.h>
#include <inet/IANAConstants.h>
#include <inet/IPAddress.h>
#include <inet/IPPrefix.h>
#include <inet/InetError.h>
#include <inet/InetInterface.h>
#include <inet/InetLayerBasis.h>
#include <inet/InetLayerEvents.h>
#if INET_CONFIG_ENABLE_DNS_RESOLVER
#include <inet/DNSResolver.h>
#endif // INET_CONFIG_ENABLE_DNS_RESOLVER
#if INET_CONFIG_ENABLE_TCP_ENDPOINT
#include <inet/TCPEndPoint.h>
#endif // INET_CONFIG_ENABLE_TCP_ENDPOINT
#if INET_CONFIG_ENABLE_UDP_ENDPOINT
#include <inet/UDPEndPoint.h>
#endif // INET_CONFIG_ENABLE_UDP_ENDPOINT
#if CHIP_SYSTEM_CONFIG_USE_SOCKETS
#if INET_CONFIG_ENABLE_DNS_RESOLVER && INET_CONFIG_ENABLE_ASYNC_DNS_SOCKETS
#include <inet/AsyncDNSResolverSockets.h>
#endif // INET_CONFIG_ENABLE_DNS_RESOLVER && INET_CONFIG_ENABLE_ASYNC_DNS_SOCKETS
#endif // CHIP_SYSTEM_CONFIG_USE_SOCKETS
#include <system/SystemLayer.h>
#include <system/SystemStats.h>
#include <lib/support/DLLUtil.h>
#if INET_CONFIG_MAX_DROPPABLE_EVENTS
#if CHIP_SYSTEM_CONFIG_POSIX_LOCKING
#include <pthread.h>
#include <semaphore.h>
#endif // CHIP_SYSTEM_CONFIG_POSIX_LOCKING
#if CHIP_SYSTEM_CONFIG_FREERTOS_LOCKING
#if defined(ESP_PLATFORM)
#include "freertos/FreeRTOS.h"
#else
#include <FreeRTOS.h>
#endif
#include <semphr.h>
#endif // CHIP_SYSTEM_CONFIG_FREERTOS_LOCKING
#endif // INET_CONFIG_MAX_DROPPABLE_EVENTS
#include <stdint.h>
namespace chip {
namespace Inet {
// Forward Declarations
class InetLayer;
namespace Platform {
namespace InetLayer {
extern CHIP_ERROR WillInit(Inet::InetLayer * aLayer, void * aContext);
extern void DidInit(Inet::InetLayer * aLayer, void * aContext, CHIP_ERROR anError);
extern CHIP_ERROR WillShutdown(Inet::InetLayer * aLayer, void * aContext);
extern void DidShutdown(Inet::InetLayer * aLayer, void * aContext, CHIP_ERROR anError);
} // namespace InetLayer
} // namespace Platform
/**
* @class InetLayer
*
* @brief
* This provides access to Internet services, including timers,
* Domain Name System (DNS) resolution, TCP network transport, UDP
* network transport, and raw network transport, for a single
* thread.
*
* For BSD/POSIX Sockets, event readiness notification is handled
* via file descriptors and a traditional poll / select
* implementation on the platform adaptation.
*
* For LwIP, event readiness notification is handle via events /
* messages and platform- and system-specific hooks for the event /
* message system.
*
*/
class DLL_EXPORT InetLayer
{
#if INET_CONFIG_ENABLE_DNS_RESOLVER
friend class DNSResolver;
#endif // INET_CONFIG_ENABLE_DNS_RESOLVER
#if INET_CONFIG_ENABLE_TCP_ENDPOINT
friend class TCPEndPoint;
#endif // INET_CONFIG_ENABLE_TCP_ENDPOINT
#if INET_CONFIG_ENABLE_UDP_ENDPOINT
friend class UDPEndPoint;
#endif // INET_CONFIG_ENABLE_UDP_ENDPOINT
#if CHIP_SYSTEM_CONFIG_USE_SOCKETS
#if INET_CONFIG_ENABLE_DNS_RESOLVER && INET_CONFIG_ENABLE_ASYNC_DNS_SOCKETS
friend class AsyncDNSResolverSockets;
#endif // INET_CONFIG_ENABLE_DNS_RESOLVER && INET_CONFIG_ENABLE_ASYNC_DNS_SOCKETS
#endif // CHIP_SYSTEM_CONFIG_USE_SOCKETS
public:
/**
* The current state of the InetLayer object.
*
*/
volatile enum {
kState_NotInitialized = 0, /**< Not initialized state. */
kState_Initialized = 1, /**< Initialized state. */
kState_ShutdownInProgress = 2, /**< State where Shutdown has been triggered. */
} State; /**< [READ-ONLY] Current state. */
InetLayer();
CHIP_ERROR Init(chip::System::Layer & aSystemLayer, void * aContext);
// Must be called before System::Layer::Shutdown(), since this holds a pointer to that.
CHIP_ERROR Shutdown();
chip::System::Layer * SystemLayer() const { return mSystemLayer; }
// End Points
#if INET_CONFIG_ENABLE_TCP_ENDPOINT
CHIP_ERROR NewTCPEndPoint(TCPEndPoint ** retEndPoint);
#endif // INET_CONFIG_ENABLE_TCP_ENDPOINT
#if INET_CONFIG_ENABLE_UDP_ENDPOINT
CHIP_ERROR NewUDPEndPoint(UDPEndPoint ** retEndPoint);
#endif // INET_CONFIG_ENABLE_UDP_ENDPOINT
// DNS Resolution
#if INET_CONFIG_ENABLE_DNS_RESOLVER
typedef DNSResolver::OnResolveCompleteFunct DNSResolveCompleteFunct;
CHIP_ERROR ResolveHostAddress(const char * hostName, uint16_t hostNameLen, uint8_t options, uint8_t maxAddrs,
IPAddress * addrArray, DNSResolveCompleteFunct onComplete, void * appState);
CHIP_ERROR ResolveHostAddress(const char * hostName, uint16_t hostNameLen, uint8_t maxAddrs, IPAddress * addrArray,
DNSResolveCompleteFunct onComplete, void * appState);
CHIP_ERROR ResolveHostAddress(const char * hostName, uint8_t maxAddrs, IPAddress * addrArray,
DNSResolveCompleteFunct onComplete, void * appState);
void CancelResolveHostAddress(DNSResolveCompleteFunct onComplete, void * appState);
#endif // INET_CONFIG_ENABLE_DNS_RESOLVER
CHIP_ERROR GetInterfaceFromAddr(const IPAddress & addr, InterfaceId & intfId);
CHIP_ERROR GetLinkLocalAddr(InterfaceId link, IPAddress * llAddr);
bool MatchLocalIPv6Subnet(const IPAddress & addr);
static void UpdateSnapshot(chip::System::Stats::Snapshot & aSnapshot);
void * GetPlatformData();
void SetPlatformData(void * aPlatformData);
#if CHIP_SYSTEM_CONFIG_USE_LWIP
static CHIP_ERROR HandleInetLayerEvent(chip::System::Object & aTarget, chip::System::EventType aEventType, uintptr_t aArgument);
static chip::System::LayerLwIP::EventHandlerDelegate sInetEventHandlerDelegate;
// In some implementations, there may be a shared event / message
// queue for the InetLayer used by other system events / messages.
//
// If the length of that queue is considerably longer than the
// number of packet buffers available, it may lead to buffer
// exhaustion. As a result, using the queue itself to implement
// backpressure is insufficient, and we need an external mechanism
// to prevent buffer starvation in the rest of the system and
// getting into deadlock situations.
// For both UDP and raw network transport traffic we can easily
// drop incoming packets without impacting the correctness of
// higher level protocols.
#if INET_CONFIG_MAX_DROPPABLE_EVENTS
inline static bool IsDroppableEvent(chip::System::EventType type)
{
return
#if INET_CONFIG_ENABLE_UDP_ENDPOINT
type == kInetEvent_UDPDataReceived ||
#endif // INET_CONFIG_ENABLE_UDP_ENDPOINT
false;
}
CHIP_ERROR InitQueueLimiter(void);
bool CanEnqueueDroppableEvent(void);
void DroppableEventDequeued(void);
#if CHIP_SYSTEM_CONFIG_NO_LOCKING
volatile int32_t mDroppableEvents;
#elif CHIP_SYSTEM_CONFIG_POSIX_LOCKING
sem_t mDroppableEvents;
#elif CHIP_SYSTEM_CONFIG_FREERTOS_LOCKING
#if (configSUPPORT_STATIC_ALLOCATION == 1)
StaticSemaphore_t mDroppableEventsObj;
#endif // (configSUPPORT_STATIC_ALLOCATION == 1)
SemaphoreHandle_t mDroppableEvents;
#endif // CHIP_SYSTEM_CONFIG_FREERTOS_LOCKING
#else // !INET_CONFIG_MAX_DROPPABLE_EVENTS
inline static bool IsDroppableEvent(chip::System::EventType aType) { return false; }
inline CHIP_ERROR InitQueueLimiter(void) { return CHIP_NO_ERROR; }
inline bool CanEnqueueDroppableEvent(void) { return true; }
inline void DroppableEventDequeued(void) { return; }
#endif // !INET_CONFIG_MAX_DROPPABLE_EVENTS
#endif // CHIP_SYSTEM_CONFIG_USE_LWIP
#if INET_CONFIG_ENABLE_TCP_ENDPOINT && INET_TCP_IDLE_CHECK_INTERVAL > 0
static void HandleTCPInactivityTimer(chip::System::Layer * aSystemLayer, void * aAppState);
#endif // INET_CONFIG_ENABLE_TCP_ENDPOINT && INET_TCP_IDLE_CHECK_INTERVAL > 0
private:
void * mContext;
void * mPlatformData;
chip::System::Layer * mSystemLayer;
#if CHIP_SYSTEM_CONFIG_USE_SOCKETS
#if INET_CONFIG_ENABLE_DNS_RESOLVER && INET_CONFIG_ENABLE_ASYNC_DNS_SOCKETS
AsyncDNSResolverSockets mAsyncDNSResolver;
#endif // INET_CONFIG_ENABLE_DNS_RESOLVER && INET_CONFIG_ENABLE_ASYNC_DNS_SOCKETS
#endif // CHIP_SYSTEM_CONFIG_USE_SOCKETS
friend CHIP_ERROR Platform::InetLayer::WillInit(Inet::InetLayer * aLayer, void * aContext);
friend void Platform::InetLayer::DidInit(Inet::InetLayer * aLayer, void * aContext, CHIP_ERROR anError);
friend CHIP_ERROR Platform::InetLayer::WillShutdown(Inet::InetLayer * aLayer, void * aContext);
friend void Platform::InetLayer::DidShutdown(Inet::InetLayer * aLayer, void * aContext, CHIP_ERROR anError);
bool IsIdleTimerRunning();
};
/**
* @class IPPacketInfo
*
* @brief
* Information about an incoming/outgoing message/connection.
*
* @warning
* Do not alter the contents of this class without first reading and understanding
* the code/comments in IPEndPointBasis::GetPacketInfo().
*/
class IPPacketInfo
{
public:
IPAddress SrcAddress; /**< The source IPAddress in the packet. */
IPAddress DestAddress; /**< The destination IPAddress in the packet. */
InterfaceId Interface; /**< The interface identifier for the connection. */
uint16_t SrcPort; /**< The source port in the packet. */
uint16_t DestPort; /**< The destination port in the packet. */
void Clear();
};
extern CHIP_ERROR ParseHostAndPort(const char * aString, uint16_t aStringLen, const char *& aHost, uint16_t & aHostLen,
uint16_t & aPort);
extern CHIP_ERROR ParseHostPortAndInterface(const char * aString, uint16_t aStringLen, const char *& aHost, uint16_t & aHostLen,
uint16_t & aPort, const char *& aInterface, uint16_t & aInterfaceLen);
} // namespace Inet
} // namespace chip