Fix for x86_64 build fail
[platform/upstream/connectedhomeip.git] / src / inet / InetLayer.h
1 /*
2  *
3  *    Copyright (c) 2020 Project CHIP Authors
4  *    Copyright (c) 2013-2017 Nest Labs, Inc.
5  *
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
9  *
10  *        http://www.apache.org/licenses/LICENSE-2.0
11  *
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.
17  */
18
19 /**
20  *    @file
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.
25  *
26  *      Major abstractions provided are:
27  *
28  *        * Timers
29  *        * Domain Name System (DNS) resolution
30  *        * TCP network transport
31  *        * UDP network transport
32  *        * Raw network transport
33  *
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.
37  *
38  *      For LwIP, event readiness notification is handled via events /
39  *      messages and platform- and system-specific hooks for the event
40  *      / message system.
41  *
42  */
43
44 #pragma once
45
46 #ifndef __STDC_LIMIT_MACROS
47 #define __STDC_LIMIT_MACROS
48 #endif
49
50 #include <inet/InetConfig.h>
51
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>
59
60 #if INET_CONFIG_ENABLE_DNS_RESOLVER
61 #include <inet/DNSResolver.h>
62 #endif // INET_CONFIG_ENABLE_DNS_RESOLVER
63
64 #if INET_CONFIG_ENABLE_RAW_ENDPOINT
65 #include <inet/RawEndPoint.h>
66 #endif // INET_CONFIG_ENABLE_RAW_ENDPOINT
67
68 #if INET_CONFIG_ENABLE_TCP_ENDPOINT
69 #include <inet/TCPEndPoint.h>
70 #endif // INET_CONFIG_ENABLE_TCP_ENDPOINT
71
72 #if INET_CONFIG_ENABLE_UDP_ENDPOINT
73 #include <inet/UDPEndPoint.h>
74 #endif // INET_CONFIG_ENABLE_UDP_ENDPOINT
75
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
81
82 #include <system/SystemLayer.h>
83 #include <system/SystemStats.h>
84
85 #include <support/DLLUtil.h>
86
87 #if INET_CONFIG_MAX_DROPPABLE_EVENTS
88
89 #if CHIP_SYSTEM_CONFIG_POSIX_LOCKING
90 #include <pthread.h>
91 #include <semaphore.h>
92 #endif // CHIP_SYSTEM_CONFIG_POSIX_LOCKING
93
94 #if CHIP_SYSTEM_CONFIG_FREERTOS_LOCKING
95 #include <FreeRTOS.h>
96 #include <semphr.h>
97 #endif // CHIP_SYSTEM_CONFIG_FREERTOS_LOCKING
98
99 #endif // INET_CONFIG_MAX_DROPPABLE_EVENTS
100
101 #include <stdint.h>
102
103 namespace chip {
104 namespace Inet {
105
106 // Forward Declarations
107
108 class InetLayer;
109
110 namespace Platform {
111 namespace InetLayer {
112
113 extern INET_ERROR WillInit(Inet::InetLayer * aLayer, void * aContext);
114 extern void DidInit(Inet::InetLayer * aLayer, void * aContext, INET_ERROR anError);
115
116 extern INET_ERROR WillShutdown(Inet::InetLayer * aLayer, void * aContext);
117 extern void DidShutdown(Inet::InetLayer * aLayer, void * aContext, INET_ERROR anError);
118
119 } // namespace InetLayer
120 } // namespace Platform
121
122 /**
123  *  @class InetLayer
124  *
125  *  @brief
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
129  *    thread.
130  *
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.
134  *
135  *    For LwIP, event readiness notification is handle via events /
136  *    messages and platform- and system-specific hooks for the event /
137  *    message system.
138  *
139  */
140 class DLL_EXPORT InetLayer
141 {
142 #if INET_CONFIG_ENABLE_DNS_RESOLVER
143     friend class DNSResolver;
144 #endif // INET_CONFIG_ENABLE_DNS_RESOLVER
145
146 #if INET_CONFIG_ENABLE_RAW_ENDPOINT
147     friend class RawEndPoint;
148 #endif // INET_CONFIG_ENABLE_RAW_ENDPOINT
149
150 #if INET_CONFIG_ENABLE_TCP_ENDPOINT
151     friend class TCPEndPoint;
152 #endif // INET_CONFIG_ENABLE_TCP_ENDPOINT
153
154 #if INET_CONFIG_ENABLE_UDP_ENDPOINT
155     friend class UDPEndPoint;
156 #endif // INET_CONFIG_ENABLE_UDP_ENDPOINT
157
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
163
164 public:
165     /**
166      *  The current state of the InetLayer object.
167      *
168      */
169     volatile enum {
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. */
174
175     InetLayer();
176
177     INET_ERROR Init(chip::System::Layer & aSystemLayer, void * aContext);
178     INET_ERROR Shutdown();
179
180     chip::System::Layer * SystemLayer() const;
181
182     // End Points
183
184 #if INET_CONFIG_ENABLE_RAW_ENDPOINT
185     INET_ERROR NewRawEndPoint(IPVersion ipVer, IPProtocol ipProto, RawEndPoint ** retEndPoint);
186 #endif // INET_CONFIG_ENABLE_RAW_ENDPOINT
187
188 #if INET_CONFIG_ENABLE_TCP_ENDPOINT
189     INET_ERROR NewTCPEndPoint(TCPEndPoint ** retEndPoint);
190 #endif // INET_CONFIG_ENABLE_TCP_ENDPOINT
191
192 #if INET_CONFIG_ENABLE_UDP_ENDPOINT
193     INET_ERROR NewUDPEndPoint(UDPEndPoint ** retEndPoint);
194 #endif // INET_CONFIG_ENABLE_UDP_ENDPOINT
195
196     // DNS Resolution
197
198 #if INET_CONFIG_ENABLE_DNS_RESOLVER
199
200     typedef DNSResolver::OnResolveCompleteFunct DNSResolveCompleteFunct;
201
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);
209
210 #endif // INET_CONFIG_ENABLE_DNS_RESOLVER
211
212     INET_ERROR GetInterfaceFromAddr(const IPAddress & addr, InterfaceId & intfId);
213
214     INET_ERROR GetLinkLocalAddr(InterfaceId link, IPAddress * llAddr);
215     bool MatchLocalIPv6Subnet(const IPAddress & addr);
216
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
221
222     static void UpdateSnapshot(chip::System::Stats::Snapshot & aSnapshot);
223
224     void * GetPlatformData();
225     void SetPlatformData(void * aPlatformData);
226
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);
230
231     static chip::System::LwIPEventHandlerDelegate sInetEventHandlerDelegate;
232
233     // In some implementations, there may be a shared event / message
234     // queue for the InetLayer used by other system events / messages.
235     //
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.
242
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.
246
247 #if INET_CONFIG_MAX_DROPPABLE_EVENTS
248     inline static bool IsDroppableEvent(chip::System::EventType type)
249     {
250         return
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
257             false;
258     }
259
260     INET_ERROR InitQueueLimiter(void);
261     bool CanEnqueueDroppableEvent(void);
262     void DroppableEventDequeued(void);
263
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
274
275 #else  // !INET_CONFIG_MAX_DROPPABLE_EVENTS
276
277     inline static bool IsDroppableEvent(chip::System::EventType aType) { return false; }
278
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
284
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
288
289 private:
290     void * mContext;
291     void * mPlatformData;
292     chip::System::Layer * mSystemLayer;
293
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
298
299 #endif // CHIP_SYSTEM_CONFIG_USE_SOCKETS
300
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);
303
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);
306
307     bool IsIdleTimerRunning();
308 };
309
310 inline chip::System::Layer * InetLayer::SystemLayer() const
311 {
312     return mSystemLayer;
313 }
314
315 /**
316  *  @class IPPacketInfo
317  *
318  *  @brief
319  *     Information about an incoming/outgoing message/connection.
320  *
321  *   @warning
322  *     Do not alter the contents of this class without first reading and understanding
323  *     the code/comments in IPEndPointBasis::GetPacketInfo().
324  */
325 class IPPacketInfo
326 {
327 public:
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. */
333
334     void Clear();
335 };
336
337 extern INET_ERROR ParseHostAndPort(const char * aString, uint16_t aStringLen, const char *& aHost, uint16_t & aHostLen,
338                                    uint16_t & aPort);
339
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);
342
343 } // namespace Inet
344 } // namespace chip