825 |
this if the sequence number of the incoming segment is less |
this if the sequence number of the incoming segment is less |
826 |
than rcv_nxt, and the sequence number plus the length of the |
than rcv_nxt, and the sequence number plus the length of the |
827 |
segment is larger than rcv_nxt. */ |
segment is larger than rcv_nxt. */ |
828 |
if(TCP_SEQ_LT(seqno, pcb->rcv_nxt) && |
if(TCP_SEQ_LT(seqno, pcb->rcv_nxt)){ |
829 |
TCP_SEQ_LT(pcb->rcv_nxt, seqno + tcplen)) { |
if(TCP_SEQ_LT(pcb->rcv_nxt, seqno + tcplen)) { |
830 |
/* Trimming the first edge is done by pushing the payload |
/* Trimming the first edge is done by pushing the payload |
831 |
pointer in the pbuf downwards. This is somewhat tricky since |
pointer in the pbuf downwards. This is somewhat tricky since |
832 |
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 |
833 |
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 |
834 |
TCP header which is present in the first pbuf in the chain. |
TCP header which is present in the first pbuf in the chain. |
835 |
|
|
836 |
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 |
837 |
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 |
838 |
able to deallocate the whole pbuf, we cannot change this |
able to deallocate the whole pbuf, we cannot change this |
839 |
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 |
840 |
chain. Instead, we point the ->payload pointer in the first |
chain. Instead, we point the ->payload pointer in the first |
841 |
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 |
842 |
inseg.data pointer to point to the right place. This way, the |
inseg.data pointer to point to the right place. This way, the |
843 |
->p pointer will still point to the first pbuf, but the |
->p pointer will still point to the first pbuf, but the |
844 |
->p->payload pointer will point to data in another pbuf. |
->p->payload pointer will point to data in another pbuf. |
845 |
|
|
846 |
After we are done with adjusting the pbuf pointers we must |
After we are done with adjusting the pbuf pointers we must |
847 |
adjust the ->data pointer in the seg and the segment |
adjust the ->data pointer in the seg and the segment |
848 |
length.*/ |
length.*/ |
849 |
off = pcb->rcv_nxt - seqno; |
off = pcb->rcv_nxt - seqno; |
850 |
if(inseg.p->len < off) { |
if(inseg.p->len < off) { |
851 |
p = inseg.p; |
p = inseg.p; |
852 |
while(p->len < off) { |
while(p->len < off) { |
853 |
off -= p->len; |
off -= p->len; |
854 |
inseg.p->tot_len -= p->len; |
inseg.p->tot_len -= p->len; |
855 |
p->len = 0; |
p->len = 0; |
856 |
p = p->next; |
p = p->next; |
857 |
|
} |
858 |
|
pbuf_header(p, -off); |
859 |
|
} else { |
860 |
|
pbuf_header(inseg.p, -off); |
861 |
} |
} |
862 |
pbuf_header(p, -off); |
inseg.dataptr = inseg.p->payload; |
863 |
} else { |
inseg.len -= pcb->rcv_nxt - seqno; |
864 |
pbuf_header(inseg.p, -off); |
inseg.tcphdr->seqno = seqno = pcb->rcv_nxt; |
865 |
|
} |
866 |
|
else{ |
867 |
|
/* the whole segment is < rcv_nxt */ |
868 |
|
/* must be a duplicate of a packet that has already been correctly handled */ |
869 |
|
|
870 |
|
DEBUGF(TCP_INPUT_DEBUG, ("tcp_receive: duplicate seqno %ld\n", seqno)); |
871 |
} |
} |
|
inseg.dataptr = inseg.p->payload; |
|
|
inseg.len -= pcb->rcv_nxt - seqno; |
|
|
inseg.tcphdr->seqno = seqno = pcb->rcv_nxt; |
|
872 |
} |
} |
873 |
|
|
874 |
/* The sequence number must be within the window (above rcv_nxt |
/* The sequence number must be within the window (above rcv_nxt |