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