3 * Copyright (c) 2020 Project CHIP Authors
4 * Copyright (c) 2013-2017 Nest Labs, Inc.
6 * Licensed under the Apache License, Version 2.0 (the "License");
7 * you may not use this file except in compliance with the License.
8 * You may obtain a copy of the License at
10 * http://www.apache.org/licenses/LICENSE-2.0
12 * Unless required by applicable law or agreed to in writing, software
13 * distributed under the License is distributed on an "AS IS" BASIS,
14 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15 * See the License for the specific language governing permissions and
16 * limitations under the License.
21 * This file defines classes for abstracting access to and
22 * interactions with a platform- and system-specific Internet
23 * Protocol stack which, as of this implementation, may be either
24 * BSD/POSIX Sockets, LwIP or Network.framework.
26 * Major abstractions provided are:
29 * * Domain Name System (DNS) resolution
30 * * TCP network transport
31 * * UDP network transport
32 * * Raw network transport
34 * For BSD/POSIX Sockets, event readiness notification is handled
35 * via file descriptors and a traditional poll / select
36 * implementation on the platform adaptation.
38 * For LwIP, event readiness notification is handled via events /
39 * messages and platform- and system-specific hooks for the event
46 #ifndef __STDC_LIMIT_MACROS
47 #define __STDC_LIMIT_MACROS
50 #include <inet/InetConfig.h>
52 #include <inet/IANAConstants.h>
53 #include <inet/IPAddress.h>
54 #include <inet/IPPrefix.h>
55 #include <inet/InetError.h>
56 #include <inet/InetInterface.h>
57 #include <inet/InetLayerBasis.h>
58 #include <inet/InetLayerEvents.h>
60 #if INET_CONFIG_ENABLE_DNS_RESOLVER
61 #include <inet/DNSResolver.h>
62 #endif // INET_CONFIG_ENABLE_DNS_RESOLVER
64 #if INET_CONFIG_ENABLE_RAW_ENDPOINT
65 #include <inet/RawEndPoint.h>
66 #endif // INET_CONFIG_ENABLE_RAW_ENDPOINT
68 #if INET_CONFIG_ENABLE_TCP_ENDPOINT
69 #include <inet/TCPEndPoint.h>
70 #endif // INET_CONFIG_ENABLE_TCP_ENDPOINT
72 #if INET_CONFIG_ENABLE_UDP_ENDPOINT
73 #include <inet/UDPEndPoint.h>
74 #endif // INET_CONFIG_ENABLE_UDP_ENDPOINT
76 #if CHIP_SYSTEM_CONFIG_USE_SOCKETS
77 #if INET_CONFIG_ENABLE_DNS_RESOLVER && INET_CONFIG_ENABLE_ASYNC_DNS_SOCKETS
78 #include <inet/AsyncDNSResolverSockets.h>
79 #endif // INET_CONFIG_ENABLE_DNS_RESOLVER && INET_CONFIG_ENABLE_ASYNC_DNS_SOCKETS
80 #endif // CHIP_SYSTEM_CONFIG_USE_SOCKETS
82 #include <system/SystemLayer.h>
83 #include <system/SystemStats.h>
85 #include <support/DLLUtil.h>
87 #if INET_CONFIG_MAX_DROPPABLE_EVENTS
89 #if CHIP_SYSTEM_CONFIG_POSIX_LOCKING
91 #include <semaphore.h>
92 #endif // CHIP_SYSTEM_CONFIG_POSIX_LOCKING
94 #if CHIP_SYSTEM_CONFIG_FREERTOS_LOCKING
97 #endif // CHIP_SYSTEM_CONFIG_FREERTOS_LOCKING
99 #endif // INET_CONFIG_MAX_DROPPABLE_EVENTS
106 // Forward Declarations
111 namespace InetLayer {
113 extern INET_ERROR WillInit(Inet::InetLayer * aLayer, void * aContext);
114 extern void DidInit(Inet::InetLayer * aLayer, void * aContext, INET_ERROR anError);
116 extern INET_ERROR WillShutdown(Inet::InetLayer * aLayer, void * aContext);
117 extern void DidShutdown(Inet::InetLayer * aLayer, void * aContext, INET_ERROR anError);
119 } // namespace InetLayer
120 } // namespace Platform
126 * This provides access to Internet services, including timers,
127 * Domain Name System (DNS) resolution, TCP network transport, UDP
128 * network transport, and raw network transport, for a single
131 * For BSD/POSIX Sockets, event readiness notification is handled
132 * via file descriptors and a traditional poll / select
133 * implementation on the platform adaptation.
135 * For LwIP, event readiness notification is handle via events /
136 * messages and platform- and system-specific hooks for the event /
140 class DLL_EXPORT InetLayer
142 #if INET_CONFIG_ENABLE_DNS_RESOLVER
143 friend class DNSResolver;
144 #endif // INET_CONFIG_ENABLE_DNS_RESOLVER
146 #if INET_CONFIG_ENABLE_RAW_ENDPOINT
147 friend class RawEndPoint;
148 #endif // INET_CONFIG_ENABLE_RAW_ENDPOINT
150 #if INET_CONFIG_ENABLE_TCP_ENDPOINT
151 friend class TCPEndPoint;
152 #endif // INET_CONFIG_ENABLE_TCP_ENDPOINT
154 #if INET_CONFIG_ENABLE_UDP_ENDPOINT
155 friend class UDPEndPoint;
156 #endif // INET_CONFIG_ENABLE_UDP_ENDPOINT
158 #if CHIP_SYSTEM_CONFIG_USE_SOCKETS
159 #if INET_CONFIG_ENABLE_DNS_RESOLVER && INET_CONFIG_ENABLE_ASYNC_DNS_SOCKETS
160 friend class AsyncDNSResolverSockets;
161 #endif // INET_CONFIG_ENABLE_DNS_RESOLVER && INET_CONFIG_ENABLE_ASYNC_DNS_SOCKETS
162 #endif // CHIP_SYSTEM_CONFIG_USE_SOCKETS
166 * The current state of the InetLayer object.
170 kState_NotInitialized = 0, /**< Not initialized state. */
171 kState_Initialized = 1, /**< Initialized state. */
172 kState_ShutdownInProgress = 2, /**< State where Shutdown has been triggered. */
173 } State; /**< [READ-ONLY] Current state. */
177 INET_ERROR Init(chip::System::Layer & aSystemLayer, void * aContext);
178 INET_ERROR Shutdown();
180 chip::System::Layer * SystemLayer() const;
184 #if INET_CONFIG_ENABLE_RAW_ENDPOINT
185 INET_ERROR NewRawEndPoint(IPVersion ipVer, IPProtocol ipProto, RawEndPoint ** retEndPoint);
186 #endif // INET_CONFIG_ENABLE_RAW_ENDPOINT
188 #if INET_CONFIG_ENABLE_TCP_ENDPOINT
189 INET_ERROR NewTCPEndPoint(TCPEndPoint ** retEndPoint);
190 #endif // INET_CONFIG_ENABLE_TCP_ENDPOINT
192 #if INET_CONFIG_ENABLE_UDP_ENDPOINT
193 INET_ERROR NewUDPEndPoint(UDPEndPoint ** retEndPoint);
194 #endif // INET_CONFIG_ENABLE_UDP_ENDPOINT
198 #if INET_CONFIG_ENABLE_DNS_RESOLVER
200 typedef DNSResolver::OnResolveCompleteFunct DNSResolveCompleteFunct;
202 INET_ERROR ResolveHostAddress(const char * hostName, uint16_t hostNameLen, uint8_t options, uint8_t maxAddrs,
203 IPAddress * addrArray, DNSResolveCompleteFunct onComplete, void * appState);
204 INET_ERROR ResolveHostAddress(const char * hostName, uint16_t hostNameLen, uint8_t maxAddrs, IPAddress * addrArray,
205 DNSResolveCompleteFunct onComplete, void * appState);
206 INET_ERROR ResolveHostAddress(const char * hostName, uint8_t maxAddrs, IPAddress * addrArray,
207 DNSResolveCompleteFunct onComplete, void * appState);
208 void CancelResolveHostAddress(DNSResolveCompleteFunct onComplete, void * appState);
210 #endif // INET_CONFIG_ENABLE_DNS_RESOLVER
212 INET_ERROR GetInterfaceFromAddr(const IPAddress & addr, InterfaceId & intfId);
214 INET_ERROR GetLinkLocalAddr(InterfaceId link, IPAddress * llAddr);
215 bool MatchLocalIPv6Subnet(const IPAddress & addr);
217 #if CHIP_SYSTEM_CONFIG_USE_SOCKETS
218 void PrepareSelect(int & nfds, fd_set * readfds, fd_set * writefds, fd_set * exceptfds, struct timeval & sleepTime);
219 void HandleSelectResult(int selectRes, fd_set * readfds, fd_set * writefds, fd_set * exceptfds);
220 #endif // CHIP_SYSTEM_CONFIG_USE_SOCKETS
222 static void UpdateSnapshot(chip::System::Stats::Snapshot & aSnapshot);
224 void * GetPlatformData();
225 void SetPlatformData(void * aPlatformData);
227 #if CHIP_SYSTEM_CONFIG_USE_LWIP
228 static chip::System::Error HandleInetLayerEvent(chip::System::Object & aTarget, chip::System::EventType aEventType,
229 uintptr_t aArgument);
231 static chip::System::LwIPEventHandlerDelegate sInetEventHandlerDelegate;
233 // In some implementations, there may be a shared event / message
234 // queue for the InetLayer used by other system events / messages.
236 // If the length of that queue is considerably longer than the
237 // number of packet buffers available, it may lead to buffer
238 // exhaustion. As a result, using the queue itself to implement
239 // backpressure is insufficient, and we need an external mechanism
240 // to prevent buffer starvation in the rest of the system and
241 // getting into deadlock situations.
243 // For both UDP and raw network transport traffic we can easily
244 // drop incoming packets without impacting the correctness of
245 // higher level protocols.
247 #if INET_CONFIG_MAX_DROPPABLE_EVENTS
248 inline static bool IsDroppableEvent(chip::System::EventType type)
251 #if INET_CONFIG_ENABLE_UDP_ENDPOINT
252 type == kInetEvent_UDPDataReceived ||
253 #endif // INET_CONFIG_ENABLE_UDP_ENDPOINT
254 #if INET_CONFIG_ENABLE_RAW_ENDPOINT
255 type == kInetEvent_RawDataReceived ||
256 #endif // INET_CONFIG_ENABLE_RAW_ENDPOINT
260 INET_ERROR InitQueueLimiter(void);
261 bool CanEnqueueDroppableEvent(void);
262 void DroppableEventDequeued(void);
264 #if CHIP_SYSTEM_CONFIG_NO_LOCKING
265 volatile int32_t mDroppableEvents;
266 #elif CHIP_SYSTEM_CONFIG_POSIX_LOCKING
267 sem_t mDroppableEvents;
268 #elif CHIP_SYSTEM_CONFIG_FREERTOS_LOCKING
269 #if (configSUPPORT_STATIC_ALLOCATION == 1)
270 StaticSemaphore_t mDroppableEventsObj;
271 #endif // (configSUPPORT_STATIC_ALLOCATION == 1)
272 SemaphoreHandle_t mDroppableEvents;
273 #endif // CHIP_SYSTEM_CONFIG_FREERTOS_LOCKING
275 #else // !INET_CONFIG_MAX_DROPPABLE_EVENTS
277 inline static bool IsDroppableEvent(chip::System::EventType aType) { return false; }
279 inline INET_ERROR InitQueueLimiter(void) { return INET_NO_ERROR; }
280 inline bool CanEnqueueDroppableEvent(void) { return true; }
281 inline void DroppableEventDequeued(void) { return; }
282 #endif // !INET_CONFIG_MAX_DROPPABLE_EVENTS
283 #endif // CHIP_SYSTEM_CONFIG_USE_LWIP
285 #if INET_CONFIG_ENABLE_TCP_ENDPOINT && INET_TCP_IDLE_CHECK_INTERVAL > 0
286 static void HandleTCPInactivityTimer(chip::System::Layer * aSystemLayer, void * aAppState, chip::System::Error aError);
287 #endif // INET_CONFIG_ENABLE_TCP_ENDPOINT && INET_TCP_IDLE_CHECK_INTERVAL > 0
291 void * mPlatformData;
292 chip::System::Layer * mSystemLayer;
294 #if CHIP_SYSTEM_CONFIG_USE_SOCKETS
295 #if INET_CONFIG_ENABLE_DNS_RESOLVER && INET_CONFIG_ENABLE_ASYNC_DNS_SOCKETS
296 AsyncDNSResolverSockets mAsyncDNSResolver;
297 #endif // INET_CONFIG_ENABLE_DNS_RESOLVER && INET_CONFIG_ENABLE_ASYNC_DNS_SOCKETS
299 #endif // CHIP_SYSTEM_CONFIG_USE_SOCKETS
301 friend INET_ERROR Platform::InetLayer::WillInit(Inet::InetLayer * aLayer, void * aContext);
302 friend void Platform::InetLayer::DidInit(Inet::InetLayer * aLayer, void * aContext, INET_ERROR anError);
304 friend INET_ERROR Platform::InetLayer::WillShutdown(Inet::InetLayer * aLayer, void * aContext);
305 friend void Platform::InetLayer::DidShutdown(Inet::InetLayer * aLayer, void * aContext, INET_ERROR anError);
307 bool IsIdleTimerRunning();
310 inline chip::System::Layer * InetLayer::SystemLayer() const
316 * @class IPPacketInfo
319 * Information about an incoming/outgoing message/connection.
322 * Do not alter the contents of this class without first reading and understanding
323 * the code/comments in IPEndPointBasis::GetPacketInfo().
328 IPAddress SrcAddress; /**< The source IPAddress in the packet. */
329 IPAddress DestAddress; /**< The destination IPAddress in the packet. */
330 InterfaceId Interface; /**< The interface identifier for the connection. */
331 uint16_t SrcPort; /**< The source port in the packet. */
332 uint16_t DestPort; /**< The destination port in the packet. */
337 extern INET_ERROR ParseHostAndPort(const char * aString, uint16_t aStringLen, const char *& aHost, uint16_t & aHostLen,
340 extern INET_ERROR ParseHostPortAndInterface(const char * aString, uint16_t aStringLen, const char *& aHost, uint16_t & aHostLen,
341 uint16_t & aPort, const char *& aInterface, uint16_t & aInterfaceLen);