mirror of
https://github.com/lwip-tcpip/lwip.git
synced 2024-10-05 22:29:49 +00:00
Added check on entire sequence number of received packet being less than the rcv_nxt variable.
(see http://www.sics.se/mailing-lists/lwip.html/msg01409.html)
This commit is contained in:
parent
aa69784495
commit
8b5fcad039
@ -825,43 +825,50 @@ tcp_receive(struct tcp_pcb *pcb)
|
|||||||
this if the sequence number of the incoming segment is less
|
this if the sequence number of the incoming segment is less
|
||||||
than rcv_nxt, and the sequence number plus the length of the
|
than rcv_nxt, and the sequence number plus the length of the
|
||||||
segment is larger than rcv_nxt. */
|
segment is larger than rcv_nxt. */
|
||||||
if(TCP_SEQ_LT(seqno, pcb->rcv_nxt) &&
|
if(TCP_SEQ_LT(seqno, pcb->rcv_nxt)){
|
||||||
TCP_SEQ_LT(pcb->rcv_nxt, seqno + tcplen)) {
|
if(TCP_SEQ_LT(pcb->rcv_nxt, seqno + tcplen)) {
|
||||||
/* Trimming the first edge is done by pushing the payload
|
/* Trimming the first edge is done by pushing the payload
|
||||||
pointer in the pbuf downwards. This is somewhat tricky since
|
pointer in the pbuf downwards. This is somewhat tricky since
|
||||||
we do not want to discard the full contents of the pbuf up to
|
we do not want to discard the full contents of the pbuf up to
|
||||||
the new starting point of the data since we have to keep the
|
the new starting point of the data since we have to keep the
|
||||||
TCP header which is present in the first pbuf in the chain.
|
TCP header which is present in the first pbuf in the chain.
|
||||||
|
|
||||||
What is done is really quite a nasty hack: the first pbuf in
|
What is done is really quite a nasty hack: the first pbuf in
|
||||||
the pbuf chain is pointed to by inseg.p. Since we need to be
|
the pbuf chain is pointed to by inseg.p. Since we need to be
|
||||||
able to deallocate the whole pbuf, we cannot change this
|
able to deallocate the whole pbuf, we cannot change this
|
||||||
inseg.p pointer to point to any of the later pbufs in the
|
inseg.p pointer to point to any of the later pbufs in the
|
||||||
chain. Instead, we point the ->payload pointer in the first
|
chain. Instead, we point the ->payload pointer in the first
|
||||||
pbuf to data in one of the later pbufs. We also set the
|
pbuf to data in one of the later pbufs. We also set the
|
||||||
inseg.data pointer to point to the right place. This way, the
|
inseg.data pointer to point to the right place. This way, the
|
||||||
->p pointer will still point to the first pbuf, but the
|
->p pointer will still point to the first pbuf, but the
|
||||||
->p->payload pointer will point to data in another pbuf.
|
->p->payload pointer will point to data in another pbuf.
|
||||||
|
|
||||||
After we are done with adjusting the pbuf pointers we must
|
After we are done with adjusting the pbuf pointers we must
|
||||||
adjust the ->data pointer in the seg and the segment
|
adjust the ->data pointer in the seg and the segment
|
||||||
length.*/
|
length.*/
|
||||||
off = pcb->rcv_nxt - seqno;
|
off = pcb->rcv_nxt - seqno;
|
||||||
if(inseg.p->len < off) {
|
if(inseg.p->len < off) {
|
||||||
p = inseg.p;
|
p = inseg.p;
|
||||||
while(p->len < off) {
|
while(p->len < off) {
|
||||||
off -= p->len;
|
off -= p->len;
|
||||||
inseg.p->tot_len -= p->len;
|
inseg.p->tot_len -= p->len;
|
||||||
p->len = 0;
|
p->len = 0;
|
||||||
p = p->next;
|
p = p->next;
|
||||||
|
}
|
||||||
|
pbuf_header(p, -off);
|
||||||
|
} else {
|
||||||
|
pbuf_header(inseg.p, -off);
|
||||||
}
|
}
|
||||||
pbuf_header(p, -off);
|
inseg.dataptr = inseg.p->payload;
|
||||||
} else {
|
inseg.len -= pcb->rcv_nxt - seqno;
|
||||||
pbuf_header(inseg.p, -off);
|
inseg.tcphdr->seqno = seqno = pcb->rcv_nxt;
|
||||||
|
}
|
||||||
|
else{
|
||||||
|
/* the whole segment is < rcv_nxt */
|
||||||
|
/* must be a duplicate of a packet that has already been correctly handled */
|
||||||
|
|
||||||
|
DEBUGF(TCP_INPUT_DEBUG, ("tcp_receive: duplicate seqno %ld\n", seqno));
|
||||||
}
|
}
|
||||||
inseg.dataptr = inseg.p->payload;
|
|
||||||
inseg.len -= pcb->rcv_nxt - seqno;
|
|
||||||
inseg.tcphdr->seqno = seqno = pcb->rcv_nxt;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/* The sequence number must be within the window (above rcv_nxt
|
/* The sequence number must be within the window (above rcv_nxt
|
||||||
|
Loading…
Reference in New Issue
Block a user