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