1 /** @file
2  @brief TCP data handler
3 
4  This is not to be included by the application.
5  */
6 
7 /*
8  * Copyright (c) 2016 Intel Corporation
9  *
10  * SPDX-License-Identifier: Apache-2.0
11  */
12 
13 #ifndef __TCP_INTERNAL_H
14 #define __TCP_INTERNAL_H
15 
16 #include <zephyr/types.h>
17 #include <zephyr/random/random.h>
18 
19 #include <zephyr/net/net_core.h>
20 #include <zephyr/net/net_ip.h>
21 #include <zephyr/net/net_pkt.h>
22 #include <zephyr/net/net_context.h>
23 
24 #include "connection.h"
25 
26 #ifdef __cplusplus
27 extern "C" {
28 #endif
29 
30 
31 #include "tcp_private.h"
32 
33 enum tcp_conn_option {
34 	TCP_OPT_NODELAY	= 1,
35 	TCP_OPT_KEEPALIVE = 2,
36 	TCP_OPT_KEEPIDLE = 3,
37 	TCP_OPT_KEEPINTVL = 4,
38 	TCP_OPT_KEEPCNT = 5,
39 };
40 
41 /**
42  * @brief Calculates and returns the MSS for a given TCP context
43  *
44  * @param tcp TCP context
45  *
46  * @return Maximum Segment Size
47  */
48 #if defined(CONFIG_NET_NATIVE_TCP)
49 uint16_t net_tcp_get_supported_mss(const struct tcp *conn);
50 #else
net_tcp_get_supported_mss(const struct tcp * conn)51 static inline uint16_t net_tcp_get_supported_mss(const struct tcp *conn)
52 {
53 	ARG_UNUSED(conn);
54 	return 0;
55 }
56 #endif
57 
58 const char *net_tcp_state_str(enum tcp_state state);
59 
60 /**
61  * @brief Obtains the state for a TCP context
62  *
63  * @param tcp TCP context
64  */
65 #if defined(CONFIG_NET_NATIVE_TCP)
net_tcp_get_state(const struct tcp * conn)66 static inline enum tcp_state net_tcp_get_state(const struct tcp *conn)
67 {
68 	return conn->state;
69 }
70 #else
net_tcp_get_state(const struct tcp * conn)71 static inline enum tcp_state net_tcp_get_state(const struct tcp *conn)
72 {
73 	ARG_UNUSED(conn);
74 	return TCP_CLOSED;
75 }
76 #endif
77 
78 /**
79  * @brief Go through all the TCP connections and call callback
80  * for each of them.
81  *
82  * @param cb User supplied callback function to call.
83  * @param user_data User specified data.
84  */
85 #if defined(CONFIG_NET_NATIVE_TCP)
86 void net_tcp_foreach(net_tcp_cb_t cb, void *user_data);
87 #else
net_tcp_foreach(net_tcp_cb_t cb,void * user_data)88 static inline void net_tcp_foreach(net_tcp_cb_t cb, void *user_data)
89 {
90 	ARG_UNUSED(cb);
91 	ARG_UNUSED(user_data);
92 }
93 #endif
94 
95 /**
96  * @brief Initialize TCP parts of a context
97  *
98  * @param context Network context
99  *
100  * @return 0 if successful, < 0 on error
101  */
102 #if defined(CONFIG_NET_NATIVE_TCP)
103 int net_tcp_get(struct net_context *context);
104 #else
net_tcp_get(struct net_context * context)105 static inline int net_tcp_get(struct net_context *context)
106 {
107 	ARG_UNUSED(context);
108 
109 	return -EPROTONOSUPPORT;
110 }
111 #endif
112 
113 /**
114  * @brief Connect TCP connection
115  *
116  * @param context Network context
117  * @param addr Remote address
118  * @param laddr Local address
119  * @param rport Remote port
120  * @param lport Local port
121  * @param timeout Connect timeout
122  * @param cb Connect callback
123  * @param user_data Connect callback user data
124  *
125  * @return 0 on success, < 0 on error
126  */
127 #if defined(CONFIG_NET_NATIVE_TCP)
128 int net_tcp_connect(struct net_context *context,
129 		    const struct sockaddr *addr,
130 		    struct sockaddr *laddr,
131 		    uint16_t rport,
132 		    uint16_t lport,
133 		    k_timeout_t timeout,
134 		    net_context_connect_cb_t cb,
135 		    void *user_data);
136 #else
net_tcp_connect(struct net_context * context,const struct sockaddr * addr,struct sockaddr * laddr,uint16_t rport,uint16_t lport,k_timeout_t timeout,net_context_connect_cb_t cb,void * user_data)137 static inline int net_tcp_connect(struct net_context *context,
138 				  const struct sockaddr *addr,
139 				  struct sockaddr *laddr,
140 				  uint16_t rport, uint16_t lport,
141 				  k_timeout_t timeout,
142 				  net_context_connect_cb_t cb, void *user_data)
143 {
144 	ARG_UNUSED(context);
145 	ARG_UNUSED(addr);
146 	ARG_UNUSED(laddr);
147 	ARG_UNUSED(rport);
148 	ARG_UNUSED(lport);
149 	ARG_UNUSED(cb);
150 	ARG_UNUSED(user_data);
151 
152 	return -EPROTONOSUPPORT;
153 }
154 #endif
155 
156 /**
157  * @brief Set TCP socket into listening state
158  *
159  * @param context Network context
160  *
161  * @return 0 if successful, -EOPNOTSUPP if the context was not for TCP,
162  *         -EPROTONOSUPPORT if TCP is not supported
163  */
164 #if defined(CONFIG_NET_NATIVE_TCP)
165 int net_tcp_listen(struct net_context *context);
166 #else
net_tcp_listen(struct net_context * context)167 static inline int net_tcp_listen(struct net_context *context)
168 {
169 	ARG_UNUSED(context);
170 
171 	return -EPROTONOSUPPORT;
172 }
173 #endif
174 
175 /**
176  * @brief Accept TCP connection
177  *
178  * @param context Network context
179  * @param cb Accept callback
180  * @param user_data Accept callback user data
181  *
182  * @return 0 on success, < 0 on error
183  */
184 #if defined(CONFIG_NET_NATIVE_TCP)
185 int net_tcp_accept(struct net_context *context, net_tcp_accept_cb_t cb,
186 		   void *user_data);
187 #else
net_tcp_accept(struct net_context * context,net_tcp_accept_cb_t cb,void * user_data)188 static inline int net_tcp_accept(struct net_context *context,
189 				 net_tcp_accept_cb_t cb, void *user_data)
190 {
191 	ARG_UNUSED(context);
192 	ARG_UNUSED(cb);
193 	ARG_UNUSED(user_data);
194 
195 	return -EPROTONOSUPPORT;
196 }
197 #endif
198 
199 /**
200  * @brief Send available queued data over TCP connection
201  *
202  * @param context TCP context
203  * @param cb TCP callback function
204  * @param user_data User specified data
205  *
206  * @return 0 if ok, < 0 if error
207  */
208 #if defined(CONFIG_NET_NATIVE_TCP)
209 int net_tcp_send_data(struct net_context *context, net_context_send_cb_t cb,
210 		      void *user_data);
211 #else
net_tcp_send_data(struct net_context * context,net_context_send_cb_t cb,void * user_data)212 static inline int net_tcp_send_data(struct net_context *context,
213 				    net_context_send_cb_t cb,
214 				    void *user_data)
215 {
216 	ARG_UNUSED(context);
217 	ARG_UNUSED(cb);
218 	ARG_UNUSED(user_data);
219 
220 	return 0;
221 }
222 #endif
223 
224 /**
225  * @brief TCP receive function
226  *
227  * @param context Network context
228  * @param cb TCP receive callback function
229  * @param user_data TCP receive callback user data
230  *
231  * @return 0 if no error, < 0 in case of error
232  */
233 #if defined(CONFIG_NET_NATIVE_TCP)
234 int net_tcp_recv(struct net_context *context, net_context_recv_cb_t cb,
235 		 void *user_data);
236 #else
net_tcp_recv(struct net_context * context,net_context_recv_cb_t cb,void * user_data)237 static inline int net_tcp_recv(struct net_context *context,
238 			       net_context_recv_cb_t cb, void *user_data)
239 {
240 	ARG_UNUSED(context);
241 	ARG_UNUSED(cb);
242 	ARG_UNUSED(user_data);
243 
244 	return -EPROTOTYPE;
245 }
246 #endif
247 
248 /**
249  * @brief Finalize TCP packet
250  *
251  * @param pkt Network packet
252  *
253  * @return 0 on success, negative errno otherwise.
254  */
255 #if defined(CONFIG_NET_NATIVE_TCP)
256 int net_tcp_finalize(struct net_pkt *pkt, bool force_chksum);
257 #else
net_tcp_finalize(struct net_pkt * pkt,bool force_chksum)258 static inline int net_tcp_finalize(struct net_pkt *pkt, bool force_chksum)
259 {
260 	ARG_UNUSED(pkt);
261 	ARG_UNUSED(force_chksum);
262 	return 0;
263 }
264 #endif
265 
266 /**
267  * @brief Get pointer to TCP header in net_pkt
268  *
269  * @param pkt Network packet
270  * @param tcp_access Helper variable for accessing TCP header
271  *
272  * @return TCP header on success, NULL on error
273  */
274 #if defined(CONFIG_NET_NATIVE_TCP)
275 struct net_tcp_hdr *net_tcp_input(struct net_pkt *pkt,
276 				  struct net_pkt_data_access *tcp_access);
277 #else
278 static inline
net_tcp_input(struct net_pkt * pkt,struct net_pkt_data_access * tcp_access)279 struct net_tcp_hdr *net_tcp_input(struct net_pkt *pkt,
280 				  struct net_pkt_data_access *tcp_access)
281 {
282 	ARG_UNUSED(pkt);
283 	ARG_UNUSED(tcp_access);
284 
285 	return NULL;
286 }
287 #endif
288 
289 /**
290  * @brief Enqueue data for transmission
291  *
292  * @param context	Network context
293  * @param data		Pointer to the data
294  * @param len		Number of bytes
295  * @param msg		Data for a vector array operation
296  *
297  * @return 0 if ok, < 0 if error
298  */
299 #if defined(CONFIG_NET_NATIVE_TCP)
300 int net_tcp_queue(struct net_context *context, const void *data, size_t len,
301 		  const struct msghdr *msg);
302 #else
net_tcp_queue(struct net_context * context,const void * data,size_t len,const struct msghdr * msg)303 static inline int net_tcp_queue(struct net_context *context, const void *data,
304 				size_t len, const struct msghdr *msg)
305 {
306 	ARG_UNUSED(context);
307 	ARG_UNUSED(data);
308 	ARG_UNUSED(len);
309 	ARG_UNUSED(msg);
310 
311 	return -EPROTONOSUPPORT;
312 }
313 #endif
314 
315 /**
316  * @brief Update TCP receive window
317  *
318  * @param context Network context
319  * @param delta Receive window delta
320  *
321  * @return 0 on success, -EPROTOTYPE if there is no TCP context, -EINVAL
322  *         if the receive window delta is out of bounds, -EPROTONOSUPPORT
323  *         if TCP is not supported
324  */
325 #if defined(CONFIG_NET_NATIVE_TCP)
326 int net_tcp_update_recv_wnd(struct net_context *context, int32_t delta);
327 #else
net_tcp_update_recv_wnd(struct net_context * context,int32_t delta)328 static inline int net_tcp_update_recv_wnd(struct net_context *context,
329 					  int32_t delta)
330 {
331 	ARG_UNUSED(context);
332 	ARG_UNUSED(delta);
333 
334 	return -EPROTONOSUPPORT;
335 }
336 #endif
337 
338 /**
339  * @brief Queue a TCP FIN packet if needed to close the socket
340  *
341  * @param context Network context
342  *
343  * @return 0 on success where a TCP FIN packet has been queued, -ENOTCONN
344  *         in case the socket was not connected or listening, -EOPNOTSUPP
345  *         in case it was not a TCP socket or -EPROTONOSUPPORT if TCP is not
346  *         supported
347  */
348 #if defined(CONFIG_NET_NATIVE_TCP)
349 int net_tcp_put(struct net_context *context);
350 #else
net_tcp_put(struct net_context * context)351 static inline int net_tcp_put(struct net_context *context)
352 {
353 	ARG_UNUSED(context);
354 
355 	return -EPROTONOSUPPORT;
356 }
357 #endif
358 
359 #define NET_TCP_MAX_OPT_SIZE  8
360 
361 #if defined(CONFIG_NET_NATIVE_TCP)
362 void net_tcp_init(void);
363 #else
364 #define net_tcp_init(...)
365 #endif
366 
367 /**
368  * @brief Set tcp specific options of a socket
369  *
370  * @param context Network context
371  *
372  * @return 0 on success, -EINVAL if the value is not allowed
373  */
374 #if defined(CONFIG_NET_NATIVE_TCP)
375 int net_tcp_set_option(struct net_context *context,
376 		       enum tcp_conn_option option,
377 		       const void *value, size_t len);
378 #else
net_tcp_set_option(struct net_context * context,enum tcp_conn_option option,const void * value,size_t len)379 static inline int net_tcp_set_option(struct net_context *context,
380 				     enum tcp_conn_option option,
381 				     const void *value, size_t len)
382 {
383 	ARG_UNUSED(context);
384 	ARG_UNUSED(option);
385 	ARG_UNUSED(value);
386 	ARG_UNUSED(len);
387 
388 	return -EPROTONOSUPPORT;
389 }
390 #endif
391 
392 
393 /**
394  * @brief Obtain tcp specific options of a socket
395  *
396  * @param context Network context
397  *
398  * @return 0 on success
399  */
400 #if defined(CONFIG_NET_NATIVE_TCP)
401 int net_tcp_get_option(struct net_context *context,
402 		       enum tcp_conn_option option,
403 		       void *value, size_t *len);
404 #else
net_tcp_get_option(struct net_context * context,enum tcp_conn_option option,void * value,size_t * len)405 static inline int net_tcp_get_option(struct net_context *context,
406 				     enum tcp_conn_option option,
407 				     void *value, size_t *len)
408 {
409 	ARG_UNUSED(context);
410 	ARG_UNUSED(option);
411 	ARG_UNUSED(value);
412 	ARG_UNUSED(len);
413 
414 	return -EPROTONOSUPPORT;
415 }
416 #endif
417 
418 /**
419  * @brief Obtain a semaphore indicating if transfers are blocked (either due to
420  *        filling TX window or entering retransmission mode).
421  *
422  * @param context Network context
423  *
424  * @return semaphore indicating if transfers are blocked
425  */
426 struct k_sem *net_tcp_tx_sem_get(struct net_context *context);
427 
428 /**
429  * @brief Obtain a semaphore indicating if connection is connected.
430  *
431  * @param context Network context
432  *
433  * @return semaphore indicating if connection is connected
434  */
435 struct k_sem *net_tcp_conn_sem_get(struct net_context *context);
436 
437 /**
438  * @brief Send a TCP RST reply for the received packet w/o associated connection.
439  *
440  * @param pkt TCP packet to reply for.
441  */
442 #if defined(CONFIG_NET_NATIVE_TCP)
443 void net_tcp_reply_rst(struct net_pkt *pkt);
444 #else
net_tcp_reply_rst(struct net_pkt * pkt)445 static inline void net_tcp_reply_rst(struct net_pkt *pkt)
446 {
447 	ARG_UNUSED(pkt);
448 }
449 #endif
450 
451 #ifdef __cplusplus
452 }
453 #endif
454 
455 #endif /* __TCP_INTERNAL_H */
456