mirror of
https://github.com/lwip-tcpip/lwip.git
synced 2024-11-04 23:29:25 +00:00
Another fix for bug #28241 (ooseq processing) and adapted corresponding unit test
This commit is contained in:
parent
dc8639bc06
commit
bf261f4f13
@ -22,6 +22,10 @@ HISTORY
|
|||||||
|
|
||||||
++ Bugfixes:
|
++ Bugfixes:
|
||||||
|
|
||||||
|
2009-12-27: Simon Goldschmidt
|
||||||
|
* tcp_in.c: Another fix for bug #28241 (ooseq processing) and adapted
|
||||||
|
unit test
|
||||||
|
|
||||||
|
|
||||||
(STABLE-1.3.2)
|
(STABLE-1.3.2)
|
||||||
|
|
||||||
|
@ -1167,11 +1167,7 @@ tcp_receive(struct tcp_pcb *pcb)
|
|||||||
("tcp_receive: received in-order FIN, binning ooseq queue\n"));
|
("tcp_receive: received in-order FIN, binning ooseq queue\n"));
|
||||||
/* Received in-order FIN means anything that was received
|
/* Received in-order FIN means anything that was received
|
||||||
* out of order must now have been received in-order, so
|
* out of order must now have been received in-order, so
|
||||||
* bin the ooseq queue
|
* bin the ooseq queue */
|
||||||
* rcv_nxt
|
|
||||||
* . |--ooseq--|
|
|
||||||
* .==seg============|FIN
|
|
||||||
*/
|
|
||||||
while (pcb->ooseq != NULL) {
|
while (pcb->ooseq != NULL) {
|
||||||
struct tcp_seg *old_ooseq = pcb->ooseq;
|
struct tcp_seg *old_ooseq = pcb->ooseq;
|
||||||
pcb->ooseq = pcb->ooseq->next;
|
pcb->ooseq = pcb->ooseq->next;
|
||||||
@ -1179,42 +1175,37 @@ tcp_receive(struct tcp_pcb *pcb)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
struct tcp_seg* next = pcb->ooseq;
|
next = pcb->ooseq;
|
||||||
struct tcp_seg *old_seg;
|
/* Remove all segments on ooseq that are covered by inseg already.
|
||||||
/* rcv_nxt
|
* FIN is copied from ooseq to inseg if present. */
|
||||||
* . |--ooseq--|
|
|
||||||
* .==seg============|
|
|
||||||
*/
|
|
||||||
while (next &&
|
while (next &&
|
||||||
TCP_SEQ_GEQ(seqno + tcplen,
|
TCP_SEQ_GEQ(seqno + tcplen,
|
||||||
next->tcphdr->seqno + next->len)) {
|
next->tcphdr->seqno + next->len)) {
|
||||||
/* inseg doesn't have FIN (already processed) */
|
/* inseg cannot have FIN here (already processed above) */
|
||||||
if (TCPH_FLAGS(next->tcphdr) & TCP_FIN &&
|
if (TCPH_FLAGS(next->tcphdr) & TCP_FIN &&
|
||||||
(TCPH_FLAGS(inseg.tcphdr) & TCP_SYN) == 0) {
|
(TCPH_FLAGS(inseg.tcphdr) & TCP_SYN) == 0) {
|
||||||
TCPH_FLAGS_SET(inseg.tcphdr,
|
TCPH_FLAGS_SET(inseg.tcphdr,
|
||||||
TCPH_FLAGS(inseg.tcphdr) | TCP_FIN);
|
TCPH_FLAGS(inseg.tcphdr) | TCP_FIN);
|
||||||
tcplen = TCP_TCPLEN(&inseg);
|
tcplen = TCP_TCPLEN(&inseg);
|
||||||
}
|
}
|
||||||
old_seg = next;
|
prev = next;
|
||||||
next = next->next;
|
next = next->next;
|
||||||
tcp_seg_free(old_seg);
|
tcp_seg_free(prev);
|
||||||
}
|
}
|
||||||
/* rcv_nxt
|
/* Now trim right side of inseg if it overlaps with the first
|
||||||
* . |--ooseq--|
|
* segment on ooseq */
|
||||||
* .==seg============|
|
|
||||||
*/
|
|
||||||
if (next &&
|
if (next &&
|
||||||
TCP_SEQ_GT(seqno + tcplen,
|
TCP_SEQ_GT(seqno + tcplen,
|
||||||
next->tcphdr->seqno)) {
|
next->tcphdr->seqno)) {
|
||||||
/* FIN in inseg already handled by dropping whole ooseq queue */
|
/* inseg cannot have FIN here (already processed above) */
|
||||||
inseg.len = (u16_t)(pcb->ooseq->tcphdr->seqno - seqno);
|
inseg.len = (u16_t)(next->tcphdr->seqno - seqno);
|
||||||
if (TCPH_FLAGS(inseg.tcphdr) & TCP_SYN) {
|
if (TCPH_FLAGS(inseg.tcphdr) & TCP_SYN) {
|
||||||
inseg.len -= 1;
|
inseg.len -= 1;
|
||||||
}
|
}
|
||||||
pbuf_realloc(inseg.p, inseg.len);
|
pbuf_realloc(inseg.p, inseg.len);
|
||||||
tcplen = TCP_TCPLEN(&inseg);
|
tcplen = TCP_TCPLEN(&inseg);
|
||||||
LWIP_ASSERT("tcp_receive: segment not trimmed correctly to ooseq queue\n",
|
LWIP_ASSERT("tcp_receive: segment not trimmed correctly to ooseq queue\n",
|
||||||
(seqno + tcplen) == pcb->ooseq->tcphdr->seqno);
|
(seqno + tcplen) == next->tcphdr->seqno);
|
||||||
}
|
}
|
||||||
pcb->ooseq = next;
|
pcb->ooseq = next;
|
||||||
}
|
}
|
||||||
|
@ -208,11 +208,9 @@ START_TEST(test_tcp_recv_ooseq_FIN_OOSEQ)
|
|||||||
EXPECT(counters.recved_bytes == 0);
|
EXPECT(counters.recved_bytes == 0);
|
||||||
EXPECT(counters.err_calls == 0);
|
EXPECT(counters.err_calls == 0);
|
||||||
/* check ooseq queue */
|
/* check ooseq queue */
|
||||||
EXPECT_OOSEQ(tcp_oos_count(pcb) == 2);
|
EXPECT_OOSEQ(tcp_oos_count(pcb) == 1);
|
||||||
EXPECT_OOSEQ(tcp_oos_seg_seqno(pcb, 0) == 2);
|
EXPECT_OOSEQ(tcp_oos_seg_seqno(pcb, 0) == 2);
|
||||||
EXPECT_OOSEQ(tcp_oos_seg_tcplen(pcb, 0) == 6);
|
EXPECT_OOSEQ(tcp_oos_seg_tcplen(pcb, 0) == 15); /* includes FIN */
|
||||||
EXPECT_OOSEQ(tcp_oos_seg_seqno(pcb, 1) == 8);
|
|
||||||
EXPECT_OOSEQ(tcp_oos_seg_tcplen(pcb, 1) == 9); /* includes FIN */
|
|
||||||
|
|
||||||
/* pass the segment to tcp_input */
|
/* pass the segment to tcp_input */
|
||||||
tcp_input(p_fin, &netif);
|
tcp_input(p_fin, &netif);
|
||||||
@ -222,11 +220,9 @@ START_TEST(test_tcp_recv_ooseq_FIN_OOSEQ)
|
|||||||
EXPECT(counters.recved_bytes == 0);
|
EXPECT(counters.recved_bytes == 0);
|
||||||
EXPECT(counters.err_calls == 0);
|
EXPECT(counters.err_calls == 0);
|
||||||
/* ooseq queue: unchanged */
|
/* ooseq queue: unchanged */
|
||||||
EXPECT_OOSEQ(tcp_oos_count(pcb) == 2);
|
EXPECT_OOSEQ(tcp_oos_count(pcb) == 1);
|
||||||
EXPECT_OOSEQ(tcp_oos_seg_seqno(pcb, 0) == 2);
|
EXPECT_OOSEQ(tcp_oos_seg_seqno(pcb, 0) == 2);
|
||||||
EXPECT_OOSEQ(tcp_oos_seg_tcplen(pcb, 0) == 6);
|
EXPECT_OOSEQ(tcp_oos_seg_tcplen(pcb, 0) == 15); /* includes FIN */
|
||||||
EXPECT_OOSEQ(tcp_oos_seg_seqno(pcb, 1) == 8);
|
|
||||||
EXPECT_OOSEQ(tcp_oos_seg_tcplen(pcb, 1) == 9); /* includes FIN */
|
|
||||||
|
|
||||||
/* pass the segment to tcp_input */
|
/* pass the segment to tcp_input */
|
||||||
tcp_input(pinseq, &netif);
|
tcp_input(pinseq, &netif);
|
||||||
@ -363,13 +359,11 @@ START_TEST(test_tcp_recv_ooseq_FIN_INSEQ)
|
|||||||
EXPECT(counters.recved_bytes == 0);
|
EXPECT(counters.recved_bytes == 0);
|
||||||
EXPECT(counters.err_calls == 0);
|
EXPECT(counters.err_calls == 0);
|
||||||
/* check ooseq queue */
|
/* check ooseq queue */
|
||||||
EXPECT_OOSEQ(tcp_oos_count(pcb) == 3);
|
EXPECT_OOSEQ(tcp_oos_count(pcb) == 2);
|
||||||
EXPECT_OOSEQ(tcp_oos_seg_seqno(pcb, 0) == 1);
|
EXPECT_OOSEQ(tcp_oos_seg_seqno(pcb, 0) == 1);
|
||||||
EXPECT_OOSEQ(tcp_oos_seg_tcplen(pcb, 0) == 1);
|
EXPECT_OOSEQ(tcp_oos_seg_tcplen(pcb, 0) == 1);
|
||||||
EXPECT_OOSEQ(tcp_oos_seg_seqno(pcb, 1) == 2);
|
EXPECT_OOSEQ(tcp_oos_seg_seqno(pcb, 1) == 2);
|
||||||
EXPECT_OOSEQ(tcp_oos_seg_tcplen(pcb, 1) == 1);
|
EXPECT_OOSEQ(tcp_oos_seg_tcplen(pcb, 1) == 12);
|
||||||
EXPECT_OOSEQ(tcp_oos_seg_seqno(pcb, 2) == 3);
|
|
||||||
EXPECT_OOSEQ(tcp_oos_seg_tcplen(pcb, 2) == 11);
|
|
||||||
|
|
||||||
/* pass the segment to tcp_input */
|
/* pass the segment to tcp_input */
|
||||||
tcp_input(pinseq, &netif);
|
tcp_input(pinseq, &netif);
|
||||||
|
Loading…
Reference in New Issue
Block a user