/[lwip]/lwip/src/core/tcp_in.c
ViewVC logotype

Diff of /lwip/src/core/tcp_in.c

Parent Directory Parent Directory | Revision Log Revision Log | View Patch Patch

revision 1.22.2.1 by likewise, Thu Apr 10 09:05:19 2003 UTC revision 1.22.2.2 by likewise, Wed May 14 14:38:28 2003 UTC
# Line 116  tcp_input(struct pbuf *p, struct netif * Line 116  tcp_input(struct pbuf *p, struct netif *
116    pbuf_header(p, -((s16_t)(IPH_HL(iphdr) * 4)));    pbuf_header(p, -((s16_t)(IPH_HL(iphdr) * 4)));
117        
118    /* Don't even process incoming broadcasts/multicasts. */    /* Don't even process incoming broadcasts/multicasts. */
119    if(ip_addr_isbroadcast(&(iphdr->dest), &(inp->netmask)) ||    if (ip_addr_isbroadcast(&(iphdr->dest), &(inp->netmask)) ||
120       ip_addr_ismulticast(&(iphdr->dest))) {       ip_addr_ismulticast(&(iphdr->dest))) {
121      pbuf_free(p);      pbuf_free(p);
122      return;      return;
123    }    }
124    
125    /* Verify TCP checksum. */    /* Verify TCP checksum. */
126    if(inet_chksum_pseudo(p, (struct ip_addr *)&(iphdr->src),    if (inet_chksum_pseudo(p, (struct ip_addr *)&(iphdr->src),
127                          (struct ip_addr *)&(iphdr->dest),                          (struct ip_addr *)&(iphdr->dest),
128                          IP_PROTO_TCP, p->tot_len) != 0) {                          IP_PROTO_TCP, p->tot_len) != 0) {
129      DEBUGF(TCP_INPUT_DEBUG, ("tcp_input: packet discarded due to failing checksum 0x%04x\n", inet_chksum_pseudo(p, (struct ip_addr *)&(iphdr->src),      DEBUGF(TCP_INPUT_DEBUG, ("tcp_input: packet discarded due to failing checksum 0x%04x\n", inet_chksum_pseudo(p, (struct ip_addr *)&(iphdr->src),
# Line 164  tcp_input(struct pbuf *p, struct netif * Line 164  tcp_input(struct pbuf *p, struct netif *
164      LWIP_ASSERT("tcp_input: active pcb->state != CLOSED", pcb->state != CLOSED);      LWIP_ASSERT("tcp_input: active pcb->state != CLOSED", pcb->state != CLOSED);
165      LWIP_ASSERT("tcp_input: active pcb->state != TIME-WAIT", pcb->state != TIME_WAIT);      LWIP_ASSERT("tcp_input: active pcb->state != TIME-WAIT", pcb->state != TIME_WAIT);
166      LWIP_ASSERT("tcp_input: active pcb->state != LISTEN", pcb->state != LISTEN);      LWIP_ASSERT("tcp_input: active pcb->state != LISTEN", pcb->state != LISTEN);
167      if(pcb->remote_port == tcphdr->src &&      if (pcb->remote_port == tcphdr->src &&
168         pcb->local_port == tcphdr->dest &&         pcb->local_port == tcphdr->dest &&
169         ip_addr_cmp(&(pcb->remote_ip), &(iphdr->src)) &&         ip_addr_cmp(&(pcb->remote_ip), &(iphdr->src)) &&
170         ip_addr_cmp(&(pcb->local_ip), &(iphdr->dest))) {         ip_addr_cmp(&(pcb->local_ip), &(iphdr->dest))) {
# Line 173  tcp_input(struct pbuf *p, struct netif * Line 173  tcp_input(struct pbuf *p, struct netif *
173           lookups will be faster (we exploit locality in TCP segment           lookups will be faster (we exploit locality in TCP segment
174           arrivals). */           arrivals). */
175        LWIP_ASSERT("tcp_input: pcb->next != pcb (before cache)", pcb->next != pcb);        LWIP_ASSERT("tcp_input: pcb->next != pcb (before cache)", pcb->next != pcb);
176        if(prev != NULL) {        if (prev != NULL) {
177          prev->next = pcb->next;          prev->next = pcb->next;
178          pcb->next = tcp_active_pcbs;          pcb->next = tcp_active_pcbs;
179          tcp_active_pcbs = pcb;          tcp_active_pcbs = pcb;
# Line 190  tcp_input(struct pbuf *p, struct netif * Line 190  tcp_input(struct pbuf *p, struct netif *
190    
191      for(pcb = tcp_tw_pcbs; pcb != NULL; pcb = pcb->next) {      for(pcb = tcp_tw_pcbs; pcb != NULL; pcb = pcb->next) {
192        LWIP_ASSERT("tcp_input: TIME-WAIT pcb->state == TIME-WAIT", pcb->state == TIME_WAIT);        LWIP_ASSERT("tcp_input: TIME-WAIT pcb->state == TIME-WAIT", pcb->state == TIME_WAIT);
193        if(pcb->remote_port == tcphdr->src &&        if (pcb->remote_port == tcphdr->src &&
194           pcb->local_port == tcphdr->dest &&           pcb->local_port == tcphdr->dest &&
195           ip_addr_cmp(&(pcb->remote_ip), &(iphdr->src)) &&           ip_addr_cmp(&(pcb->remote_ip), &(iphdr->src)) &&
196           ip_addr_cmp(&(pcb->local_ip), &(iphdr->dest))) {           ip_addr_cmp(&(pcb->local_ip), &(iphdr->dest))) {
# Line 208  tcp_input(struct pbuf *p, struct netif * Line 208  tcp_input(struct pbuf *p, struct netif *
208       are LISTENing for incoming connections. */       are LISTENing for incoming connections. */
209      prev = NULL;        prev = NULL;  
210      for(lpcb = tcp_listen_pcbs; lpcb != NULL; lpcb = lpcb->next) {      for(lpcb = tcp_listen_pcbs; lpcb != NULL; lpcb = lpcb->next) {
211        if((ip_addr_isany(&(lpcb->local_ip)) ||        if ((ip_addr_isany(&(lpcb->local_ip)) ||
212            ip_addr_cmp(&(lpcb->local_ip), &(iphdr->dest))) &&            ip_addr_cmp(&(lpcb->local_ip), &(iphdr->dest))) &&
213           lpcb->local_port == tcphdr->dest) {                 lpcb->local_port == tcphdr->dest) {      
214          /* Move this PCB to the front of the list so that subsequent          /* Move this PCB to the front of the list so that subsequent
215             lookups will be faster (we exploit locality in TCP segment             lookups will be faster (we exploit locality in TCP segment
216             arrivals). */             arrivals). */
217          if(prev != NULL) {          if (prev != NULL) {
218            ((struct tcp_pcb_listen *)prev)->next = lpcb->next;            ((struct tcp_pcb_listen *)prev)->next = lpcb->next;
219            /* our successor is the remainder of the listening list */            /* our successor is the remainder of the listening list */
220            lpcb->next = tcp_listen_pcbs;            lpcb->next = tcp_listen_pcbs;
# Line 238  tcp_input(struct pbuf *p, struct netif * Line 238  tcp_input(struct pbuf *p, struct netif *
238  #endif /* TCP_INPUT_DEBUG */  #endif /* TCP_INPUT_DEBUG */
239    
240        
241    if(pcb != NULL) {    if (pcb != NULL) {
242      /* The incoming segment belongs to a connection. */      /* The incoming segment belongs to a connection. */
243  #if TCP_INPUT_DEBUG  #if TCP_INPUT_DEBUG
244  #if TCP_DEBUG  #if TCP_DEBUG
# Line 261  tcp_input(struct pbuf *p, struct netif * Line 261  tcp_input(struct pbuf *p, struct netif *
261      tcp_input_pcb = NULL;      tcp_input_pcb = NULL;
262      /* A return value of ERR_ABRT means that tcp_abort() was called      /* A return value of ERR_ABRT means that tcp_abort() was called
263         and that the pcb has been freed. If so, we don't do anything. */         and that the pcb has been freed. If so, we don't do anything. */
264      if(err != ERR_ABRT) {      if (err != ERR_ABRT) {
265        if(recv_flags & TF_RESET) {        if (recv_flags & TF_RESET) {
266          /* TF_RESET means that the connection was reset by the other          /* TF_RESET means that the connection was reset by the other
267             end. We then call the error callback to inform the             end. We then call the error callback to inform the
268             application that the connection is dead before we             application that the connection is dead before we
# Line 270  tcp_input(struct pbuf *p, struct netif * Line 270  tcp_input(struct pbuf *p, struct netif *
270          TCP_EVENT_ERR(pcb->errf, pcb->callback_arg, ERR_RST);          TCP_EVENT_ERR(pcb->errf, pcb->callback_arg, ERR_RST);
271          tcp_pcb_remove(&tcp_active_pcbs, pcb);                      tcp_pcb_remove(&tcp_active_pcbs, pcb);            
272          memp_free(MEMP_TCP_PCB, pcb);          memp_free(MEMP_TCP_PCB, pcb);
273        } else if(recv_flags & TF_CLOSED) {        } else if (recv_flags & TF_CLOSED) {
274          /* The connection has been closed and we will deallocate the          /* The connection has been closed and we will deallocate the
275             PCB. */             PCB. */
276          tcp_pcb_remove(&tcp_active_pcbs, pcb);          tcp_pcb_remove(&tcp_active_pcbs, pcb);
# Line 280  tcp_input(struct pbuf *p, struct netif * Line 280  tcp_input(struct pbuf *p, struct netif *
280          /* If the application has registered a "sent" function to be          /* If the application has registered a "sent" function to be
281             called when new send buffer space is available, we call it             called when new send buffer space is available, we call it
282             now. */             now. */
283          if(pcb->acked > 0) {          if (pcb->acked > 0) {
284            TCP_EVENT_SENT(pcb, pcb->acked, err);            TCP_EVENT_SENT(pcb, pcb->acked, err);
285          }          }
286    
287          if(recv_data != NULL) {          if (recv_data != NULL) {
288            /* Notify application that data has been received. */            /* Notify application that data has been received. */
289            TCP_EVENT_RECV(pcb, recv_data, ERR_OK, err);            TCP_EVENT_RECV(pcb, recv_data, ERR_OK, err);
290          }          }
291                    
292          /* If a FIN segment was received, we call the callback          /* If a FIN segment was received, we call the callback
293             function with a NULL buffer to indicate EOF. */             function with a NULL buffer to indicate EOF. */
294          if(recv_flags & TF_GOT_FIN) {          if (recv_flags & TF_GOT_FIN) {
295            TCP_EVENT_RECV(pcb, NULL, ERR_OK, err);            TCP_EVENT_RECV(pcb, NULL, ERR_OK, err);
296          }          }
297          /* If there were no errors, we try to send something out. */          /* If there were no errors, we try to send something out. */
298          if(err == ERR_OK) {          if (err == ERR_OK) {
299            tcp_output(pcb);            tcp_output(pcb);
300          }          }
301        }        }
# Line 318  tcp_input(struct pbuf *p, struct netif * Line 318  tcp_input(struct pbuf *p, struct netif *
318      /* If no matching PCB was found, send a TCP RST (reset) to the      /* If no matching PCB was found, send a TCP RST (reset) to the
319         sender. */         sender. */
320      DEBUGF(TCP_RST_DEBUG, ("tcp_input: no PCB match found, resetting.\n"));      DEBUGF(TCP_RST_DEBUG, ("tcp_input: no PCB match found, resetting.\n"));
321      if(!(TCPH_FLAGS(tcphdr) & TCP_RST)) {      if (!(TCPH_FLAGS(tcphdr) & TCP_RST)) {
322  #ifdef TCP_STATS  #ifdef TCP_STATS
323        ++lwip_stats.tcp.proterr;        ++lwip_stats.tcp.proterr;
324        ++lwip_stats.tcp.drop;        ++lwip_stats.tcp.drop;
# Line 348  tcp_listen_input(struct tcp_pcb_listen * Line 348  tcp_listen_input(struct tcp_pcb_listen *
348            
349    /* In the LISTEN state, we check for incoming SYN segments,    /* In the LISTEN state, we check for incoming SYN segments,
350       creates a new PCB, and responds with a SYN|ACK. */       creates a new PCB, and responds with a SYN|ACK. */
351    if(flags & TCP_ACK) {    if (flags & TCP_ACK) {
352      /* For incoming segments with the ACK flag set, respond with a      /* For incoming segments with the ACK flag set, respond with a
353         RST. */         RST. */
354      DEBUGF(TCP_RST_DEBUG, ("tcp_listen_input: ACK in LISTEN, sending reset\n"));      DEBUGF(TCP_RST_DEBUG, ("tcp_listen_input: ACK in LISTEN, sending reset\n"));
355      tcp_rst(ackno + 1, seqno + tcplen,      tcp_rst(ackno + 1, seqno + tcplen,
356              &(iphdr->dest), &(iphdr->src),              &(iphdr->dest), &(iphdr->src),
357              tcphdr->dest, tcphdr->src);              tcphdr->dest, tcphdr->src);
358    } else if(flags & TCP_SYN) {    } else if (flags & TCP_SYN) {
359      DEBUGF(DEMO_DEBUG, ("TCP connection request %d -> %d.\n", tcphdr->src, tcphdr->dest));      DEBUGF(DEMO_DEBUG, ("TCP connection request %d -> %d.\n", tcphdr->src, tcphdr->dest));
360      npcb = tcp_alloc(pcb->prio);      npcb = tcp_alloc(pcb->prio);
361      /* If a new PCB could not be created (probably due to lack of memory),      /* If a new PCB could not be created (probably due to lack of memory),
362         we don't do anything, but rely on the sender will retransmit the         we don't do anything, but rely on the sender will retransmit the
363         SYN at a time when we have more memory available. */         SYN at a time when we have more memory available. */
364      if(npcb == NULL) {      if (npcb == NULL) {
365        DEBUGF(TCP_DEBUG, ("tcp_listen_input: could not allocate PCB\n"));        DEBUGF(TCP_DEBUG, ("tcp_listen_input: could not allocate PCB\n"));
366  #ifdef TCP_STATS  #ifdef TCP_STATS
367        ++lwip_stats.tcp.memerr;        ++lwip_stats.tcp.memerr;
# Line 411  tcp_listen_input(struct tcp_pcb_listen * Line 411  tcp_listen_input(struct tcp_pcb_listen *
411  static err_t  static err_t
412  tcp_timewait_input(struct tcp_pcb *pcb)  tcp_timewait_input(struct tcp_pcb *pcb)
413  {  {
414    if(TCP_SEQ_GT(seqno + tcplen, pcb->rcv_nxt)) {    if (TCP_SEQ_GT(seqno + tcplen, pcb->rcv_nxt)) {
415      pcb->rcv_nxt = seqno + tcplen;      pcb->rcv_nxt = seqno + tcplen;
416    }    }
417    if(tcplen > 0) {    if (tcplen > 0) {
418      tcp_ack_now(pcb);      tcp_ack_now(pcb);
419    }    }
420    return tcp_output(pcb);    return tcp_output(pcb);
# Line 439  tcp_process(struct tcp_pcb *pcb) Line 439  tcp_process(struct tcp_pcb *pcb)
439    err = ERR_OK;    err = ERR_OK;
440        
441    /* Process incoming RST segments. */    /* Process incoming RST segments. */
442    if(flags & TCP_RST) {    if (flags & TCP_RST) {
443      /* First, determine if the reset is acceptable. */      /* First, determine if the reset is acceptable. */
444      if(pcb->state == SYN_SENT) {      if (pcb->state == SYN_SENT) {
445        if(ackno == pcb->snd_nxt) {        if (ackno == pcb->snd_nxt) {
446          acceptable = 1;          acceptable = 1;
447        }        }
448      } else {      } else {
449        if(TCP_SEQ_GEQ(seqno, pcb->rcv_nxt) &&        if (TCP_SEQ_GEQ(seqno, pcb->rcv_nxt) &&
450           TCP_SEQ_LEQ(seqno, pcb->rcv_nxt + pcb->rcv_wnd)) {           TCP_SEQ_LEQ(seqno, pcb->rcv_nxt + pcb->rcv_wnd)) {
451          acceptable = 1;          acceptable = 1;
452        }        }
453      }      }
454            
455      if(acceptable) {      if (acceptable) {
456        DEBUGF(TCP_INPUT_DEBUG, ("tcp_process: Connection RESET\n"));        DEBUGF(TCP_INPUT_DEBUG, ("tcp_process: Connection RESET\n"));
457        LWIP_ASSERT("tcp_input: pcb->state != CLOSED", pcb->state != CLOSED);        LWIP_ASSERT("tcp_input: pcb->state != CLOSED", pcb->state != CLOSED);
458        recv_flags = TF_RESET;        recv_flags = TF_RESET;
# Line 471  tcp_process(struct tcp_pcb *pcb) Line 471  tcp_process(struct tcp_pcb *pcb)
471    pcb->tmr = tcp_ticks;    pcb->tmr = tcp_ticks;
472        
473    /* Do different things depending on the TCP state. */    /* Do different things depending on the TCP state. */
474    switch(pcb->state) {    switch (pcb->state) {
475    case SYN_SENT:    case SYN_SENT:
476      DEBUGF(TCP_INPUT_DEBUG, ("SYN-SENT: ackno %lu pcb->snd_nxt %lu unacked %lu\n", ackno,      DEBUGF(TCP_INPUT_DEBUG, ("SYN-SENT: ackno %lu pcb->snd_nxt %lu unacked %lu\n", ackno,
477             pcb->snd_nxt, ntohl(pcb->unacked->tcphdr->seqno)));             pcb->snd_nxt, ntohl(pcb->unacked->tcphdr->seqno)));
478      if(flags & (TCP_ACK | TCP_SYN) &&      if (flags & (TCP_ACK | TCP_SYN) &&
479         ackno == ntohl(pcb->unacked->tcphdr->seqno) + 1) {         ackno == ntohl(pcb->unacked->tcphdr->seqno) + 1) {
480        pcb->rcv_nxt = seqno + 1;        pcb->rcv_nxt = seqno + 1;
481        pcb->lastack = ackno;        pcb->lastack = ackno;
# Line 498  tcp_process(struct tcp_pcb *pcb) Line 498  tcp_process(struct tcp_pcb *pcb)
498      }          }    
499      break;      break;
500    case SYN_RCVD:    case SYN_RCVD:
501      if(flags & TCP_ACK &&      if (flags & TCP_ACK &&
502         !(flags & TCP_RST)) {         !(flags & TCP_RST)) {
503        if(TCP_SEQ_LT(pcb->lastack, ackno) &&        if (TCP_SEQ_LT(pcb->lastack, ackno) &&
504           TCP_SEQ_LEQ(ackno, pcb->snd_nxt)) {           TCP_SEQ_LEQ(ackno, pcb->snd_nxt)) {
505          pcb->state = ESTABLISHED;          pcb->state = ESTABLISHED;
506          DEBUGF(DEMO_DEBUG, ("TCP connection established %d -> %d.\n", inseg.tcphdr->src, inseg.tcphdr->dest));          DEBUGF(DEMO_DEBUG, ("TCP connection established %d -> %d.\n", inseg.tcphdr->src, inseg.tcphdr->dest));
507          LWIP_ASSERT("pcb->accept != NULL", pcb->accept != NULL);          LWIP_ASSERT("pcb->accept != NULL", pcb->accept != NULL);
508          /* Call the accept function. */          /* Call the accept function. */
509          TCP_EVENT_ACCEPT(pcb, ERR_OK, err);          TCP_EVENT_ACCEPT(pcb, ERR_OK, err);
510          if(err != ERR_OK) {          if (err != ERR_OK) {
511            /* If the accept function returns with an error, we abort            /* If the accept function returns with an error, we abort
512               the connection. */               the connection. */
513            tcp_abort(pcb);            tcp_abort(pcb);
# Line 524  tcp_process(struct tcp_pcb *pcb) Line 524  tcp_process(struct tcp_pcb *pcb)
524      /* FALLTHROUGH */      /* FALLTHROUGH */
525    case ESTABLISHED:    case ESTABLISHED:
526      tcp_receive(pcb);          tcp_receive(pcb);    
527      if(flags & TCP_FIN) {      if (flags & TCP_FIN) {
528        tcp_ack_now(pcb);        tcp_ack_now(pcb);
529        pcb->state = CLOSE_WAIT;        pcb->state = CLOSE_WAIT;
530      }      }
531      break;      break;
532    case FIN_WAIT_1:    case FIN_WAIT_1:
533      tcp_receive(pcb);      tcp_receive(pcb);
534      if(flags & TCP_FIN) {      if (flags & TCP_FIN) {
535        if(flags & TCP_ACK && ackno == pcb->snd_nxt) {        if (flags & TCP_ACK && ackno == pcb->snd_nxt) {
536          DEBUGF(DEMO_DEBUG,          DEBUGF(DEMO_DEBUG,
537                 ("TCP connection closed %d -> %d.\n", inseg.tcphdr->src, inseg.tcphdr->dest));                 ("TCP connection closed %d -> %d.\n", inseg.tcphdr->src, inseg.tcphdr->dest));
538          tcp_ack_now(pcb);          tcp_ack_now(pcb);
# Line 544  tcp_process(struct tcp_pcb *pcb) Line 544  tcp_process(struct tcp_pcb *pcb)
544          tcp_ack_now(pcb);          tcp_ack_now(pcb);
545          pcb->state = CLOSING;          pcb->state = CLOSING;
546        }        }
547      } else if(flags & TCP_ACK && ackno == pcb->snd_nxt) {      } else if (flags & TCP_ACK && ackno == pcb->snd_nxt) {
548        pcb->state = FIN_WAIT_2;        pcb->state = FIN_WAIT_2;
549      }      }
550      break;      break;
551    case FIN_WAIT_2:    case FIN_WAIT_2:
552      tcp_receive(pcb);      tcp_receive(pcb);
553      if(flags & TCP_FIN) {      if (flags & TCP_FIN) {
554        DEBUGF(DEMO_DEBUG, ("TCP connection closed %d -> %d.\n", inseg.tcphdr->src, inseg.tcphdr->dest));        DEBUGF(DEMO_DEBUG, ("TCP connection closed %d -> %d.\n", inseg.tcphdr->src, inseg.tcphdr->dest));
555        tcp_ack_now(pcb);        tcp_ack_now(pcb);
556        tcp_pcb_purge(pcb);        tcp_pcb_purge(pcb);
# Line 561  tcp_process(struct tcp_pcb *pcb) Line 561  tcp_process(struct tcp_pcb *pcb)
561      break;      break;
562    case CLOSING:    case CLOSING:
563      tcp_receive(pcb);      tcp_receive(pcb);
564      if(flags & TCP_ACK && ackno == pcb->snd_nxt) {      if (flags & TCP_ACK && ackno == pcb->snd_nxt) {
565        DEBUGF(DEMO_DEBUG, ("TCP connection closed %d -> %d.\n", inseg.tcphdr->src, inseg.tcphdr->dest));        DEBUGF(DEMO_DEBUG, ("TCP connection closed %d -> %d.\n", inseg.tcphdr->src, inseg.tcphdr->dest));
566        tcp_ack_now(pcb);        tcp_ack_now(pcb);
567        tcp_pcb_purge(pcb);        tcp_pcb_purge(pcb);
# Line 572  tcp_process(struct tcp_pcb *pcb) Line 572  tcp_process(struct tcp_pcb *pcb)
572      break;      break;
573    case LAST_ACK:    case LAST_ACK:
574      tcp_receive(pcb);      tcp_receive(pcb);
575      if(flags & TCP_ACK && ackno == pcb->snd_nxt) {      if (flags & TCP_ACK && ackno == pcb->snd_nxt) {
576        DEBUGF(DEMO_DEBUG, ("TCP connection closed %d -> %d.\n", inseg.tcphdr->src, inseg.tcphdr->dest));        DEBUGF(DEMO_DEBUG, ("TCP connection closed %d -> %d.\n", inseg.tcphdr->src, inseg.tcphdr->dest));
577        pcb->state = CLOSED;        pcb->state = CLOSED;
578        recv_flags = TF_CLOSED;        recv_flags = TF_CLOSED;
# Line 610  tcp_receive(struct tcp_pcb *pcb) Line 610  tcp_receive(struct tcp_pcb *pcb)
610    u32_t right_wnd_edge;    u32_t right_wnd_edge;
611    
612                
613    if(flags & TCP_ACK) {    if (flags & TCP_ACK) {
614      right_wnd_edge = pcb->snd_wnd + pcb->snd_wl1;      right_wnd_edge = pcb->snd_wnd + pcb->snd_wl1;
615    
616      /* Update window. */      /* Update window. */
617      if(TCP_SEQ_LT(pcb->snd_wl1, seqno) ||      if (TCP_SEQ_LT(pcb->snd_wl1, seqno) ||
618         (pcb->snd_wl1 == seqno && TCP_SEQ_LT(pcb->snd_wl2, ackno)) ||         (pcb->snd_wl1 == seqno && TCP_SEQ_LT(pcb->snd_wl2, ackno)) ||
619         (pcb->snd_wl2 == ackno && tcphdr->wnd > pcb->snd_wnd)) {         (pcb->snd_wl2 == ackno && tcphdr->wnd > pcb->snd_wnd)) {
620        pcb->snd_wnd = tcphdr->wnd;        pcb->snd_wnd = tcphdr->wnd;
# Line 623  tcp_receive(struct tcp_pcb *pcb) Line 623  tcp_receive(struct tcp_pcb *pcb)
623        DEBUGF(TCP_WND_DEBUG, ("tcp_receive: window update %lu\n", pcb->snd_wnd));        DEBUGF(TCP_WND_DEBUG, ("tcp_receive: window update %lu\n", pcb->snd_wnd));
624  #if TCP_WND_DEBUG  #if TCP_WND_DEBUG
625      } else {      } else {
626        if(pcb->snd_wnd != tcphdr->wnd) {        if (pcb->snd_wnd != tcphdr->wnd) {
627          DEBUGF(TCP_WND_DEBUG, ("tcp_receive: no window update lastack %lu snd_max %lu ackno %lu wl1 %lu seqno %lu wl2 %lu\n",          DEBUGF(TCP_WND_DEBUG, ("tcp_receive: no window update lastack %lu snd_max %lu ackno %lu wl1 %lu seqno %lu wl2 %lu\n",
628                                 pcb->lastack, pcb->snd_max, ackno, pcb->snd_wl1, seqno, pcb->snd_wl2));                                 pcb->lastack, pcb->snd_max, ackno, pcb->snd_wl1, seqno, pcb->snd_wl2));
629        }        }
# Line 631  tcp_receive(struct tcp_pcb *pcb) Line 631  tcp_receive(struct tcp_pcb *pcb)
631      }      }
632            
633    
634      if(pcb->lastack == ackno) {      if (pcb->lastack == ackno) {
635        pcb->acked = 0;        pcb->acked = 0;
636    
637        if(pcb->snd_wl1 + pcb->snd_wnd == right_wnd_edge){        if (pcb->snd_wl1 + pcb->snd_wnd == right_wnd_edge){
638          ++pcb->dupacks;          ++pcb->dupacks;
639          if(pcb->dupacks >= 3 && pcb->unacked != NULL) {          if (pcb->dupacks >= 3 && pcb->unacked != NULL) {
640            if(!(pcb->flags & TF_INFR)) {            if (!(pcb->flags & TF_INFR)) {
641              /* This is fast retransmit. Retransmit the first unacked segment. */              /* This is fast retransmit. Retransmit the first unacked segment. */
642              DEBUGF(TCP_FR_DEBUG, ("tcp_receive: dupacks %d (%lu), fast retransmit %lu\n",              DEBUGF(TCP_FR_DEBUG, ("tcp_receive: dupacks %d (%lu), fast retransmit %lu\n",
643                                    pcb->dupacks, pcb->lastack,                                    pcb->dupacks, pcb->lastack,
# Line 653  tcp_receive(struct tcp_pcb *pcb) Line 653  tcp_receive(struct tcp_pcb *pcb)
653            } else {            } else {
654              /* Inflate the congestion window, but not if it means that              /* Inflate the congestion window, but not if it means that
655                 the value overflows. */                 the value overflows. */
656              if((u16_t)(pcb->cwnd + pcb->mss) > pcb->cwnd) {              if ((u16_t)(pcb->cwnd + pcb->mss) > pcb->cwnd) {
657                pcb->cwnd += pcb->mss;                pcb->cwnd += pcb->mss;
658              }              }
659            }            }
# Line 662  tcp_receive(struct tcp_pcb *pcb) Line 662  tcp_receive(struct tcp_pcb *pcb)
662          DEBUGF(TCP_FR_DEBUG, ("tcp_receive: dupack averted %lu %lu\n",          DEBUGF(TCP_FR_DEBUG, ("tcp_receive: dupack averted %lu %lu\n",
663                                pcb->snd_wl1 + pcb->snd_wnd, right_wnd_edge));                                    pcb->snd_wl1 + pcb->snd_wnd, right_wnd_edge));    
664        }        }
665      } else if(TCP_SEQ_LT(pcb->lastack, ackno) &&      } else if (TCP_SEQ_LT(pcb->lastack, ackno) &&
666                TCP_SEQ_LEQ(ackno, pcb->snd_max)) {                TCP_SEQ_LEQ(ackno, pcb->snd_max)) {
667        /* We come here when the ACK acknowledges new data. */        /* We come here when the ACK acknowledges new data. */
668    
669        /* Reset the "IN Fast Retransmit" flag, since we are no longer        /* Reset the "IN Fast Retransmit" flag, since we are no longer
670           in fast retransmit. Also reset the congestion window to the           in fast retransmit. Also reset the congestion window to the
671           slow start threshold. */           slow start threshold. */
672        if(pcb->flags & TF_INFR) {        if (pcb->flags & TF_INFR) {
673          pcb->flags &= ~TF_INFR;          pcb->flags &= ~TF_INFR;
674          pcb->cwnd = pcb->ssthresh;          pcb->cwnd = pcb->ssthresh;
675        }        }
# Line 690  tcp_receive(struct tcp_pcb *pcb) Line 690  tcp_receive(struct tcp_pcb *pcb)
690                
691        /* Update the congestion control variables (cwnd and        /* Update the congestion control variables (cwnd and
692           ssthresh). */           ssthresh). */
693        if(pcb->state >= ESTABLISHED) {        if (pcb->state >= ESTABLISHED) {
694          if(pcb->cwnd < pcb->ssthresh) {          if (pcb->cwnd < pcb->ssthresh) {
695            if((u16_t)(pcb->cwnd + pcb->mss) > pcb->cwnd) {            if ((u16_t)(pcb->cwnd + pcb->mss) > pcb->cwnd) {
696              pcb->cwnd += pcb->mss;              pcb->cwnd += pcb->mss;
697            }            }
698            DEBUGF(TCP_CWND_DEBUG, ("tcp_receive: slow start cwnd %u\n", pcb->cwnd));            DEBUGF(TCP_CWND_DEBUG, ("tcp_receive: slow start cwnd %u\n", pcb->cwnd));
699          } else {          } else {
700            u16_t new_cwnd = (pcb->cwnd + pcb->mss * pcb->mss / pcb->cwnd);            u16_t new_cwnd = (pcb->cwnd + pcb->mss * pcb->mss / pcb->cwnd);
701            if(new_cwnd > pcb->cwnd) {            if (new_cwnd > pcb->cwnd) {
702              pcb->cwnd = new_cwnd;              pcb->cwnd = new_cwnd;
703            }            }
704            DEBUGF(TCP_CWND_DEBUG, ("tcp_receive: congestion avoidance cwnd %u\n", pcb->cwnd));            DEBUGF(TCP_CWND_DEBUG, ("tcp_receive: congestion avoidance cwnd %u\n", pcb->cwnd));
# Line 713  tcp_receive(struct tcp_pcb *pcb) Line 713  tcp_receive(struct tcp_pcb *pcb)
713    
714        /* Remove segment from the unacknowledged list if the incoming        /* Remove segment from the unacknowledged list if the incoming
715           ACK acknowlegdes them. */           ACK acknowlegdes them. */
716        while(pcb->unacked != NULL &&        while (pcb->unacked != NULL &&
717              TCP_SEQ_LEQ(ntohl(pcb->unacked->tcphdr->seqno) +              TCP_SEQ_LEQ(ntohl(pcb->unacked->tcphdr->seqno) +
718                          TCP_TCPLEN(pcb->unacked), ackno)) {                          TCP_TCPLEN(pcb->unacked), ackno)) {
719          DEBUGF(TCP_INPUT_DEBUG, ("tcp_receive: removing %lu:%lu from pcb->unacked\n",          DEBUGF(TCP_INPUT_DEBUG, ("tcp_receive: removing %lu:%lu from pcb->unacked\n",
# Line 729  tcp_receive(struct tcp_pcb *pcb) Line 729  tcp_receive(struct tcp_pcb *pcb)
729          tcp_seg_free(next);          tcp_seg_free(next);
730                    
731          DEBUGF(TCP_QLEN_DEBUG, ("%d (after freeing unacked)\n", pcb->snd_queuelen));          DEBUGF(TCP_QLEN_DEBUG, ("%d (after freeing unacked)\n", pcb->snd_queuelen));
732          if(pcb->snd_queuelen != 0) {          if (pcb->snd_queuelen != 0) {
733            LWIP_ASSERT("tcp_receive: valid queue length", pcb->unacked != NULL ||            LWIP_ASSERT("tcp_receive: valid queue length", pcb->unacked != NULL ||
734                   pcb->unsent != NULL);                         pcb->unsent != NULL);      
735          }          }
# Line 743  tcp_receive(struct tcp_pcb *pcb) Line 743  tcp_receive(struct tcp_pcb *pcb)
743           rationale is that lwIP puts all outstanding segments on the           rationale is that lwIP puts all outstanding segments on the
744           ->unsent list after a retransmission, so these segments may           ->unsent list after a retransmission, so these segments may
745           in fact have been sent once. */           in fact have been sent once. */
746        while(pcb->unsent != NULL &&        while (pcb->unsent != NULL &&
747              TCP_SEQ_LEQ(ntohl(pcb->unsent->tcphdr->seqno) + TCP_TCPLEN(pcb->unsent),              TCP_SEQ_LEQ(ntohl(pcb->unsent->tcphdr->seqno) + TCP_TCPLEN(pcb->unsent),
748                          ackno) &&                          ackno) &&
749              TCP_SEQ_LEQ(ackno, pcb->snd_max)) {              TCP_SEQ_LEQ(ackno, pcb->snd_max)) {
# Line 758  tcp_receive(struct tcp_pcb *pcb) Line 758  tcp_receive(struct tcp_pcb *pcb)
758          pcb->snd_queuelen -= pbuf_clen(next->p);          pcb->snd_queuelen -= pbuf_clen(next->p);
759          tcp_seg_free(next);          tcp_seg_free(next);
760          DEBUGF(TCP_QLEN_DEBUG, ("%d (after freeing unsent)\n", pcb->snd_queuelen));          DEBUGF(TCP_QLEN_DEBUG, ("%d (after freeing unsent)\n", pcb->snd_queuelen));
761          if(pcb->snd_queuelen != 0) {          if (pcb->snd_queuelen != 0) {
762            LWIP_ASSERT("tcp_receive: valid queue length", pcb->unacked != NULL ||            LWIP_ASSERT("tcp_receive: valid queue length", pcb->unacked != NULL ||
763                   pcb->unsent != NULL);                         pcb->unsent != NULL);      
764          }          }
765                    
766          if(pcb->unsent != NULL) {          if (pcb->unsent != NULL) {
767            pcb->snd_nxt = htonl(pcb->unsent->tcphdr->seqno);            pcb->snd_nxt = htonl(pcb->unsent->tcphdr->seqno);
768          }          }
769        }        }
# Line 776  tcp_receive(struct tcp_pcb *pcb) Line 776  tcp_receive(struct tcp_pcb *pcb)
776      /* RTT estimation calculations. This is done by checking if the      /* RTT estimation calculations. This is done by checking if the
777         incoming segment acknowledges the segment we use to take a         incoming segment acknowledges the segment we use to take a
778         round-trip time measurement. */         round-trip time measurement. */
779      if(pcb->rttest && TCP_SEQ_LT(pcb->rtseq, ackno)) {      if (pcb->rttest && TCP_SEQ_LT(pcb->rtseq, ackno)) {
780        m = tcp_ticks - pcb->rttest;        m = tcp_ticks - pcb->rttest;
781    
782        DEBUGF(TCP_RTO_DEBUG, ("tcp_receive: experienced rtt %d ticks (%d msec).\n",        DEBUGF(TCP_RTO_DEBUG, ("tcp_receive: experienced rtt %d ticks (%d msec).\n",
# Line 785  tcp_receive(struct tcp_pcb *pcb) Line 785  tcp_receive(struct tcp_pcb *pcb)
785        /* This is taken directly from VJs original code in his paper */              /* This is taken directly from VJs original code in his paper */      
786        m = m - (pcb->sa >> 3);        m = m - (pcb->sa >> 3);
787        pcb->sa += m;        pcb->sa += m;
788        if(m < 0) {        if (m < 0) {
789          m = -m;          m = -m;
790        }        }
791        m = m - (pcb->sv >> 2);        m = m - (pcb->sv >> 2);
# Line 801  tcp_receive(struct tcp_pcb *pcb) Line 801  tcp_receive(struct tcp_pcb *pcb)
801        
802    /* If the incoming segment contains data, we must process it    /* If the incoming segment contains data, we must process it
803       further. */       further. */
804    if(tcplen > 0) {    if (tcplen > 0) {
805      /* This code basically does three things:      /* This code basically does three things:
806    
807       +) If the incoming segment contains data that is the next       +) If the incoming segment contains data that is the next
# Line 830  tcp_receive(struct tcp_pcb *pcb) Line 830  tcp_receive(struct tcp_pcb *pcb)
830         this if the sequence number of the incoming segment is less         this if the sequence number of the incoming segment is less
831         than rcv_nxt, and the sequence number plus the length of the         than rcv_nxt, and the sequence number plus the length of the
832         segment is larger than rcv_nxt. */         segment is larger than rcv_nxt. */
833      if(TCP_SEQ_LT(seqno, pcb->rcv_nxt)){      if (TCP_SEQ_LT(seqno, pcb->rcv_nxt)){
834        if(TCP_SEQ_LT(pcb->rcv_nxt, seqno + tcplen)) {        if (TCP_SEQ_LT(pcb->rcv_nxt, seqno + tcplen)) {
835          /* Trimming the first edge is done by pushing the payload          /* Trimming the first edge is done by pushing the payload
836             pointer in the pbuf downwards. This is somewhat tricky since             pointer in the pbuf downwards. This is somewhat tricky since
837             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
# Line 852  tcp_receive(struct tcp_pcb *pcb) Line 852  tcp_receive(struct tcp_pcb *pcb)
852             adjust the ->data pointer in the seg and the segment             adjust the ->data pointer in the seg and the segment
853             length.*/             length.*/
854          off = pcb->rcv_nxt - seqno;          off = pcb->rcv_nxt - seqno;
855          if(inseg.p->len < off) {          if (inseg.p->len < off) {
856            p = inseg.p;            p = inseg.p;
857            while(p->len < off) {            while (p->len < off) {
858              off -= p->len;              off -= p->len;
859              inseg.p->tot_len -= p->len;              inseg.p->tot_len -= p->len;
860              p->len = 0;              p->len = 0;
# Line 880  tcp_receive(struct tcp_pcb *pcb) Line 880  tcp_receive(struct tcp_pcb *pcb)
880      /* The sequence number must be within the window (above rcv_nxt      /* The sequence number must be within the window (above rcv_nxt
881         and below rcv_nxt + rcv_wnd) in order to be further         and below rcv_nxt + rcv_wnd) in order to be further
882         processed. */         processed. */
883      if(TCP_SEQ_GEQ(seqno, pcb->rcv_nxt) &&      if (TCP_SEQ_GEQ(seqno, pcb->rcv_nxt) &&
884         TCP_SEQ_LT(seqno, pcb->rcv_nxt + pcb->rcv_wnd)) {         TCP_SEQ_LT(seqno, pcb->rcv_nxt + pcb->rcv_wnd)) {
885        if(pcb->rcv_nxt == seqno) {                              if (pcb->rcv_nxt == seqno) {                      
886          /* The incoming segment is the next in sequence. We check if          /* The incoming segment is the next in sequence. We check if
887             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
888             and pass the data to the application. */             and pass the data to the application. */
889  #if TCP_QUEUE_OOSEQ  #if TCP_QUEUE_OOSEQ
890          if(pcb->ooseq != NULL &&          if (pcb->ooseq != NULL &&
891             TCP_SEQ_LEQ(pcb->ooseq->tcphdr->seqno, seqno + inseg.len)) {             TCP_SEQ_LEQ(pcb->ooseq->tcphdr->seqno, seqno + inseg.len)) {
892            /* We have to trim the second edge of the incoming            /* We have to trim the second edge of the incoming
893               segment. */               segment. */
# Line 901  tcp_receive(struct tcp_pcb *pcb) Line 901  tcp_receive(struct tcp_pcb *pcb)
901          pcb->rcv_nxt += tcplen;          pcb->rcv_nxt += tcplen;
902                    
903          /* Update the receiver's (our) window. */          /* Update the receiver's (our) window. */
904          if(pcb->rcv_wnd < tcplen) {          if (pcb->rcv_wnd < tcplen) {
905            pcb->rcv_wnd = 0;            pcb->rcv_wnd = 0;
906          } else {          } else {
907            pcb->rcv_wnd -= tcplen;            pcb->rcv_wnd -= tcplen;
# Line 916  tcp_receive(struct tcp_pcb *pcb) Line 916  tcp_receive(struct tcp_pcb *pcb)
916             If the segment was a FIN, we set the TF_GOT_FIN flag that will             If the segment was a FIN, we set the TF_GOT_FIN flag that will
917             be used to indicate to the application that the remote side has             be used to indicate to the application that the remote side has
918             closed its end of the connection. */                   closed its end of the connection. */      
919          if(inseg.p->tot_len > 0) {          if (inseg.p->tot_len > 0) {
920            recv_data = inseg.p;            recv_data = inseg.p;
921            /* Since this pbuf now is the responsibility of the            /* Since this pbuf now is the responsibility of the
922               application, we delete our reference to it so that we won't               application, we delete our reference to it so that we won't
923               (mistakingly) deallocate it. */               (mistakingly) deallocate it. */
924            inseg.p = NULL;            inseg.p = NULL;
925          }          }
926          if(TCPH_FLAGS(inseg.tcphdr) & TCP_FIN) {          if (TCPH_FLAGS(inseg.tcphdr) & TCP_FIN) {
927            DEBUGF(TCP_INPUT_DEBUG, ("tcp_receive: received FIN."));            DEBUGF(TCP_INPUT_DEBUG, ("tcp_receive: received FIN."));
928            recv_flags = TF_GOT_FIN;            recv_flags = TF_GOT_FIN;
929          }          }
# Line 931  tcp_receive(struct tcp_pcb *pcb) Line 931  tcp_receive(struct tcp_pcb *pcb)
931  #if TCP_QUEUE_OOSEQ  #if TCP_QUEUE_OOSEQ
932          /* We now check if we have segments on the ->ooseq queue that          /* We now check if we have segments on the ->ooseq queue that
933             is now in sequence. */             is now in sequence. */
934          while(pcb->ooseq != NULL &&          while (pcb->ooseq != NULL &&
935                pcb->ooseq->tcphdr->seqno == pcb->rcv_nxt) {                pcb->ooseq->tcphdr->seqno == pcb->rcv_nxt) {
936    
937            cseg = pcb->ooseq;            cseg = pcb->ooseq;
938            seqno = pcb->ooseq->tcphdr->seqno;            seqno = pcb->ooseq->tcphdr->seqno;
939                        
940            pcb->rcv_nxt += TCP_TCPLEN(cseg);            pcb->rcv_nxt += TCP_TCPLEN(cseg);
941            if(pcb->rcv_wnd < TCP_TCPLEN(cseg)) {            if (pcb->rcv_wnd < TCP_TCPLEN(cseg)) {
942              pcb->rcv_wnd = 0;              pcb->rcv_wnd = 0;
943            } else {            } else {
944              pcb->rcv_wnd -= TCP_TCPLEN(cseg);              pcb->rcv_wnd -= TCP_TCPLEN(cseg);
945            }            }
946            if(cseg->p->tot_len > 0) {            if (cseg->p->tot_len > 0) {
947              /* Chain this pbuf onto the pbuf that we will pass to              /* Chain this pbuf onto the pbuf that we will pass to
948                 the application. */                 the application. */
949              if(recv_data) {              if (recv_data) {
950                pbuf_chain(recv_data, cseg->p);                pbuf_chain(recv_data, cseg->p);
951                pbuf_free(cseg->p);                pbuf_free(cseg->p);
952              } else {              } else {
# Line 954  tcp_receive(struct tcp_pcb *pcb) Line 954  tcp_receive(struct tcp_pcb *pcb)
954              }              }
955              cseg->p = NULL;              cseg->p = NULL;
956            }            }
957            if(flags & TCP_FIN) {            if (flags & TCP_FIN) {
958              DEBUGF(TCP_INPUT_DEBUG, ("tcp_receive: dequeued FIN."));              DEBUGF(TCP_INPUT_DEBUG, ("tcp_receive: dequeued FIN."));
959              recv_flags = TF_GOT_FIN;              recv_flags = TF_GOT_FIN;
960            }                    }        
# Line 974  tcp_receive(struct tcp_pcb *pcb) Line 974  tcp_receive(struct tcp_pcb *pcb)
974          tcp_ack_now(pcb);          tcp_ack_now(pcb);
975  #if TCP_QUEUE_OOSEQ  #if TCP_QUEUE_OOSEQ
976          /* We queue the segment on the ->ooseq queue. */          /* We queue the segment on the ->ooseq queue. */
977          if(pcb->ooseq == NULL) {          if (pcb->ooseq == NULL) {
978            pcb->ooseq = tcp_seg_copy(&inseg);            pcb->ooseq = tcp_seg_copy(&inseg);
979          } else {          } else {
980            /* If the queue is not empty, we walk through the queue and            /* If the queue is not empty, we walk through the queue and
# Line 991  tcp_receive(struct tcp_pcb *pcb) Line 991  tcp_receive(struct tcp_pcb *pcb)
991    
992            prev = NULL;            prev = NULL;
993            for(next = pcb->ooseq; next != NULL; next = next->next) {            for(next = pcb->ooseq; next != NULL; next = next->next) {
994              if(seqno == next->tcphdr->seqno) {              if (seqno == next->tcphdr->seqno) {
995                /* The sequence number of the incoming segment is the                /* The sequence number of the incoming segment is the
996                   same as the sequence number of the segment on                   same as the sequence number of the segment on
997                   ->ooseq. We check the lengths to see which one to                   ->ooseq. We check the lengths to see which one to
998                   discard. */                   discard. */
999                if(inseg.len > next->len) {                if (inseg.len > next->len) {
1000                  /* The incoming segment is larger than the old                  /* The incoming segment is larger than the old
1001                     segment. We replace the old segment with the new                     segment. We replace the old segment with the new
1002                     one. */                     one. */
1003                  cseg = tcp_seg_copy(&inseg);                  cseg = tcp_seg_copy(&inseg);
1004                  if(cseg != NULL) {                  if (cseg != NULL) {
1005                    cseg->next = next->next;                    cseg->next = next->next;
1006                    if(prev != NULL) {                    if (prev != NULL) {
1007                      prev->next = cseg;                      prev->next = cseg;
1008                    } else {                    } else {
1009                      pcb->ooseq = cseg;                      pcb->ooseq = cseg;
# Line 1017  tcp_receive(struct tcp_pcb *pcb) Line 1017  tcp_receive(struct tcp_pcb *pcb)
1017                  break;                  break;
1018                }                }
1019              } else {              } else {
1020                if(prev == NULL) {                if (prev == NULL) {
1021                  if(TCP_SEQ_LT(seqno, next->tcphdr->seqno)) {                  if (TCP_SEQ_LT(seqno, next->tcphdr->seqno)) {
1022                    /* The sequence number of the incoming segment is lower                    /* The sequence number of the incoming segment is lower
1023                       than the sequence number of the first segment on the                       than the sequence number of the first segment on the
1024                       queue. We put the incoming segment first on the                       queue. We put the incoming segment first on the
1025                       queue. */                       queue. */
1026                                        
1027                    if(TCP_SEQ_GT(seqno + inseg.len, next->tcphdr->seqno)) {                    if (TCP_SEQ_GT(seqno + inseg.len, next->tcphdr->seqno)) {
1028                      /* We need to trim the incoming segment. */                      /* We need to trim the incoming segment. */
1029                      inseg.len = next->tcphdr->seqno - seqno;                      inseg.len = next->tcphdr->seqno - seqno;
1030                      pbuf_realloc(inseg.p, inseg.len);                      pbuf_realloc(inseg.p, inseg.len);
1031                    }                    }
1032                    cseg = tcp_seg_copy(&inseg);                    cseg = tcp_seg_copy(&inseg);
1033                    if(cseg != NULL) {                    if (cseg != NULL) {
1034                      cseg->next = next;                      cseg->next = next;
1035                      pcb->ooseq = cseg;                      pcb->ooseq = cseg;
1036                    }                    }
1037                    break;                    break;
1038                  }                  }
1039                } else if(TCP_SEQ_LT(prev->tcphdr->seqno, seqno) &&                } else if (TCP_SEQ_LT(prev->tcphdr->seqno, seqno) &&
1040                   TCP_SEQ_LT(seqno, next->tcphdr->seqno)) {                   TCP_SEQ_LT(seqno, next->tcphdr->seqno)) {
1041                  /* The sequence number of the incoming segment is in                  /* The sequence number of the incoming segment is in
1042                     between the sequence numbers of the previous and                     between the sequence numbers of the previous and
1043                     the next segment on ->ooseq. We trim and insert the                     the next segment on ->ooseq. We trim and insert the
1044                     incoming segment and trim the previous segment, if                     incoming segment and trim the previous segment, if
1045                     needed. */                     needed. */
1046                  if(TCP_SEQ_GT(seqno + inseg.len, next->tcphdr->seqno)) {                  if (TCP_SEQ_GT(seqno + inseg.len, next->tcphdr->seqno)) {
1047                    /* We need to trim the incoming segment. */                    /* We need to trim the incoming segment. */
1048                    inseg.len = next->tcphdr->seqno - seqno;                    inseg.len = next->tcphdr->seqno - seqno;
1049                    pbuf_realloc(inseg.p, inseg.len);                    pbuf_realloc(inseg.p, inseg.len);
1050                  }                  }
1051    
1052                  cseg = tcp_seg_copy(&inseg);                  cseg = tcp_seg_copy(&inseg);
1053                  if(cseg != NULL) {                                                  if (cseg != NULL) {                              
1054                    cseg->next = next;                    cseg->next = next;
1055                    prev->next = cseg;                    prev->next = cseg;
1056                    if(TCP_SEQ_GT(prev->tcphdr->seqno + prev->len, seqno)) {                    if (TCP_SEQ_GT(prev->tcphdr->seqno + prev->len, seqno)) {
1057                      /* We need to trim the prev segment. */                      /* We need to trim the prev segment. */
1058                      prev->len = seqno - prev->tcphdr->seqno;                      prev->len = seqno - prev->tcphdr->seqno;
1059                      pbuf_realloc(prev->p, prev->len);                      pbuf_realloc(prev->p, prev->len);
# Line 1064  tcp_receive(struct tcp_pcb *pcb) Line 1064  tcp_receive(struct tcp_pcb *pcb)
1064                /* If the "next" segment is the last segment on the                /* If the "next" segment is the last segment on the
1065                   ooseq queue, we add the incoming segment to the end                   ooseq queue, we add the incoming segment to the end
1066                   of the list. */                   of the list. */
1067                if(next->next == NULL &&                if (next->next == NULL &&
1068                   TCP_SEQ_GT(seqno, next->tcphdr->seqno)) {                   TCP_SEQ_GT(seqno, next->tcphdr->seqno)) {
1069                  next->next = tcp_seg_copy(&inseg);                  next->next = tcp_seg_copy(&inseg);
1070                  if(next->next != NULL) {                                  if (next->next != NULL) {              
1071                    if(TCP_SEQ_GT(next->tcphdr->seqno + next->len, seqno)) {                    if (TCP_SEQ_GT(next->tcphdr->seqno + next->len, seqno)) {
1072                      /* We need to trim the last segment. */                      /* We need to trim the last segment. */
1073                      next->len = seqno - next->tcphdr->seqno;                      next->len = seqno - next->tcphdr->seqno;
1074                      pbuf_realloc(next->p, next->len);                      pbuf_realloc(next->p, next->len);
# Line 1087  tcp_receive(struct tcp_pcb *pcb) Line 1087  tcp_receive(struct tcp_pcb *pcb)
1087    } else {    } else {
1088      /* Segments with length 0 is taken care of here. Segments that      /* Segments with length 0 is taken care of here. Segments that
1089         fall out of the window are ACKed. */         fall out of the window are ACKed. */
1090      if(TCP_SEQ_GT(pcb->rcv_nxt, seqno) ||      if (TCP_SEQ_GT(pcb->rcv_nxt, seqno) ||
1091         TCP_SEQ_GEQ(seqno, pcb->rcv_nxt + pcb->rcv_wnd)) {         TCP_SEQ_GEQ(seqno, pcb->rcv_nxt + pcb->rcv_wnd)) {
1092        tcp_ack_now(pcb);        tcp_ack_now(pcb);
1093      }            }      
# Line 1112  tcp_parseopt(struct tcp_pcb *pcb) Line 1112  tcp_parseopt(struct tcp_pcb *pcb)
1112    opts = (u8_t *)tcphdr + TCP_HLEN;    opts = (u8_t *)tcphdr + TCP_HLEN;
1113        
1114    /* Parse the TCP MSS option, if present. */    /* Parse the TCP MSS option, if present. */
1115    if((TCPH_OFFSET(tcphdr) & 0xf0) > 0x50) {    if ((TCPH_OFFSET(tcphdr) & 0xf0) > 0x50) {
1116      for(c = 0; c < ((TCPH_OFFSET(tcphdr) >> 4) - 5) << 2 ;) {      for(c = 0; c < ((TCPH_OFFSET(tcphdr) >> 4) - 5) << 2 ;) {
1117        opt = opts[c];        opt = opts[c];
1118        if(opt == 0x00) {        if (opt == 0x00) {
1119          /* End of options. */            /* End of options. */  
1120          break;          break;
1121        } else if(opt == 0x01) {        } else if (opt == 0x01) {
1122          ++c;          ++c;
1123          /* NOP option. */          /* NOP option. */
1124        } else if(opt == 0x02 &&        } else if (opt == 0x02 &&
1125                  opts[c + 1] == 0x04) {                  opts[c + 1] == 0x04) {
1126          /* An MSS option with the right option length. */                /* An MSS option with the right option length. */      
1127          mss = (opts[c + 2] << 8) | opts[c + 3];          mss = (opts[c + 2] << 8) | opts[c + 3];
# Line 1130  tcp_parseopt(struct tcp_pcb *pcb) Line 1130  tcp_parseopt(struct tcp_pcb *pcb)
1130          /* And we are done processing options. */          /* And we are done processing options. */
1131          break;          break;
1132        } else {        } else {
1133          if(opts[c + 1] == 0) {          if (opts[c + 1] == 0) {
1134            /* If the length field is zero, the options are malformed            /* If the length field is zero, the options are malformed
1135               and we don't process them further. */               and we don't process them further. */
1136            break;            break;

Legend:
Removed from v.1.22.2.1  
changed lines
  Added in v.1.22.2.2

savannah-hackers-public@gnu.org
ViewVC Help
Powered by ViewVC 1.1.26