Skip to content

Commit 564d8cd

Browse files
lpereirajukkar
authored andcommitted
net: tcp: Revisit implementation of passive close
This change moves the handling of passive close to a callback function that handles the {CLOSE_WAIT, LAST_ACK} states. This cleans up the callback that handles the established estate, leaving only the handling for that specific state in the tcp_established() callback. Also, send the correct acknowledge number and send only an ACK rather than a FIN+ACK packet while transitioning from ESTABLISHED to CLOSE_WAIT. These changes makes Wireshark happy when the connection is closed. Change-Id: Ieeced5dff845f53a6b61af973dcf0fe3b7b8601f Signed-off-by: Leandro Pereira <leandro.pereira@intel.com>
1 parent bab9430 commit 564d8cd

File tree

2 files changed

+53
-30
lines changed

2 files changed

+53
-30
lines changed

net/yaip/net_context.c

Lines changed: 51 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -626,21 +626,15 @@ static int tcp_hdr_len(struct net_buf *buf)
626626
return 4 * (hdr->offset >> 4);
627627
}
628628

629-
/* This is called when we receive data after the connection has been
630-
* established. The core TCP logic is located here.
631-
*/
632-
static enum net_verdict tcp_established(struct net_conn *conn,
629+
static enum net_verdict tcp_passive_close(struct net_conn *conn,
633630
struct net_buf *buf,
634631
void *user_data)
635632
{
636633
struct net_context *context = (struct net_context *)user_data;
637-
struct net_tcp_hdr *hdr;
638-
enum net_verdict ret;
639634

640635
NET_ASSERT(context && context->tcp);
641636

642637
switch (context->tcp->state) {
643-
case NET_TCP_ESTABLISHED:
644638
case NET_TCP_CLOSE_WAIT:
645639
case NET_TCP_LAST_ACK:
646640
break;
@@ -650,36 +644,65 @@ static enum net_verdict tcp_established(struct net_conn *conn,
650644
return NET_DROP;
651645
}
652646

653-
net_tcp_print_recv_info("DATA", buf, NET_TCP_BUF(buf)->src_port);
647+
net_tcp_print_recv_info("PASSCLOSE", buf, NET_TCP_BUF(buf)->src_port);
648+
649+
if (context->tcp->state == NET_TCP_LAST_ACK &&
650+
NET_TCP_FLAGS(buf) & NET_TCP_ACK) {
651+
net_context_put(context);
652+
}
653+
654+
return NET_DROP;
655+
}
654656

655-
hdr = (void *)net_nbuf_tcp_data(buf);
657+
/* This is called when we receive data after the connection has been
658+
* established. The core TCP logic is located here.
659+
*/
660+
static enum net_verdict tcp_established(struct net_conn *conn,
661+
struct net_buf *buf,
662+
void *user_data)
663+
{
664+
struct net_context *context = (struct net_context *)user_data;
665+
enum net_verdict ret;
666+
667+
NET_ASSERT(context && context->tcp);
668+
669+
if (context->tcp->state != NET_TCP_ESTABLISHED) {
670+
NET_DBG("Context %p in wrong state %d",
671+
context, context->tcp->state);
672+
return NET_DROP;
673+
}
674+
675+
net_tcp_print_recv_info("DATA", buf, NET_TCP_BUF(buf)->src_port);
656676

657677
if (NET_TCP_FLAGS(buf) & NET_TCP_FIN) {
658-
/* Sending a FIN and ACK in the CLOSE_WAIT state will
659-
* transition to LAST_ACK state
678+
/* Sending an ACK in the CLOSE_WAIT state will transition to
679+
* LAST_ACK state
660680
*/
661681
net_tcp_change_state(context->tcp, NET_TCP_CLOSE_WAIT);
662-
send_fin_ack(context, &conn->remote_addr);
663-
return NET_DROP;
664-
}
665-
if (NET_TCP_FLAGS(buf) & NET_TCP_ACK) {
666-
if (context->tcp->state == NET_TCP_LAST_ACK) {
667-
net_context_put(context);
682+
net_conn_change_callback(context->conn_handler,
683+
tcp_passive_close, context);
684+
685+
ret = NET_DROP;
686+
687+
context->tcp->send_ack =
688+
sys_get_be32(NET_TCP_BUF(buf)->seq) + 1;
689+
} else {
690+
struct net_tcp_hdr *hdr = (void *)net_nbuf_tcp_data(buf);
691+
692+
if (sys_get_be32(hdr->seq) - context->tcp->send_ack) {
693+
/* Don't try to reorder packets. If it doesn't
694+
* match the next segment exactly, drop and wait for
695+
* retransmit
696+
*/
668697
return NET_DROP;
669698
}
670-
}
671-
if (sys_get_be32(hdr->seq) - context->tcp->send_ack) {
672-
/* Don't try to reorder packets. If it doesn't match
673-
* the next segment exactly, drop and wait for
674-
* retransmit
675-
*/
676-
return NET_DROP;
677-
}
678699

679-
ret = packet_received(conn, buf, user_data);
700+
ret = packet_received(conn, buf, user_data);
701+
702+
context->tcp->send_ack += net_buf_frags_len(buf)
703+
- net_nbuf_ip_hdr_len(buf) - tcp_hdr_len(buf);
704+
}
680705

681-
context->tcp->send_ack += net_buf_frags_len(buf)
682-
- net_nbuf_ip_hdr_len(buf) - tcp_hdr_len(buf);
683706
send_ack(context, &conn->remote_addr);
684707

685708
return ret;

net/yaip/tcp.c

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -335,6 +335,8 @@ int net_tcp_prepare_segment(struct net_tcp *tcp, uint8_t flags,
335335
}
336336
} else if (tcp->state == NET_TCP_FIN_WAIT_2) {
337337
net_tcp_change_state(tcp, NET_TCP_TIME_WAIT);
338+
} else if (tcp->state == NET_TCP_CLOSE_WAIT) {
339+
net_tcp_change_state(tcp, NET_TCP_LAST_ACK);
338340
}
339341
}
340342

@@ -345,8 +347,6 @@ int net_tcp_prepare_segment(struct net_tcp *tcp, uint8_t flags,
345347
if (tcp->state == NET_TCP_ESTABLISHED ||
346348
tcp->state == NET_TCP_SYN_RCVD) {
347349
net_tcp_change_state(tcp, NET_TCP_FIN_WAIT_1);
348-
} else if (tcp->state == NET_TCP_CLOSE_WAIT) {
349-
net_tcp_change_state(tcp, NET_TCP_LAST_ACK);
350350
}
351351
}
352352

0 commit comments

Comments
 (0)