From 8286a558c86d07468c1b29607c154e849cd92800 Mon Sep 17 00:00:00 2001 From: Alan Carvalho de Assis Date: Wed, 2 Nov 2022 13:40:08 -0300 Subject: [PATCH] net/tcp: Avoid starting TCP sequence number 0 --- net/tcp/tcp_conn.c | 10 ++++++++++ net/tcp/tcp_seqno.c | 37 +++++++++++++++++++++++++++++++++++++ 2 files changed, 47 insertions(+) diff --git a/net/tcp/tcp_conn.c b/net/tcp/tcp_conn.c index ab42955afe..de09d72c13 100644 --- a/net/tcp/tcp_conn.c +++ b/net/tcp/tcp_conn.c @@ -1039,6 +1039,10 @@ FAR struct tcp_conn_s *tcp_alloc_accept(FAR struct net_driver_s *dev, conn->tcpstateflags = TCP_SYN_RCVD; tcp_initsequence(conn->sndseq); +#if !defined(CONFIG_NET_TCP_WRITE_BUFFERS) + conn->rexmit_seq = tcp_getsequence(conn->sndseq); +#endif + conn->tx_unacked = 1; #ifdef CONFIG_NET_TCP_WRITE_BUFFERS conn->expired = 0; @@ -1313,6 +1317,12 @@ int tcp_connect(FAR struct tcp_conn_s *conn, FAR const struct sockaddr *addr) conn->tcpstateflags = TCP_SYN_SENT; tcp_initsequence(conn->sndseq); + /* Save initial sndseq to rexmit_seq, otherwise it will be zero */ + +#if !defined(CONFIG_NET_TCP_WRITE_BUFFERS) + conn->rexmit_seq = tcp_getsequence(conn->sndseq); +#endif + conn->tx_unacked = 1; /* TCP length of the SYN is one. */ conn->nrtx = 0; conn->timeout = true; /* Send the SYN immediately. */ diff --git a/net/tcp/tcp_seqno.c b/net/tcp/tcp_seqno.c index 58b4c587ad..eeaa1d43c1 100644 --- a/net/tcp/tcp_seqno.c +++ b/net/tcp/tcp_seqno.c @@ -45,7 +45,9 @@ #include #include +#include +#include #include #include @@ -142,6 +144,41 @@ uint32_t tcp_addsequence(FAR uint8_t *seqno, uint16_t len) void tcp_initsequence(FAR uint8_t *seqno) { + int ret; + + /* If g_tcpsequence is already initialized, just copy it */ + + if (g_tcpsequence == 0) + { + /* Get a random TCP sequence number */ + + ret = getrandom(&g_tcpsequence, sizeof(uint32_t), 0); + if (ret < 0) + { + ret = getrandom(&g_tcpsequence, sizeof(uint32_t), GRND_RANDOM); + } + + /* If getrandom() failed use sys ticks, use about half of allowed + * values + */ + + if (ret != sizeof(uint32_t)) + { + g_tcpsequence = clock_systime_ticks() % 2000000000; + } + else + { + g_tcpsequence = g_tcpsequence % 2000000000; + } + + /* If the random value is "small" increase it */ + + if (g_tcpsequence < 1000000000) + { + g_tcpsequence += 1000000000; + } + } + tcp_setsequence(seqno, g_tcpsequence); }