Add TCP_SEQ_BETWEEN macro for comparing a range of sequence numbers

This commit is contained in:
kieranm 2004-09-12 15:56:12 +00:00
parent 89abd1f58e
commit a3d27e30e0
2 changed files with 80 additions and 66 deletions

View File

@ -506,9 +506,11 @@ tcp_process(struct tcp_pcb *pcb)
acceptable = 1; acceptable = 1;
} }
} else { } else {
if (TCP_SEQ_GEQ(seqno, pcb->rcv_nxt) && /*if (TCP_SEQ_GEQ(seqno, pcb->rcv_nxt) &&
TCP_SEQ_LEQ(seqno, pcb->rcv_nxt + pcb->rcv_wnd)) { TCP_SEQ_LEQ(seqno, pcb->rcv_nxt + pcb->rcv_wnd)) {
acceptable = 1; */
if(TCP_SEQ_BETWEEN(seqno, pcb->rcv_nxt, pcb->rcv_nxt+pcb->rcv_wnd)){
acceptable = 1;
} }
} }
@ -562,8 +564,9 @@ tcp_process(struct tcp_pcb *pcb)
case SYN_RCVD: case SYN_RCVD:
if (flags & TCP_ACK && if (flags & TCP_ACK &&
!(flags & TCP_RST)) { !(flags & TCP_RST)) {
if (TCP_SEQ_LT(pcb->lastack, ackno) && /*if (TCP_SEQ_LT(pcb->lastack, ackno) &&
TCP_SEQ_LEQ(ackno, pcb->snd_nxt)) { TCP_SEQ_LEQ(ackno, pcb->snd_nxt)) { */
if(TCP_SEQ_BETWEEN(ackno, pcb->lastack+1, pcb->snd_nxt))
pcb->state = ESTABLISHED; pcb->state = ESTABLISHED;
LWIP_DEBUGF(TCP_DEBUG, ("TCP connection established %u -> %u.\n", inseg.tcphdr->src, inseg.tcphdr->dest)); LWIP_DEBUGF(TCP_DEBUG, ("TCP connection established %u -> %u.\n", inseg.tcphdr->src, inseg.tcphdr->dest));
#if LWIP_CALLBACK_API #if LWIP_CALLBACK_API
@ -732,8 +735,10 @@ tcp_receive(struct tcp_pcb *pcb)
LWIP_DEBUGF(TCP_FR_DEBUG, ("tcp_receive: dupack averted %lu %lu\n", LWIP_DEBUGF(TCP_FR_DEBUG, ("tcp_receive: dupack averted %lu %lu\n",
pcb->snd_wl1 + pcb->snd_wnd, right_wnd_edge)); pcb->snd_wl1 + pcb->snd_wnd, right_wnd_edge));
} }
} else if (TCP_SEQ_LT(pcb->lastack, ackno) && } else
TCP_SEQ_LEQ(ackno, pcb->snd_max)) { /*if (TCP_SEQ_LT(pcb->lastack, ackno) &&
TCP_SEQ_LEQ(ackno, pcb->snd_max)) { */
if(TCP_SEQ_BETWEEN(ackno, pcb->lastack+1, pcb->snd_max)){
/* We come here when the ACK acknowledges new data. */ /* We come here when the ACK acknowledges new data. */
/* Reset the "IN Fast Retransmit" flag, since we are no longer /* Reset the "IN Fast Retransmit" flag, since we are no longer
@ -818,12 +823,13 @@ tcp_receive(struct tcp_pcb *pcb)
segments on the unsent queue when performing retransmit */ segments on the unsent queue when performing retransmit */
#if 0 #if 0
while (pcb->unsent != NULL && while (pcb->unsent != NULL &&
TCP_SEQ_LEQ(ntohl(pcb->unsent->tcphdr->seqno) + TCP_TCPLEN(pcb->unsent), /*TCP_SEQ_LEQ(ntohl(pcb->unsent->tcphdr->seqno) + TCP_TCPLEN(pcb->unsent), ackno) &&
ackno) && TCP_SEQ_LEQ(ackno, pcb->snd_max)*/
TCP_SEQ_LEQ(ackno, pcb->snd_max)) { TCP_SEQ_BETWEEN(ackno, ntohl(pcb->unsent->tcphdr->seqno) + TCP_TCPLEN(pcb->unsent), pcb->snd_max)
) {
LWIP_DEBUGF(TCP_INPUT_DEBUG, ("tcp_receive: removing %lu:%lu from pcb->unsent\n", LWIP_DEBUGF(TCP_INPUT_DEBUG, ("tcp_receive: removing %lu:%lu from pcb->unsent\n",
ntohl(pcb->unsent->tcphdr->seqno), ntohl(pcb->unsent->tcphdr->seqno) + ntohl(pcb->unsent->tcphdr->seqno), ntohl(pcb->unsent->tcphdr->seqno) +
TCP_TCPLEN(pcb->unsent))); TCP_TCPLEN(pcb->unsent)));
next = pcb->unsent; next = pcb->unsent;
pcb->unsent = pcb->unsent->next; pcb->unsent = pcb->unsent->next;
@ -903,55 +909,57 @@ 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)){
if (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 if(TCP_SEQ_BETWEEN(pcb->rcv_nxt, seqno+1, seqno+tcplen-1)){
pointer in the pbuf downwards. This is somewhat tricky since /* Trimming the first edge is done by pushing the payload
we do not want to discard the full contents of the pbuf up to pointer in the pbuf downwards. This is somewhat tricky since
the new starting point of the data since we have to keep the we do not want to discard the full contents of the pbuf up to
TCP header which is present in the first pbuf in the chain. 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.
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 What is done is really quite a nasty hack: the first pbuf in
able to deallocate the whole pbuf, we cannot change this the pbuf chain is pointed to by inseg.p. Since we need to be
inseg.p pointer to point to any of the later pbufs in the able to deallocate the whole pbuf, we cannot change this
chain. Instead, we point the ->payload pointer in the first inseg.p pointer to point to any of the later pbufs in the
pbuf to data in one of the later pbufs. We also set the chain. Instead, we point the ->payload pointer in the first
inseg.data pointer to point to the right place. This way, the pbuf to data in one of the later pbufs. We also set the
->p pointer will still point to the first pbuf, but the inseg.data pointer to point to the right place. This way, the
->p->payload pointer will point to data in another pbuf. ->p pointer will still point to the first pbuf, but the
->p->payload pointer will point to data in another pbuf.
After we are done with adjusting the pbuf pointers we must
adjust the ->data pointer in the seg and the segment After we are done with adjusting the pbuf pointers we must
length.*/ adjust the ->data pointer in the seg and the segment
length.*/
off = pcb->rcv_nxt - seqno;
p = inseg.p; off = pcb->rcv_nxt - seqno;
if (inseg.p->len < off) { p = inseg.p;
new_tot_len = inseg.p->tot_len - off; if (inseg.p->len < off) {
while (p->len < off) { new_tot_len = inseg.p->tot_len - off;
off -= p->len; while (p->len < off) {
/* KJM following line changed (with addition of new_tot_len var) off -= p->len;
to fix bug #9076 /* KJM following line changed (with addition of new_tot_len var)
inseg.p->tot_len -= p->len; */ to fix bug #9076
p->tot_len = new_tot_len; inseg.p->tot_len -= p->len; */
p->len = 0; p->tot_len = new_tot_len;
p = p->next; p->len = 0;
} p = p->next;
pbuf_header(p, -off);
} else {
pbuf_header(inseg.p, -off);
} }
/* KJM following line changed to use p->payload rather than inseg->p->payload pbuf_header(p, -off);
to fix bug #9076 */ } else {
inseg.dataptr = p->payload; pbuf_header(inseg.p, -off);
inseg.len -= pcb->rcv_nxt - seqno;
inseg.tcphdr->seqno = seqno = pcb->rcv_nxt;
} }
else{ /* KJM following line changed to use p->payload rather than inseg->p->payload
to fix bug #9076 */
inseg.dataptr = p->payload;
inseg.len -= pcb->rcv_nxt - seqno;
inseg.tcphdr->seqno = seqno = pcb->rcv_nxt;
}
else{
if(TCP_SEQ_LT(seqno, pcb->rcv_nxt)){
/* the whole segment is < rcv_nxt */ /* the whole segment is < rcv_nxt */
/* must be a duplicate of a packet that has already been correctly handled */ /* must be a duplicate of a packet that has already been correctly handled */
LWIP_DEBUGF(TCP_INPUT_DEBUG, ("tcp_receive: duplicate seqno %lu\n", seqno)); LWIP_DEBUGF(TCP_INPUT_DEBUG, ("tcp_receive: duplicate seqno %lu\n", seqno));
tcp_ack_now(pcb); tcp_ack_now(pcb);
} }
@ -960,8 +968,9 @@ tcp_receive(struct tcp_pcb *pcb)
/* The sequence number must be within the window (above rcv_nxt /* The sequence number must be within the window (above rcv_nxt
and below rcv_nxt + rcv_wnd) in order to be further and below rcv_nxt + rcv_wnd) in order to be further
processed. */ processed. */
if (TCP_SEQ_GEQ(seqno, pcb->rcv_nxt) && /*if (TCP_SEQ_GEQ(seqno, pcb->rcv_nxt) &&
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 (pcb->rcv_nxt == seqno) { if (pcb->rcv_nxt == seqno) {
/* 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
@ -1115,8 +1124,10 @@ tcp_receive(struct tcp_pcb *pcb)
} }
break; break;
} }
} else if (TCP_SEQ_LT(prev->tcphdr->seqno, seqno) && } else
TCP_SEQ_LT(seqno, next->tcphdr->seqno)) { /*if (TCP_SEQ_LT(prev->tcphdr->seqno, seqno) &&
TCP_SEQ_LT(seqno, next->tcphdr->seqno)) {*/
if(TCP_SEQ_BETWEEN(seqno, prev->tcphdr->seqno, next->tcphdr->seqno-1)){
/* The sequence number of the incoming segment is in /* The sequence number of the incoming segment is in
between the sequence numbers of the previous and between the sequence numbers of the previous and
the next segment on ->ooseq. We trim and insert the the next segment on ->ooseq. We trim and insert the
@ -1163,16 +1174,18 @@ tcp_receive(struct tcp_pcb *pcb)
} }
} else { } else {
if (TCP_SEQ_GT(pcb->rcv_nxt, seqno) || /*if (TCP_SEQ_GT(pcb->rcv_nxt, seqno) ||
TCP_SEQ_GEQ(seqno, pcb->rcv_nxt + pcb->rcv_wnd)) { TCP_SEQ_GEQ(seqno, pcb->rcv_nxt + pcb->rcv_wnd)) {*/
if(!TCP_SEQ_BETWEEN(seqno, pcb->rcv_nxt, pcb->rcv_nxt + pcb->rcv_wnd-1)){
tcp_ack_now(pcb); tcp_ack_now(pcb);
} }
} }
} else { } else {
/* Segments with length 0 is taken care of here. Segments that /* Segments with length 0 is taken care of here. Segments that
fall out of the window are ACKed. */ fall out of the window are ACKed. */
if (TCP_SEQ_GT(pcb->rcv_nxt, seqno) || /*if (TCP_SEQ_GT(pcb->rcv_nxt, seqno) ||
TCP_SEQ_GEQ(seqno, pcb->rcv_nxt + pcb->rcv_wnd)) { TCP_SEQ_GEQ(seqno, pcb->rcv_nxt + pcb->rcv_wnd)) {*/
if(!TCP_SEQ_BETWEEN(seqno, pcb->rcv_nxt, pcb->rcv_nxt + pcb->rcv_wnd-1)){
tcp_ack_now(pcb); tcp_ack_now(pcb);
} }
} }

View File

@ -112,7 +112,8 @@ void tcp_rexmit (struct tcp_pcb *pcb);
#define TCP_SEQ_LEQ(a,b) ((s32_t)((a)-(b)) <= 0) #define TCP_SEQ_LEQ(a,b) ((s32_t)((a)-(b)) <= 0)
#define TCP_SEQ_GT(a,b) ((s32_t)((a)-(b)) > 0) #define TCP_SEQ_GT(a,b) ((s32_t)((a)-(b)) > 0)
#define TCP_SEQ_GEQ(a,b) ((s32_t)((a)-(b)) >= 0) #define TCP_SEQ_GEQ(a,b) ((s32_t)((a)-(b)) >= 0)
/* is b<=a<=c? */
#define TCP_SEQ_BETWEEN(a,b,c) ((c)-(b) >= (a)-(b))
#define TCP_FIN 0x01U #define TCP_FIN 0x01U
#define TCP_SYN 0x02U #define TCP_SYN 0x02U
#define TCP_RST 0x04U #define TCP_RST 0x04U