1 /*
2 * Copyright (c) 2018-2020 Intel Corporation
3 *
4 * SPDX-License-Identifier: Apache-2.0
5 */
6
7 #include <zephyr/logging/log.h>
8 LOG_MODULE_REGISTER(net_tcp, CONFIG_NET_TCP_LOG_LEVEL);
9
10 #include <stdarg.h>
11 #include <stdio.h>
12 #include <stdlib.h>
13 #include <zephyr/kernel.h>
14 #include <zephyr/random/random.h>
15
16 #if defined(CONFIG_NET_TCP_ISN_RFC6528)
17 #include <psa/crypto.h>
18 #endif
19 #include <zephyr/net/net_pkt.h>
20 #include <zephyr/net/net_context.h>
21 #include <zephyr/net/udp.h>
22 #include "ipv4.h"
23 #include "ipv6.h"
24 #include "connection.h"
25 #include "net_stats.h"
26 #include "net_private.h"
27 #include "tcp_internal.h"
28
29 #define ACK_TIMEOUT_MS tcp_max_timeout_ms
30 #define ACK_TIMEOUT K_MSEC(ACK_TIMEOUT_MS)
31 #define LAST_ACK_TIMEOUT_MS tcp_max_timeout_ms
32 #define LAST_ACK_TIMEOUT K_MSEC(LAST_ACK_TIMEOUT_MS)
33 #define FIN_TIMEOUT K_MSEC(tcp_max_timeout_ms)
34 #define ACK_DELAY K_MSEC(100)
35 #define ZWP_MAX_DELAY_MS 120000
36 #define DUPLICATE_ACK_RETRANSMIT_TRHESHOLD 3
37
38 static int tcp_rto = CONFIG_NET_TCP_INIT_RETRANSMISSION_TIMEOUT;
39 static int tcp_retries = CONFIG_NET_TCP_RETRY_COUNT;
40 static int tcp_max_timeout_ms;
41 static int tcp_rx_window =
42 #if (CONFIG_NET_TCP_MAX_RECV_WINDOW_SIZE != 0)
43 CONFIG_NET_TCP_MAX_RECV_WINDOW_SIZE;
44 #else
45 #if defined(CONFIG_NET_BUF_FIXED_DATA_SIZE)
46 (CONFIG_NET_BUF_RX_COUNT * CONFIG_NET_BUF_DATA_SIZE) / 3;
47 #else
48 CONFIG_NET_PKT_BUF_RX_DATA_POOL_SIZE / 3;
49 #endif /* CONFIG_NET_BUF_FIXED_DATA_SIZE */
50 #endif
51 static int tcp_tx_window =
52 #if (CONFIG_NET_TCP_MAX_SEND_WINDOW_SIZE != 0)
53 CONFIG_NET_TCP_MAX_SEND_WINDOW_SIZE;
54 #else
55 #if defined(CONFIG_NET_BUF_FIXED_DATA_SIZE)
56 (CONFIG_NET_BUF_TX_COUNT * CONFIG_NET_BUF_DATA_SIZE) / 3;
57 #else
58 CONFIG_NET_PKT_BUF_TX_DATA_POOL_SIZE / 3;
59 #endif /* CONFIG_NET_BUF_FIXED_DATA_SIZE */
60 #endif
61 #ifdef CONFIG_NET_TCP_RANDOMIZED_RTO
62 #define TCP_RTO_MS (conn->rto)
63 #else
64 #define TCP_RTO_MS (tcp_rto)
65 #endif
66
67 /* Define the number of MSS sections the congestion window is initialized at */
68 #define TCP_CONGESTION_INITIAL_WIN 1
69 #define TCP_CONGESTION_INITIAL_SSTHRESH 3
70
71 static sys_slist_t tcp_conns = SYS_SLIST_STATIC_INIT(&tcp_conns);
72
73 static K_MUTEX_DEFINE(tcp_lock);
74
75 K_MEM_SLAB_DEFINE_STATIC(tcp_conns_slab, sizeof(struct tcp),
76 CONFIG_NET_MAX_CONTEXTS, 4);
77
78 static struct k_work_q tcp_work_q;
79 static K_KERNEL_STACK_DEFINE(work_q_stack, CONFIG_NET_TCP_WORKQ_STACK_SIZE);
80
81 static enum net_verdict tcp_in(struct tcp *conn, struct net_pkt *pkt);
82 static bool is_destination_local(struct net_pkt *pkt);
83 static void tcp_out(struct tcp *conn, uint8_t flags);
84 static const char *tcp_state_to_str(enum tcp_state state, bool prefix);
85
86 int (*tcp_send_cb)(struct net_pkt *pkt) = NULL;
87 size_t (*tcp_recv_cb)(struct tcp *conn, struct net_pkt *pkt) = NULL;
88
tcp_get_seq(struct net_buf * buf)89 static uint32_t tcp_get_seq(struct net_buf *buf)
90 {
91 return *(uint32_t *)net_buf_user_data(buf);
92 }
93
tcp_set_seq(struct net_buf * buf,uint32_t seq)94 static void tcp_set_seq(struct net_buf *buf, uint32_t seq)
95 {
96 *(uint32_t *)net_buf_user_data(buf) = seq;
97 }
98
tcp_pkt_linearize(struct net_pkt * pkt,size_t pos,size_t len)99 static int tcp_pkt_linearize(struct net_pkt *pkt, size_t pos, size_t len)
100 {
101 struct net_buf *buf, *first = pkt->cursor.buf, *second = first->frags;
102 int ret = 0;
103 size_t len1, len2;
104
105 if (net_pkt_get_len(pkt) < (pos + len)) {
106 NET_ERR("Insufficient packet len=%zd (pos+len=%zu)",
107 net_pkt_get_len(pkt), pos + len);
108 ret = -EINVAL;
109 goto out;
110 }
111
112 buf = net_pkt_get_frag(pkt, len, TCP_PKT_ALLOC_TIMEOUT);
113
114 if (!buf || net_buf_max_len(buf) < len) {
115 if (buf) {
116 net_buf_unref(buf);
117 }
118 ret = -ENOBUFS;
119 goto out;
120 }
121
122 net_buf_linearize(buf->data, net_buf_max_len(buf), pkt->frags, pos, len);
123 net_buf_add(buf, len);
124
125 len1 = first->len - (pkt->cursor.pos - pkt->cursor.buf->data);
126 len2 = len - len1;
127
128 first->len -= len1;
129
130 while (len2) {
131 size_t pull_len = MIN(second->len, len2);
132 struct net_buf *next;
133
134 len2 -= pull_len;
135 net_buf_pull(second, pull_len);
136 next = second->frags;
137 if (second->len == 0) {
138 net_buf_unref(second);
139 }
140 second = next;
141 }
142
143 buf->frags = second;
144 first->frags = buf;
145 out:
146 return ret;
147 }
148
th_get(struct net_pkt * pkt)149 static struct tcphdr *th_get(struct net_pkt *pkt)
150 {
151 size_t ip_len = net_pkt_ip_hdr_len(pkt) + net_pkt_ip_opts_len(pkt);
152 struct tcphdr *th = NULL;
153 again:
154 net_pkt_cursor_init(pkt);
155 net_pkt_set_overwrite(pkt, true);
156
157 if (net_pkt_skip(pkt, ip_len) != 0) {
158 goto out;
159 }
160
161 if (!net_pkt_is_contiguous(pkt, sizeof(*th))) {
162 if (tcp_pkt_linearize(pkt, ip_len, sizeof(*th)) < 0) {
163 goto out;
164 }
165
166 goto again;
167 }
168
169 th = net_pkt_cursor_get_pos(pkt);
170 out:
171 return th;
172 }
173
tcp_endpoint_len(sa_family_t af)174 static size_t tcp_endpoint_len(sa_family_t af)
175 {
176 return (af == AF_INET) ? sizeof(struct sockaddr_in) :
177 sizeof(struct sockaddr_in6);
178 }
179
tcp_endpoint_set(union tcp_endpoint * ep,struct net_pkt * pkt,enum pkt_addr src)180 static int tcp_endpoint_set(union tcp_endpoint *ep, struct net_pkt *pkt,
181 enum pkt_addr src)
182 {
183 int ret = 0;
184
185 switch (net_pkt_family(pkt)) {
186 case AF_INET:
187 if (IS_ENABLED(CONFIG_NET_IPV4)) {
188 struct net_ipv4_hdr *ip = NET_IPV4_HDR(pkt);
189 struct tcphdr *th;
190
191 th = th_get(pkt);
192 if (!th) {
193 return -ENOBUFS;
194 }
195
196 memset(ep, 0, sizeof(*ep));
197
198 ep->sin.sin_port = src == TCP_EP_SRC ? th_sport(th) :
199 th_dport(th);
200 net_ipv4_addr_copy_raw((uint8_t *)&ep->sin.sin_addr,
201 src == TCP_EP_SRC ?
202 ip->src : ip->dst);
203 ep->sa.sa_family = AF_INET;
204 } else {
205 ret = -EINVAL;
206 }
207
208 break;
209
210 case AF_INET6:
211 if (IS_ENABLED(CONFIG_NET_IPV6)) {
212 struct net_ipv6_hdr *ip = NET_IPV6_HDR(pkt);
213 struct tcphdr *th;
214
215 th = th_get(pkt);
216 if (!th) {
217 return -ENOBUFS;
218 }
219
220 memset(ep, 0, sizeof(*ep));
221
222 ep->sin6.sin6_port = src == TCP_EP_SRC ? th_sport(th) :
223 th_dport(th);
224 net_ipv6_addr_copy_raw((uint8_t *)&ep->sin6.sin6_addr,
225 src == TCP_EP_SRC ?
226 ip->src : ip->dst);
227 ep->sa.sa_family = AF_INET6;
228 } else {
229 ret = -EINVAL;
230 }
231
232 break;
233
234 default:
235 NET_ERR("Unknown address family: %hu", net_pkt_family(pkt));
236 ret = -EINVAL;
237 }
238
239 return ret;
240 }
241
net_tcp_endpoint_copy(struct net_context * ctx,struct sockaddr * local,struct sockaddr * peer,socklen_t * addrlen)242 int net_tcp_endpoint_copy(struct net_context *ctx,
243 struct sockaddr *local,
244 struct sockaddr *peer,
245 socklen_t *addrlen)
246 {
247 const struct tcp *conn = ctx->tcp;
248 socklen_t newlen = ctx->local.family == AF_INET ?
249 sizeof(struct sockaddr_in) :
250 sizeof(struct sockaddr_in6);
251
252 if (local != NULL) {
253 /* If we are connected, then get the address we are actually
254 * using, otherwise get the address we are bound as these might
255 * be different if we are bound to any address.
256 */
257 if (conn->state < TCP_ESTABLISHED) {
258 if (IS_ENABLED(CONFIG_NET_IPV4) && ctx->local.family == AF_INET) {
259 memcpy(&net_sin(local)->sin_addr,
260 net_sin_ptr(&ctx->local)->sin_addr,
261 sizeof(struct in_addr));
262 net_sin(local)->sin_port = net_sin_ptr(&ctx->local)->sin_port;
263 net_sin(local)->sin_family = AF_INET;
264 } else if (IS_ENABLED(CONFIG_NET_IPV4) && ctx->local.family == AF_INET6) {
265 memcpy(&net_sin6(local)->sin6_addr,
266 net_sin6_ptr(&ctx->local)->sin6_addr,
267 sizeof(struct in6_addr));
268 net_sin6(local)->sin6_port = net_sin6_ptr(&ctx->local)->sin6_port;
269 net_sin6(local)->sin6_family = AF_INET6;
270 net_sin6(local)->sin6_scope_id =
271 net_sin6_ptr(&ctx->local)->sin6_scope_id;
272 } else {
273 return -EINVAL;
274 }
275 } else {
276 memcpy(local, &conn->src.sa, newlen);
277 }
278 }
279
280 if (peer != NULL) {
281 memcpy(peer, &conn->dst.sa, newlen);
282 }
283
284 return 0;
285 }
286
tcp_flags(uint8_t flags)287 static const char *tcp_flags(uint8_t flags)
288 {
289 #define BUF_SIZE 25 /* 6 * 4 + 1 */
290 static char buf[BUF_SIZE];
291 int len = 0;
292
293 buf[0] = '\0';
294
295 if (flags) {
296 if (flags & SYN) {
297 len += snprintk(buf + len, BUF_SIZE - len, "SYN,");
298 }
299 if (flags & FIN) {
300 len += snprintk(buf + len, BUF_SIZE - len, "FIN,");
301 }
302 if (flags & ACK) {
303 len += snprintk(buf + len, BUF_SIZE - len, "ACK,");
304 }
305 if (flags & PSH) {
306 len += snprintk(buf + len, BUF_SIZE - len, "PSH,");
307 }
308 if (flags & RST) {
309 len += snprintk(buf + len, BUF_SIZE - len, "RST,");
310 }
311 if (flags & URG) {
312 len += snprintk(buf + len, BUF_SIZE - len, "URG,");
313 }
314
315 if (len > 0) {
316 buf[len - 1] = '\0'; /* delete the last comma */
317 }
318 }
319 #undef BUF_SIZE
320 return buf;
321 }
322
tcp_data_len(struct net_pkt * pkt)323 static size_t tcp_data_len(struct net_pkt *pkt)
324 {
325 struct tcphdr *th = th_get(pkt);
326 size_t tcp_options_len = (th_off(th) - 5) * 4;
327 int len = net_pkt_get_len(pkt) - net_pkt_ip_hdr_len(pkt) -
328 net_pkt_ip_opts_len(pkt) - sizeof(*th) - tcp_options_len;
329
330 return len > 0 ? (size_t)len : 0;
331 }
332
tcp_th(struct net_pkt * pkt)333 static const char *tcp_th(struct net_pkt *pkt)
334 {
335 #define BUF_SIZE 80
336 static char buf[BUF_SIZE];
337 int len = 0;
338 struct tcphdr *th = th_get(pkt);
339
340 buf[0] = '\0';
341
342 if (th_off(th) < 5) {
343 len += snprintk(buf + len, BUF_SIZE - len,
344 "bogus th_off: %hu", (uint16_t)th_off(th));
345 goto end;
346 }
347
348 len += snprintk(buf + len, BUF_SIZE - len,
349 "%s Seq=%u", tcp_flags(th_flags(th)), th_seq(th));
350
351 if (th_flags(th) & ACK) {
352 len += snprintk(buf + len, BUF_SIZE - len,
353 " Ack=%u", th_ack(th));
354 }
355
356 len += snprintk(buf + len, BUF_SIZE - len,
357 " Len=%ld", (long)tcp_data_len(pkt));
358 end:
359 #undef BUF_SIZE
360 return buf;
361 }
362
363 #define is_6lo_technology(pkt) \
364 (IS_ENABLED(CONFIG_NET_IPV6) && net_pkt_family(pkt) == AF_INET6 && \
365 (IS_ENABLED(CONFIG_NET_L2_IEEE802154) && \
366 net_pkt_lladdr_dst(pkt)->type == NET_LINK_IEEE802154))
367
tcp_send(struct net_pkt * pkt)368 static void tcp_send(struct net_pkt *pkt)
369 {
370 tcp_pkt_ref(pkt);
371
372 if (tcp_send_cb) {
373 if (tcp_send_cb(pkt) < 0) {
374 NET_ERR("net_send_data()");
375 tcp_pkt_unref(pkt);
376 }
377 goto out;
378 }
379
380 /* We must have special handling for some network technologies that
381 * tweak the IP protocol headers during packet sending. This happens
382 * with Bluetooth and IEEE 802.15.4 which use IPv6 header compression
383 * (6lo) and alter the sent network packet. So in order to avoid any
384 * corruption of the original data buffer, we must copy the sent data.
385 * For Bluetooth, its fragmentation code will even mangle the data
386 * part of the message so we need to copy those too.
387 */
388 if (is_6lo_technology(pkt)) {
389 struct net_pkt *new_pkt;
390
391 new_pkt = tcp_pkt_clone(pkt);
392 if (!new_pkt) {
393 /* The caller of this func assumes that the net_pkt
394 * is consumed by this function. We call unref here
395 * so that the unref at the end of the func will
396 * free the net_pkt.
397 */
398 tcp_pkt_unref(pkt);
399 NET_WARN("net_pkt alloc failure");
400 goto out;
401 }
402
403 if (net_send_data(new_pkt) < 0) {
404 tcp_pkt_unref(new_pkt);
405 }
406
407 /* We simulate sending of the original pkt and unref it like
408 * the device driver would do.
409 */
410 tcp_pkt_unref(pkt);
411 } else {
412 if (net_send_data(pkt) < 0) {
413 NET_ERR("net_send_data()");
414 tcp_pkt_unref(pkt);
415 }
416 }
417 out:
418 tcp_pkt_unref(pkt);
419 }
420
tcp_derive_rto(struct tcp * conn)421 static void tcp_derive_rto(struct tcp *conn)
422 {
423 #ifdef CONFIG_NET_TCP_RANDOMIZED_RTO
424 /* Compute a randomized rto 1 and 1.5 times tcp_rto */
425 uint32_t gain;
426 uint8_t gain8;
427 uint32_t rto;
428
429 /* Getting random is computational expensive, so only use 8 bits */
430 sys_rand_get(&gain8, sizeof(uint8_t));
431
432 gain = (uint32_t)gain8;
433 gain += 1 << 9;
434
435 rto = (uint32_t)tcp_rto;
436 rto = (gain * rto) >> 9;
437 conn->rto = (uint16_t)rto;
438 #else
439 ARG_UNUSED(conn);
440 #endif
441 }
442
443 #ifdef CONFIG_NET_TCP_CONGESTION_AVOIDANCE
444
445 /* Implementation according to RFC6582 */
446
tcp_new_reno_log(struct tcp * conn,char * step)447 static void tcp_new_reno_log(struct tcp *conn, char *step)
448 {
449 NET_DBG("conn: %p, ca %s, cwnd=%d, ssthres=%d, fast_pend=%i",
450 conn, step, conn->ca.cwnd, conn->ca.ssthresh,
451 conn->ca.pending_fast_retransmit_bytes);
452 }
453
tcp_new_reno_init(struct tcp * conn)454 static void tcp_new_reno_init(struct tcp *conn)
455 {
456 conn->ca.cwnd = conn_mss(conn) * TCP_CONGESTION_INITIAL_WIN;
457 conn->ca.ssthresh = conn_mss(conn) * TCP_CONGESTION_INITIAL_SSTHRESH;
458 conn->ca.pending_fast_retransmit_bytes = 0;
459 tcp_new_reno_log(conn, "init");
460 }
461
tcp_new_reno_fast_retransmit(struct tcp * conn)462 static void tcp_new_reno_fast_retransmit(struct tcp *conn)
463 {
464 if (conn->ca.pending_fast_retransmit_bytes == 0) {
465 conn->ca.ssthresh = MAX(conn_mss(conn) * 2, conn->unacked_len / 2);
466 /* Account for the lost segments */
467 conn->ca.cwnd = conn_mss(conn) * 3 + conn->ca.ssthresh;
468 conn->ca.pending_fast_retransmit_bytes = conn->unacked_len;
469 tcp_new_reno_log(conn, "fast_retransmit");
470 }
471 }
472
tcp_new_reno_timeout(struct tcp * conn)473 static void tcp_new_reno_timeout(struct tcp *conn)
474 {
475 conn->ca.ssthresh = MAX(conn_mss(conn) * 2, conn->unacked_len / 2);
476 conn->ca.cwnd = conn_mss(conn);
477 tcp_new_reno_log(conn, "timeout");
478 }
479
480 /* For every duplicate ack increment the cwnd by mss */
tcp_new_reno_dup_ack(struct tcp * conn)481 static void tcp_new_reno_dup_ack(struct tcp *conn)
482 {
483 int32_t new_win = conn->ca.cwnd;
484
485 new_win += conn_mss(conn);
486 conn->ca.cwnd = MIN(new_win, UINT16_MAX);
487 tcp_new_reno_log(conn, "dup_ack");
488 }
489
tcp_new_reno_pkts_acked(struct tcp * conn,uint32_t acked_len)490 static void tcp_new_reno_pkts_acked(struct tcp *conn, uint32_t acked_len)
491 {
492 int32_t new_win = conn->ca.cwnd;
493 int32_t win_inc = MIN(acked_len, conn_mss(conn));
494
495 if (conn->ca.pending_fast_retransmit_bytes == 0) {
496 if (conn->ca.cwnd < conn->ca.ssthresh) {
497 new_win += win_inc;
498 } else {
499 /* Implement a div_ceil to avoid rounding to 0 */
500 new_win += ((win_inc * win_inc) + conn->ca.cwnd - 1) / conn->ca.cwnd;
501 }
502 conn->ca.cwnd = MIN(new_win, UINT16_MAX);
503 } else {
504 /* Check if it is still in fast recovery mode */
505 if (conn->ca.pending_fast_retransmit_bytes <= acked_len) {
506 conn->ca.pending_fast_retransmit_bytes = 0;
507 conn->ca.cwnd = conn->ca.ssthresh;
508 } else {
509 conn->ca.pending_fast_retransmit_bytes -= acked_len;
510 conn->ca.cwnd -= acked_len;
511 }
512 }
513 tcp_new_reno_log(conn, "pkts_acked");
514 }
515
tcp_ca_init(struct tcp * conn)516 static void tcp_ca_init(struct tcp *conn)
517 {
518 tcp_new_reno_init(conn);
519 }
520
tcp_ca_fast_retransmit(struct tcp * conn)521 static void tcp_ca_fast_retransmit(struct tcp *conn)
522 {
523 tcp_new_reno_fast_retransmit(conn);
524 }
525
tcp_ca_timeout(struct tcp * conn)526 static void tcp_ca_timeout(struct tcp *conn)
527 {
528 tcp_new_reno_timeout(conn);
529 }
530
tcp_ca_dup_ack(struct tcp * conn)531 static void tcp_ca_dup_ack(struct tcp *conn)
532 {
533 tcp_new_reno_dup_ack(conn);
534 }
535
tcp_ca_pkts_acked(struct tcp * conn,uint32_t acked_len)536 static void tcp_ca_pkts_acked(struct tcp *conn, uint32_t acked_len)
537 {
538 tcp_new_reno_pkts_acked(conn, acked_len);
539 }
540 #else
541
tcp_ca_init(struct tcp * conn)542 static void tcp_ca_init(struct tcp *conn) { }
543
tcp_ca_fast_retransmit(struct tcp * conn)544 static void tcp_ca_fast_retransmit(struct tcp *conn) { }
545
tcp_ca_timeout(struct tcp * conn)546 static void tcp_ca_timeout(struct tcp *conn) { }
547
tcp_ca_dup_ack(struct tcp * conn)548 static void tcp_ca_dup_ack(struct tcp *conn) { }
549
tcp_ca_pkts_acked(struct tcp * conn,uint32_t acked_len)550 static void tcp_ca_pkts_acked(struct tcp *conn, uint32_t acked_len) { }
551
552 #endif
553
554 #if defined(CONFIG_NET_TCP_KEEPALIVE)
555
556 static void tcp_send_keepalive_probe(struct k_work *work);
557
keep_alive_timer_init(struct tcp * conn)558 static void keep_alive_timer_init(struct tcp *conn)
559 {
560 conn->keep_alive = false;
561 conn->keep_idle = CONFIG_NET_TCP_KEEPIDLE_DEFAULT;
562 conn->keep_intvl = CONFIG_NET_TCP_KEEPINTVL_DEFAULT;
563 conn->keep_cnt = CONFIG_NET_TCP_KEEPCNT_DEFAULT;
564 NET_DBG("keepalive timer init idle = %d, interval = %d, cnt = %d",
565 conn->keep_idle, conn->keep_intvl, conn->keep_cnt);
566 k_work_init_delayable(&conn->keepalive_timer, tcp_send_keepalive_probe);
567 }
568
keep_alive_param_copy(struct tcp * to,struct tcp * from)569 static void keep_alive_param_copy(struct tcp *to, struct tcp *from)
570 {
571 to->keep_alive = from->keep_alive;
572 to->keep_idle = from->keep_idle;
573 to->keep_intvl = from->keep_intvl;
574 to->keep_cnt = from->keep_cnt;
575 }
576
keep_alive_timer_restart(struct tcp * conn)577 static void keep_alive_timer_restart(struct tcp *conn)
578 {
579 if (!conn->keep_alive || conn->state != TCP_ESTABLISHED) {
580 return;
581 }
582
583 conn->keep_cur = 0;
584 k_work_reschedule_for_queue(&tcp_work_q, &conn->keepalive_timer,
585 K_SECONDS(conn->keep_idle));
586 }
587
keep_alive_timer_stop(struct tcp * conn)588 static void keep_alive_timer_stop(struct tcp *conn)
589 {
590 k_work_cancel_delayable(&conn->keepalive_timer);
591 }
592
set_tcp_keep_alive(struct tcp * conn,const void * value,size_t len)593 static int set_tcp_keep_alive(struct tcp *conn, const void *value, size_t len)
594 {
595 int keep_alive;
596
597 if (conn == NULL || value == NULL || len != sizeof(int)) {
598 return -EINVAL;
599 }
600
601 keep_alive = *(int *)value;
602 if ((keep_alive < 0) || (keep_alive > 1)) {
603 return -EINVAL;
604 }
605
606 conn->keep_alive = (bool)keep_alive;
607
608 if (keep_alive) {
609 keep_alive_timer_restart(conn);
610 } else {
611 keep_alive_timer_stop(conn);
612 }
613
614 return 0;
615 }
616
set_tcp_keep_idle(struct tcp * conn,const void * value,size_t len)617 static int set_tcp_keep_idle(struct tcp *conn, const void *value, size_t len)
618 {
619 int keep_idle;
620
621 if (conn == NULL || value == NULL || len != sizeof(int)) {
622 return -EINVAL;
623 }
624
625 keep_idle = *(int *)value;
626 if (keep_idle < 1) {
627 return -EINVAL;
628 }
629
630 conn->keep_idle = keep_idle;
631
632 keep_alive_timer_restart(conn);
633
634 return 0;
635 }
636
set_tcp_keep_intvl(struct tcp * conn,const void * value,size_t len)637 static int set_tcp_keep_intvl(struct tcp *conn, const void *value, size_t len)
638 {
639 int keep_intvl;
640
641 if (conn == NULL || value == NULL || len != sizeof(int)) {
642 return -EINVAL;
643 }
644
645 keep_intvl = *(int *)value;
646 if (keep_intvl < 1) {
647 return -EINVAL;
648 }
649
650 conn->keep_intvl = keep_intvl;
651
652 keep_alive_timer_restart(conn);
653
654 return 0;
655 }
656
set_tcp_keep_cnt(struct tcp * conn,const void * value,size_t len)657 static int set_tcp_keep_cnt(struct tcp *conn, const void *value, size_t len)
658 {
659 int keep_cnt;
660
661 if (conn == NULL || value == NULL || len != sizeof(int)) {
662 return -EINVAL;
663 }
664
665 keep_cnt = *(int *)value;
666 if (keep_cnt < 1) {
667 return -EINVAL;
668 }
669
670 conn->keep_cnt = keep_cnt;
671
672 keep_alive_timer_restart(conn);
673
674 return 0;
675 }
676
get_tcp_keep_alive(struct tcp * conn,void * value,size_t * len)677 static int get_tcp_keep_alive(struct tcp *conn, void *value, size_t *len)
678 {
679 if (conn == NULL || value == NULL || len == NULL ||
680 *len != sizeof(int)) {
681 return -EINVAL;
682 }
683
684 *((int *)value) = (int)conn->keep_alive;
685
686 return 0;
687 }
688
get_tcp_keep_idle(struct tcp * conn,void * value,size_t * len)689 static int get_tcp_keep_idle(struct tcp *conn, void *value, size_t *len)
690 {
691 if (conn == NULL || value == NULL || len == NULL ||
692 *len != sizeof(int)) {
693 return -EINVAL;
694 }
695
696 *((int *)value) = (int)conn->keep_idle;
697
698 return 0;
699 }
700
get_tcp_keep_intvl(struct tcp * conn,void * value,size_t * len)701 static int get_tcp_keep_intvl(struct tcp *conn, void *value, size_t *len)
702 {
703 if (conn == NULL || value == NULL || len == NULL ||
704 *len != sizeof(int)) {
705 return -EINVAL;
706 }
707
708 *((int *)value) = (int)conn->keep_intvl;
709
710 return 0;
711 }
712
get_tcp_keep_cnt(struct tcp * conn,void * value,size_t * len)713 static int get_tcp_keep_cnt(struct tcp *conn, void *value, size_t *len)
714 {
715 if (conn == NULL || value == NULL || len == NULL ||
716 *len != sizeof(int)) {
717 return -EINVAL;
718 }
719
720 *((int *)value) = (int)conn->keep_cnt;
721
722 return 0;
723 }
724
725 #else /* CONFIG_NET_TCP_KEEPALIVE */
726
727 #define keep_alive_timer_init(...)
728 #define keep_alive_param_copy(...)
729 #define keep_alive_timer_restart(...)
730 #define keep_alive_timer_stop(...)
731 #define set_tcp_keep_alive(...) (-ENOPROTOOPT)
732 #define set_tcp_keep_idle(...) (-ENOPROTOOPT)
733 #define set_tcp_keep_intvl(...) (-ENOPROTOOPT)
734 #define set_tcp_keep_cnt(...) (-ENOPROTOOPT)
735 #define get_tcp_keep_alive(...) (-ENOPROTOOPT)
736 #define get_tcp_keep_idle(...) (-ENOPROTOOPT)
737 #define get_tcp_keep_intvl(...) (-ENOPROTOOPT)
738 #define get_tcp_keep_cnt(...) (-ENOPROTOOPT)
739
740 #endif /* CONFIG_NET_TCP_KEEPALIVE */
741
tcp_send_queue_flush(struct tcp * conn)742 static void tcp_send_queue_flush(struct tcp *conn)
743 {
744 struct net_pkt *pkt;
745
746 k_work_cancel_delayable(&conn->send_timer);
747
748 while ((pkt = tcp_slist(conn, &conn->send_queue, get,
749 struct net_pkt, next))) {
750 tcp_pkt_unref(pkt);
751 }
752 }
753
tcp_conn_release(struct k_work * work)754 static void tcp_conn_release(struct k_work *work)
755 {
756 struct tcp *conn = CONTAINER_OF(work, struct tcp, conn_release);
757 struct net_pkt *pkt;
758
759 #if defined(CONFIG_NET_TEST)
760 if (conn->test_closed_cb != NULL) {
761 conn->test_closed_cb(conn, conn->test_user_data);
762 }
763 #endif
764
765 /* Application is no longer there, unref any remaining packets on the
766 * fifo (although there shouldn't be any at this point.)
767 */
768 while ((pkt = k_fifo_get(&conn->recv_data, K_NO_WAIT)) != NULL) {
769 tcp_pkt_unref(pkt);
770 }
771
772 k_mutex_lock(&conn->lock, K_FOREVER);
773
774 if (conn->context->conn_handler) {
775 net_conn_unregister(conn->context->conn_handler);
776 conn->context->conn_handler = NULL;
777 }
778
779 /* As the TCP socket could be closed without connect being called,
780 * check if the address reference is done before releasing the address.
781 */
782 if (conn->iface != NULL && conn->addr_ref_done) {
783 net_if_addr_unref(conn->iface, conn->src.sa.sa_family,
784 conn->src.sa.sa_family == AF_INET ?
785 (const void *)&conn->src.sin.sin_addr :
786 (const void *)&conn->src.sin6.sin6_addr);
787 }
788
789 conn->context->tcp = NULL;
790 conn->state = TCP_UNUSED;
791
792 tcp_send_queue_flush(conn);
793
794 (void)k_work_cancel_delayable(&conn->send_data_timer);
795 tcp_pkt_unref(conn->send_data);
796
797 if (CONFIG_NET_TCP_RECV_QUEUE_TIMEOUT) {
798 tcp_pkt_unref(conn->queue_recv_data);
799 }
800
801 (void)k_work_cancel_delayable(&conn->timewait_timer);
802 (void)k_work_cancel_delayable(&conn->fin_timer);
803 (void)k_work_cancel_delayable(&conn->persist_timer);
804 (void)k_work_cancel_delayable(&conn->ack_timer);
805 (void)k_work_cancel_delayable(&conn->send_timer);
806 (void)k_work_cancel_delayable(&conn->recv_queue_timer);
807 keep_alive_timer_stop(conn);
808
809 k_mutex_unlock(&conn->lock);
810
811 net_context_unref(conn->context);
812 conn->context = NULL;
813
814 k_mutex_lock(&tcp_lock, K_FOREVER);
815 sys_slist_find_and_remove(&tcp_conns, &conn->next);
816 k_mutex_unlock(&tcp_lock);
817
818 k_mem_slab_free(&tcp_conns_slab, (void *)conn);
819 }
820
821 #if defined(CONFIG_NET_TEST)
tcp_install_close_cb(struct net_context * ctx,net_tcp_closed_cb_t cb,void * user_data)822 void tcp_install_close_cb(struct net_context *ctx,
823 net_tcp_closed_cb_t cb,
824 void *user_data)
825 {
826 NET_ASSERT(ctx->tcp != NULL);
827
828 ((struct tcp *)ctx->tcp)->test_closed_cb = cb;
829 ((struct tcp *)ctx->tcp)->test_user_data = user_data;
830 }
831 #endif
832
tcp_conn_unref(struct tcp * conn)833 static int tcp_conn_unref(struct tcp *conn)
834 {
835 int ref_count = atomic_get(&conn->ref_count);
836
837 NET_DBG("conn: %p, ref_count=%d", conn, ref_count);
838
839 k_mutex_lock(&conn->lock, K_FOREVER);
840
841 #if !defined(CONFIG_NET_TEST_PROTOCOL)
842 if (conn->in_connect) {
843 conn->in_connect = false;
844 k_sem_reset(&conn->connect_sem);
845 }
846 #endif /* CONFIG_NET_TEST_PROTOCOL */
847
848 k_mutex_unlock(&conn->lock);
849
850 ref_count = atomic_dec(&conn->ref_count) - 1;
851 if (ref_count != 0) {
852 tp_out(net_context_get_family(conn->context), conn->iface,
853 "TP_TRACE", "event", "CONN_DELETE");
854 return ref_count;
855 }
856
857 /* Release the TCP context from the TCP workqueue. This will ensure,
858 * that all pending TCP works are cancelled properly, when the context
859 * is released.
860 */
861 k_work_submit_to_queue(&tcp_work_q, &conn->conn_release);
862
863 return ref_count;
864 }
865
866 #if CONFIG_NET_TCP_LOG_LEVEL >= LOG_LEVEL_DBG
867 #define tcp_conn_close(conn, status) \
868 tcp_conn_close_debug(conn, status, __func__, __LINE__)
869
tcp_conn_close_debug(struct tcp * conn,int status,const char * caller,int line)870 static int tcp_conn_close_debug(struct tcp *conn, int status,
871 const char *caller, int line)
872 #else
873 static int tcp_conn_close(struct tcp *conn, int status)
874 #endif
875 {
876 #if CONFIG_NET_TCP_LOG_LEVEL >= LOG_LEVEL_DBG
877 NET_DBG("conn: %p closed by TCP stack (%s():%d)", conn, caller, line);
878 #endif
879 k_mutex_lock(&conn->lock, K_FOREVER);
880 conn_state(conn, TCP_CLOSED);
881 keep_alive_timer_stop(conn);
882 k_mutex_unlock(&conn->lock);
883
884 if (conn->in_connect) {
885 if (conn->connect_cb) {
886 conn->connect_cb(conn->context, status, conn->context->user_data);
887
888 /* Make sure the connect_cb is only called once. */
889 conn->connect_cb = NULL;
890 }
891 } else if (conn->context->recv_cb) {
892 conn->context->recv_cb(conn->context, NULL, NULL, NULL,
893 status, conn->recv_user_data);
894 }
895
896 k_sem_give(&conn->tx_sem);
897
898 return tcp_conn_unref(conn);
899 }
900
tcp_send_process_no_lock(struct tcp * conn)901 static bool tcp_send_process_no_lock(struct tcp *conn)
902 {
903 bool unref = false;
904 struct net_pkt *pkt;
905 bool local = false;
906
907 pkt = tcp_slist(conn, &conn->send_queue, peek_head,
908 struct net_pkt, next);
909 if (!pkt) {
910 goto out;
911 }
912
913 NET_DBG("%s %s", tcp_th(pkt), conn->in_retransmission ?
914 "in_retransmission" : "");
915
916 if (conn->in_retransmission) {
917 if (conn->send_retries > 0) {
918 struct net_pkt *clone = tcp_pkt_clone(pkt);
919
920 if (clone) {
921 tcp_send(clone);
922 conn->send_retries--;
923 } else {
924 NET_WARN("net_pkt alloc failure");
925 }
926 } else {
927 unref = true;
928 goto out;
929 }
930 } else {
931 uint8_t fl = th_get(pkt)->th_flags;
932 bool forget = ACK == fl || PSH == fl || (ACK | PSH) == fl ||
933 RST & fl;
934
935 pkt = forget ? tcp_slist(conn, &conn->send_queue, get,
936 struct net_pkt, next) :
937 tcp_pkt_clone(pkt);
938 if (!pkt) {
939 NET_WARN("net_pkt alloc failure");
940 goto out;
941 }
942
943 if (is_destination_local(pkt)) {
944 local = true;
945 }
946
947 tcp_send(pkt);
948
949 if (forget == false &&
950 !k_work_delayable_remaining_get(&conn->send_timer)) {
951 conn->send_retries = tcp_retries;
952 conn->in_retransmission = true;
953 }
954 }
955
956 if (conn->in_retransmission) {
957 k_work_reschedule_for_queue(&tcp_work_q, &conn->send_timer,
958 K_MSEC(TCP_RTO_MS));
959 } else if (local && !sys_slist_is_empty(&conn->send_queue)) {
960 k_work_reschedule_for_queue(&tcp_work_q, &conn->send_timer,
961 K_NO_WAIT);
962 }
963
964 out:
965 return unref;
966 }
967
tcp_send_process(struct k_work * work)968 static void tcp_send_process(struct k_work *work)
969 {
970 struct k_work_delayable *dwork = k_work_delayable_from_work(work);
971 struct tcp *conn = CONTAINER_OF(dwork, struct tcp, send_timer);
972 bool unref;
973
974 k_mutex_lock(&conn->lock, K_FOREVER);
975
976 unref = tcp_send_process_no_lock(conn);
977
978 k_mutex_unlock(&conn->lock);
979
980 if (unref) {
981 tcp_conn_close(conn, -ETIMEDOUT);
982 }
983 }
984
tcp_send_timer_cancel(struct tcp * conn)985 static void tcp_send_timer_cancel(struct tcp *conn)
986 {
987 if (conn->in_retransmission == false) {
988 return;
989 }
990
991 k_work_cancel_delayable(&conn->send_timer);
992
993 {
994 struct net_pkt *pkt = tcp_slist(conn, &conn->send_queue, get,
995 struct net_pkt, next);
996 if (pkt) {
997 NET_DBG("%s", tcp_th(pkt));
998 tcp_pkt_unref(pkt);
999 }
1000 }
1001
1002 if (sys_slist_is_empty(&conn->send_queue)) {
1003 conn->in_retransmission = false;
1004 } else {
1005 conn->send_retries = tcp_retries;
1006 k_work_reschedule_for_queue(&tcp_work_q, &conn->send_timer,
1007 K_MSEC(TCP_RTO_MS));
1008 }
1009 }
1010
1011 #if defined(CONFIG_NET_TCP_IPV6_ND_REACHABILITY_HINT)
1012
tcp_nbr_reachability_hint(struct tcp * conn)1013 static void tcp_nbr_reachability_hint(struct tcp *conn)
1014 {
1015 int64_t now;
1016 struct net_if *iface;
1017
1018 if (net_context_get_family(conn->context) != AF_INET6) {
1019 return;
1020 }
1021
1022 now = k_uptime_get();
1023 iface = net_context_get_iface(conn->context);
1024
1025 /* Ensure that Neighbor Reachability hints are rate-limited (using threshold
1026 * of half of reachable time).
1027 */
1028 if ((now - conn->last_nd_hint_time) > (net_if_ipv6_get_reachable_time(iface) / 2)) {
1029 net_ipv6_nbr_reachability_hint(iface, &conn->dst.sin6.sin6_addr);
1030 conn->last_nd_hint_time = now;
1031 }
1032 }
1033
1034 #else /* CONFIG_NET_TCP_IPV6_ND_REACHABILITY_HINT */
1035
1036 #define tcp_nbr_reachability_hint(...)
1037
1038 #endif /* CONFIG_NET_TCP_IPV6_ND_REACHABILITY_HINT */
1039
tcp_state_to_str(enum tcp_state state,bool prefix)1040 static const char *tcp_state_to_str(enum tcp_state state, bool prefix)
1041 {
1042 const char *s = NULL;
1043 #define _(_x) case _x: do { s = #_x; goto out; } while (0)
1044 switch (state) {
1045 _(TCP_UNUSED);
1046 _(TCP_LISTEN);
1047 _(TCP_SYN_SENT);
1048 _(TCP_SYN_RECEIVED);
1049 _(TCP_ESTABLISHED);
1050 _(TCP_FIN_WAIT_1);
1051 _(TCP_FIN_WAIT_2);
1052 _(TCP_CLOSE_WAIT);
1053 _(TCP_CLOSING);
1054 _(TCP_LAST_ACK);
1055 _(TCP_TIME_WAIT);
1056 _(TCP_CLOSED);
1057 }
1058 #undef _
1059 NET_ASSERT(s, "Invalid TCP state: %u", state);
1060 out:
1061 return prefix ? s : (s + 4);
1062 }
1063
tcp_conn_state(struct tcp * conn,struct net_pkt * pkt)1064 static const char *tcp_conn_state(struct tcp *conn, struct net_pkt *pkt)
1065 {
1066 #define BUF_SIZE 160
1067 static char buf[BUF_SIZE];
1068
1069 snprintk(buf, BUF_SIZE, "%s [%s Seq=%u Ack=%u]", pkt ? tcp_th(pkt) : "",
1070 tcp_state_to_str(conn->state, false),
1071 conn->seq, conn->ack);
1072 #undef BUF_SIZE
1073 return buf;
1074 }
1075
tcp_options_get(struct net_pkt * pkt,int tcp_options_len,uint8_t * buf,size_t buf_len)1076 static uint8_t *tcp_options_get(struct net_pkt *pkt, int tcp_options_len,
1077 uint8_t *buf, size_t buf_len)
1078 {
1079 struct net_pkt_cursor backup;
1080 int ret;
1081
1082 net_pkt_cursor_backup(pkt, &backup);
1083 net_pkt_cursor_init(pkt);
1084 net_pkt_skip(pkt, net_pkt_ip_hdr_len(pkt) + net_pkt_ip_opts_len(pkt) +
1085 sizeof(struct tcphdr));
1086 ret = net_pkt_read(pkt, buf, MIN(tcp_options_len, buf_len));
1087 if (ret < 0) {
1088 buf = NULL;
1089 }
1090
1091 net_pkt_cursor_restore(pkt, &backup);
1092
1093 return buf;
1094 }
1095
tcp_options_check(struct tcp_options * recv_options,struct net_pkt * pkt,ssize_t len)1096 static bool tcp_options_check(struct tcp_options *recv_options,
1097 struct net_pkt *pkt, ssize_t len)
1098 {
1099 uint8_t options_buf[40]; /* TCP header max options size is 40 */
1100 bool result = len > 0 && ((len % 4) == 0) ? true : false;
1101 uint8_t *options = tcp_options_get(pkt, len, options_buf,
1102 sizeof(options_buf));
1103 uint8_t opt, opt_len;
1104
1105 NET_DBG("len=%zd", len);
1106
1107 recv_options->mss_found = false;
1108 recv_options->wnd_found = false;
1109
1110 for ( ; options && len >= 1; options += opt_len, len -= opt_len) {
1111 opt = options[0];
1112
1113 if (opt == NET_TCP_END_OPT) {
1114 break;
1115 } else if (opt == NET_TCP_NOP_OPT) {
1116 opt_len = 1;
1117 continue;
1118 } else {
1119 if (len < 2) { /* Only END and NOP can have length 1 */
1120 NET_ERR("Illegal option %d with length %zd",
1121 opt, len);
1122 result = false;
1123 break;
1124 }
1125 opt_len = options[1];
1126 }
1127
1128 NET_DBG("opt: %hu, opt_len: %hu",
1129 (uint16_t)opt, (uint16_t)opt_len);
1130
1131 if (opt_len < 2 || opt_len > len) {
1132 result = false;
1133 break;
1134 }
1135
1136 switch (opt) {
1137 case NET_TCP_MSS_OPT:
1138 if (opt_len != 4) {
1139 result = false;
1140 goto end;
1141 }
1142
1143 recv_options->mss =
1144 ntohs(UNALIGNED_GET((uint16_t *)(options + 2)));
1145 recv_options->mss_found = true;
1146 NET_DBG("MSS=%hu", recv_options->mss);
1147 break;
1148 case NET_TCP_WINDOW_SCALE_OPT:
1149 if (opt_len != 3) {
1150 result = false;
1151 goto end;
1152 }
1153
1154 recv_options->window = opt;
1155 recv_options->wnd_found = true;
1156 break;
1157 default:
1158 continue;
1159 }
1160 }
1161 end:
1162 if (false == result) {
1163 NET_WARN("Invalid TCP options");
1164 }
1165
1166 return result;
1167 }
1168
tcp_short_window(struct tcp * conn)1169 static bool tcp_short_window(struct tcp *conn)
1170 {
1171 int32_t threshold = MIN(conn_mss(conn), conn->recv_win_max / 2);
1172
1173 if (conn->recv_win > threshold) {
1174 return false;
1175 }
1176
1177 return true;
1178 }
1179
tcp_need_window_update(struct tcp * conn)1180 static bool tcp_need_window_update(struct tcp *conn)
1181 {
1182 int32_t threshold = MAX(conn_mss(conn), conn->recv_win_max / 2);
1183
1184 /* In case window is full again, and we didn't send a window update
1185 * since the window size dropped below threshold, do it now.
1186 */
1187 return (conn->recv_win == conn->recv_win_max &&
1188 conn->recv_win_sent <= threshold);
1189 }
1190
1191 /**
1192 * @brief Update TCP receive window
1193 *
1194 * @param conn TCP network connection
1195 * @param delta Receive window delta
1196 *
1197 * @return 0 on success, -EINVAL
1198 * if the receive window delta is out of bounds
1199 */
tcp_update_recv_wnd(struct tcp * conn,int32_t delta)1200 static int tcp_update_recv_wnd(struct tcp *conn, int32_t delta)
1201 {
1202 int32_t new_win;
1203 bool short_win_before;
1204 bool short_win_after;
1205
1206 new_win = conn->recv_win + delta;
1207 if (new_win < 0) {
1208 new_win = 0;
1209 } else if (new_win > conn->recv_win_max) {
1210 new_win = conn->recv_win_max;
1211 }
1212
1213 short_win_before = tcp_short_window(conn);
1214
1215 conn->recv_win = new_win;
1216
1217 short_win_after = tcp_short_window(conn);
1218
1219 if (((short_win_before && !short_win_after) ||
1220 tcp_need_window_update(conn)) &&
1221 conn->state == TCP_ESTABLISHED) {
1222 k_work_cancel_delayable(&conn->ack_timer);
1223 tcp_out(conn, ACK);
1224 }
1225
1226 return 0;
1227 }
1228
tcp_check_pending_data(struct tcp * conn,struct net_pkt * pkt,size_t len)1229 static size_t tcp_check_pending_data(struct tcp *conn, struct net_pkt *pkt,
1230 size_t len)
1231 {
1232 size_t pending_len = 0;
1233
1234 if (CONFIG_NET_TCP_RECV_QUEUE_TIMEOUT &&
1235 !net_pkt_is_empty(conn->queue_recv_data)) {
1236 /* Some potentential cases:
1237 * Note: MI = MAX_INT
1238 * Packet | Queued| End off | Gap size | Required handling
1239 * Seq|Len|Seq|Len| | |
1240 * 3 | 3 | 6 | 4 | 3+3-6= 0 | 6-3-3=0 | Append
1241 * 3 | 4 | 6 | 4 | 3+4-6 = 1 | 6-3-4=-1 | Append, pull from queue
1242 * 3 | 7 | 6 | 4 | 3+7-6 = 4 | 6-3-7=-4 | Drop queued data
1243 * 3 | 8 | 6 | 4 | 3+8-6 = 5 | 6-3-8=-5 | Drop queued data
1244 * 6 | 5 | 6 | 4 | 6+5-6 = 5 | 6-6-5=-5 | Drop queued data
1245 * 6 | 4 | 6 | 4 | 6+4-6 = 4 | 6-6-4=-4 | Drop queued data / packet
1246 * 10 | 2 | 6 | 4 | 10+2-6= 6 | 6-10-2=-6| Should not happen, dropping queue
1247 * 7 | 4 | 6 | 4 | 7+4-6 = 5 | 6-7-4=-5 | Should not happen, dropping queue
1248 * 11 | 2 | 6 | 4 | 11+2-6= 7 | 6-11-2=-7| Should not happen, dropping queue
1249 * 2 | 3 | 6 | 4 | 2+3-6= MI | 6-2-3=1 | Keep queued data
1250 */
1251 struct tcphdr *th = th_get(pkt);
1252 uint32_t expected_seq = th_seq(th) + len;
1253 uint32_t pending_seq;
1254 int32_t gap_size;
1255 uint32_t end_offset;
1256
1257 pending_seq = tcp_get_seq(conn->queue_recv_data->buffer);
1258 end_offset = expected_seq - pending_seq;
1259 gap_size = (int32_t)(pending_seq - th_seq(th) - ((uint32_t)len));
1260 pending_len = net_pkt_get_len(conn->queue_recv_data);
1261 if (end_offset < pending_len) {
1262 if (end_offset) {
1263 net_pkt_remove_tail(pkt, end_offset);
1264 pending_len -= end_offset;
1265 }
1266
1267 NET_DBG("Found pending data seq %u len %zd",
1268 expected_seq, pending_len);
1269
1270 net_buf_frag_add(pkt->buffer,
1271 conn->queue_recv_data->buffer);
1272 conn->queue_recv_data->buffer = NULL;
1273
1274 k_work_cancel_delayable(&conn->recv_queue_timer);
1275 } else {
1276 /* Check if the queued data is just a section of the incoming data */
1277 if (gap_size <= 0) {
1278 net_buf_unref(conn->queue_recv_data->buffer);
1279 conn->queue_recv_data->buffer = NULL;
1280
1281 k_work_cancel_delayable(&conn->recv_queue_timer);
1282 }
1283
1284 pending_len = 0;
1285 }
1286 }
1287
1288 return pending_len;
1289 }
1290
tcp_data_get(struct tcp * conn,struct net_pkt * pkt,size_t * len)1291 static enum net_verdict tcp_data_get(struct tcp *conn, struct net_pkt *pkt, size_t *len)
1292 {
1293 enum net_verdict ret = NET_DROP;
1294
1295 if (tcp_recv_cb) {
1296 tcp_recv_cb(conn, pkt);
1297 goto out;
1298 }
1299
1300 if (conn->context->recv_cb) {
1301 /* If there is any out-of-order pending data, then pass it
1302 * to the application here.
1303 */
1304 *len += tcp_check_pending_data(conn, pkt, *len);
1305
1306 net_pkt_cursor_init(pkt);
1307 net_pkt_set_overwrite(pkt, true);
1308
1309 net_pkt_skip(pkt, net_pkt_get_len(pkt) - *len);
1310
1311 tcp_update_recv_wnd(conn, -*len);
1312 if (*len > conn->recv_win_sent) {
1313 conn->recv_win_sent = 0;
1314 } else {
1315 conn->recv_win_sent -= *len;
1316 }
1317
1318 /* Do not pass data to application with TCP conn
1319 * locked as there could be an issue when the app tries
1320 * to send the data and the conn is locked. So the recv
1321 * data is placed in fifo which is flushed in tcp_in()
1322 * after unlocking the conn
1323 */
1324 k_fifo_put(&conn->recv_data, pkt);
1325
1326 ret = NET_OK;
1327 }
1328 out:
1329 return ret;
1330 }
1331
tcp_finalize_pkt(struct net_pkt * pkt)1332 static int tcp_finalize_pkt(struct net_pkt *pkt)
1333 {
1334 net_pkt_cursor_init(pkt);
1335
1336 if (IS_ENABLED(CONFIG_NET_IPV4) && net_pkt_family(pkt) == AF_INET) {
1337 return net_ipv4_finalize(pkt, IPPROTO_TCP);
1338 }
1339
1340 if (IS_ENABLED(CONFIG_NET_IPV6) && net_pkt_family(pkt) == AF_INET6) {
1341 return net_ipv6_finalize(pkt, IPPROTO_TCP);
1342 }
1343
1344 return -EINVAL;
1345 }
1346
tcp_header_add(struct tcp * conn,struct net_pkt * pkt,uint8_t flags,uint32_t seq)1347 static int tcp_header_add(struct tcp *conn, struct net_pkt *pkt, uint8_t flags,
1348 uint32_t seq)
1349 {
1350 NET_PKT_DATA_ACCESS_DEFINE(tcp_access, struct tcphdr);
1351 struct tcphdr *th;
1352
1353 th = (struct tcphdr *)net_pkt_get_data(pkt, &tcp_access);
1354 if (!th) {
1355 return -ENOBUFS;
1356 }
1357
1358 memset(th, 0, sizeof(struct tcphdr));
1359
1360 UNALIGNED_PUT(conn->src.sin.sin_port, &th->th_sport);
1361 UNALIGNED_PUT(conn->dst.sin.sin_port, &th->th_dport);
1362 th->th_off = 5;
1363
1364 if (conn->send_options.mss_found) {
1365 th->th_off++;
1366 }
1367
1368 UNALIGNED_PUT(flags, &th->th_flags);
1369 UNALIGNED_PUT(htons(conn->recv_win), &th->th_win);
1370 UNALIGNED_PUT(htonl(seq), &th->th_seq);
1371
1372 if (ACK & flags) {
1373 UNALIGNED_PUT(htonl(conn->ack), &th->th_ack);
1374 }
1375
1376 return net_pkt_set_data(pkt, &tcp_access);
1377 }
1378
ip_header_add(struct tcp * conn,struct net_pkt * pkt)1379 static int ip_header_add(struct tcp *conn, struct net_pkt *pkt)
1380 {
1381 if (IS_ENABLED(CONFIG_NET_IPV4) && net_pkt_family(pkt) == AF_INET) {
1382 return net_context_create_ipv4_new(conn->context, pkt,
1383 &conn->src.sin.sin_addr,
1384 &conn->dst.sin.sin_addr);
1385 }
1386
1387 if (IS_ENABLED(CONFIG_NET_IPV6) && net_pkt_family(pkt) == AF_INET6) {
1388 return net_context_create_ipv6_new(conn->context, pkt,
1389 &conn->src.sin6.sin6_addr,
1390 &conn->dst.sin6.sin6_addr);
1391 }
1392
1393 return -EINVAL;
1394 }
1395
set_tcp_nodelay(struct tcp * conn,const void * value,size_t len)1396 static int set_tcp_nodelay(struct tcp *conn, const void *value, size_t len)
1397 {
1398 int no_delay_int;
1399
1400 if (len != sizeof(int)) {
1401 return -EINVAL;
1402 }
1403
1404 no_delay_int = *(int *)value;
1405
1406 if ((no_delay_int < 0) || (no_delay_int > 1)) {
1407 return -EINVAL;
1408 }
1409
1410 conn->tcp_nodelay = (bool)no_delay_int;
1411
1412 return 0;
1413 }
1414
get_tcp_nodelay(struct tcp * conn,void * value,size_t * len)1415 static int get_tcp_nodelay(struct tcp *conn, void *value, size_t *len)
1416 {
1417 int no_delay_int = (int)conn->tcp_nodelay;
1418
1419 *((int *)value) = no_delay_int;
1420
1421 if (len) {
1422 *len = sizeof(int);
1423 }
1424 return 0;
1425 }
1426
net_tcp_set_mss_opt(struct tcp * conn,struct net_pkt * pkt)1427 static int net_tcp_set_mss_opt(struct tcp *conn, struct net_pkt *pkt)
1428 {
1429 NET_PKT_DATA_ACCESS_DEFINE(mss_opt_access, struct tcp_mss_option);
1430 struct tcp_mss_option *mss;
1431 uint32_t recv_mss;
1432
1433 mss = net_pkt_get_data(pkt, &mss_opt_access);
1434 if (!mss) {
1435 return -ENOBUFS;
1436 }
1437
1438 recv_mss = net_tcp_get_supported_mss(conn);
1439 recv_mss |= (NET_TCP_MSS_OPT << 24) | (NET_TCP_MSS_SIZE << 16);
1440
1441 UNALIGNED_PUT(htonl(recv_mss), (uint32_t *)mss);
1442
1443 return net_pkt_set_data(pkt, &mss_opt_access);
1444 }
1445
is_destination_local(struct net_pkt * pkt)1446 static bool is_destination_local(struct net_pkt *pkt)
1447 {
1448 if (IS_ENABLED(CONFIG_NET_IPV4) && net_pkt_family(pkt) == AF_INET) {
1449 if (net_ipv4_is_addr_loopback(
1450 (struct in_addr *)NET_IPV4_HDR(pkt)->dst) ||
1451 net_ipv4_is_my_addr(
1452 (struct in_addr *)NET_IPV4_HDR(pkt)->dst)) {
1453 return true;
1454 }
1455 }
1456
1457 if (IS_ENABLED(CONFIG_NET_IPV6) && net_pkt_family(pkt) == AF_INET6) {
1458 if (net_ipv6_is_addr_loopback(
1459 (struct in6_addr *)NET_IPV6_HDR(pkt)->dst) ||
1460 net_ipv6_is_my_addr(
1461 (struct in6_addr *)NET_IPV6_HDR(pkt)->dst)) {
1462 return true;
1463 }
1464 }
1465
1466 return false;
1467 }
1468
net_tcp_reply_rst(struct net_pkt * pkt)1469 void net_tcp_reply_rst(struct net_pkt *pkt)
1470 {
1471 NET_PKT_DATA_ACCESS_DEFINE(tcp_access_rst, struct tcphdr);
1472 struct tcphdr *th_pkt = th_get(pkt);
1473 struct tcphdr *th_rst;
1474 struct net_pkt *rst;
1475 int ret;
1476
1477 if (th_pkt == NULL || (th_flags(th_pkt) & RST)) {
1478 /* Don't reply to a RST segment. */
1479 return;
1480 }
1481
1482 rst = tcp_pkt_alloc_no_conn(pkt->iface, pkt->family,
1483 sizeof(struct tcphdr));
1484 if (rst == NULL) {
1485 return;
1486 }
1487
1488 /* IP header */
1489 if (IS_ENABLED(CONFIG_NET_IPV4) && net_pkt_family(pkt) == AF_INET) {
1490 ret = net_ipv4_create(rst,
1491 (struct in_addr *)NET_IPV4_HDR(pkt)->dst,
1492 (struct in_addr *)NET_IPV4_HDR(pkt)->src);
1493 } else if (IS_ENABLED(CONFIG_NET_IPV6) && net_pkt_family(pkt) == AF_INET6) {
1494 ret = net_ipv6_create(rst,
1495 (struct in6_addr *)NET_IPV6_HDR(pkt)->dst,
1496 (struct in6_addr *)NET_IPV6_HDR(pkt)->src);
1497 } else {
1498 ret = -EINVAL;
1499 }
1500
1501 if (ret < 0) {
1502 goto err;
1503 }
1504
1505 /* TCP header */
1506 th_rst = (struct tcphdr *)net_pkt_get_data(rst, &tcp_access_rst);
1507 if (th_rst == NULL) {
1508 goto err;
1509 }
1510
1511 memset(th_rst, 0, sizeof(struct tcphdr));
1512
1513 UNALIGNED_PUT(th_pkt->th_dport, &th_rst->th_sport);
1514 UNALIGNED_PUT(th_pkt->th_sport, &th_rst->th_dport);
1515 th_rst->th_off = 5;
1516
1517 if (th_flags(th_pkt) & ACK) {
1518 UNALIGNED_PUT(RST, &th_rst->th_flags);
1519 UNALIGNED_PUT(th_pkt->th_ack, &th_rst->th_seq);
1520 } else {
1521 uint32_t ack = ntohl(th_pkt->th_seq) + tcp_data_len(pkt);
1522
1523 UNALIGNED_PUT(RST | ACK, &th_rst->th_flags);
1524 UNALIGNED_PUT(htonl(ack), &th_rst->th_ack);
1525 }
1526
1527 ret = net_pkt_set_data(rst, &tcp_access_rst);
1528 if (ret < 0) {
1529 goto err;
1530 }
1531
1532 ret = tcp_finalize_pkt(rst);
1533 if (ret < 0) {
1534 goto err;
1535 }
1536
1537 NET_DBG("%s", tcp_th(rst));
1538
1539 tcp_send(rst);
1540
1541 return;
1542
1543 err:
1544 tcp_pkt_unref(rst);
1545 }
1546
tcp_out_ext(struct tcp * conn,uint8_t flags,struct net_pkt * data,uint32_t seq)1547 static int tcp_out_ext(struct tcp *conn, uint8_t flags, struct net_pkt *data,
1548 uint32_t seq)
1549 {
1550 size_t alloc_len = sizeof(struct tcphdr);
1551 struct net_pkt *pkt;
1552 int ret = 0;
1553
1554 if (conn->send_options.mss_found) {
1555 alloc_len += sizeof(uint32_t);
1556 }
1557
1558 pkt = tcp_pkt_alloc(conn, alloc_len);
1559 if (!pkt) {
1560 ret = -ENOBUFS;
1561 goto out;
1562 }
1563
1564 if (data) {
1565 /* Append the data buffer to the pkt */
1566 net_pkt_append_buffer(pkt, data->buffer);
1567 data->buffer = NULL;
1568 }
1569
1570 ret = ip_header_add(conn, pkt);
1571 if (ret < 0) {
1572 tcp_pkt_unref(pkt);
1573 goto out;
1574 }
1575
1576 ret = tcp_header_add(conn, pkt, flags, seq);
1577 if (ret < 0) {
1578 tcp_pkt_unref(pkt);
1579 goto out;
1580 }
1581
1582 if (conn->send_options.mss_found) {
1583 ret = net_tcp_set_mss_opt(conn, pkt);
1584 if (ret < 0) {
1585 tcp_pkt_unref(pkt);
1586 goto out;
1587 }
1588 }
1589
1590 ret = tcp_finalize_pkt(pkt);
1591 if (ret < 0) {
1592 tcp_pkt_unref(pkt);
1593 goto out;
1594 }
1595
1596 if (tcp_send_cb) {
1597 ret = tcp_send_cb(pkt);
1598 goto out;
1599 }
1600
1601 sys_slist_append(&conn->send_queue, &pkt->next);
1602
1603 if (flags & ACK) {
1604 conn->recv_win_sent = conn->recv_win;
1605 }
1606
1607 if (is_destination_local(pkt)) {
1608 /* If the destination is local, we have to let the current
1609 * thread to finish with any state-machine changes before
1610 * sending the packet, or it might lead to state inconsistencies
1611 */
1612 k_work_schedule_for_queue(&tcp_work_q,
1613 &conn->send_timer, K_NO_WAIT);
1614 } else if (tcp_send_process_no_lock(conn)) {
1615 tcp_conn_close(conn, -ETIMEDOUT);
1616 }
1617 out:
1618 return ret;
1619 }
1620
tcp_out(struct tcp * conn,uint8_t flags)1621 static void tcp_out(struct tcp *conn, uint8_t flags)
1622 {
1623 (void)tcp_out_ext(conn, flags, NULL /* no data */, conn->seq);
1624 }
1625
tcp_pkt_pull(struct net_pkt * pkt,size_t len)1626 static int tcp_pkt_pull(struct net_pkt *pkt, size_t len)
1627 {
1628 int total = net_pkt_get_len(pkt);
1629 int ret = 0;
1630
1631 if (len > total) {
1632 ret = -EINVAL;
1633 goto out;
1634 }
1635
1636 net_pkt_cursor_init(pkt);
1637 net_pkt_set_overwrite(pkt, true);
1638 net_pkt_pull(pkt, len);
1639 net_pkt_trim_buffer(pkt);
1640 out:
1641 return ret;
1642 }
1643
tcp_pkt_peek(struct net_pkt * to,struct net_pkt * from,size_t pos,size_t len)1644 static int tcp_pkt_peek(struct net_pkt *to, struct net_pkt *from, size_t pos,
1645 size_t len)
1646 {
1647 net_pkt_cursor_init(to);
1648 net_pkt_cursor_init(from);
1649
1650 if (pos) {
1651 net_pkt_set_overwrite(from, true);
1652 net_pkt_skip(from, pos);
1653 }
1654
1655 return net_pkt_copy(to, from, len);
1656 }
1657
tcp_pkt_append(struct net_pkt * pkt,const uint8_t * data,size_t len)1658 static int tcp_pkt_append(struct net_pkt *pkt, const uint8_t *data, size_t len)
1659 {
1660 size_t alloc_len = len;
1661 struct net_buf *buf = NULL;
1662 int ret = 0;
1663
1664 if (pkt->buffer) {
1665 buf = net_buf_frag_last(pkt->buffer);
1666
1667 if (len > net_buf_tailroom(buf)) {
1668 alloc_len -= net_buf_tailroom(buf);
1669 } else {
1670 alloc_len = 0;
1671 }
1672 }
1673
1674 if (alloc_len > 0) {
1675 ret = net_pkt_alloc_buffer_raw(pkt, alloc_len,
1676 TCP_PKT_ALLOC_TIMEOUT);
1677 if (ret < 0) {
1678 return -ENOBUFS;
1679 }
1680 }
1681
1682 if (buf == NULL) {
1683 buf = pkt->buffer;
1684 }
1685
1686 while (buf != NULL && len > 0) {
1687 size_t write_len = MIN(len, net_buf_tailroom(buf));
1688
1689 net_buf_add_mem(buf, data, write_len);
1690
1691 data += write_len;
1692 len -= write_len;
1693 buf = buf->frags;
1694 }
1695
1696 NET_ASSERT(len == 0, "Not all bytes written");
1697
1698 return ret;
1699 }
1700
tcp_window_full(struct tcp * conn)1701 static bool tcp_window_full(struct tcp *conn)
1702 {
1703 bool window_full = (conn->send_data_total >= conn->send_win);
1704
1705 #ifdef CONFIG_NET_TCP_CONGESTION_AVOIDANCE
1706 window_full = window_full || (conn->send_data_total >= conn->ca.cwnd);
1707 #endif
1708
1709 if (window_full) {
1710 NET_DBG("conn: %p TX window_full", conn);
1711 }
1712
1713 return window_full;
1714 }
1715
tcp_unsent_len(struct tcp * conn)1716 static int tcp_unsent_len(struct tcp *conn)
1717 {
1718 int unsent_len;
1719
1720 if (conn->unacked_len > conn->send_data_total) {
1721 NET_ERR("total=%zu, unacked_len=%d",
1722 conn->send_data_total, conn->unacked_len);
1723 unsent_len = -ERANGE;
1724 goto out;
1725 }
1726
1727 unsent_len = conn->send_data_total - conn->unacked_len;
1728 if (conn->unacked_len >= conn->send_win) {
1729 unsent_len = 0;
1730 } else {
1731 unsent_len = MIN(unsent_len, conn->send_win - conn->unacked_len);
1732
1733 #ifdef CONFIG_NET_TCP_CONGESTION_AVOIDANCE
1734 if (conn->unacked_len >= conn->ca.cwnd) {
1735 unsent_len = 0;
1736 } else {
1737 unsent_len = MIN(unsent_len, conn->ca.cwnd - conn->unacked_len);
1738 }
1739 #endif
1740 }
1741 out:
1742 return unsent_len;
1743 }
1744
tcp_send_data(struct tcp * conn)1745 static int tcp_send_data(struct tcp *conn)
1746 {
1747 int ret = 0;
1748 int len;
1749 struct net_pkt *pkt;
1750
1751 len = MIN(tcp_unsent_len(conn), conn_mss(conn));
1752 if (len < 0) {
1753 ret = len;
1754 goto out;
1755 }
1756 if (len == 0) {
1757 NET_DBG("conn: %p no data to send", conn);
1758 ret = -ENODATA;
1759 goto out;
1760 }
1761
1762 pkt = tcp_pkt_alloc(conn, len);
1763 if (!pkt) {
1764 NET_ERR("conn: %p packet allocation failed, len=%d", conn, len);
1765 ret = -ENOBUFS;
1766 goto out;
1767 }
1768
1769 ret = tcp_pkt_peek(pkt, conn->send_data, conn->unacked_len, len);
1770 if (ret < 0) {
1771 tcp_pkt_unref(pkt);
1772 ret = -ENOBUFS;
1773 goto out;
1774 }
1775
1776 ret = tcp_out_ext(conn, PSH | ACK, pkt, conn->seq + conn->unacked_len);
1777 if (ret == 0) {
1778 conn->unacked_len += len;
1779
1780 if (conn->data_mode == TCP_DATA_MODE_RESEND) {
1781 net_stats_update_tcp_resent(conn->iface, len);
1782 net_stats_update_tcp_seg_rexmit(conn->iface);
1783 } else {
1784 net_stats_update_tcp_sent(conn->iface, len);
1785 net_stats_update_tcp_seg_sent(conn->iface);
1786 }
1787 }
1788
1789 /* The data we want to send, has been moved to the send queue so we
1790 * can unref the head net_pkt. If there was an error, we need to remove
1791 * the packet anyway.
1792 */
1793 tcp_pkt_unref(pkt);
1794
1795 conn_send_data_dump(conn);
1796
1797 out:
1798 return ret;
1799 }
1800
1801 /* Send all queued but unsent data from the send_data packet by packet
1802 * until the receiver's window is full. */
tcp_send_queued_data(struct tcp * conn)1803 static int tcp_send_queued_data(struct tcp *conn)
1804 {
1805 int ret = 0;
1806 bool subscribe = false;
1807
1808 if (conn->data_mode == TCP_DATA_MODE_RESEND) {
1809 goto out;
1810 }
1811
1812 while (tcp_unsent_len(conn) > 0) {
1813 /* Implement Nagle's algorithm */
1814 if ((conn->tcp_nodelay == false) && (conn->unacked_len > 0)) {
1815 /* If there is already pending data */
1816 if (tcp_unsent_len(conn) < conn_mss(conn)) {
1817 /* The number of bytes to be transmitted is less than an MSS,
1818 * skip transmission for now.
1819 * Wait for more data to be transmitted or all pending data
1820 * being acknowledged.
1821 */
1822 break;
1823 }
1824 }
1825
1826 ret = tcp_send_data(conn);
1827 if (ret < 0) {
1828 break;
1829 }
1830 }
1831
1832 if (conn->send_data_total) {
1833 subscribe = true;
1834 }
1835
1836 if (k_work_delayable_remaining_get(&conn->send_data_timer)) {
1837 subscribe = false;
1838 }
1839
1840 if (subscribe) {
1841 conn->send_data_retries = 0;
1842 k_work_reschedule_for_queue(&tcp_work_q, &conn->send_data_timer,
1843 K_MSEC(TCP_RTO_MS));
1844 }
1845 out:
1846 return ret;
1847 }
1848
tcp_cleanup_recv_queue(struct k_work * work)1849 static void tcp_cleanup_recv_queue(struct k_work *work)
1850 {
1851 struct k_work_delayable *dwork = k_work_delayable_from_work(work);
1852 struct tcp *conn = CONTAINER_OF(dwork, struct tcp, recv_queue_timer);
1853
1854 k_mutex_lock(&conn->lock, K_FOREVER);
1855
1856 NET_DBG("Cleanup recv queue conn %p len %zd seq %u", conn,
1857 net_pkt_get_len(conn->queue_recv_data),
1858 tcp_get_seq(conn->queue_recv_data->buffer));
1859
1860 net_buf_unref(conn->queue_recv_data->buffer);
1861 conn->queue_recv_data->buffer = NULL;
1862
1863 k_mutex_unlock(&conn->lock);
1864 }
1865
tcp_resend_data(struct k_work * work)1866 static void tcp_resend_data(struct k_work *work)
1867 {
1868 struct k_work_delayable *dwork = k_work_delayable_from_work(work);
1869 struct tcp *conn = CONTAINER_OF(dwork, struct tcp, send_data_timer);
1870 bool conn_unref = false;
1871 int ret;
1872 int exp_tcp_rto;
1873
1874 k_mutex_lock(&conn->lock, K_FOREVER);
1875
1876 NET_DBG("send_data_retries=%hu", conn->send_data_retries);
1877
1878 if (conn->send_data_retries >= tcp_retries) {
1879 NET_DBG("conn: %p close, data retransmissions exceeded", conn);
1880 conn_unref = true;
1881 goto out;
1882 }
1883
1884 if (IS_ENABLED(CONFIG_NET_TCP_CONGESTION_AVOIDANCE) &&
1885 (conn->send_data_retries == 0)) {
1886 tcp_ca_timeout(conn);
1887 if (tcp_window_full(conn)) {
1888 (void)k_sem_take(&conn->tx_sem, K_NO_WAIT);
1889 }
1890 }
1891
1892 conn->data_mode = TCP_DATA_MODE_RESEND;
1893 conn->unacked_len = 0;
1894
1895 ret = tcp_send_data(conn);
1896 conn->send_data_retries++;
1897 if (ret == 0) {
1898 if (conn->in_close && conn->send_data_total == 0) {
1899 NET_DBG("TCP connection in %s close, "
1900 "not disposing yet (waiting %dms)",
1901 "active", tcp_max_timeout_ms);
1902 k_work_reschedule_for_queue(&tcp_work_q,
1903 &conn->fin_timer,
1904 FIN_TIMEOUT);
1905
1906 conn_state(conn, TCP_FIN_WAIT_1);
1907
1908 ret = tcp_out_ext(conn, FIN | ACK, NULL,
1909 conn->seq + conn->unacked_len);
1910 if (ret == 0) {
1911 conn_seq(conn, + 1);
1912 }
1913
1914 keep_alive_timer_stop(conn);
1915
1916 goto out;
1917 }
1918 } else if (ret == -ENODATA) {
1919 conn->data_mode = TCP_DATA_MODE_SEND;
1920
1921 goto out;
1922 } else if (ret == -ENOBUFS) {
1923 NET_ERR("TCP failed to allocate buffer in retransmission");
1924 }
1925
1926 exp_tcp_rto = TCP_RTO_MS;
1927 /* The last retransmit does not need to wait that long */
1928 if (conn->send_data_retries < tcp_retries) {
1929 /* Every retransmit, the retransmission timeout increases by a factor 1.5 */
1930 for (int i = 0; i < conn->send_data_retries; i++) {
1931 exp_tcp_rto += exp_tcp_rto >> 1;
1932 }
1933 }
1934
1935 k_work_reschedule_for_queue(&tcp_work_q, &conn->send_data_timer,
1936 K_MSEC(exp_tcp_rto));
1937
1938 out:
1939 k_mutex_unlock(&conn->lock);
1940
1941 if (conn_unref) {
1942 tcp_conn_close(conn, -ETIMEDOUT);
1943 }
1944 }
1945
tcp_timewait_timeout(struct k_work * work)1946 static void tcp_timewait_timeout(struct k_work *work)
1947 {
1948 struct k_work_delayable *dwork = k_work_delayable_from_work(work);
1949 struct tcp *conn = CONTAINER_OF(dwork, struct tcp, timewait_timer);
1950
1951 /* no need to acquire the conn->lock as there is nothing scheduled here */
1952 NET_DBG("conn: %p %s", conn, tcp_conn_state(conn, NULL));
1953
1954 (void)tcp_conn_close(conn, -ETIMEDOUT);
1955 }
1956
tcp_establish_timeout(struct tcp * conn)1957 static void tcp_establish_timeout(struct tcp *conn)
1958 {
1959 NET_DBG("Did not receive %s in %dms", "ACK", ACK_TIMEOUT_MS);
1960 NET_DBG("conn: %p %s", conn, tcp_conn_state(conn, NULL));
1961
1962 (void)tcp_conn_close(conn, -ETIMEDOUT);
1963 }
1964
tcp_fin_timeout(struct k_work * work)1965 static void tcp_fin_timeout(struct k_work *work)
1966 {
1967 struct k_work_delayable *dwork = k_work_delayable_from_work(work);
1968 struct tcp *conn = CONTAINER_OF(dwork, struct tcp, fin_timer);
1969
1970 /* no need to acquire the conn->lock as there is nothing scheduled here */
1971 if (conn->state == TCP_SYN_RECEIVED) {
1972 tcp_establish_timeout(conn);
1973 return;
1974 }
1975
1976 NET_DBG("Did not receive %s in %dms", "FIN", tcp_max_timeout_ms);
1977 NET_DBG("conn: %p %s", conn, tcp_conn_state(conn, NULL));
1978
1979 (void)tcp_conn_close(conn, -ETIMEDOUT);
1980 }
1981
tcp_last_ack_timeout(struct k_work * work)1982 static void tcp_last_ack_timeout(struct k_work *work)
1983 {
1984 struct k_work_delayable *dwork = k_work_delayable_from_work(work);
1985 struct tcp *conn = CONTAINER_OF(dwork, struct tcp, fin_timer);
1986
1987 NET_DBG("Did not receive %s in %dms", "last ACK", LAST_ACK_TIMEOUT_MS);
1988 NET_DBG("conn: %p %s", conn, tcp_conn_state(conn, NULL));
1989
1990 (void)tcp_conn_close(conn, -ETIMEDOUT);
1991 }
1992
tcp_setup_last_ack_timer(struct tcp * conn)1993 static void tcp_setup_last_ack_timer(struct tcp *conn)
1994 {
1995 /* Just in case the last ack is lost, install a timer that will
1996 * close the connection in that case. Use the fin_timer for that
1997 * as the fin handling cannot be done in this passive close state.
1998 * Instead of default tcp_fin_timeout() function, have a separate
1999 * function to catch this last ack case.
2000 */
2001 k_work_init_delayable(&conn->fin_timer, tcp_last_ack_timeout);
2002
2003 NET_DBG("TCP connection in %s close, "
2004 "not disposing yet (waiting %dms)",
2005 "passive", LAST_ACK_TIMEOUT_MS);
2006 k_work_reschedule_for_queue(&tcp_work_q,
2007 &conn->fin_timer,
2008 LAST_ACK_TIMEOUT);
2009 }
2010
tcp_cancel_last_ack_timer(struct tcp * conn)2011 static void tcp_cancel_last_ack_timer(struct tcp *conn)
2012 {
2013 k_work_cancel_delayable(&conn->fin_timer);
2014 }
2015
2016 #if defined(CONFIG_NET_TCP_KEEPALIVE)
tcp_send_keepalive_probe(struct k_work * work)2017 static void tcp_send_keepalive_probe(struct k_work *work)
2018 {
2019 struct k_work_delayable *dwork = k_work_delayable_from_work(work);
2020 struct tcp *conn = CONTAINER_OF(dwork, struct tcp, keepalive_timer);
2021
2022 if (conn->state != TCP_ESTABLISHED) {
2023 NET_DBG("conn: %p TCP connection not established", conn);
2024 return;
2025 }
2026
2027 if (!conn->keep_alive) {
2028 NET_DBG("conn: %p keepalive is not enabled", conn);
2029 return;
2030 }
2031
2032 conn->keep_cur++;
2033 if (conn->keep_cur > conn->keep_cnt) {
2034 NET_DBG("conn: %p keepalive probe failed multiple times",
2035 conn);
2036 tcp_conn_close(conn, -ETIMEDOUT);
2037 return;
2038 }
2039
2040 NET_DBG("conn: %p keepalive probe", conn);
2041 k_work_reschedule_for_queue(&tcp_work_q, &conn->keepalive_timer,
2042 K_SECONDS(conn->keep_intvl));
2043
2044
2045 (void)tcp_out_ext(conn, ACK, NULL, conn->seq - 1);
2046 }
2047 #endif /* CONFIG_NET_TCP_KEEPALIVE */
2048
tcp_send_zwp(struct k_work * work)2049 static void tcp_send_zwp(struct k_work *work)
2050 {
2051 struct k_work_delayable *dwork = k_work_delayable_from_work(work);
2052 struct tcp *conn = CONTAINER_OF(dwork, struct tcp, persist_timer);
2053
2054 k_mutex_lock(&conn->lock, K_FOREVER);
2055
2056 (void)tcp_out_ext(conn, ACK, NULL, conn->seq - 1);
2057
2058 tcp_derive_rto(conn);
2059
2060 if (conn->send_win == 0) {
2061 uint64_t timeout = TCP_RTO_MS;
2062
2063 /* Make sure the bitwise shift does not result in undefined behaviour */
2064 if (conn->zwp_retries < 63) {
2065 conn->zwp_retries++;
2066 }
2067
2068 timeout <<= conn->zwp_retries;
2069 if (timeout == 0 || timeout > ZWP_MAX_DELAY_MS) {
2070 timeout = ZWP_MAX_DELAY_MS;
2071 }
2072
2073 (void)k_work_reschedule_for_queue(
2074 &tcp_work_q, &conn->persist_timer, K_MSEC(timeout));
2075 }
2076
2077 k_mutex_unlock(&conn->lock);
2078 }
2079
tcp_send_ack(struct k_work * work)2080 static void tcp_send_ack(struct k_work *work)
2081 {
2082 struct k_work_delayable *dwork = k_work_delayable_from_work(work);
2083 struct tcp *conn = CONTAINER_OF(dwork, struct tcp, ack_timer);
2084
2085 k_mutex_lock(&conn->lock, K_FOREVER);
2086
2087 tcp_out(conn, ACK);
2088
2089 k_mutex_unlock(&conn->lock);
2090 }
2091
tcp_conn_ref(struct tcp * conn)2092 static void tcp_conn_ref(struct tcp *conn)
2093 {
2094 int ref_count = atomic_inc(&conn->ref_count) + 1;
2095
2096 NET_DBG("conn: %p, ref_count: %d", conn, ref_count);
2097 }
2098
tcp_conn_alloc(void)2099 static struct tcp *tcp_conn_alloc(void)
2100 {
2101 struct tcp *conn = NULL;
2102 int ret;
2103
2104 ret = k_mem_slab_alloc(&tcp_conns_slab, (void **)&conn, K_NO_WAIT);
2105 if (ret) {
2106 NET_ERR("Cannot allocate slab");
2107 goto out;
2108 }
2109
2110 memset(conn, 0, sizeof(*conn));
2111
2112 if (CONFIG_NET_TCP_RECV_QUEUE_TIMEOUT) {
2113 conn->queue_recv_data = tcp_rx_pkt_alloc(conn, 0);
2114 if (conn->queue_recv_data == NULL) {
2115 NET_ERR("Cannot allocate %s queue for conn %p", "recv",
2116 conn);
2117 goto fail;
2118 }
2119 }
2120
2121 conn->send_data = tcp_pkt_alloc(conn, 0);
2122 if (conn->send_data == NULL) {
2123 NET_ERR("Cannot allocate %s queue for conn %p", "send", conn);
2124 goto fail;
2125 }
2126
2127 k_mutex_init(&conn->lock);
2128 k_fifo_init(&conn->recv_data);
2129 k_sem_init(&conn->connect_sem, 0, K_SEM_MAX_LIMIT);
2130 k_sem_init(&conn->tx_sem, 1, 1);
2131
2132 conn->in_connect = false;
2133 conn->state = TCP_LISTEN;
2134 conn->recv_win_max = tcp_rx_window;
2135 conn->recv_win = conn->recv_win_max;
2136 conn->recv_win_sent = conn->recv_win_max;
2137 conn->send_win_max = MAX(tcp_tx_window, NET_IPV6_MTU);
2138 conn->send_win = conn->send_win_max;
2139 conn->tcp_nodelay = false;
2140 conn->addr_ref_done = false;
2141 #ifdef CONFIG_NET_TCP_FAST_RETRANSMIT
2142 conn->dup_ack_cnt = 0;
2143 #endif
2144 #ifdef CONFIG_NET_TCP_CONGESTION_AVOIDANCE
2145 /* Initially set the congestion window at its max size, since only the MSS
2146 * is available as soon as the connection is established
2147 */
2148 conn->ca.cwnd = UINT16_MAX;
2149 #endif
2150
2151 /* The ISN value will be set when we get the connection attempt or
2152 * when trying to create a connection.
2153 */
2154 conn->seq = 0U;
2155
2156 sys_slist_init(&conn->send_queue);
2157
2158 k_work_init_delayable(&conn->send_timer, tcp_send_process);
2159 k_work_init_delayable(&conn->timewait_timer, tcp_timewait_timeout);
2160 k_work_init_delayable(&conn->fin_timer, tcp_fin_timeout);
2161 k_work_init_delayable(&conn->send_data_timer, tcp_resend_data);
2162 k_work_init_delayable(&conn->recv_queue_timer, tcp_cleanup_recv_queue);
2163 k_work_init_delayable(&conn->persist_timer, tcp_send_zwp);
2164 k_work_init_delayable(&conn->ack_timer, tcp_send_ack);
2165 k_work_init(&conn->conn_release, tcp_conn_release);
2166 keep_alive_timer_init(conn);
2167
2168 tcp_conn_ref(conn);
2169
2170 k_mutex_lock(&tcp_lock, K_FOREVER);
2171 sys_slist_append(&tcp_conns, &conn->next);
2172 k_mutex_unlock(&tcp_lock);
2173 out:
2174 NET_DBG("conn: %p", conn);
2175
2176 return conn;
2177
2178 fail:
2179 if (CONFIG_NET_TCP_RECV_QUEUE_TIMEOUT && conn->queue_recv_data) {
2180 tcp_pkt_unref(conn->queue_recv_data);
2181 conn->queue_recv_data = NULL;
2182 }
2183
2184 k_mem_slab_free(&tcp_conns_slab, (void *)conn);
2185 return NULL;
2186 }
2187
net_tcp_get(struct net_context * context)2188 int net_tcp_get(struct net_context *context)
2189 {
2190 int ret = 0;
2191 struct tcp *conn;
2192
2193 conn = tcp_conn_alloc();
2194 if (conn == NULL) {
2195 ret = -ENOMEM;
2196 return ret;
2197 }
2198
2199 /* Mutually link the net_context and tcp connection */
2200 conn->context = context;
2201 context->tcp = conn;
2202
2203 return ret;
2204 }
2205
tcp_endpoint_cmp(union tcp_endpoint * ep,struct net_pkt * pkt,enum pkt_addr which)2206 static bool tcp_endpoint_cmp(union tcp_endpoint *ep, struct net_pkt *pkt,
2207 enum pkt_addr which)
2208 {
2209 union tcp_endpoint ep_tmp;
2210
2211 if (tcp_endpoint_set(&ep_tmp, pkt, which) < 0) {
2212 return false;
2213 }
2214
2215 return !memcmp(ep, &ep_tmp, tcp_endpoint_len(ep->sa.sa_family));
2216 }
2217
tcp_conn_cmp(struct tcp * conn,struct net_pkt * pkt)2218 static bool tcp_conn_cmp(struct tcp *conn, struct net_pkt *pkt)
2219 {
2220 return tcp_endpoint_cmp(&conn->src, pkt, TCP_EP_DST) &&
2221 tcp_endpoint_cmp(&conn->dst, pkt, TCP_EP_SRC);
2222 }
2223
tcp_conn_search(struct net_pkt * pkt)2224 static struct tcp *tcp_conn_search(struct net_pkt *pkt)
2225 {
2226 bool found = false;
2227 struct tcp *conn;
2228 struct tcp *tmp;
2229
2230 k_mutex_lock(&tcp_lock, K_FOREVER);
2231
2232 SYS_SLIST_FOR_EACH_CONTAINER_SAFE(&tcp_conns, conn, tmp, next) {
2233 found = tcp_conn_cmp(conn, pkt);
2234 if (found) {
2235 break;
2236 }
2237 }
2238
2239 k_mutex_unlock(&tcp_lock);
2240
2241 return found ? conn : NULL;
2242 }
2243
2244 static struct tcp *tcp_conn_new(struct net_pkt *pkt);
2245
tcp_recv(struct net_conn * net_conn,struct net_pkt * pkt,union net_ip_header * ip,union net_proto_header * proto,void * user_data)2246 static enum net_verdict tcp_recv(struct net_conn *net_conn,
2247 struct net_pkt *pkt,
2248 union net_ip_header *ip,
2249 union net_proto_header *proto,
2250 void *user_data)
2251 {
2252 struct tcp *conn;
2253 struct tcphdr *th;
2254 enum net_verdict verdict = NET_DROP;
2255
2256 ARG_UNUSED(net_conn);
2257 ARG_UNUSED(proto);
2258
2259 conn = tcp_conn_search(pkt);
2260 if (conn) {
2261 goto in;
2262 }
2263
2264 th = th_get(pkt);
2265
2266 if (th_flags(th) & SYN && !(th_flags(th) & ACK)) {
2267 struct tcp *conn_old = ((struct net_context *)user_data)->tcp;
2268
2269 conn = tcp_conn_new(pkt);
2270 if (!conn) {
2271 NET_ERR("Cannot allocate a new TCP connection");
2272 goto in;
2273 }
2274
2275 conn->accepted_conn = conn_old;
2276 }
2277 in:
2278 if (conn) {
2279 verdict = tcp_in(conn, pkt);
2280 } else {
2281 net_tcp_reply_rst(pkt);
2282 }
2283
2284 return verdict;
2285 }
2286
2287 #if defined(CONFIG_NET_TCP_ISN_RFC6528)
2288
seq_scale(uint32_t seq)2289 static uint32_t seq_scale(uint32_t seq)
2290 {
2291 return seq + (k_ticks_to_ns_floor32(k_uptime_ticks()) >> 6);
2292 }
2293
2294 static uint8_t unique_key[16]; /* MD5 128 bits as described in RFC6528 */
2295
tcpv6_init_isn(struct in6_addr * saddr,struct in6_addr * daddr,uint16_t sport,uint16_t dport)2296 static uint32_t tcpv6_init_isn(struct in6_addr *saddr,
2297 struct in6_addr *daddr,
2298 uint16_t sport,
2299 uint16_t dport)
2300 {
2301 struct {
2302 uint8_t key[sizeof(unique_key)];
2303 struct in6_addr saddr;
2304 struct in6_addr daddr;
2305 uint16_t sport;
2306 uint16_t dport;
2307 } buf = {
2308 .saddr = *(struct in6_addr *)saddr,
2309 .daddr = *(struct in6_addr *)daddr,
2310 .sport = sport,
2311 .dport = dport
2312 };
2313
2314 uint8_t hash[16];
2315 size_t hash_len;
2316 static bool once;
2317
2318 if (!once) {
2319 sys_csrand_get(unique_key, sizeof(unique_key));
2320 once = true;
2321 }
2322
2323 memcpy(buf.key, unique_key, sizeof(buf.key));
2324
2325 psa_hash_compute(PSA_ALG_SHA_256, (const unsigned char *)&buf, sizeof(buf),
2326 hash, sizeof(hash), &hash_len);
2327
2328 return seq_scale(UNALIGNED_GET((uint32_t *)&hash[0]));
2329 }
2330
tcpv4_init_isn(struct in_addr * saddr,struct in_addr * daddr,uint16_t sport,uint16_t dport)2331 static uint32_t tcpv4_init_isn(struct in_addr *saddr,
2332 struct in_addr *daddr,
2333 uint16_t sport,
2334 uint16_t dport)
2335 {
2336 struct {
2337 uint8_t key[sizeof(unique_key)];
2338 struct in_addr saddr;
2339 struct in_addr daddr;
2340 uint16_t sport;
2341 uint16_t dport;
2342 } buf = {
2343 .saddr = *(struct in_addr *)saddr,
2344 .daddr = *(struct in_addr *)daddr,
2345 .sport = sport,
2346 .dport = dport
2347 };
2348
2349 uint8_t hash[16];
2350 size_t hash_len;
2351 static bool once;
2352
2353 if (!once) {
2354 sys_csrand_get(unique_key, sizeof(unique_key));
2355 once = true;
2356 }
2357
2358 memcpy(buf.key, unique_key, sizeof(unique_key));
2359
2360
2361 psa_hash_compute(PSA_ALG_SHA_256, (const unsigned char *)&buf, sizeof(buf),
2362 hash, sizeof(hash), &hash_len);
2363
2364 return seq_scale(UNALIGNED_GET((uint32_t *)&hash[0]));
2365 }
2366
2367 #else
2368
2369 #define tcpv6_init_isn(...) (0UL)
2370 #define tcpv4_init_isn(...) (0UL)
2371
2372 #endif /* CONFIG_NET_TCP_ISN_RFC6528 */
2373
tcp_init_isn(struct sockaddr * saddr,struct sockaddr * daddr)2374 static uint32_t tcp_init_isn(struct sockaddr *saddr, struct sockaddr *daddr)
2375 {
2376 if (IS_ENABLED(CONFIG_NET_TCP_ISN_RFC6528)) {
2377 if (IS_ENABLED(CONFIG_NET_IPV6) &&
2378 saddr->sa_family == AF_INET6) {
2379 return tcpv6_init_isn(&net_sin6(saddr)->sin6_addr,
2380 &net_sin6(daddr)->sin6_addr,
2381 net_sin6(saddr)->sin6_port,
2382 net_sin6(daddr)->sin6_port);
2383 } else if (IS_ENABLED(CONFIG_NET_IPV4) &&
2384 saddr->sa_family == AF_INET) {
2385 return tcpv4_init_isn(&net_sin(saddr)->sin_addr,
2386 &net_sin(daddr)->sin_addr,
2387 net_sin(saddr)->sin_port,
2388 net_sin(daddr)->sin_port);
2389 }
2390 }
2391
2392 return sys_rand32_get();
2393 }
2394
2395 /* Create a new tcp connection, as a part of it, create and register
2396 * net_context
2397 */
tcp_conn_new(struct net_pkt * pkt)2398 static struct tcp *tcp_conn_new(struct net_pkt *pkt)
2399 {
2400 struct tcp *conn = NULL;
2401 struct net_context *context = NULL;
2402 sa_family_t af = net_pkt_family(pkt);
2403 struct sockaddr local_addr = { 0 };
2404 int ret;
2405
2406 ret = net_context_get(af, SOCK_STREAM, IPPROTO_TCP, &context);
2407 if (ret < 0) {
2408 NET_ERR("net_context_get(): %d", ret);
2409 goto err;
2410 }
2411
2412 conn = context->tcp;
2413 conn->iface = pkt->iface;
2414 tcp_derive_rto(conn);
2415
2416 net_context_set_family(conn->context, net_pkt_family(pkt));
2417
2418 if (tcp_endpoint_set(&conn->dst, pkt, TCP_EP_SRC) < 0) {
2419 net_context_put(context);
2420 conn = NULL;
2421 goto err;
2422 }
2423
2424 if (tcp_endpoint_set(&conn->src, pkt, TCP_EP_DST) < 0) {
2425 net_context_put(context);
2426 conn = NULL;
2427 goto err;
2428 }
2429
2430 NET_DBG("conn: src: %s, dst: %s",
2431 net_sprint_addr(conn->src.sa.sa_family,
2432 (const void *)&conn->src.sin.sin_addr),
2433 net_sprint_addr(conn->dst.sa.sa_family,
2434 (const void *)&conn->dst.sin.sin_addr));
2435
2436 memcpy(&context->remote, &conn->dst, sizeof(context->remote));
2437 context->flags |= NET_CONTEXT_REMOTE_ADDR_SET;
2438
2439 net_sin_ptr(&context->local)->sin_family = af;
2440
2441 local_addr.sa_family = net_context_get_family(context);
2442
2443 if (IS_ENABLED(CONFIG_NET_IPV6) &&
2444 net_context_get_family(context) == AF_INET6) {
2445 net_ipaddr_copy(&net_sin6(&local_addr)->sin6_addr,
2446 &conn->src.sin6.sin6_addr);
2447 } else if (IS_ENABLED(CONFIG_NET_IPV4) &&
2448 net_context_get_family(context) == AF_INET) {
2449 net_ipaddr_copy(&net_sin(&local_addr)->sin_addr,
2450 &conn->src.sin.sin_addr);
2451 }
2452
2453 ret = net_context_bind(context, &local_addr, sizeof(local_addr));
2454 if (ret < 0) {
2455 NET_DBG("Cannot bind accepted context, connection reset");
2456 net_context_put(context);
2457 conn = NULL;
2458 goto err;
2459 }
2460
2461 /* The newly created context object for the new TCP client connection needs
2462 * all four parameters of the tuple (local address, local port, remote
2463 * address, remote port) to be properly identified. Remote address and port
2464 * are already copied above from conn->dst. The call to net_context_bind
2465 * with the prepared local_addr further copies the local address. However,
2466 * this call won't copy the local port, as the bind would then fail due to
2467 * an address/port reuse without the REUSEPORT option enables for both
2468 * connections. Therefore, we copy the port after the bind call.
2469 * It is safe to bind to this address/port combination, as the new TCP
2470 * client connection is separated from the local listening connection
2471 * by the specified remote address and remote port.
2472 */
2473 if (IS_ENABLED(CONFIG_NET_IPV6) &&
2474 net_context_get_family(context) == AF_INET6) {
2475 net_sin6_ptr(&context->local)->sin6_port = conn->src.sin6.sin6_port;
2476 } else if (IS_ENABLED(CONFIG_NET_IPV4) &&
2477 net_context_get_family(context) == AF_INET) {
2478 net_sin_ptr(&context->local)->sin_port = conn->src.sin.sin_port;
2479 }
2480
2481 if (!(IS_ENABLED(CONFIG_NET_TEST_PROTOCOL) ||
2482 IS_ENABLED(CONFIG_NET_TEST))) {
2483 conn->seq = tcp_init_isn(&local_addr, &context->remote);
2484 }
2485
2486 NET_DBG("context: local: %s, remote: %s",
2487 net_sprint_addr(local_addr.sa_family,
2488 (const void *)&net_sin(&local_addr)->sin_addr),
2489 net_sprint_addr(context->remote.sa_family,
2490 (const void *)&net_sin(&context->remote)->sin_addr));
2491
2492 ret = net_conn_register(IPPROTO_TCP, af,
2493 &context->remote, &local_addr,
2494 ntohs(conn->dst.sin.sin_port),/* local port */
2495 ntohs(conn->src.sin.sin_port),/* remote port */
2496 context, tcp_recv, context,
2497 &context->conn_handler);
2498 if (ret < 0) {
2499 NET_ERR("net_conn_register(): %d", ret);
2500 net_context_put(context);
2501 conn = NULL;
2502 goto err;
2503 }
2504
2505 net_if_addr_ref(conn->iface, conn->dst.sa.sa_family,
2506 conn->src.sa.sa_family == AF_INET ?
2507 (const void *)&conn->src.sin.sin_addr :
2508 (const void *)&conn->src.sin6.sin6_addr);
2509 conn->addr_ref_done = true;
2510
2511 err:
2512 if (!conn) {
2513 net_stats_update_tcp_seg_conndrop(net_pkt_iface(pkt));
2514 }
2515
2516 return conn;
2517 }
2518
tcp_validate_seq(struct tcp * conn,struct tcphdr * hdr)2519 static bool tcp_validate_seq(struct tcp *conn, struct tcphdr *hdr)
2520 {
2521 return (net_tcp_seq_cmp(th_seq(hdr), conn->ack) >= 0) &&
2522 (net_tcp_seq_cmp(th_seq(hdr), conn->ack + conn->recv_win) < 0);
2523 }
2524
tcp_compute_new_length(struct tcp * conn,struct tcphdr * hdr,size_t len,bool fin_received)2525 static int32_t tcp_compute_new_length(struct tcp *conn, struct tcphdr *hdr, size_t len,
2526 bool fin_received)
2527 {
2528 int32_t new_len = 0;
2529
2530 if (len > 0) {
2531 /* Cases:
2532 * - Data already received earlier: new_len <= 0
2533 * - Partially new data new_len > 0
2534 * - Out of order data new_len > 0,
2535 * should be checked by sequence number
2536 */
2537 new_len = (int32_t)(len) - net_tcp_seq_cmp(conn->ack, th_seq(hdr));
2538 if (fin_received) {
2539 /* Add with one additional byte as the FIN flag has to be subtracted */
2540 new_len++;
2541 }
2542 }
2543 return new_len;
2544 }
2545
tcp_enter_time_wait(struct tcp * conn)2546 static enum tcp_state tcp_enter_time_wait(struct tcp *conn)
2547 {
2548 tcp_send_timer_cancel(conn);
2549 /* Entering TIME-WAIT, so cancel the timer and start the TIME-WAIT timer */
2550 k_work_cancel_delayable(&conn->fin_timer);
2551 k_work_reschedule_for_queue(
2552 &tcp_work_q, &conn->timewait_timer,
2553 K_MSEC(CONFIG_NET_TCP_TIME_WAIT_DELAY));
2554 return TCP_TIME_WAIT;
2555 }
2556
check_seq_list(struct net_buf * buf)2557 static bool check_seq_list(struct net_buf *buf)
2558 {
2559 struct net_buf *last = NULL;
2560 struct net_buf *tmp = buf;
2561 uint32_t seq;
2562 uint32_t next_seq = 0;
2563 bool result = true;
2564
2565 while (tmp) {
2566 seq = tcp_get_seq(tmp);
2567
2568 NET_DBG("buf %p seq %u len %d", tmp, seq, tmp->len);
2569
2570 if (last != NULL) {
2571 if (next_seq != seq) {
2572 result = false;
2573 }
2574 }
2575
2576 next_seq = seq + tmp->len;
2577 last = tmp;
2578 tmp = tmp->frags;
2579 }
2580 return result;
2581 }
2582
tcp_queue_recv_data(struct tcp * conn,struct net_pkt * pkt,size_t len,uint32_t seq)2583 static void tcp_queue_recv_data(struct tcp *conn, struct net_pkt *pkt,
2584 size_t len, uint32_t seq)
2585 {
2586 uint32_t seq_start = seq;
2587 bool inserted = false;
2588 struct net_buf *tmp;
2589
2590 NET_DBG("conn: %p len %zd seq %u ack %u", conn, len, seq, conn->ack);
2591
2592 tmp = pkt->buffer;
2593
2594 tcp_set_seq(tmp, seq);
2595 seq += tmp->len;
2596 tmp = tmp->frags;
2597
2598 while (tmp) {
2599 tcp_set_seq(tmp, seq);
2600 seq += tmp->len;
2601 tmp = tmp->frags;
2602 }
2603
2604 if (IS_ENABLED(CONFIG_NET_TCP_LOG_LEVEL_DBG)) {
2605 NET_DBG("Queuing data: conn %p", conn);
2606 }
2607
2608 if (!net_pkt_is_empty(conn->queue_recv_data)) {
2609 /* Place the data to correct place in the list. If the data
2610 * would not be sequential, then drop this packet.
2611 *
2612 * Only work with subtractions between sequence numbers in uint32_t format
2613 * to proper handle cases that are around the wrapping point.
2614 */
2615
2616 /* Some potentential cases:
2617 * Note: MI = MAX_INT
2618 * Packet | Queued| End off1 | Start off| End off2 | Required handling
2619 * Seq|Len|Seq|Len| | | |
2620 * 3 | 3 | 6 | 4 | 3+3-6= 0 | NA | NA | Prepend
2621 * 3 | 4 | 6 | 4 | 3+4-6 = 1 | NA | NA | Prepend, pull from buffer
2622 * 3 | 7 | 6 | 4 | 3+7-6 = 4 | 6-3=3 | 6+4-3=7 | Drop queued data
2623 * 3 | 8 | 6 | 4 | 3+8-6 = 5 | 6-3=3 | 6+4-3=7 | Drop queued data
2624 * 6 | 5 | 6 | 4 | 6+5-6 = 5 | 6-6=0 | 6+4-6=4 | Drop queued data
2625 * 6 | 4 | 6 | 4 | 6+4-6 = 4 | 6-6=0 | 6+4-6=4 | Drop queued data / packet
2626 * 7 | 2 | 6 | 4 | 7+2-6 = 3 | 6-7=MI | 6+4-7=3 | Drop packet
2627 * 10 | 2 | 6 | 4 | 10+2-6= 6 | 6-10=MI-3| 6+4-10=0 | Append
2628 * 7 | 4 | 6 | 4 | 7+4-6 = 5 | 6-7 =MI | 6+4-7 =3 | Append, pull from packet
2629 * 11 | 2 | 6 | 4 | 11+2-6= 7 | 6-11=MI-6| 6+4-11=MI-1 | Drop incoming packet
2630 * 2 | 3 | 6 | 4 | 2+3-6= MI | 6-2=4 | 6+4-2=8 | Drop incoming packet
2631 */
2632
2633 uint32_t pending_seq;
2634 uint32_t start_offset;
2635 uint32_t end_offset;
2636 size_t pending_len;
2637
2638 pending_seq = tcp_get_seq(conn->queue_recv_data->buffer);
2639 end_offset = seq - pending_seq;
2640 pending_len = net_pkt_get_len(conn->queue_recv_data);
2641 if (end_offset < pending_len) {
2642 if (end_offset < len) {
2643 if (end_offset) {
2644 net_pkt_remove_tail(pkt, end_offset);
2645 }
2646
2647 /* Put new data before the pending data */
2648 net_buf_frag_add(pkt->buffer,
2649 conn->queue_recv_data->buffer);
2650 NET_DBG("Adding at before queue, end_offset %i, pending_len %zu",
2651 end_offset, pending_len);
2652 conn->queue_recv_data->buffer = pkt->buffer;
2653 inserted = true;
2654 }
2655 } else {
2656 struct net_buf *last;
2657
2658 last = net_buf_frag_last(conn->queue_recv_data->buffer);
2659 pending_seq = tcp_get_seq(last);
2660
2661 start_offset = pending_seq - seq_start;
2662 /* Compute the offset w.r.t. the start point of the new packet */
2663 end_offset = (pending_seq + last->len) - seq_start;
2664
2665 /* Check if queue start with within the within the new packet */
2666 if ((start_offset < len) && (end_offset <= len)) {
2667 /* The queued data is irrelevant since the new packet overlaps the
2668 * new packet, take the new packet as contents
2669 */
2670 net_buf_unref(conn->queue_recv_data->buffer);
2671 conn->queue_recv_data->buffer = pkt->buffer;
2672 inserted = true;
2673 } else {
2674 if (end_offset < len) {
2675 if (end_offset) {
2676 net_pkt_remove_tail(conn->queue_recv_data,
2677 end_offset);
2678 }
2679
2680 /* Put new data after pending data */
2681 NET_DBG("Adding at end of queue, start %i, end %i, len %zu",
2682 start_offset, end_offset, len);
2683 net_buf_frag_add(conn->queue_recv_data->buffer,
2684 pkt->buffer);
2685 inserted = true;
2686 }
2687 }
2688 }
2689
2690 if (inserted) {
2691 NET_DBG("All pending data: conn %p", conn);
2692 if (check_seq_list(conn->queue_recv_data->buffer) == false) {
2693 NET_ERR("Incorrect order in out of order sequence for conn %p",
2694 conn);
2695 /* error in sequence list, drop it */
2696 net_buf_unref(conn->queue_recv_data->buffer);
2697 conn->queue_recv_data->buffer = NULL;
2698 }
2699 } else {
2700 NET_DBG("Cannot add new data to queue");
2701 }
2702 } else {
2703 net_pkt_append_buffer(conn->queue_recv_data, pkt->buffer);
2704 inserted = true;
2705 }
2706
2707 if (inserted) {
2708 /* We need to keep the received data but free the pkt */
2709 pkt->buffer = NULL;
2710
2711 if (!k_work_delayable_is_pending(&conn->recv_queue_timer)) {
2712 k_work_reschedule_for_queue(
2713 &tcp_work_q, &conn->recv_queue_timer,
2714 K_MSEC(CONFIG_NET_TCP_RECV_QUEUE_TIMEOUT));
2715 }
2716 }
2717 }
2718
tcp_data_received(struct tcp * conn,struct net_pkt * pkt,size_t * len,bool psh)2719 static enum net_verdict tcp_data_received(struct tcp *conn, struct net_pkt *pkt,
2720 size_t *len, bool psh)
2721 {
2722 enum net_verdict ret;
2723
2724 if (*len == 0) {
2725 return NET_DROP;
2726 }
2727
2728 ret = tcp_data_get(conn, pkt, len);
2729
2730 net_stats_update_tcp_seg_recv(conn->iface);
2731 conn_ack(conn, *len);
2732
2733 /* Delay ACK response in case of small window or missing PSH,
2734 * as described in RFC 813.
2735 */
2736 if (tcp_short_window(conn) || !psh) {
2737 k_work_schedule_for_queue(&tcp_work_q, &conn->ack_timer,
2738 ACK_DELAY);
2739 } else {
2740 k_work_cancel_delayable(&conn->ack_timer);
2741 tcp_out(conn, ACK);
2742 }
2743
2744 return ret;
2745 }
2746
tcp_out_of_order_data(struct tcp * conn,struct net_pkt * pkt,size_t data_len,uint32_t seq)2747 static void tcp_out_of_order_data(struct tcp *conn, struct net_pkt *pkt,
2748 size_t data_len, uint32_t seq)
2749 {
2750 size_t headers_len;
2751
2752 if (data_len == 0) {
2753 return;
2754 }
2755
2756 headers_len = net_pkt_get_len(pkt) - data_len;
2757
2758 /* Get rid of protocol headers from the data */
2759 if (tcp_pkt_pull(pkt, headers_len) < 0) {
2760 return;
2761 }
2762
2763 /* We received out-of-order data. Try to queue it.
2764 */
2765 tcp_queue_recv_data(conn, pkt, data_len, seq);
2766 }
2767
tcp_check_sock_options(struct tcp * conn)2768 static void tcp_check_sock_options(struct tcp *conn)
2769 {
2770 int sndbuf_opt = 0;
2771 int rcvbuf_opt = 0;
2772
2773 if (IS_ENABLED(CONFIG_NET_CONTEXT_SNDBUF)) {
2774 (void)net_context_get_option(conn->context, NET_OPT_SNDBUF,
2775 &sndbuf_opt, NULL);
2776 }
2777
2778 if (IS_ENABLED(CONFIG_NET_CONTEXT_RCVBUF)) {
2779 (void)net_context_get_option(conn->context, NET_OPT_RCVBUF,
2780 &rcvbuf_opt, NULL);
2781 }
2782
2783 if (sndbuf_opt > 0 && sndbuf_opt != conn->send_win_max) {
2784 k_mutex_lock(&conn->lock, K_FOREVER);
2785
2786 conn->send_win_max = sndbuf_opt;
2787 if (conn->send_win > conn->send_win_max) {
2788 conn->send_win = conn->send_win_max;
2789 }
2790
2791 k_mutex_unlock(&conn->lock);
2792 }
2793
2794 if (rcvbuf_opt > 0 && rcvbuf_opt != conn->recv_win_max) {
2795 int diff;
2796
2797 k_mutex_lock(&conn->lock, K_FOREVER);
2798
2799 diff = rcvbuf_opt - conn->recv_win_max;
2800 conn->recv_win_max = rcvbuf_opt;
2801 tcp_update_recv_wnd(conn, diff);
2802
2803 k_mutex_unlock(&conn->lock);
2804 }
2805 }
2806
2807 /* TCP state machine, everything happens here */
tcp_in(struct tcp * conn,struct net_pkt * pkt)2808 static enum net_verdict tcp_in(struct tcp *conn, struct net_pkt *pkt)
2809 {
2810 struct tcphdr *th = pkt ? th_get(pkt) : NULL;
2811 uint8_t next = 0, fl = 0;
2812 bool do_close = false;
2813 bool connection_ok = false;
2814 size_t tcp_options_len = th ? (th_off(th) - 5) * 4 : 0;
2815 struct net_conn *conn_handler = NULL;
2816 struct net_pkt *recv_pkt;
2817 void *recv_user_data;
2818 struct k_fifo *recv_data_fifo;
2819 size_t len;
2820 int ret;
2821 int close_status = 0;
2822 enum net_verdict verdict = NET_DROP;
2823
2824 if (th) {
2825 /* Currently we ignore ECN and CWR flags */
2826 fl = th_flags(th) & ~(ECN | CWR);
2827 }
2828
2829 if (conn->state != TCP_SYN_SENT) {
2830 tcp_check_sock_options(conn);
2831 }
2832
2833 k_mutex_lock(&conn->lock, K_FOREVER);
2834
2835 /* Connection context was already freed. */
2836 if (conn->state == TCP_UNUSED) {
2837 k_mutex_unlock(&conn->lock);
2838 return NET_DROP;
2839 }
2840
2841 NET_DBG("%s", tcp_conn_state(conn, pkt));
2842
2843 if (th && th_off(th) < 5) {
2844 tcp_out(conn, RST);
2845 do_close = true;
2846 close_status = -ECONNRESET;
2847 goto out;
2848 }
2849
2850 if (FL(&fl, &, RST)) {
2851 /* We only accept RST packet that has valid seq field. */
2852 if (!tcp_validate_seq(conn, th)) {
2853 net_stats_update_tcp_seg_rsterr(net_pkt_iface(pkt));
2854 k_mutex_unlock(&conn->lock);
2855 return NET_DROP;
2856 }
2857
2858 /* Valid RST received. */
2859 verdict = NET_OK;
2860 net_stats_update_tcp_seg_rst(net_pkt_iface(pkt));
2861 do_close = true;
2862 close_status = -ECONNRESET;
2863
2864 /* If we receive RST and ACK for the sent SYN, it means
2865 * that there is no socket listening the port we are trying
2866 * to connect to. Set the errno properly in this case.
2867 */
2868 if (conn->in_connect) {
2869 fl = th_flags(th);
2870 if (FL(&fl, ==, RST | ACK)) {
2871 close_status = -ECONNREFUSED;
2872 }
2873 }
2874
2875 goto out;
2876 }
2877
2878 if (tcp_options_len && !tcp_options_check(&conn->recv_options, pkt,
2879 tcp_options_len)) {
2880 NET_DBG("DROP: Invalid TCP option list");
2881 tcp_out(conn, RST);
2882 do_close = true;
2883 close_status = -ECONNRESET;
2884 goto out;
2885 }
2886
2887 if (th && (conn->state != TCP_LISTEN) && (conn->state != TCP_SYN_SENT) &&
2888 tcp_validate_seq(conn, th) && FL(&fl, &, SYN)) {
2889 /* According to RFC 793, ch 3.9 Event Processing, receiving SYN
2890 * once the connection has been established is an error
2891 * condition, reset should be sent and connection closed.
2892 */
2893 NET_DBG("conn: %p, SYN received in %s state, dropping connection",
2894 conn, tcp_state_to_str(conn->state, false));
2895 net_stats_update_tcp_seg_drop(conn->iface);
2896 tcp_out(conn, RST);
2897 do_close = true;
2898 close_status = -ECONNRESET;
2899 goto out;
2900 }
2901
2902 if (th) {
2903 conn->send_win = ntohs(th_win(th));
2904 if (conn->send_win > conn->send_win_max) {
2905 NET_DBG("Lowering send window from %u to %u",
2906 conn->send_win, conn->send_win_max);
2907
2908 conn->send_win = conn->send_win_max;
2909 }
2910
2911 if (conn->send_win == 0) {
2912 if (!k_work_delayable_is_pending(&conn->persist_timer)) {
2913 conn->zwp_retries = 0;
2914 (void)k_work_reschedule_for_queue(
2915 &tcp_work_q, &conn->persist_timer,
2916 K_MSEC(TCP_RTO_MS));
2917 }
2918 } else {
2919 (void)k_work_cancel_delayable(&conn->persist_timer);
2920 }
2921
2922 if (tcp_window_full(conn)) {
2923 (void)k_sem_take(&conn->tx_sem, K_NO_WAIT);
2924 } else {
2925 k_sem_give(&conn->tx_sem);
2926 }
2927 }
2928
2929 next_state:
2930 len = pkt ? tcp_data_len(pkt) : 0;
2931
2932 switch (conn->state) {
2933 case TCP_LISTEN:
2934 if (FL(&fl, ==, SYN)) {
2935 /* Make sure our MSS is also sent in the ACK */
2936 conn->send_options.mss_found = true;
2937 conn_ack(conn, th_seq(th) + 1); /* capture peer's isn */
2938 tcp_out(conn, SYN | ACK);
2939 conn->send_options.mss_found = false;
2940 conn_seq(conn, + 1);
2941 next = TCP_SYN_RECEIVED;
2942
2943 /* Close the connection if we do not receive ACK on time.
2944 */
2945 k_work_reschedule_for_queue(&tcp_work_q,
2946 &conn->establish_timer,
2947 ACK_TIMEOUT);
2948 verdict = NET_OK;
2949 } else {
2950 conn->send_options.mss_found = true;
2951 ret = tcp_out_ext(conn, SYN, NULL /* no data */, conn->seq);
2952 if (ret < 0) {
2953 do_close = true;
2954 close_status = ret;
2955 } else {
2956 conn->send_options.mss_found = false;
2957 conn_seq(conn, + 1);
2958 next = TCP_SYN_SENT;
2959 tcp_conn_ref(conn);
2960 }
2961 }
2962 break;
2963 case TCP_SYN_RECEIVED:
2964 if (FL(&fl, &, ACK, th_ack(th) == conn->seq &&
2965 th_seq(th) == conn->ack)) {
2966 net_tcp_accept_cb_t accept_cb = NULL;
2967 struct net_context *context = NULL;
2968
2969 if (conn->accepted_conn != NULL) {
2970 accept_cb = conn->accepted_conn->accept_cb;
2971 context = conn->accepted_conn->context;
2972 keep_alive_param_copy(conn, conn->accepted_conn);
2973 }
2974
2975 k_work_cancel_delayable(&conn->establish_timer);
2976 tcp_send_timer_cancel(conn);
2977 tcp_conn_ref(conn);
2978 net_context_set_state(conn->context,
2979 NET_CONTEXT_CONNECTED);
2980
2981 /* Make sure the accept_cb is only called once. */
2982 conn->accepted_conn = NULL;
2983
2984 if (accept_cb == NULL) {
2985 /* In case of no accept_cb registered,
2986 * application will not take ownership of the
2987 * connection. To prevent connection leak, unref
2988 * the TCP context and put the connection into
2989 * active close (TCP_FIN_WAIT_1).
2990 */
2991 net_tcp_put(conn->context);
2992 break;
2993 }
2994
2995 keep_alive_timer_restart(conn);
2996
2997 net_ipaddr_copy(&conn->context->remote, &conn->dst.sa);
2998
2999 /* Check if v4-mapping-to-v6 needs to be done for
3000 * the accepted socket.
3001 */
3002 if (IS_ENABLED(CONFIG_NET_IPV4_MAPPING_TO_IPV6) &&
3003 net_context_get_family(conn->context) == AF_INET &&
3004 net_context_get_family(context) == AF_INET6 &&
3005 !net_context_is_v6only_set(context)) {
3006 struct in6_addr mapped;
3007
3008 net_ipv6_addr_create_v4_mapped(
3009 &net_sin(&conn->context->remote)->sin_addr,
3010 &mapped);
3011 net_ipaddr_copy(&net_sin6(&conn->context->remote)->sin6_addr,
3012 &mapped);
3013
3014 net_sin6(&conn->context->remote)->sin6_family = AF_INET6;
3015
3016 NET_DBG("Setting v4 mapped address %s",
3017 net_sprint_ipv6_addr(&mapped));
3018
3019 /* Note that we cannot set the local address to IPv6 one
3020 * as that is used to match the connection, and not just
3021 * for printing. The remote address is only used for
3022 * passing it to accept() and printing it by "net conn"
3023 * command.
3024 */
3025 }
3026
3027 accept_cb(conn->context, &conn->context->remote,
3028 net_context_get_family(context) == AF_INET6 ?
3029 sizeof(struct sockaddr_in6) : sizeof(struct sockaddr_in),
3030 0, context);
3031
3032 next = TCP_ESTABLISHED;
3033
3034 tcp_ca_init(conn);
3035
3036 if (len) {
3037 verdict = tcp_data_get(conn, pkt, &len);
3038 if (verdict == NET_OK) {
3039 /* net_pkt owned by the recv fifo now */
3040 pkt = NULL;
3041 }
3042
3043 conn_ack(conn, + len);
3044 tcp_out(conn, ACK);
3045 } else {
3046 verdict = NET_OK;
3047 }
3048
3049 /* ACK for SYN | ACK has been received. This signilizes that
3050 * the connection makes a "forward progress".
3051 */
3052 tcp_nbr_reachability_hint(conn);
3053 }
3054 break;
3055 case TCP_SYN_SENT:
3056 /* if we are in SYN SENT and receive only a SYN without an
3057 * ACK , shouldn't we go to SYN RECEIVED state? See Figure
3058 * 6 of RFC 793
3059 */
3060 if (FL(&fl, &, SYN | ACK, th && th_ack(th) == conn->seq)) {
3061 tcp_send_timer_cancel(conn);
3062 conn_ack(conn, th_seq(th) + 1);
3063 if (len) {
3064 verdict = tcp_data_get(conn, pkt, &len);
3065 if (verdict == NET_OK) {
3066 /* net_pkt owned by the recv fifo now */
3067 pkt = NULL;
3068 }
3069
3070 conn_ack(conn, + len);
3071 } else {
3072 verdict = NET_OK;
3073 }
3074
3075 next = TCP_ESTABLISHED;
3076 net_context_set_state(conn->context,
3077 NET_CONTEXT_CONNECTED);
3078 tcp_ca_init(conn);
3079 tcp_out(conn, ACK);
3080 keep_alive_timer_restart(conn);
3081
3082 /* The connection semaphore is released *after*
3083 * we have changed the connection state. This way
3084 * the application can send data and it is queued
3085 * properly even if this thread is running in lower
3086 * priority.
3087 */
3088 connection_ok = true;
3089
3090 /* ACK for SYN has been received. This signilizes that
3091 * the connection makes a "forward progress".
3092 */
3093 tcp_nbr_reachability_hint(conn);
3094 } else if (pkt) {
3095 net_tcp_reply_rst(pkt);
3096 }
3097
3098 break;
3099 case TCP_ESTABLISHED:
3100 /* full-close */
3101 if (th && FL(&fl, &, FIN, th_seq(th) == conn->ack)) {
3102 bool acked = false;
3103
3104 if (len) {
3105 verdict = tcp_data_get(conn, pkt, &len);
3106 if (verdict == NET_OK) {
3107 /* net_pkt owned by the recv fifo now */
3108 pkt = NULL;
3109 }
3110 } else {
3111 verdict = NET_OK;
3112 }
3113
3114 conn_ack(conn, + len + 1);
3115 keep_alive_timer_stop(conn);
3116
3117 if (FL(&fl, &, ACK)) {
3118 acked = true;
3119
3120 if (net_tcp_seq_cmp(th_ack(th), conn->seq) > 0) {
3121 uint32_t len_acked = th_ack(th) - conn->seq;
3122
3123 conn_seq(conn, + len_acked);
3124 }
3125 }
3126
3127 if (acked) {
3128 tcp_out(conn, FIN | ACK);
3129 conn_seq(conn, + 1);
3130 tcp_setup_last_ack_timer(conn);
3131 next = TCP_LAST_ACK;
3132 } else {
3133 tcp_out(conn, ACK);
3134 next = TCP_CLOSE_WAIT;
3135 }
3136
3137 break;
3138 }
3139
3140 /* Whatever we've received, we know that peer is alive, so reset
3141 * the keepalive timer.
3142 */
3143 keep_alive_timer_restart(conn);
3144
3145 #ifdef CONFIG_NET_TCP_FAST_RETRANSMIT
3146 if (th && (net_tcp_seq_cmp(th_ack(th), conn->seq) == 0)) {
3147 /* Only if there is pending data, increment the duplicate ack count */
3148 if (conn->send_data_total > 0) {
3149 /* There could be also payload, only without payload account them */
3150 if (len == 0) {
3151 /* Increment the duplicate acc counter,
3152 * but maximize the value
3153 */
3154 conn->dup_ack_cnt = MIN(conn->dup_ack_cnt + 1,
3155 DUPLICATE_ACK_RETRANSMIT_TRHESHOLD + 1);
3156 tcp_ca_dup_ack(conn);
3157 }
3158 } else {
3159 conn->dup_ack_cnt = 0;
3160 }
3161
3162 /* Only do fast retransmit when not already in a resend state */
3163 if ((conn->data_mode == TCP_DATA_MODE_SEND) &&
3164 (conn->dup_ack_cnt == DUPLICATE_ACK_RETRANSMIT_TRHESHOLD)) {
3165 /* Apply a fast retransmit */
3166 int temp_unacked_len = conn->unacked_len;
3167
3168 conn->unacked_len = 0;
3169
3170 (void)tcp_send_data(conn);
3171
3172 /* Restore the current transmission */
3173 conn->unacked_len = temp_unacked_len;
3174
3175 tcp_ca_fast_retransmit(conn);
3176 if (tcp_window_full(conn)) {
3177 (void)k_sem_take(&conn->tx_sem, K_NO_WAIT);
3178 }
3179 }
3180 }
3181 #endif
3182 NET_ASSERT((conn->send_data_total == 0) ||
3183 k_work_delayable_is_pending(&conn->send_data_timer),
3184 "conn: %p, Missing a subscription "
3185 "of the send_data queue timer", conn);
3186
3187 if (th && (net_tcp_seq_cmp(th_ack(th), conn->seq) > 0)) {
3188 uint32_t len_acked = th_ack(th) - conn->seq;
3189
3190 NET_DBG("conn: %p len_acked=%u", conn, len_acked);
3191
3192 if ((conn->send_data_total < len_acked) ||
3193 (tcp_pkt_pull(conn->send_data,
3194 len_acked) < 0)) {
3195 NET_ERR("conn: %p, Invalid len_acked=%u "
3196 "(total=%zu)", conn, len_acked,
3197 conn->send_data_total);
3198 net_stats_update_tcp_seg_drop(conn->iface);
3199 tcp_out(conn, RST);
3200 do_close = true;
3201 close_status = -ECONNRESET;
3202 break;
3203 }
3204
3205 #ifdef CONFIG_NET_TCP_FAST_RETRANSMIT
3206 /* New segment, reset duplicate ack counter */
3207 conn->dup_ack_cnt = 0;
3208 #endif
3209 tcp_ca_pkts_acked(conn, len_acked);
3210
3211 conn->send_data_total -= len_acked;
3212 if (conn->unacked_len < len_acked) {
3213 conn->unacked_len = 0;
3214 } else {
3215 conn->unacked_len -= len_acked;
3216 }
3217
3218 if (!tcp_window_full(conn)) {
3219 k_sem_give(&conn->tx_sem);
3220 }
3221
3222 conn_seq(conn, + len_acked);
3223 net_stats_update_tcp_seg_recv(conn->iface);
3224
3225 /* Receipt of an acknowledgment that covers a sequence number
3226 * not previously acknowledged indicates that the connection
3227 * makes a "forward progress".
3228 */
3229 tcp_nbr_reachability_hint(conn);
3230
3231 conn_send_data_dump(conn);
3232
3233 conn->send_data_retries = 0;
3234 if (conn->data_mode == TCP_DATA_MODE_RESEND) {
3235 conn->unacked_len = 0;
3236 tcp_derive_rto(conn);
3237 }
3238 conn->data_mode = TCP_DATA_MODE_SEND;
3239 if (conn->send_data_total > 0) {
3240 k_work_reschedule_for_queue(&tcp_work_q, &conn->send_data_timer,
3241 K_MSEC(TCP_RTO_MS));
3242 }
3243
3244 /* We are closing the connection, send a FIN to peer */
3245 if (conn->in_close && conn->send_data_total == 0) {
3246 tcp_send_timer_cancel(conn);
3247 next = TCP_FIN_WAIT_1;
3248
3249 k_work_reschedule_for_queue(&tcp_work_q,
3250 &conn->fin_timer,
3251 FIN_TIMEOUT);
3252
3253 tcp_out(conn, FIN | ACK);
3254 conn_seq(conn, + 1);
3255 verdict = NET_OK;
3256 keep_alive_timer_stop(conn);
3257 break;
3258 }
3259
3260 ret = tcp_send_queued_data(conn);
3261 if (ret < 0 && ret != -ENOBUFS) {
3262 tcp_out(conn, RST);
3263 do_close = true;
3264 close_status = ret;
3265 verdict = NET_OK;
3266 break;
3267 }
3268
3269 if (tcp_window_full(conn)) {
3270 (void)k_sem_take(&conn->tx_sem, K_NO_WAIT);
3271 }
3272 }
3273
3274 if (th) {
3275 if (th_seq(th) == conn->ack) {
3276 if (len > 0) {
3277 bool psh = FL(&fl, &, PSH);
3278
3279 verdict = tcp_data_received(conn, pkt, &len, psh);
3280 if (verdict == NET_OK) {
3281 /* net_pkt owned by the recv fifo now */
3282 pkt = NULL;
3283 }
3284 } else {
3285 /* ACK, no data */
3286 verdict = NET_OK;
3287 }
3288 } else if (net_tcp_seq_greater(conn->ack, th_seq(th))) {
3289 /* This should handle the acknowledgements of keep alive
3290 * packets and retransmitted data.
3291 * RISK:
3292 * There is a tiny risk of creating a ACK loop this way when
3293 * both ends of the connection are out of order due to packet
3294 * loss is a simultaneous bidirectional data flow.
3295 */
3296 tcp_out(conn, ACK); /* peer has resent */
3297
3298 net_stats_update_tcp_seg_ackerr(conn->iface);
3299 verdict = NET_OK;
3300 } else if (CONFIG_NET_TCP_RECV_QUEUE_TIMEOUT) {
3301 tcp_out_of_order_data(conn, pkt, len,
3302 th_seq(th));
3303 /* Send out a duplicated ACK */
3304 if ((len > 0) || FL(&fl, &, FIN)) {
3305 tcp_out(conn, ACK);
3306 }
3307
3308 verdict = NET_OK;
3309 }
3310 }
3311
3312 /* Check if there is any data left to retransmit possibly*/
3313 if (conn->send_data_total == 0) {
3314 conn->send_data_retries = 0;
3315 k_work_cancel_delayable(&conn->send_data_timer);
3316 }
3317
3318 /* A lot could have happened to the transmission window check the situation here */
3319 if (tcp_window_full(conn)) {
3320 (void)k_sem_take(&conn->tx_sem, K_NO_WAIT);
3321 } else {
3322 k_sem_give(&conn->tx_sem);
3323 }
3324
3325 break;
3326 case TCP_CLOSE_WAIT:
3327 tcp_out(conn, FIN);
3328 conn_seq(conn, + 1);
3329 next = TCP_LAST_ACK;
3330 tcp_setup_last_ack_timer(conn);
3331 break;
3332 case TCP_LAST_ACK:
3333 if (th && FL(&fl, ==, ACK, th_ack(th) == conn->seq)) {
3334 tcp_send_timer_cancel(conn);
3335 do_close = true;
3336 verdict = NET_OK;
3337 close_status = 0;
3338
3339 /* Remove the last ack timer if we received it in time */
3340 tcp_cancel_last_ack_timer(conn);
3341 }
3342 break;
3343 case TCP_CLOSED:
3344 break;
3345 case TCP_FIN_WAIT_1:
3346 /*
3347 * FIN1:
3348 * Acknowledge path and sequence path are independent, treat them that way
3349 * The table of incoming messages and their destination states:
3350 * - & - -> TCP_FIN_WAIT_1
3351 * FIN & - -> TCP_CLOSING
3352 * - & ACK -> TCP_FIN_WAIT_2
3353 * FIN & ACK -> TCP_TIME_WAIT
3354 */
3355 if (th) {
3356 bool fin_acked = false;
3357
3358 if (tcp_compute_new_length(conn, th, len, false) > 0) {
3359 /* We do not implement half closed sockets, therefore
3360 * cannot accept new data in after sending our FIN, as
3361 * we are in sequence can send a reset now.
3362 */
3363 net_stats_update_tcp_seg_drop(conn->iface);
3364
3365 next = tcp_enter_time_wait(conn);
3366
3367 tcp_out(conn, RST);
3368 break;
3369 }
3370 if (FL(&fl, &, ACK, th_ack(th) == conn->seq)) {
3371 NET_DBG("conn %p: FIN acknowledged, going to FIN_WAIT_2 "
3372 "state seq %u, ack %u"
3373 , conn, conn->seq, conn->ack);
3374 tcp_send_timer_cancel(conn);
3375 fin_acked = true;
3376 next = TCP_FIN_WAIT_2;
3377 verdict = NET_OK;
3378 }
3379
3380 /*
3381 * There can also be data in the message, so compute with the length
3382 * of the packet to check the sequence number of the FIN flag with the ACK
3383 */
3384 if (FL(&fl, &, FIN, net_tcp_seq_cmp(th_seq(th) + len, conn->ack) == 0)) {
3385 conn_ack(conn, + 1);
3386
3387 /* State path is dependent on if the acknowledge is in */
3388 if (fin_acked) {
3389 /* Already acknowledged, we can go further */
3390 NET_DBG("conn %p: FIN received, going to TIME WAIT", conn);
3391
3392 next = tcp_enter_time_wait(conn);
3393
3394 tcp_out(conn, ACK);
3395 } else {
3396 /* Fin not yet acknowledged, waiting for the ack in CLOSING
3397 */
3398 NET_DBG("conn %p: FIN received, going to CLOSING as no "
3399 "ACK has been received", conn);
3400 tcp_send_timer_cancel(conn);
3401 tcp_out_ext(conn, FIN | ACK, NULL, conn->seq - 1);
3402 next = TCP_CLOSING;
3403 }
3404 verdict = NET_OK;
3405 } else {
3406 if (len > 0) {
3407 if (fin_acked) {
3408 /* Send out a duplicate ACK */
3409 tcp_send_timer_cancel(conn);
3410 tcp_out(conn, ACK);
3411 } else {
3412 /* In FIN1 state
3413 * Send out a duplicate ACK, with the pending FIN
3414 * flag
3415 */
3416 tcp_send_timer_cancel(conn);
3417 tcp_out_ext(conn, FIN | ACK, NULL, conn->seq - 1);
3418 }
3419 verdict = NET_OK;
3420 }
3421 }
3422 }
3423 break;
3424 case TCP_FIN_WAIT_2:
3425 /*
3426 * FIN2:
3427 * Only FIN is relevant in this state, as our FIN was already acknowledged
3428 * - -> TCP_FIN_WAIT_2
3429 * FIN -> TCP_TIME_WAIT
3430 */
3431 if (th) {
3432 /* No tcp_send_timer_cancel call required here, as is has been called
3433 * before entering this state, only allowed through the
3434 * tcp_enter_time_wait function.
3435 */
3436
3437 /* Compute if there is new data after our close */
3438 if (tcp_compute_new_length(conn, th, len, false) > 0) {
3439 /* We do not implement half closed sockets, therefore
3440 * cannot accept new data in after sending our FIN, as
3441 * we are in sequence can send a reset now.
3442 */
3443 net_stats_update_tcp_seg_drop(conn->iface);
3444
3445 next = tcp_enter_time_wait(conn);
3446
3447 tcp_out(conn, RST);
3448 break;
3449 }
3450 /*
3451 * There can also be data in the message, so compute with the length
3452 * of the packet to check the sequence number of the FIN flag with the ACK
3453 */
3454 if (FL(&fl, &, FIN, net_tcp_seq_cmp(th_seq(th) + len, conn->ack) == 0)) {
3455 conn_ack(conn, + 1);
3456 NET_DBG("conn %p: FIN received, going to TIME WAIT", conn);
3457
3458 next = tcp_enter_time_wait(conn);
3459
3460 verdict = NET_OK;
3461 tcp_out(conn, ACK);
3462 } else {
3463 if (len > 0) {
3464 /* Send out a duplicate ACK */
3465 tcp_out(conn, ACK);
3466 verdict = NET_OK;
3467 }
3468 }
3469 }
3470 break;
3471 case TCP_CLOSING:
3472 if (th) {
3473 bool fin_acked = false;
3474
3475 /*
3476 * Closing:
3477 * Our FIN has to be acknowledged
3478 * - -> TCP_CLOSING
3479 * ACK -> TCP_TIME_WAIT
3480 */
3481 int32_t new_len = tcp_compute_new_length(conn, th, len, true);
3482
3483 if (new_len > 0) {
3484 /* This should not happen here, as no data can be send after
3485 * the FIN flag has been send.
3486 */
3487 NET_ERR("conn: %p, new bytes %u during CLOSING state "
3488 "sending reset", conn, new_len);
3489 net_stats_update_tcp_seg_drop(conn->iface);
3490
3491 next = tcp_enter_time_wait(conn);
3492
3493 tcp_out(conn, RST);
3494 break;
3495 }
3496
3497 if (FL(&fl, &, ACK, th_ack(th) == conn->seq)) {
3498 NET_DBG("conn %p: FIN acknowledged, going to TIME WAIT "
3499 "state seq %u, ack %u"
3500 , conn, conn->seq, conn->ack);
3501
3502 next = tcp_enter_time_wait(conn);
3503 fin_acked = true;
3504
3505 verdict = NET_OK;
3506 }
3507
3508 /*
3509 * There can also be data in the message, so compute with the length
3510 * of the packet to check with the ack
3511 * Since the conn->ack was already incremented in TCP_FIN_WAIT_1
3512 * add 1 in the comparison sequence
3513 */
3514 if ((FL(&fl, &, FIN,
3515 net_tcp_seq_cmp(th_seq(th) + len + 1, conn->ack) == 0)) ||
3516 (len > 0)) {
3517 tcp_send_timer_cancel(conn);
3518 if (fin_acked) {
3519 /* Send out a duplicate ACK */
3520 tcp_out(conn, ACK);
3521 } else {
3522 /* Send out a duplicate ACK, with the pending FIN
3523 * flag
3524 */
3525 tcp_out_ext(conn, FIN | ACK, NULL, conn->seq - 1);
3526 }
3527 verdict = NET_OK;
3528 }
3529 }
3530 break;
3531 case TCP_TIME_WAIT:
3532 if (th) {
3533 int32_t new_len = tcp_compute_new_length(conn, th, len, true);
3534
3535 /* No tcp_send_timer_cancel call required here, as is has been called
3536 * before entering this state, only allowed through the
3537 * tcp_enter_time_wait function.
3538 */
3539
3540 if (new_len > 0) {
3541 /* This should not happen here, as no data can be send after
3542 * the FIN flag has been send.
3543 */
3544 NET_ERR("conn: %p, new bytes %u during TIME-WAIT state "
3545 "sending reset", conn, new_len);
3546 net_stats_update_tcp_seg_drop(conn->iface);
3547
3548 tcp_out(conn, RST);
3549 } else {
3550 /* Acknowledge any FIN attempts, in case retransmission took
3551 * place.
3552 */
3553 if ((FL(&fl, &, FIN,
3554 net_tcp_seq_cmp(th_seq(th) + 1, conn->ack) == 0)) ||
3555 (len > 0)) {
3556 tcp_out(conn, ACK);
3557 verdict = NET_OK;
3558 }
3559 }
3560 }
3561 break;
3562 default:
3563 NET_ASSERT(false, "%s is unimplemented",
3564 tcp_state_to_str(conn->state, true));
3565 }
3566
3567 out:
3568 if (pkt) {
3569 if (verdict == NET_OK) {
3570 net_pkt_unref(pkt);
3571 }
3572
3573 pkt = NULL;
3574 }
3575
3576 if (next) {
3577 th = NULL;
3578 conn_state(conn, next);
3579 next = 0;
3580
3581 if (connection_ok) {
3582 conn->in_connect = false;
3583 if (conn->connect_cb) {
3584 conn->connect_cb(conn->context, 0, conn->context->user_data);
3585
3586 /* Make sure the connect_cb is only called once. */
3587 conn->connect_cb = NULL;
3588 }
3589
3590 k_sem_give(&conn->connect_sem);
3591 }
3592
3593 goto next_state;
3594 }
3595
3596 if (conn->context) {
3597 /* If the conn->context is not set, then the connection was
3598 * already closed.
3599 */
3600 conn_handler = (struct net_conn *)conn->context->conn_handler;
3601 }
3602
3603 recv_user_data = conn->recv_user_data;
3604 recv_data_fifo = &conn->recv_data;
3605
3606 k_mutex_unlock(&conn->lock);
3607
3608 /* Pass all the received data stored in recv fifo to the application.
3609 * This is done like this so that we do not have any connection lock
3610 * held.
3611 */
3612 while (conn_handler && atomic_get(&conn->ref_count) > 0 &&
3613 (recv_pkt = k_fifo_get(recv_data_fifo, K_NO_WAIT)) != NULL) {
3614 if (net_context_packet_received(conn_handler, recv_pkt, NULL,
3615 NULL, recv_user_data) ==
3616 NET_DROP) {
3617 /* Application is no longer there, unref the pkt */
3618 tcp_pkt_unref(recv_pkt);
3619 }
3620 }
3621
3622 /* Make sure we close the connection only once by checking connection
3623 * state.
3624 */
3625 if (do_close && conn->state != TCP_UNUSED && conn->state != TCP_CLOSED) {
3626 tcp_conn_close(conn, close_status);
3627 }
3628
3629 return verdict;
3630 }
3631
3632 /* Active connection close: send FIN and go to FIN_WAIT_1 state */
net_tcp_put(struct net_context * context)3633 int net_tcp_put(struct net_context *context)
3634 {
3635 struct tcp *conn = context->tcp;
3636
3637 if (!conn) {
3638 return -ENOENT;
3639 }
3640
3641 k_mutex_lock(&conn->lock, K_FOREVER);
3642
3643 NET_DBG("%s", conn ? tcp_conn_state(conn, NULL) : "");
3644 NET_DBG("context %p %s", context,
3645 ({ const char *state = net_context_state(context);
3646 state ? state : "<unknown>"; }));
3647
3648 if (conn && (conn->state == TCP_ESTABLISHED ||
3649 conn->state == TCP_SYN_RECEIVED)) {
3650 /* Send all remaining data if possible. */
3651 if (conn->send_data_total > 0) {
3652 NET_DBG("conn %p pending %zu bytes", conn,
3653 conn->send_data_total);
3654 conn->in_close = true;
3655
3656 /* How long to wait until all the data has been sent?
3657 */
3658 k_work_reschedule_for_queue(&tcp_work_q,
3659 &conn->send_data_timer,
3660 K_MSEC(TCP_RTO_MS));
3661 } else {
3662 int ret;
3663
3664 NET_DBG("TCP connection in %s close, "
3665 "not disposing yet (waiting %dms)",
3666 "active", tcp_max_timeout_ms);
3667 k_work_reschedule_for_queue(&tcp_work_q,
3668 &conn->fin_timer,
3669 FIN_TIMEOUT);
3670
3671 ret = tcp_out_ext(conn, FIN | ACK, NULL,
3672 conn->seq + conn->unacked_len);
3673 if (ret == 0) {
3674 conn_seq(conn, + 1);
3675 }
3676
3677 conn_state(conn, TCP_FIN_WAIT_1);
3678
3679 keep_alive_timer_stop(conn);
3680 }
3681 } else if (conn && conn->in_connect) {
3682 conn->in_connect = false;
3683 }
3684
3685 k_mutex_unlock(&conn->lock);
3686
3687 tcp_conn_unref(conn);
3688
3689 return 0;
3690 }
3691
net_tcp_listen(struct net_context * context)3692 int net_tcp_listen(struct net_context *context)
3693 {
3694 /* when created, tcp connections are in state TCP_LISTEN */
3695 net_context_set_state(context, NET_CONTEXT_LISTENING);
3696
3697 return 0;
3698 }
3699
net_tcp_update_recv_wnd(struct net_context * context,int32_t delta)3700 int net_tcp_update_recv_wnd(struct net_context *context, int32_t delta)
3701 {
3702 struct tcp *conn = context->tcp;
3703 int ret;
3704
3705 if (!conn) {
3706 NET_ERR("context->tcp == NULL");
3707 return -EPROTOTYPE;
3708 }
3709
3710 k_mutex_lock(&conn->lock, K_FOREVER);
3711
3712 ret = tcp_update_recv_wnd((struct tcp *)context->tcp, delta);
3713
3714 k_mutex_unlock(&conn->lock);
3715
3716 return ret;
3717 }
3718
net_tcp_queue(struct net_context * context,const void * data,size_t len,const struct msghdr * msg)3719 int net_tcp_queue(struct net_context *context, const void *data, size_t len,
3720 const struct msghdr *msg)
3721 {
3722 struct tcp *conn = context->tcp;
3723 size_t queued_len = 0;
3724 int ret = 0;
3725
3726 if (!conn || conn->state != TCP_ESTABLISHED) {
3727 return -ENOTCONN;
3728 }
3729
3730 k_mutex_lock(&conn->lock, K_FOREVER);
3731
3732 /* If there is no space to transmit, try at a later time.
3733 * The ZWP will make sure the window becomes available at
3734 * some point in time.
3735 */
3736 if (tcp_window_full(conn)) {
3737 ret = -EAGAIN;
3738 goto out;
3739 }
3740
3741 if (msg) {
3742 len = 0;
3743
3744 for (int i = 0; i < msg->msg_iovlen; i++) {
3745 len += msg->msg_iov[i].iov_len;
3746 }
3747 }
3748
3749 /* Queue no more than TX window permits. It's guaranteed at this point
3750 * that conn->send_data_total is less than conn->send_win, as it was
3751 * verified in tcp_window_full() check above. As the connection mutex
3752 * is held, their values shall not change since.
3753 */
3754 len = MIN(conn->send_win - conn->send_data_total, len);
3755
3756 if (msg) {
3757 for (int i = 0; i < msg->msg_iovlen; i++) {
3758 int iovlen = MIN(msg->msg_iov[i].iov_len, len);
3759
3760 ret = tcp_pkt_append(conn->send_data,
3761 msg->msg_iov[i].iov_base,
3762 iovlen);
3763 if (ret < 0) {
3764 if (queued_len == 0) {
3765 goto out;
3766 } else {
3767 break;
3768 }
3769 }
3770
3771 queued_len += iovlen;
3772 len -= iovlen;
3773
3774 if (len == 0) {
3775 break;
3776 }
3777 }
3778 } else {
3779 ret = tcp_pkt_append(conn->send_data, data, len);
3780 if (ret < 0) {
3781 goto out;
3782 }
3783
3784 queued_len = len;
3785 }
3786
3787 conn->send_data_total += queued_len;
3788
3789 /* Successfully queued data for transmission. Even if there's a transmit
3790 * failure now (out-of-buf case), it can be ignored for now, retransmit
3791 * timer will take care of queued data retransmission.
3792 */
3793 ret = tcp_send_queued_data(conn);
3794 if (ret < 0 && ret != -ENOBUFS) {
3795 tcp_conn_close(conn, ret);
3796 goto out;
3797 }
3798
3799 if (tcp_window_full(conn)) {
3800 (void)k_sem_take(&conn->tx_sem, K_NO_WAIT);
3801 }
3802
3803 ret = queued_len;
3804 out:
3805 k_mutex_unlock(&conn->lock);
3806
3807 return ret;
3808 }
3809
3810 /* net context is about to send out queued data - inform caller only */
net_tcp_send_data(struct net_context * context,net_context_send_cb_t cb,void * user_data)3811 int net_tcp_send_data(struct net_context *context, net_context_send_cb_t cb,
3812 void *user_data)
3813 {
3814 if (cb) {
3815 cb(context, 0, user_data);
3816 }
3817
3818 return 0;
3819 }
3820
3821 /* When connect() is called on a TCP socket, register the socket for incoming
3822 * traffic with net context and give the TCP packet receiving function, which
3823 * in turn will call tcp_in() to deliver the TCP packet to the stack
3824 */
net_tcp_connect(struct net_context * context,const struct sockaddr * remote_addr,struct sockaddr * local_addr,uint16_t remote_port,uint16_t local_port,k_timeout_t timeout,net_context_connect_cb_t cb,void * user_data)3825 int net_tcp_connect(struct net_context *context,
3826 const struct sockaddr *remote_addr,
3827 struct sockaddr *local_addr,
3828 uint16_t remote_port, uint16_t local_port,
3829 k_timeout_t timeout, net_context_connect_cb_t cb,
3830 void *user_data)
3831 {
3832 struct tcp *conn;
3833 int ret = 0;
3834
3835 NET_DBG("context: %p, local: %s, remote: %s", context,
3836 net_sprint_addr(local_addr->sa_family,
3837 (const void *)&net_sin(local_addr)->sin_addr),
3838 net_sprint_addr(remote_addr->sa_family,
3839 (const void *)&net_sin(remote_addr)->sin_addr));
3840
3841 conn = context->tcp;
3842 conn->iface = net_context_get_iface(context);
3843 tcp_derive_rto(conn);
3844
3845 switch (net_context_get_family(context)) {
3846 const struct in_addr *ip4;
3847 const struct in6_addr *ip6;
3848
3849 case AF_INET:
3850 if (!IS_ENABLED(CONFIG_NET_IPV4)) {
3851 ret = -EINVAL;
3852 goto out;
3853 }
3854
3855 memset(&conn->src, 0, sizeof(struct sockaddr_in));
3856 memset(&conn->dst, 0, sizeof(struct sockaddr_in));
3857
3858 conn->src.sa.sa_family = AF_INET;
3859 conn->dst.sa.sa_family = AF_INET;
3860
3861 conn->dst.sin.sin_port = remote_port;
3862 conn->src.sin.sin_port = local_port;
3863
3864 /* we have to select the source address here as
3865 * net_context_create_ipv4_new() is not called in the packet
3866 * output chain
3867 */
3868 if (net_ipv4_is_addr_unspecified(
3869 &net_sin(local_addr)->sin_addr)) {
3870 ip4 = net_if_ipv4_select_src_addr(
3871 net_context_get_iface(context),
3872 &net_sin(remote_addr)->sin_addr);
3873 net_ipaddr_copy(&conn->src.sin.sin_addr, ip4);
3874 } else {
3875 net_ipaddr_copy(&conn->src.sin.sin_addr,
3876 &net_sin(local_addr)->sin_addr);
3877 }
3878 net_ipaddr_copy(&conn->dst.sin.sin_addr,
3879 &net_sin(remote_addr)->sin_addr);
3880 break;
3881
3882 case AF_INET6:
3883 if (!IS_ENABLED(CONFIG_NET_IPV6)) {
3884 ret = -EINVAL;
3885 goto out;
3886 }
3887
3888 memset(&conn->src, 0, sizeof(struct sockaddr_in6));
3889 memset(&conn->dst, 0, sizeof(struct sockaddr_in6));
3890
3891 conn->src.sin6.sin6_family = AF_INET6;
3892 conn->dst.sin6.sin6_family = AF_INET6;
3893
3894 conn->dst.sin6.sin6_port = remote_port;
3895 conn->src.sin6.sin6_port = local_port;
3896
3897 if (net_ipv6_is_addr_unspecified(
3898 &net_sin6(local_addr)->sin6_addr)) {
3899 ip6 = net_if_ipv6_select_src_addr(
3900 net_context_get_iface(context),
3901 &net_sin6(remote_addr)->sin6_addr);
3902 net_ipaddr_copy(&conn->src.sin6.sin6_addr, ip6);
3903 } else {
3904 net_ipaddr_copy(&conn->src.sin6.sin6_addr,
3905 &net_sin6(local_addr)->sin6_addr);
3906 }
3907 net_ipaddr_copy(&conn->dst.sin6.sin6_addr,
3908 &net_sin6(remote_addr)->sin6_addr);
3909 break;
3910
3911 default:
3912 ret = -EPROTONOSUPPORT;
3913 }
3914
3915 if (!(IS_ENABLED(CONFIG_NET_TEST_PROTOCOL) ||
3916 IS_ENABLED(CONFIG_NET_TEST))) {
3917 conn->seq = tcp_init_isn(&conn->src.sa, &conn->dst.sa);
3918 }
3919
3920 NET_DBG("conn: %p src: %s, dst: %s", conn,
3921 net_sprint_addr(conn->src.sa.sa_family,
3922 (const void *)&conn->src.sin.sin_addr),
3923 net_sprint_addr(conn->dst.sa.sa_family,
3924 (const void *)&conn->dst.sin.sin_addr));
3925
3926 net_context_set_state(context, NET_CONTEXT_CONNECTING);
3927
3928 ret = net_conn_register(net_context_get_proto(context),
3929 net_context_get_family(context),
3930 remote_addr, local_addr,
3931 ntohs(remote_port), ntohs(local_port),
3932 context, tcp_recv, context,
3933 &context->conn_handler);
3934 if (ret < 0) {
3935 goto out;
3936 }
3937
3938 net_if_addr_ref(conn->iface, conn->src.sa.sa_family,
3939 conn->src.sa.sa_family == AF_INET ?
3940 (const void *)&conn->src.sin.sin_addr :
3941 (const void *)&conn->src.sin6.sin6_addr);
3942 conn->addr_ref_done = true;
3943
3944 conn->connect_cb = cb;
3945 context->user_data = user_data;
3946
3947 /* Input of a (nonexistent) packet with no flags set will cause
3948 * a TCP connection to be established
3949 */
3950 conn->in_connect = !IS_ENABLED(CONFIG_NET_TEST_PROTOCOL);
3951 (void)tcp_in(conn, NULL);
3952
3953 if (!IS_ENABLED(CONFIG_NET_TEST_PROTOCOL)) {
3954 if (conn->state == TCP_UNUSED || conn->state == TCP_CLOSED) {
3955 ret = -errno;
3956 goto out;
3957 } else if ((K_TIMEOUT_EQ(timeout, K_NO_WAIT)) &&
3958 conn->state != TCP_ESTABLISHED) {
3959 ret = -EINPROGRESS;
3960 goto out;
3961 } else if (k_sem_take(&conn->connect_sem, timeout) != 0 &&
3962 conn->state != TCP_ESTABLISHED) {
3963 if (conn->in_connect) {
3964 conn->in_connect = false;
3965 tcp_conn_close(conn, -ETIMEDOUT);
3966 }
3967
3968 ret = -ETIMEDOUT;
3969 goto out;
3970 }
3971 conn->in_connect = false;
3972 }
3973 out:
3974 NET_DBG("conn: %p, ret=%d", conn, ret);
3975
3976 return ret;
3977 }
3978
net_tcp_accept(struct net_context * context,net_tcp_accept_cb_t cb,void * user_data)3979 int net_tcp_accept(struct net_context *context, net_tcp_accept_cb_t cb,
3980 void *user_data)
3981 {
3982 struct tcp *conn = context->tcp;
3983 struct sockaddr local_addr = { };
3984 uint16_t local_port, remote_port;
3985
3986 if (!conn) {
3987 return -EINVAL;
3988 }
3989
3990 NET_DBG("context: %p, tcp: %p, cb: %p", context, conn, cb);
3991
3992 if (conn->state != TCP_LISTEN) {
3993 return -EINVAL;
3994 }
3995
3996 conn->accept_cb = cb;
3997 local_addr.sa_family = net_context_get_family(context);
3998
3999 switch (local_addr.sa_family) {
4000 struct sockaddr_in *in;
4001 struct sockaddr_in6 *in6;
4002
4003 case AF_INET:
4004 if (!IS_ENABLED(CONFIG_NET_IPV4)) {
4005 return -EINVAL;
4006 }
4007
4008 in = (struct sockaddr_in *)&local_addr;
4009
4010 if (net_sin_ptr(&context->local)->sin_addr) {
4011 net_ipaddr_copy(&in->sin_addr,
4012 net_sin_ptr(&context->local)->sin_addr);
4013 }
4014
4015 in->sin_port =
4016 net_sin((struct sockaddr *)&context->local)->sin_port;
4017 local_port = ntohs(in->sin_port);
4018 remote_port = ntohs(net_sin(&context->remote)->sin_port);
4019
4020 break;
4021
4022 case AF_INET6:
4023 if (!IS_ENABLED(CONFIG_NET_IPV6)) {
4024 return -EINVAL;
4025 }
4026
4027 in6 = (struct sockaddr_in6 *)&local_addr;
4028
4029 if (net_sin6_ptr(&context->local)->sin6_addr) {
4030 net_ipaddr_copy(&in6->sin6_addr,
4031 net_sin6_ptr(&context->local)->sin6_addr);
4032 }
4033
4034 in6->sin6_port =
4035 net_sin6((struct sockaddr *)&context->local)->sin6_port;
4036 local_port = ntohs(in6->sin6_port);
4037 remote_port = ntohs(net_sin6(&context->remote)->sin6_port);
4038
4039 break;
4040
4041 default:
4042 return -EINVAL;
4043 }
4044
4045 context->user_data = user_data;
4046
4047 /* Remove the temporary connection handler and register
4048 * a proper now as we have an established connection.
4049 */
4050 net_conn_unregister(context->conn_handler);
4051
4052 return net_conn_register(net_context_get_proto(context),
4053 local_addr.sa_family,
4054 context->flags & NET_CONTEXT_REMOTE_ADDR_SET ?
4055 &context->remote : NULL,
4056 &local_addr,
4057 remote_port, local_port,
4058 context, tcp_recv, context,
4059 &context->conn_handler);
4060 }
4061
net_tcp_recv(struct net_context * context,net_context_recv_cb_t cb,void * user_data)4062 int net_tcp_recv(struct net_context *context, net_context_recv_cb_t cb,
4063 void *user_data)
4064 {
4065 struct tcp *conn = context->tcp;
4066
4067 NET_DBG("context: %p, cb: %p, user_data: %p", context, cb, user_data);
4068
4069 context->recv_cb = cb;
4070
4071 if (conn) {
4072 conn->recv_user_data = user_data;
4073 }
4074
4075 return 0;
4076 }
4077
net_tcp_finalize(struct net_pkt * pkt,bool force_chksum)4078 int net_tcp_finalize(struct net_pkt *pkt, bool force_chksum)
4079 {
4080 NET_PKT_DATA_ACCESS_DEFINE(tcp_access, struct net_tcp_hdr);
4081 struct net_tcp_hdr *tcp_hdr;
4082 enum net_if_checksum_type type = net_pkt_family(pkt) == AF_INET6 ?
4083 NET_IF_CHECKSUM_IPV6_TCP : NET_IF_CHECKSUM_IPV4_TCP;
4084
4085 tcp_hdr = (struct net_tcp_hdr *)net_pkt_get_data(pkt, &tcp_access);
4086 if (!tcp_hdr) {
4087 return -ENOBUFS;
4088 }
4089
4090 tcp_hdr->chksum = 0U;
4091
4092 if (net_if_need_calc_tx_checksum(net_pkt_iface(pkt), type) || force_chksum) {
4093 tcp_hdr->chksum = net_calc_chksum_tcp(pkt);
4094 net_pkt_set_chksum_done(pkt, true);
4095 }
4096
4097 return net_pkt_set_data(pkt, &tcp_access);
4098 }
4099
net_tcp_input(struct net_pkt * pkt,struct net_pkt_data_access * tcp_access)4100 struct net_tcp_hdr *net_tcp_input(struct net_pkt *pkt,
4101 struct net_pkt_data_access *tcp_access)
4102 {
4103 struct net_tcp_hdr *tcp_hdr;
4104 enum net_if_checksum_type type = net_pkt_family(pkt) == AF_INET6 ?
4105 NET_IF_CHECKSUM_IPV6_TCP : NET_IF_CHECKSUM_IPV4_TCP;
4106
4107 if (IS_ENABLED(CONFIG_NET_TCP_CHECKSUM) &&
4108 (net_if_need_calc_rx_checksum(net_pkt_iface(pkt), type) ||
4109 net_pkt_is_ip_reassembled(pkt)) &&
4110 net_calc_chksum_tcp(pkt) != 0U) {
4111 NET_DBG("DROP: checksum mismatch");
4112 goto drop;
4113 }
4114
4115 tcp_hdr = (struct net_tcp_hdr *)net_pkt_get_data(pkt, tcp_access);
4116 if (tcp_hdr && !net_pkt_set_data(pkt, tcp_access)) {
4117 return tcp_hdr;
4118 }
4119
4120 drop:
4121 net_stats_update_tcp_seg_chkerr(net_pkt_iface(pkt));
4122 return NULL;
4123 }
4124
4125 #if defined(CONFIG_NET_TEST_PROTOCOL)
tcp_input(struct net_conn * net_conn,struct net_pkt * pkt,union net_ip_header * ip,union net_proto_header * proto,void * user_data)4126 static enum net_verdict tcp_input(struct net_conn *net_conn,
4127 struct net_pkt *pkt,
4128 union net_ip_header *ip,
4129 union net_proto_header *proto,
4130 void *user_data)
4131 {
4132 struct tcphdr *th = th_get(pkt);
4133 enum net_verdict verdict = NET_DROP;
4134
4135 if (th) {
4136 struct tcp *conn = tcp_conn_search(pkt);
4137
4138 if (conn == NULL && SYN == th_flags(th)) {
4139 struct net_context *context =
4140 tcp_calloc(1, sizeof(struct net_context));
4141 net_tcp_get(context);
4142 net_context_set_family(context, net_pkt_family(pkt));
4143 conn = context->tcp;
4144 tcp_endpoint_set(&conn->dst, pkt, TCP_EP_SRC);
4145 tcp_endpoint_set(&conn->src, pkt, TCP_EP_DST);
4146 /* Make an extra reference, the sanity check suite
4147 * will delete the connection explicitly
4148 */
4149 tcp_conn_ref(conn);
4150 }
4151
4152 if (conn) {
4153 conn->iface = pkt->iface;
4154 verdict = tcp_in(conn, pkt);
4155 }
4156 }
4157
4158 return verdict;
4159 }
4160
tp_tcp_recv_cb(struct tcp * conn,struct net_pkt * pkt)4161 static size_t tp_tcp_recv_cb(struct tcp *conn, struct net_pkt *pkt)
4162 {
4163 ssize_t len = tcp_data_len(pkt);
4164 struct net_pkt *up = tcp_pkt_clone(pkt);
4165
4166 NET_DBG("pkt: %p, len: %zu", pkt, net_pkt_get_len(pkt));
4167
4168 net_pkt_cursor_init(up);
4169 net_pkt_set_overwrite(up, true);
4170
4171 net_pkt_pull(up, net_pkt_get_len(up) - len);
4172
4173 for (struct net_buf *buf = pkt->buffer; buf != NULL; buf = buf->frags) {
4174 net_tcp_queue(conn->context, buf->data, buf->len);
4175 }
4176
4177 return len;
4178 }
4179
tp_tcp_recv(int fd,void * buf,size_t len,int flags)4180 static ssize_t tp_tcp_recv(int fd, void *buf, size_t len, int flags)
4181 {
4182 return 0;
4183 }
4184
tp_init(struct tcp * conn,struct tp * tp)4185 static void tp_init(struct tcp *conn, struct tp *tp)
4186 {
4187 struct tp out = {
4188 .msg = "",
4189 .status = "",
4190 .state = tcp_state_to_str(conn->state, true),
4191 .seq = conn->seq,
4192 .ack = conn->ack,
4193 .rcv = "",
4194 .data = "",
4195 .op = "",
4196 };
4197
4198 *tp = out;
4199 }
4200
tcp_to_json(struct tcp * conn,void * data,size_t * data_len)4201 static void tcp_to_json(struct tcp *conn, void *data, size_t *data_len)
4202 {
4203 struct tp tp;
4204
4205 tp_init(conn, &tp);
4206
4207 tp_encode(&tp, data, data_len);
4208 }
4209
tp_input(struct net_conn * net_conn,struct net_pkt * pkt,union net_ip_header * ip_hdr,union net_proto_header * proto,void * user_data)4210 enum net_verdict tp_input(struct net_conn *net_conn,
4211 struct net_pkt *pkt,
4212 union net_ip_header *ip_hdr,
4213 union net_proto_header *proto,
4214 void *user_data)
4215 {
4216 struct net_udp_hdr *uh = net_udp_get_hdr(pkt, NULL);
4217 size_t data_len = ntohs(uh->len) - sizeof(*uh);
4218 struct tcp *conn = tcp_conn_search(pkt);
4219 size_t json_len = 0;
4220 struct tp *tp;
4221 struct tp_new *tp_new;
4222 enum tp_type type;
4223 bool responded = false;
4224 static char buf[512];
4225 enum net_verdict verdict = NET_DROP;
4226
4227 net_pkt_cursor_init(pkt);
4228 net_pkt_set_overwrite(pkt, true);
4229 net_pkt_skip(pkt, net_pkt_ip_hdr_len(pkt) +
4230 net_pkt_ip_opts_len(pkt) + sizeof(*uh));
4231 net_pkt_read(pkt, buf, data_len);
4232 buf[data_len] = '\0';
4233 data_len += 1;
4234
4235 type = json_decode_msg(buf, data_len);
4236
4237 data_len = ntohs(uh->len) - sizeof(*uh);
4238
4239 net_pkt_cursor_init(pkt);
4240 net_pkt_set_overwrite(pkt, true);
4241 net_pkt_skip(pkt, net_pkt_ip_hdr_len(pkt) +
4242 net_pkt_ip_opts_len(pkt) + sizeof(*uh));
4243 net_pkt_read(pkt, buf, data_len);
4244 buf[data_len] = '\0';
4245 data_len += 1;
4246
4247 switch (type) {
4248 case TP_CONFIG_REQUEST:
4249 tp_new = json_to_tp_new(buf, data_len);
4250 break;
4251 default:
4252 tp = json_to_tp(buf, data_len);
4253 break;
4254 }
4255
4256 switch (type) {
4257 case TP_COMMAND:
4258 if (is("CONNECT", tp->op)) {
4259 tp_output(pkt->family, pkt->iface, buf, 1);
4260 responded = true;
4261 {
4262 struct net_context *context = tcp_calloc(1,
4263 sizeof(struct net_context));
4264 net_tcp_get(context);
4265 net_context_set_family(context,
4266 net_pkt_family(pkt));
4267 conn = context->tcp;
4268 tcp_endpoint_set(&conn->dst, pkt, TCP_EP_SRC);
4269 tcp_endpoint_set(&conn->src, pkt, TCP_EP_DST);
4270 conn->iface = pkt->iface;
4271 tcp_conn_ref(conn);
4272 }
4273 conn->seq = tp->seq;
4274 verdict = tcp_in(conn, NULL);
4275 }
4276 if (is("CLOSE", tp->op)) {
4277 tp_trace = false;
4278 {
4279 struct net_context *context;
4280
4281 conn = (void *)sys_slist_peek_head(&tcp_conns);
4282 context = conn->context;
4283 while (tcp_conn_close(conn, 0))
4284 ;
4285 tcp_free(context);
4286 }
4287 tp_mem_stat();
4288 tp_nbuf_stat();
4289 tp_pkt_stat();
4290 tp_seq_stat();
4291 }
4292 if (is("CLOSE2", tp->op)) {
4293 struct tcp *conn =
4294 (void *)sys_slist_peek_head(&tcp_conns);
4295 net_tcp_put(conn->context);
4296 }
4297 if (is("RECV", tp->op)) {
4298 #define HEXSTR_SIZE 64
4299 char hexstr[HEXSTR_SIZE];
4300 ssize_t len = tp_tcp_recv(0, buf, sizeof(buf), 0);
4301
4302 tp_init(conn, tp);
4303 bin2hex(buf, len, hexstr, HEXSTR_SIZE);
4304 tp->data = hexstr;
4305 NET_DBG("%zd = tcp_recv(\"%s\")", len, tp->data);
4306 json_len = sizeof(buf);
4307 tp_encode(tp, buf, &json_len);
4308 }
4309 if (is("SEND", tp->op)) {
4310 ssize_t len = tp_str_to_hex(buf, sizeof(buf), tp->data);
4311 struct tcp *conn =
4312 (void *)sys_slist_peek_head(&tcp_conns);
4313
4314 tp_output(pkt->family, pkt->iface, buf, 1);
4315 responded = true;
4316 NET_DBG("tcp_send(\"%s\")", tp->data);
4317 {
4318 net_tcp_queue(conn->context, buf, len);
4319 }
4320 }
4321 break;
4322 case TP_CONFIG_REQUEST:
4323 tp_new_find_and_apply(tp_new, "tcp_rto", &tcp_rto, TP_INT);
4324 tp_new_find_and_apply(tp_new, "tcp_retries", &tcp_retries,
4325 TP_INT);
4326 tp_new_find_and_apply(tp_new, "tcp_window", &tcp_rx_window,
4327 TP_INT);
4328 tp_new_find_and_apply(tp_new, "tp_trace", &tp_trace, TP_BOOL);
4329 break;
4330 case TP_INTROSPECT_REQUEST:
4331 json_len = sizeof(buf);
4332 conn = (void *)sys_slist_peek_head(&tcp_conns);
4333 tcp_to_json(conn, buf, &json_len);
4334 break;
4335 case TP_DEBUG_STOP:
4336 case TP_DEBUG_CONTINUE:
4337 tp_state = tp->type;
4338 break;
4339 default:
4340 NET_ASSERT(false, "Unimplemented tp command: %s", tp->msg);
4341 }
4342
4343 if (json_len) {
4344 tp_output(pkt->family, pkt->iface, buf, json_len);
4345 } else if ((TP_CONFIG_REQUEST == type || TP_COMMAND == type)
4346 && responded == false) {
4347 tp_output(pkt->family, pkt->iface, buf, 1);
4348 }
4349
4350 return verdict;
4351 }
4352
test_cb_register(sa_family_t family,uint8_t proto,uint16_t remote_port,uint16_t local_port,net_conn_cb_t cb)4353 static void test_cb_register(sa_family_t family, uint8_t proto, uint16_t remote_port,
4354 uint16_t local_port, net_conn_cb_t cb)
4355 {
4356 struct net_conn_handle *conn_handle = NULL;
4357 const struct sockaddr addr = { .sa_family = family, };
4358
4359 int ret = net_conn_register(proto,
4360 family,
4361 &addr, /* remote address */
4362 &addr, /* local address */
4363 local_port,
4364 remote_port,
4365 NULL,
4366 cb,
4367 NULL, /* user_data */
4368 &conn_handle);
4369 if (ret < 0) {
4370 NET_ERR("net_conn_register(): %d", ret);
4371 }
4372 }
4373 #endif /* CONFIG_NET_TEST_PROTOCOL */
4374
net_tcp_foreach(net_tcp_cb_t cb,void * user_data)4375 void net_tcp_foreach(net_tcp_cb_t cb, void *user_data)
4376 {
4377 struct tcp *conn;
4378 struct tcp *tmp;
4379
4380 k_mutex_lock(&tcp_lock, K_FOREVER);
4381
4382 SYS_SLIST_FOR_EACH_CONTAINER_SAFE(&tcp_conns, conn, tmp, next) {
4383 if (atomic_get(&conn->ref_count) > 0) {
4384 k_mutex_unlock(&tcp_lock);
4385 cb(conn, user_data);
4386 k_mutex_lock(&tcp_lock, K_FOREVER);
4387 }
4388 }
4389
4390 k_mutex_unlock(&tcp_lock);
4391 }
4392
net_tcp_get_supported_mss(const struct tcp * conn)4393 uint16_t net_tcp_get_supported_mss(const struct tcp *conn)
4394 {
4395 sa_family_t family = net_context_get_family(conn->context);
4396
4397 if (family == AF_INET) {
4398 #if defined(CONFIG_NET_IPV4)
4399 struct net_if *iface = net_context_get_iface(conn->context);
4400 int mss = 0;
4401
4402 if (iface && net_if_get_mtu(iface) >= NET_IPV4TCPH_LEN) {
4403 /* Detect MSS based on interface MTU minus "TCP,IP
4404 * header size"
4405 */
4406 mss = net_if_get_mtu(iface) - NET_IPV4TCPH_LEN;
4407 }
4408
4409 if (mss == 0) {
4410 mss = NET_IPV4_MTU - NET_IPV4TCPH_LEN;
4411 }
4412
4413 return mss;
4414 #else
4415 return 0;
4416 #endif /* CONFIG_NET_IPV4 */
4417 }
4418 #if defined(CONFIG_NET_IPV6)
4419 else if (family == AF_INET6) {
4420 struct net_if *iface = net_context_get_iface(conn->context);
4421 int mss = 0;
4422
4423 if (iface && net_if_get_mtu(iface) >= NET_IPV6TCPH_LEN) {
4424 /* Detect MSS based on interface MTU minus "TCP,IP
4425 * header size"
4426 */
4427 mss = net_if_get_mtu(iface) - NET_IPV6TCPH_LEN;
4428 }
4429
4430 if (mss == 0) {
4431 mss = NET_IPV6_MTU - NET_IPV6TCPH_LEN;
4432 }
4433
4434 return mss;
4435 }
4436 #endif /* CONFIG_NET_IPV6 */
4437
4438 return 0;
4439 }
4440
net_tcp_set_option(struct net_context * context,enum tcp_conn_option option,const void * value,size_t len)4441 int net_tcp_set_option(struct net_context *context,
4442 enum tcp_conn_option option,
4443 const void *value, size_t len)
4444 {
4445 int ret = 0;
4446
4447 NET_ASSERT(context);
4448
4449 struct tcp *conn = context->tcp;
4450
4451 NET_ASSERT(conn);
4452
4453 k_mutex_lock(&conn->lock, K_FOREVER);
4454
4455 switch (option) {
4456 case TCP_OPT_NODELAY:
4457 ret = set_tcp_nodelay(conn, value, len);
4458 break;
4459 case TCP_OPT_KEEPALIVE:
4460 ret = set_tcp_keep_alive(conn, value, len);
4461 break;
4462 case TCP_OPT_KEEPIDLE:
4463 ret = set_tcp_keep_idle(conn, value, len);
4464 break;
4465 case TCP_OPT_KEEPINTVL:
4466 ret = set_tcp_keep_intvl(conn, value, len);
4467 break;
4468 case TCP_OPT_KEEPCNT:
4469 ret = set_tcp_keep_cnt(conn, value, len);
4470 break;
4471 }
4472
4473 k_mutex_unlock(&conn->lock);
4474
4475 return ret;
4476 }
4477
net_tcp_get_option(struct net_context * context,enum tcp_conn_option option,void * value,size_t * len)4478 int net_tcp_get_option(struct net_context *context,
4479 enum tcp_conn_option option,
4480 void *value, size_t *len)
4481 {
4482 int ret = 0;
4483
4484 NET_ASSERT(context);
4485
4486 struct tcp *conn = context->tcp;
4487
4488 NET_ASSERT(conn);
4489
4490 k_mutex_lock(&conn->lock, K_FOREVER);
4491
4492 switch (option) {
4493 case TCP_OPT_NODELAY:
4494 ret = get_tcp_nodelay(conn, value, len);
4495 break;
4496 case TCP_OPT_KEEPALIVE:
4497 ret = get_tcp_keep_alive(conn, value, len);
4498 break;
4499 case TCP_OPT_KEEPIDLE:
4500 ret = get_tcp_keep_idle(conn, value, len);
4501 break;
4502 case TCP_OPT_KEEPINTVL:
4503 ret = get_tcp_keep_intvl(conn, value, len);
4504 break;
4505 case TCP_OPT_KEEPCNT:
4506 ret = get_tcp_keep_cnt(conn, value, len);
4507 break;
4508 }
4509
4510 k_mutex_unlock(&conn->lock);
4511
4512 return ret;
4513 }
4514
net_tcp_state_str(enum tcp_state state)4515 const char *net_tcp_state_str(enum tcp_state state)
4516 {
4517 return tcp_state_to_str(state, false);
4518 }
4519
net_tcp_tx_sem_get(struct net_context * context)4520 struct k_sem *net_tcp_tx_sem_get(struct net_context *context)
4521 {
4522 struct tcp *conn = context->tcp;
4523
4524 return &conn->tx_sem;
4525 }
4526
net_tcp_conn_sem_get(struct net_context * context)4527 struct k_sem *net_tcp_conn_sem_get(struct net_context *context)
4528 {
4529 struct tcp *conn = context->tcp;
4530
4531 return &conn->connect_sem;
4532 }
4533
net_tcp_init(void)4534 void net_tcp_init(void)
4535 {
4536 int i;
4537 int rto;
4538 #if defined(CONFIG_NET_TEST_PROTOCOL)
4539 /* Register inputs for TTCN-3 based TCP sanity check */
4540 test_cb_register(AF_INET, IPPROTO_TCP, 4242, 4242, tcp_input);
4541 test_cb_register(AF_INET6, IPPROTO_TCP, 4242, 4242, tcp_input);
4542 test_cb_register(AF_INET, IPPROTO_UDP, 4242, 4242, tp_input);
4543 test_cb_register(AF_INET6, IPPROTO_UDP, 4242, 4242, tp_input);
4544
4545 tcp_recv_cb = tp_tcp_recv_cb;
4546 #endif
4547
4548 #if defined(CONFIG_NET_TC_THREAD_COOPERATIVE)
4549 #define THREAD_PRIORITY K_PRIO_COOP(CONFIG_NET_TCP_WORKER_PRIO)
4550 #else
4551 #define THREAD_PRIORITY K_PRIO_PREEMPT(CONFIG_NET_TCP_WORKER_PRIO)
4552 #endif
4553
4554 /* Use private workqueue in order not to block the system work queue.
4555 */
4556 k_work_queue_start(&tcp_work_q, work_q_stack,
4557 K_KERNEL_STACK_SIZEOF(work_q_stack), THREAD_PRIORITY,
4558 NULL);
4559
4560 /* Compute the largest possible retransmission timeout */
4561 tcp_max_timeout_ms = 0;
4562 rto = tcp_rto;
4563 for (i = 0; i < tcp_retries; i++) {
4564 tcp_max_timeout_ms += rto;
4565 rto += rto >> 1;
4566 }
4567 /* At the last timeout cycle */
4568 tcp_max_timeout_ms += tcp_rto;
4569
4570 /* When CONFIG_NET_TCP_RANDOMIZED_RTO is active in can be worse case 1.5 times larger */
4571 if (IS_ENABLED(CONFIG_NET_TCP_RANDOMIZED_RTO)) {
4572 tcp_max_timeout_ms += tcp_max_timeout_ms >> 1;
4573 }
4574
4575 k_thread_name_set(&tcp_work_q.thread, "tcp_work");
4576 NET_DBG("Workq started. Thread ID: %p", &tcp_work_q.thread);
4577 }
4578