Skip to content

Commit 7ae54ad

Browse files
jukkarnashif
authored andcommitted
net: tcp2: Create a timer for connection establishment
We need to make sure that when listening a connection establishment, the connection gets cleared if we do not receive final ACK. Signed-off-by: Jukka Rissanen <[email protected]>
1 parent 8070003 commit 7ae54ad

File tree

2 files changed

+30
-2
lines changed

2 files changed

+30
-2
lines changed

subsys/net/ip/tcp2.c

Lines changed: 22 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,8 @@ LOG_MODULE_REGISTER(net_tcp, CONFIG_NET_TCP_LOG_LEVEL);
2222
#include "net_private.h"
2323
#include "tcp2_priv.h"
2424

25+
#define ACK_TIMEOUT_MS CONFIG_NET_TCP_ACK_TIMEOUT
26+
#define ACK_TIMEOUT K_MSEC(ACK_TIMEOUT_MS)
2527
#define FIN_TIMEOUT_MS MSEC_PER_SEC
2628
#define FIN_TIMEOUT K_MSEC(FIN_TIMEOUT_MS)
2729

@@ -1058,11 +1060,24 @@ static void tcp_timewait_timeout(struct k_work *work)
10581060
net_context_unref(conn->context);
10591061
}
10601062

1063+
static void tcp_establish_timeout(struct tcp *conn)
1064+
{
1065+
NET_DBG("Did not receive %s in %dms", "ACK", ACK_TIMEOUT_MS);
1066+
NET_DBG("conn: %p %s", conn, log_strdup(tcp_conn_state(conn, NULL)));
1067+
1068+
(void)tcp_conn_unref(conn);
1069+
}
1070+
10611071
static void tcp_fin_timeout(struct k_work *work)
10621072
{
10631073
struct tcp *conn = CONTAINER_OF(work, struct tcp, fin_timer);
10641074

1065-
NET_DBG("Did not receive FIN in %dms", FIN_TIMEOUT_MS);
1075+
if (conn->state == TCP_SYN_RECEIVED) {
1076+
tcp_establish_timeout(conn);
1077+
return;
1078+
}
1079+
1080+
NET_DBG("Did not receive %s in %dms", "FIN", FIN_TIMEOUT_MS);
10661081
NET_DBG("conn: %p %s", conn, log_strdup(tcp_conn_state(conn, NULL)));
10671082

10681083
/* Extra unref from net_tcp_put() */
@@ -1535,6 +1550,11 @@ static void tcp_in(struct tcp *conn, struct net_pkt *pkt)
15351550
tcp_out(conn, SYN | ACK);
15361551
conn_seq(conn, + 1);
15371552
next = TCP_SYN_RECEIVED;
1553+
1554+
/* Close the connection if we do not receive ACK on time.
1555+
*/
1556+
k_delayed_work_submit(&conn->establish_timer,
1557+
ACK_TIMEOUT);
15381558
} else {
15391559
tcp_out(conn, SYN);
15401560
conn_seq(conn, + 1);
@@ -1544,6 +1564,7 @@ static void tcp_in(struct tcp *conn, struct net_pkt *pkt)
15441564
case TCP_SYN_RECEIVED:
15451565
if (FL(&fl, &, ACK, th_ack(th) == conn->seq &&
15461566
th_seq(th) == conn->ack)) {
1567+
k_delayed_work_cancel(&conn->establish_timer);
15471568
tcp_send_timer_cancel(conn);
15481569
next = TCP_ESTABLISHED;
15491570
net_context_set_state(conn->context,

subsys/net/ip/tcp2_priv.h

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -223,7 +223,14 @@ struct tcp { /* TCP connection */
223223
struct k_delayed_work recv_queue_timer;
224224
struct k_delayed_work send_data_timer;
225225
struct k_delayed_work timewait_timer;
226-
struct k_delayed_work fin_timer;
226+
union {
227+
/* Because FIN and establish timers are never happening
228+
* at the same time, share the timer between them to
229+
* save memory.
230+
*/
231+
struct k_delayed_work fin_timer;
232+
struct k_delayed_work establish_timer;
233+
};
227234
union tcp_endpoint src;
228235
union tcp_endpoint dst;
229236
size_t send_data_total;

0 commit comments

Comments
 (0)