From 4433b77bf68495f05a76a3abd080b2dc61734e98 Mon Sep 17 00:00:00 2001 From: Paul Sokolovsky Date: Thu, 4 May 2017 17:41:56 +0300 Subject: [PATCH] net: tcp: When sending FIN, make sure it goes with ACK and proper seq Without change to add ACK to FIN, invalid TCP packet is generated, where ack sequence number is non-zero. Without adjusting sequence number as done, ACK which we send in response to peer's FIN/ACK is not recognized by peer, and peer keeps retransmitting its FIN/ACK. Jira: ZEP-2104 Signed-off-by: Paul Sokolovsky --- subsys/net/ip/tcp.c | 14 +++++++++++++- 1 file changed, 13 insertions(+), 1 deletion(-) diff --git a/subsys/net/ip/tcp.c b/subsys/net/ip/tcp.c index bff89bf54271e..8cc5d91e88a73 100644 --- a/subsys/net/ip/tcp.c +++ b/subsys/net/ip/tcp.c @@ -414,7 +414,19 @@ int net_tcp_prepare_segment(struct net_tcp *tcp, u8_t flags, if (flags & NET_TCP_FIN) { tcp->flags |= NET_TCP_FINAL_SENT; - seq++; + /* RFC793 says about ACK bit: "Once a connection is + * established this is always sent." as teardown + * happens when connection is established, it must + * have ACK set. + */ + flags |= NET_TCP_ACK; + /* FIXME: We apparently miss increment in another + * transition of the state machine, so have to + * adjust seq no by 2 here. This is required for + * Linux to detect active close on server side, and + * to make Wireshark happy about sequence numbers. + */ + seq += 2; if (net_tcp_get_state(tcp) == NET_TCP_ESTABLISHED || net_tcp_get_state(tcp) == NET_TCP_SYN_RCVD) {