[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[lwip-devel] TCP/IP - Connection attempt refused for TIME_WAIT pcbs even
From: |
Benjamin Kalytta |
Subject: |
[lwip-devel] TCP/IP - Connection attempt refused for TIME_WAIT pcbs even if seqno is valid? |
Date: |
Mon, 12 Jul 2021 13:03:14 +0000 |
Hello LwIp users,
I've a strange problem regarding TCP/IP connections. I don't know if it is a
bug or it is intended (if so why).
We are running a simple webserver on an STM32F7 system. We have encountered
problems with certain web browsers (especially Chrome) when retrieving content.
It seems to be the case whenever the local TCP/IP port is reused too quickly
(several 10th of ms) by the browser/operating system connection is
refused/reset since the PCB is still in TIME_WAIT state on the server side (in
LWIP stack) which is fine and understandable.
However, according to the specification, TIME_WAIT should be left as soon as
the new sequence number is greater than the last one used.
See https://www.freesoft.org/CIE/RFC/1122/99.htm 4.2.2.13 Closing a Connection:
RFC-793 Section 3.5:
"However, it MAY accept a new SYN from the remote TCP to reopen the connection
directly from TIME-WAIT state, if it:
- assigns its initial sequence number for the new connection to be larger than
the largest sequence number it used on the previous connection incarnation[...]"
I'm not 100% sure, but I think I found the code snippet responsible dealing
with SYN while in TIME_WAIT:
[Version LWIP 2.1.2]
738 static void
739 tcp_timewait_input(struct tcp_pcb *pcb)
{
/* RFC 1337: in TIME_WAIT, ignore RST and ACK FINs + any 'acceptable'
segments */
/* RFC 793 3.9 Event Processing - Segment Arrives:
* - first check sequence number - we skip that one in TIME_WAIT (always
* acceptable since we only send ACKs)
* - second check the RST bit (... return) */
if (flags & TCP_RST) {
return;
}
LWIP_ASSERT("tcp_timewait_input: invalid pcb", pcb != NULL);
/* - fourth, check the SYN bit, */
if (flags & TCP_SYN) {
/* If an incoming segment is not acceptable, an acknowledgment
should be sent in reply */
756 if (TCP_SEQ_BETWEEN(seqno, pcb->rcv_nxt, pcb->rcv_nxt + pcb->rcv_wnd)) {
/* If the SYN is in the window it is an error, send a reset */
tcp_rst(pcb, ackno, seqno + tcplen, ip_current_dest_addr(),
ip_current_src_addr(), tcphdr->dest, tcphdr->src);
return;
761 }
} else if (flags & TCP_FIN) {
/* - eighth, check the FIN bit: Remain in the TIME-WAIT state.
Restart the 2 MSL time-wait timeout.*/
pcb->tmr = tcp_ticks;
}
if ((tcplen > 0)) {
/* Acknowledge data, FIN or out-of-window SYN */
770 tcp_ack_now(pcb);
tcp_output(pcb);
}
return;
774 }
Here (line 758) only a RST is sent if sequence is not valid, otherwise ACK is
sent (line 770). I either case tcp_input processing is aborted which means
connection is never accepted as per RFC 793 chapter 4.2.2.13. Am I wrong here?
Are there any fixes for that issue or any other solutions?
With Kind Regards,
Benjamin Kalytta
[Prev in Thread] |
Current Thread |
[Next in Thread] |
- [lwip-devel] TCP/IP - Connection attempt refused for TIME_WAIT pcbs even if seqno is valid?,
Benjamin Kalytta <=