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 /**
452 * @brief Get the TCP connection endpoint information.
453 *
454 * @param context Network context
455 * @param local TCP connection local socket information is copied here
456 * @param peer TCP connection peer socket information is copied here
457 * @param addrlen Size of the sockaddr struct. Copied size is returned.
458 *
459 * @return <0 if there was an error, 0 if ok
460 */
461 int net_tcp_endpoint_copy(struct net_context *ctx,
462 struct sockaddr *local,
463 struct sockaddr *peer,
464 socklen_t *addrlen);
465
466 #ifdef __cplusplus
467 }
468 #endif
469
470 #endif /* __TCP_INTERNAL_H */
471