mirror of
https://github.com/lwip-tcpip/lwip.git
synced 2024-10-04 05:39:53 +00:00
Fix for out-of-sequence FIN handling, patch by Oleg Tychev.
This commit is contained in:
parent
6cb19d7e34
commit
313743c833
@ -74,7 +74,7 @@ struct tcp_pcb *tcp_input_pcb;
|
|||||||
|
|
||||||
/* Forward declarations. */
|
/* Forward declarations. */
|
||||||
static err_t tcp_process(struct tcp_pcb *pcb);
|
static err_t tcp_process(struct tcp_pcb *pcb);
|
||||||
static void tcp_receive(struct tcp_pcb *pcb);
|
static u8_t tcp_receive(struct tcp_pcb *pcb);
|
||||||
static void tcp_parseopt(struct tcp_pcb *pcb);
|
static void tcp_parseopt(struct tcp_pcb *pcb);
|
||||||
|
|
||||||
static err_t tcp_listen_input(struct tcp_pcb_listen *pcb);
|
static err_t tcp_listen_input(struct tcp_pcb_listen *pcb);
|
||||||
@ -434,7 +434,7 @@ tcp_process(struct tcp_pcb *pcb)
|
|||||||
struct tcp_seg *rseg;
|
struct tcp_seg *rseg;
|
||||||
u8_t acceptable = 0;
|
u8_t acceptable = 0;
|
||||||
err_t err;
|
err_t err;
|
||||||
|
u8_t accepted_inseq;
|
||||||
|
|
||||||
err = ERR_OK;
|
err = ERR_OK;
|
||||||
|
|
||||||
@ -543,8 +543,8 @@ tcp_process(struct tcp_pcb *pcb)
|
|||||||
case CLOSE_WAIT:
|
case CLOSE_WAIT:
|
||||||
/* FALLTHROUGH */
|
/* FALLTHROUGH */
|
||||||
case ESTABLISHED:
|
case ESTABLISHED:
|
||||||
tcp_receive(pcb);
|
accepted_inseq = tcp_receive(pcb);
|
||||||
if (flags & TCP_FIN) {
|
if ((flags & TCP_FIN) && accepted_inseq) { /* passive close */
|
||||||
tcp_ack_now(pcb);
|
tcp_ack_now(pcb);
|
||||||
pcb->state = CLOSE_WAIT;
|
pcb->state = CLOSE_WAIT;
|
||||||
}
|
}
|
||||||
@ -614,9 +614,11 @@ tcp_process(struct tcp_pcb *pcb)
|
|||||||
*
|
*
|
||||||
* If the incoming segment constitutes an ACK for a segment that was used for RTT
|
* If the incoming segment constitutes an ACK for a segment that was used for RTT
|
||||||
* estimation, the RTT is estimated here as well.
|
* estimation, the RTT is estimated here as well.
|
||||||
|
*
|
||||||
|
* @return 1 if
|
||||||
*/
|
*/
|
||||||
|
|
||||||
static void
|
static u8_t
|
||||||
tcp_receive(struct tcp_pcb *pcb)
|
tcp_receive(struct tcp_pcb *pcb)
|
||||||
{
|
{
|
||||||
struct tcp_seg *next;
|
struct tcp_seg *next;
|
||||||
@ -628,7 +630,7 @@ tcp_receive(struct tcp_pcb *pcb)
|
|||||||
s16_t m;
|
s16_t m;
|
||||||
u32_t right_wnd_edge;
|
u32_t right_wnd_edge;
|
||||||
u16_t new_tot_len;
|
u16_t new_tot_len;
|
||||||
|
u8_t accepted_inseq = 0;
|
||||||
|
|
||||||
if (flags & TCP_ACK) {
|
if (flags & TCP_ACK) {
|
||||||
right_wnd_edge = pcb->snd_wnd + pcb->snd_wl1;
|
right_wnd_edge = pcb->snd_wnd + pcb->snd_wl1;
|
||||||
@ -650,7 +652,6 @@ tcp_receive(struct tcp_pcb *pcb)
|
|||||||
#endif /* TCP_WND_DEBUG */
|
#endif /* TCP_WND_DEBUG */
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
if (pcb->lastack == ackno) {
|
if (pcb->lastack == ackno) {
|
||||||
pcb->acked = 0;
|
pcb->acked = 0;
|
||||||
|
|
||||||
@ -882,6 +883,7 @@ tcp_receive(struct tcp_pcb *pcb)
|
|||||||
|
|
||||||
off = pcb->rcv_nxt - seqno;
|
off = pcb->rcv_nxt - seqno;
|
||||||
p = inseg.p;
|
p = inseg.p;
|
||||||
|
LWIP_ASSERT("inseg.p != NULL", inseg.p);
|
||||||
if (inseg.p->len < off) {
|
if (inseg.p->len < off) {
|
||||||
new_tot_len = inseg.p->tot_len - off;
|
new_tot_len = inseg.p->tot_len - off;
|
||||||
while (p->len < off) {
|
while (p->len < off) {
|
||||||
@ -920,6 +922,7 @@ tcp_receive(struct tcp_pcb *pcb)
|
|||||||
TCP_SEQ_LT(seqno, pcb->rcv_nxt + pcb->rcv_wnd)) {*/
|
TCP_SEQ_LT(seqno, pcb->rcv_nxt + pcb->rcv_wnd)) {*/
|
||||||
if (TCP_SEQ_BETWEEN(seqno, pcb->rcv_nxt, pcb->rcv_nxt + pcb->rcv_wnd - 1)){
|
if (TCP_SEQ_BETWEEN(seqno, pcb->rcv_nxt, pcb->rcv_nxt + pcb->rcv_wnd - 1)){
|
||||||
if (pcb->rcv_nxt == seqno) {
|
if (pcb->rcv_nxt == seqno) {
|
||||||
|
accepted_inseq = 1;
|
||||||
/* The incoming segment is the next in sequence. We check if
|
/* The incoming segment is the next in sequence. We check if
|
||||||
we have to trim the end of the segment and update rcv_nxt
|
we have to trim the end of the segment and update rcv_nxt
|
||||||
and pass the data to the application. */
|
and pass the data to the application. */
|
||||||
@ -998,6 +1001,9 @@ tcp_receive(struct tcp_pcb *pcb)
|
|||||||
if (TCPH_FLAGS(cseg->tcphdr) & TCP_FIN) {
|
if (TCPH_FLAGS(cseg->tcphdr) & TCP_FIN) {
|
||||||
LWIP_DEBUGF(TCP_INPUT_DEBUG, ("tcp_receive: dequeued FIN.\n"));
|
LWIP_DEBUGF(TCP_INPUT_DEBUG, ("tcp_receive: dequeued FIN.\n"));
|
||||||
recv_flags = TF_GOT_FIN;
|
recv_flags = TF_GOT_FIN;
|
||||||
|
if (pcb->state == ESTABLISHED) { /* force passive close or we can move to active close */
|
||||||
|
pcb->state = CLOSE_WAIT;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -1142,6 +1148,7 @@ tcp_receive(struct tcp_pcb *pcb)
|
|||||||
tcp_ack_now(pcb);
|
tcp_ack_now(pcb);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
return accepted_inseq;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
Loading…
Reference in New Issue
Block a user