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