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:
kieranm 2002-10-24 13:34:36 +00:00
parent aa69784495
commit 8b5fcad039

View File

@ -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