/[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.24 by likewise, Thu May 1 08:03:51 2003 UTC revision 1.25 by likewise, Thu May 1 13:24:01 2003 UTC
# Line 125  tcp_input(struct pbuf *p, struct netif * Line 125  tcp_input(struct pbuf *p, struct netif *
125    }    }
126        
127    /* Don't even process incoming broadcasts/multicasts. */    /* Don't even process incoming broadcasts/multicasts. */
128    if(ip_addr_isbroadcast(&(iphdr->dest), &(inp->netmask)) ||    if (ip_addr_isbroadcast(&(iphdr->dest), &(inp->netmask)) ||
129       ip_addr_ismulticast(&(iphdr->dest))) {       ip_addr_ismulticast(&(iphdr->dest))) {
130      pbuf_free(p);      pbuf_free(p);
131      return;      return;
132    }    }
133    
134    /* Verify TCP checksum. */    /* Verify TCP checksum. */
135    if(inet_chksum_pseudo(p, (struct ip_addr *)&(iphdr->src),    if (inet_chksum_pseudo(p, (struct ip_addr *)&(iphdr->src),
136                          (struct ip_addr *)&(iphdr->dest),                          (struct ip_addr *)&(iphdr->dest),
137                          IP_PROTO_TCP, p->tot_len) != 0) {                          IP_PROTO_TCP, p->tot_len) != 0) {
138      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 173  tcp_input(struct pbuf *p, struct netif * Line 173  tcp_input(struct pbuf *p, struct netif *
173      LWIP_ASSERT("tcp_input: active pcb->state != CLOSED", pcb->state != CLOSED);      LWIP_ASSERT("tcp_input: active pcb->state != CLOSED", pcb->state != CLOSED);
174      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);
175      LWIP_ASSERT("tcp_input: active pcb->state != LISTEN", pcb->state != LISTEN);      LWIP_ASSERT("tcp_input: active pcb->state != LISTEN", pcb->state != LISTEN);
176      if(pcb->remote_port == tcphdr->src &&      if (pcb->remote_port == tcphdr->src &&
177         pcb->local_port == tcphdr->dest &&         pcb->local_port == tcphdr->dest &&
178         ip_addr_cmp(&(pcb->remote_ip), &(iphdr->src)) &&         ip_addr_cmp(&(pcb->remote_ip), &(iphdr->src)) &&
179         ip_addr_cmp(&(pcb->local_ip), &(iphdr->dest))) {         ip_addr_cmp(&(pcb->local_ip), &(iphdr->dest))) {
# Line 182  tcp_input(struct pbuf *p, struct netif * Line 182  tcp_input(struct pbuf *p, struct netif *
182           lookups will be faster (we exploit locality in TCP segment           lookups will be faster (we exploit locality in TCP segment
183           arrivals). */           arrivals). */
184        LWIP_ASSERT("tcp_input: pcb->next != pcb (before cache)", pcb->next != pcb);        LWIP_ASSERT("tcp_input: pcb->next != pcb (before cache)", pcb->next != pcb);
185        if(prev != NULL) {        if (prev != NULL) {
186          prev->next = pcb->next;          prev->next = pcb->next;
187          pcb->next = tcp_active_pcbs;          pcb->next = tcp_active_pcbs;
188          tcp_active_pcbs = pcb;          tcp_active_pcbs = pcb;
# Line 199  tcp_input(struct pbuf *p, struct netif * Line 199  tcp_input(struct pbuf *p, struct netif *
199    
200      for(pcb = tcp_tw_pcbs; pcb != NULL; pcb = pcb->next) {      for(pcb = tcp_tw_pcbs; pcb != NULL; pcb = pcb->next) {
201        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);
202        if(pcb->remote_port == tcphdr->src &&        if (pcb->remote_port == tcphdr->src &&
203           pcb->local_port == tcphdr->dest &&           pcb->local_port == tcphdr->dest &&
204           ip_addr_cmp(&(pcb->remote_ip), &(iphdr->src)) &&           ip_addr_cmp(&(pcb->remote_ip), &(iphdr->src)) &&
205           ip_addr_cmp(&(pcb->local_ip), &(iphdr->dest))) {           ip_addr_cmp(&(pcb->local_ip), &(iphdr->dest))) {
# Line 217  tcp_input(struct pbuf *p, struct netif * Line 217  tcp_input(struct pbuf *p, struct netif *
217       are LISTENing for incoming connections. */       are LISTENing for incoming connections. */
218      prev = NULL;        prev = NULL;  
219      for(lpcb = tcp_listen_pcbs; lpcb != NULL; lpcb = lpcb->next) {      for(lpcb = tcp_listen_pcbs; lpcb != NULL; lpcb = lpcb->next) {
220        if((ip_addr_isany(&(lpcb->local_ip)) ||        if ((ip_addr_isany(&(lpcb->local_ip)) ||
221            ip_addr_cmp(&(lpcb->local_ip), &(iphdr->dest))) &&            ip_addr_cmp(&(lpcb->local_ip), &(iphdr->dest))) &&
222           lpcb->local_port == tcphdr->dest) {                 lpcb->local_port == tcphdr->dest) {      
223          /* Move this PCB to the front of the list so that subsequent          /* Move this PCB to the front of the list so that subsequent
224             lookups will be faster (we exploit locality in TCP segment             lookups will be faster (we exploit locality in TCP segment
225             arrivals). */             arrivals). */
226          if(prev != NULL) {          if (prev != NULL) {
227            ((struct tcp_pcb_listen *)prev)->next = lpcb->next;            ((struct tcp_pcb_listen *)prev)->next = lpcb->next;
228            /* our successor is the remainder of the listening list */            /* our successor is the remainder of the listening list */
229            lpcb->next = tcp_listen_pcbs;            lpcb->next = tcp_listen_pcbs;
# Line 247  tcp_input(struct pbuf *p, struct netif * Line 247  tcp_input(struct pbuf *p, struct netif *
247  #endif /* TCP_INPUT_DEBUG */  #endif /* TCP_INPUT_DEBUG */
248    
249        
250    if(pcb != NULL) {    if (pcb != NULL) {
251      /* The incoming segment belongs to a connection. */      /* The incoming segment belongs to a connection. */
252  #if TCP_INPUT_DEBUG  #if TCP_INPUT_DEBUG
253  #if TCP_DEBUG  #if TCP_DEBUG
# Line 270  tcp_input(struct pbuf *p, struct netif * Line 270  tcp_input(struct pbuf *p, struct netif *
270      tcp_input_pcb = NULL;      tcp_input_pcb = NULL;
271      /* A return value of ERR_ABRT means that tcp_abort() was called      /* A return value of ERR_ABRT means that tcp_abort() was called
272         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. */
273      if(err != ERR_ABRT) {      if (err != ERR_ABRT) {
274        if(recv_flags & TF_RESET) {        if (recv_flags & TF_RESET) {
275          /* TF_RESET means that the connection was reset by the other          /* TF_RESET means that the connection was reset by the other
276             end. We then call the error callback to inform the             end. We then call the error callback to inform the
277             application that the connection is dead before we             application that the connection is dead before we
# Line 279  tcp_input(struct pbuf *p, struct netif * Line 279  tcp_input(struct pbuf *p, struct netif *
279          TCP_EVENT_ERR(pcb->errf, pcb->callback_arg, ERR_RST);          TCP_EVENT_ERR(pcb->errf, pcb->callback_arg, ERR_RST);
280          tcp_pcb_remove(&tcp_active_pcbs, pcb);                      tcp_pcb_remove(&tcp_active_pcbs, pcb);            
281          memp_free(MEMP_TCP_PCB, pcb);          memp_free(MEMP_TCP_PCB, pcb);
282        } else if(recv_flags & TF_CLOSED) {        } else if (recv_flags & TF_CLOSED) {
283          /* The connection has been closed and we will deallocate the          /* The connection has been closed and we will deallocate the
284             PCB. */             PCB. */
285          tcp_pcb_remove(&tcp_active_pcbs, pcb);          tcp_pcb_remove(&tcp_active_pcbs, pcb);
# Line 289  tcp_input(struct pbuf *p, struct netif * Line 289  tcp_input(struct pbuf *p, struct netif *
289          /* If the application has registered a "sent" function to be          /* If the application has registered a "sent" function to be
290             called when new send buffer space is available, we call it             called when new send buffer space is available, we call it
291             now. */             now. */
292          if(pcb->acked > 0) {          if (pcb->acked > 0) {
293            TCP_EVENT_SENT(pcb, pcb->acked, err);            TCP_EVENT_SENT(pcb, pcb->acked, err);
294          }          }
295    
296          if(recv_data != NULL) {          if (recv_data != NULL) {
297            /* Notify application that data has been received. */            /* Notify application that data has been received. */
298            TCP_EVENT_RECV(pcb, recv_data, ERR_OK, err);            TCP_EVENT_RECV(pcb, recv_data, ERR_OK, err);
299          }          }
300                    
301          /* If a FIN segment was received, we call the callback          /* If a FIN segment was received, we call the callback
302             function with a NULL buffer to indicate EOF. */             function with a NULL buffer to indicate EOF. */
303          if(recv_flags & TF_GOT_FIN) {          if (recv_flags & TF_GOT_FIN) {
304            TCP_EVENT_RECV(pcb, NULL, ERR_OK, err);            TCP_EVENT_RECV(pcb, NULL, ERR_OK, err);
305          }          }
306          /* If there were no errors, we try to send something out. */          /* If there were no errors, we try to send something out. */
307          if(err == ERR_OK) {          if (err == ERR_OK) {
308            tcp_output(pcb);            tcp_output(pcb);
309          }          }
310        }        }
# Line 327  tcp_input(struct pbuf *p, struct netif * Line 327  tcp_input(struct pbuf *p, struct netif *
327      /* 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
328         sender. */         sender. */
329      DEBUGF(TCP_RST_DEBUG, ("tcp_input: no PCB match found, resetting.\n"));      DEBUGF(TCP_RST_DEBUG, ("tcp_input: no PCB match found, resetting.\n"));
330      if(!(TCPH_FLAGS(tcphdr) & TCP_RST)) {      if (!(TCPH_FLAGS(tcphdr) & TCP_RST)) {
331  #ifdef TCP_STATS  #ifdef TCP_STATS
332        ++lwip_stats.tcp.proterr;        ++lwip_stats.tcp.proterr;
333        ++lwip_stats.tcp.drop;        ++lwip_stats.tcp.drop;
# Line 357  tcp_listen_input(struct tcp_pcb_listen * Line 357  tcp_listen_input(struct tcp_pcb_listen *
357            
358    /* In the LISTEN state, we check for incoming SYN segments,    /* In the LISTEN state, we check for incoming SYN segments,
359       creates a new PCB, and responds with a SYN|ACK. */       creates a new PCB, and responds with a SYN|ACK. */
360    if(flags & TCP_ACK) {    if (flags & TCP_ACK) {
361      /* For incoming segments with the ACK flag set, respond with a      /* For incoming segments with the ACK flag set, respond with a
362         RST. */         RST. */
363      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"));
364      tcp_rst(ackno + 1, seqno + tcplen,      tcp_rst(ackno + 1, seqno + tcplen,
365              &(iphdr->dest), &(iphdr->src),              &(iphdr->dest), &(iphdr->src),
366              tcphdr->dest, tcphdr->src);              tcphdr->dest, tcphdr->src);
367    } else if(flags & TCP_SYN) {    } else if (flags & TCP_SYN) {
368      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));
369      npcb = tcp_alloc(pcb->prio);      npcb = tcp_alloc(pcb->prio);
370      /* 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),
371         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
372         SYN at a time when we have more memory available. */         SYN at a time when we have more memory available. */
373      if(npcb == NULL) {      if (npcb == NULL) {
374        DEBUGF(TCP_DEBUG, ("tcp_listen_input: could not allocate PCB\n"));        DEBUGF(TCP_DEBUG, ("tcp_listen_input: could not allocate PCB\n"));
375  #ifdef TCP_STATS  #ifdef TCP_STATS
376        ++lwip_stats.tcp.memerr;        ++lwip_stats.tcp.memerr;
# Line 420  tcp_listen_input(struct tcp_pcb_listen * Line 420  tcp_listen_input(struct tcp_pcb_listen *
420  static err_t  static err_t
421  tcp_timewait_input(struct tcp_pcb *pcb)  tcp_timewait_input(struct tcp_pcb *pcb)
422  {  {
423    if(TCP_SEQ_GT(seqno + tcplen, pcb->rcv_nxt)) {    if (TCP_SEQ_GT(seqno + tcplen, pcb->rcv_nxt)) {
424      pcb->rcv_nxt = seqno + tcplen;      pcb->rcv_nxt = seqno + tcplen;
425    }    }
426    if(tcplen > 0) {    if (tcplen > 0) {
427      tcp_ack_now(pcb);      tcp_ack_now(pcb);
428    }    }
429    return tcp_output(pcb);    return tcp_output(pcb);
# Line 448  tcp_process(struct tcp_pcb *pcb) Line 448  tcp_process(struct tcp_pcb *pcb)
448    err = ERR_OK;    err = ERR_OK;
449        
450    /* Process incoming RST segments. */    /* Process incoming RST segments. */
451    if(flags & TCP_RST) {    if (flags & TCP_RST) {
452      /* First, determine if the reset is acceptable. */      /* First, determine if the reset is acceptable. */
453      if(pcb->state == SYN_SENT) {      if (pcb->state == SYN_SENT) {
454        if(ackno == pcb->snd_nxt) {        if (ackno == pcb->snd_nxt) {
455          acceptable = 1;          acceptable = 1;
456        }        }
457      } else {      } else {
458        if(TCP_SEQ_GEQ(seqno, pcb->rcv_nxt) &&        if (TCP_SEQ_GEQ(seqno, pcb->rcv_nxt) &&
459           TCP_SEQ_LEQ(seqno, pcb->rcv_nxt + pcb->rcv_wnd)) {           TCP_SEQ_LEQ(seqno, pcb->rcv_nxt + pcb->rcv_wnd)) {
460          acceptable = 1;          acceptable = 1;
461        }        }
462      }      }
463            
464      if(acceptable) {      if (acceptable) {
465        DEBUGF(TCP_INPUT_DEBUG, ("tcp_process: Connection RESET\n"));        DEBUGF(TCP_INPUT_DEBUG, ("tcp_process: Connection RESET\n"));
466        LWIP_ASSERT("tcp_input: pcb->state != CLOSED", pcb->state != CLOSED);        LWIP_ASSERT("tcp_input: pcb->state != CLOSED", pcb->state != CLOSED);
467        recv_flags = TF_RESET;        recv_flags = TF_RESET;
# Line 480  tcp_process(struct tcp_pcb *pcb) Line 480  tcp_process(struct tcp_pcb *pcb)
480    pcb->tmr = tcp_ticks;    pcb->tmr = tcp_ticks;
481        
482    /* Do different things depending on the TCP state. */    /* Do different things depending on the TCP state. */
483    switch(pcb->state) {    switch (pcb->state) {
484    case SYN_SENT:    case SYN_SENT:
485      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,
486             pcb->snd_nxt, ntohl(pcb->unacked->tcphdr->seqno)));             pcb->snd_nxt, ntohl(pcb->unacked->tcphdr->seqno)));
487      if(flags & (TCP_ACK | TCP_SYN) &&      if (flags & (TCP_ACK | TCP_SYN) &&
488         ackno == ntohl(pcb->unacked->tcphdr->seqno) + 1) {         ackno == ntohl(pcb->unacked->tcphdr->seqno) + 1) {
489        pcb->rcv_nxt = seqno + 1;        pcb->rcv_nxt = seqno + 1;
490        pcb->lastack = ackno;        pcb->lastack = ackno;
# Line 507  tcp_process(struct tcp_pcb *pcb) Line 507  tcp_process(struct tcp_pcb *pcb)
507      }          }    
508      break;      break;
509    case SYN_RCVD:    case SYN_RCVD:
510      if(flags & TCP_ACK &&      if (flags & TCP_ACK &&
511         !(flags & TCP_RST)) {         !(flags & TCP_RST)) {
512        if(TCP_SEQ_LT(pcb->lastack, ackno) &&        if (TCP_SEQ_LT(pcb->lastack, ackno) &&
513           TCP_SEQ_LEQ(ackno, pcb->snd_nxt)) {           TCP_SEQ_LEQ(ackno, pcb->snd_nxt)) {
514          pcb->state = ESTABLISHED;          pcb->state = ESTABLISHED;
515          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));
516          LWIP_ASSERT("pcb->accept != NULL", pcb->accept != NULL);          LWIP_ASSERT("pcb->accept != NULL", pcb->accept != NULL);
517          /* Call the accept function. */          /* Call the accept function. */
518          TCP_EVENT_ACCEPT(pcb, ERR_OK, err);          TCP_EVENT_ACCEPT(pcb, ERR_OK, err);
519          if(err != ERR_OK) {          if (err != ERR_OK) {
520            /* If the accept function returns with an error, we abort            /* If the accept function returns with an error, we abort
521               the connection. */               the connection. */
522            tcp_abort(pcb);            tcp_abort(pcb);
# Line 533  tcp_process(struct tcp_pcb *pcb) Line 533  tcp_process(struct tcp_pcb *pcb)
533      /* FALLTHROUGH */      /* FALLTHROUGH */
534    case ESTABLISHED:    case ESTABLISHED:
535      tcp_receive(pcb);          tcp_receive(pcb);    
536      if(flags & TCP_FIN) {      if (flags & TCP_FIN) {
537        tcp_ack_now(pcb);        tcp_ack_now(pcb);
538        pcb->state = CLOSE_WAIT;        pcb->state = CLOSE_WAIT;
539      }      }
540      break;      break;
541    case FIN_WAIT_1:    case FIN_WAIT_1:
542      tcp_receive(pcb);      tcp_receive(pcb);
543      if(flags & TCP_FIN) {      if (flags & TCP_FIN) {
544        if(flags & TCP_ACK && ackno == pcb->snd_nxt) {        if (flags & TCP_ACK && ackno == pcb->snd_nxt) {
545          DEBUGF(DEMO_DEBUG,          DEBUGF(DEMO_DEBUG,
546                 ("TCP connection closed %d -> %d.\n", inseg.tcphdr->src, inseg.tcphdr->dest));                 ("TCP connection closed %d -> %d.\n", inseg.tcphdr->src, inseg.tcphdr->dest));
547          tcp_ack_now(pcb);          tcp_ack_now(pcb);
# Line 553  tcp_process(struct tcp_pcb *pcb) Line 553  tcp_process(struct tcp_pcb *pcb)
553          tcp_ack_now(pcb);          tcp_ack_now(pcb);
554          pcb->state = CLOSING;          pcb->state = CLOSING;
555        }        }
556      } else if(flags & TCP_ACK && ackno == pcb->snd_nxt) {      } else if (flags & TCP_ACK && ackno == pcb->snd_nxt) {
557        pcb->state = FIN_WAIT_2;        pcb->state = FIN_WAIT_2;
558      }      }
559      break;      break;
560    case FIN_WAIT_2:    case FIN_WAIT_2:
561      tcp_receive(pcb);      tcp_receive(pcb);
562      if(flags & TCP_FIN) {      if (flags & TCP_FIN) {
563        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));
564        tcp_ack_now(pcb);        tcp_ack_now(pcb);
565        tcp_pcb_purge(pcb);        tcp_pcb_purge(pcb);
# Line 570  tcp_process(struct tcp_pcb *pcb) Line 570  tcp_process(struct tcp_pcb *pcb)
570      break;      break;
571    case CLOSING:    case CLOSING:
572      tcp_receive(pcb);      tcp_receive(pcb);
573      if(flags & TCP_ACK && ackno == pcb->snd_nxt) {      if (flags & TCP_ACK && ackno == pcb->snd_nxt) {
574        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));
575        tcp_ack_now(pcb);        tcp_ack_now(pcb);
576        tcp_pcb_purge(pcb);        tcp_pcb_purge(pcb);
# Line 581  tcp_process(struct tcp_pcb *pcb) Line 581  tcp_process(struct tcp_pcb *pcb)
581      break;      break;
582    case LAST_ACK:    case LAST_ACK:
583      tcp_receive(pcb);      tcp_receive(pcb);
584      if(flags & TCP_ACK && ackno == pcb->snd_nxt) {      if (flags & TCP_ACK && ackno == pcb->snd_nxt) {
585        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));
586        pcb->state = CLOSED;        pcb->state = CLOSED;
587        recv_flags = TF_CLOSED;        recv_flags = TF_CLOSED;
# Line 619  tcp_receive(struct tcp_pcb *pcb) Line 619  tcp_receive(struct tcp_pcb *pcb)
619    u32_t right_wnd_edge;    u32_t right_wnd_edge;
620    
621                
622    if(flags & TCP_ACK) {    if (flags & TCP_ACK) {
623      right_wnd_edge = pcb->snd_wnd + pcb->snd_wl1;      right_wnd_edge = pcb->snd_wnd + pcb->snd_wl1;
624    
625      /* Update window. */      /* Update window. */
626      if(TCP_SEQ_LT(pcb->snd_wl1, seqno) ||      if (TCP_SEQ_LT(pcb->snd_wl1, seqno) ||
627         (pcb->snd_wl1 == seqno && TCP_SEQ_LT(pcb->snd_wl2, ackno)) ||         (pcb->snd_wl1 == seqno && TCP_SEQ_LT(pcb->snd_wl2, ackno)) ||
628         (pcb->snd_wl2 == ackno && tcphdr->wnd > pcb->snd_wnd)) {         (pcb->snd_wl2 == ackno && tcphdr->wnd > pcb->snd_wnd)) {
629        pcb->snd_wnd = tcphdr->wnd;        pcb->snd_wnd = tcphdr->wnd;
# Line 632  tcp_receive(struct tcp_pcb *pcb) Line 632  tcp_receive(struct tcp_pcb *pcb)
632        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));
633  #if TCP_WND_DEBUG  #if TCP_WND_DEBUG
634      } else {      } else {
635        if(pcb->snd_wnd != tcphdr->wnd) {        if (pcb->snd_wnd != tcphdr->wnd) {
636          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",
637                                 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));
638        }        }
# Line 640  tcp_receive(struct tcp_pcb *pcb) Line 640  tcp_receive(struct tcp_pcb *pcb)
640      }      }
641            
642    
643      if(pcb->lastack == ackno) {      if (pcb->lastack == ackno) {
644        pcb->acked = 0;        pcb->acked = 0;
645    
646        if(pcb->snd_wl1 + pcb->snd_wnd == right_wnd_edge){        if (pcb->snd_wl1 + pcb->snd_wnd == right_wnd_edge){
647          ++pcb->dupacks;          ++pcb->dupacks;
648          if(pcb->dupacks >= 3 && pcb->unacked != NULL) {          if (pcb->dupacks >= 3 && pcb->unacked != NULL) {
649            if(!(pcb->flags & TF_INFR)) {            if (!(pcb->flags & TF_INFR)) {
650              /* This is fast retransmit. Retransmit the first unacked segment. */              /* This is fast retransmit. Retransmit the first unacked segment. */
651              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",
652                                    pcb->dupacks, pcb->lastack,                                    pcb->dupacks, pcb->lastack,
# Line 662  tcp_receive(struct tcp_pcb *pcb) Line 662  tcp_receive(struct tcp_pcb *pcb)
662            } else {            } else {
663              /* Inflate the congestion window, but not if it means that              /* Inflate the congestion window, but not if it means that
664                 the value overflows. */                 the value overflows. */
665              if((u16_t)(pcb->cwnd + pcb->mss) > pcb->cwnd) {              if ((u16_t)(pcb->cwnd + pcb->mss) > pcb->cwnd) {
666                pcb->cwnd += pcb->mss;                pcb->cwnd += pcb->mss;
667              }              }
668            }            }
# Line 671  tcp_receive(struct tcp_pcb *pcb) Line 671  tcp_receive(struct tcp_pcb *pcb)
671          DEBUGF(TCP_FR_DEBUG, ("tcp_receive: dupack averted %lu %lu\n",          DEBUGF(TCP_FR_DEBUG, ("tcp_receive: dupack averted %lu %lu\n",
672                                pcb->snd_wl1 + pcb->snd_wnd, right_wnd_edge));                                    pcb->snd_wl1 + pcb->snd_wnd, right_wnd_edge));    
673        }        }
674      } else if(TCP_SEQ_LT(pcb->lastack, ackno) &&      } else if (TCP_SEQ_LT(pcb->lastack, ackno) &&
675                TCP_SEQ_LEQ(ackno, pcb->snd_max)) {                TCP_SEQ_LEQ(ackno, pcb->snd_max)) {
676        /* We come here when the ACK acknowledges new data. */        /* We come here when the ACK acknowledges new data. */
677    
678        /* Reset the "IN Fast Retransmit" flag, since we are no longer        /* Reset the "IN Fast Retransmit" flag, since we are no longer
679           in fast retransmit. Also reset the congestion window to the           in fast retransmit. Also reset the congestion window to the
680           slow start threshold. */           slow start threshold. */
681        if(pcb->flags & TF_INFR) {        if (pcb->flags & TF_INFR) {
682          pcb->flags &= ~TF_INFR;          pcb->flags &= ~TF_INFR;
683          pcb->cwnd = pcb->ssthresh;          pcb->cwnd = pcb->ssthresh;
684        }        }
# Line 699  tcp_receive(struct tcp_pcb *pcb) Line 699  tcp_receive(struct tcp_pcb *pcb)
699                
700        /* Update the congestion control variables (cwnd and        /* Update the congestion control variables (cwnd and
701           ssthresh). */           ssthresh). */
702        if(pcb->state >= ESTABLISHED) {        if (pcb->state >= ESTABLISHED) {
703          if(pcb->cwnd < pcb->ssthresh) {          if (pcb->cwnd < pcb->ssthresh) {
704            if((u16_t)(pcb->cwnd + pcb->mss) > pcb->cwnd) {            if ((u16_t)(pcb->cwnd + pcb->mss) > pcb->cwnd) {
705              pcb->cwnd += pcb->mss;              pcb->cwnd += pcb->mss;
706            }            }
707            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));
708          } else {          } else {
709            u16_t new_cwnd = (pcb->cwnd + pcb->mss * pcb->mss / pcb->cwnd);            u16_t new_cwnd = (pcb->cwnd + pcb->mss * pcb->mss / pcb->cwnd);
710            if(new_cwnd > pcb->cwnd) {            if (new_cwnd > pcb->cwnd) {
711              pcb->cwnd = new_cwnd;              pcb->cwnd = new_cwnd;
712            }            }
713            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 722  tcp_receive(struct tcp_pcb *pcb) Line 722  tcp_receive(struct tcp_pcb *pcb)
722    
723        /* Remove segment from the unacknowledged list if the incoming        /* Remove segment from the unacknowledged list if the incoming
724           ACK acknowlegdes them. */           ACK acknowlegdes them. */
725        while(pcb->unacked != NULL &&        while (pcb->unacked != NULL &&
726              TCP_SEQ_LEQ(ntohl(pcb->unacked->tcphdr->seqno) +              TCP_SEQ_LEQ(ntohl(pcb->unacked->tcphdr->seqno) +
727                          TCP_TCPLEN(pcb->unacked), ackno)) {                          TCP_TCPLEN(pcb->unacked), ackno)) {
728          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 738  tcp_receive(struct tcp_pcb *pcb) Line 738  tcp_receive(struct tcp_pcb *pcb)
738          tcp_seg_free(next);          tcp_seg_free(next);
739                    
740          DEBUGF(TCP_QLEN_DEBUG, ("%d (after freeing unacked)\n", pcb->snd_queuelen));          DEBUGF(TCP_QLEN_DEBUG, ("%d (after freeing unacked)\n", pcb->snd_queuelen));
741          if(pcb->snd_queuelen != 0) {          if (pcb->snd_queuelen != 0) {
742            LWIP_ASSERT("tcp_receive: valid queue length", pcb->unacked != NULL ||            LWIP_ASSERT("tcp_receive: valid queue length", pcb->unacked != NULL ||
743                   pcb->unsent != NULL);                         pcb->unsent != NULL);      
744          }          }
# Line 752  tcp_receive(struct tcp_pcb *pcb) Line 752  tcp_receive(struct tcp_pcb *pcb)
752           rationale is that lwIP puts all outstanding segments on the           rationale is that lwIP puts all outstanding segments on the
753           ->unsent list after a retransmission, so these segments may           ->unsent list after a retransmission, so these segments may
754           in fact have been sent once. */           in fact have been sent once. */
755        while(pcb->unsent != NULL &&        while (pcb->unsent != NULL &&
756              TCP_SEQ_LEQ(ntohl(pcb->unsent->tcphdr->seqno) + TCP_TCPLEN(pcb->unsent),              TCP_SEQ_LEQ(ntohl(pcb->unsent->tcphdr->seqno) + TCP_TCPLEN(pcb->unsent),
757                          ackno) &&                          ackno) &&
758              TCP_SEQ_LEQ(ackno, pcb->snd_max)) {              TCP_SEQ_LEQ(ackno, pcb->snd_max)) {
# Line 767  tcp_receive(struct tcp_pcb *pcb) Line 767  tcp_receive(struct tcp_pcb *pcb)
767          pcb->snd_queuelen -= pbuf_clen(next->p);          pcb->snd_queuelen -= pbuf_clen(next->p);
768          tcp_seg_free(next);          tcp_seg_free(next);
769          DEBUGF(TCP_QLEN_DEBUG, ("%d (after freeing unsent)\n", pcb->snd_queuelen));          DEBUGF(TCP_QLEN_DEBUG, ("%d (after freeing unsent)\n", pcb->snd_queuelen));
770          if(pcb->snd_queuelen != 0) {          if (pcb->snd_queuelen != 0) {
771            LWIP_ASSERT("tcp_receive: valid queue length", pcb->unacked != NULL ||            LWIP_ASSERT("tcp_receive: valid queue length", pcb->unacked != NULL ||
772                   pcb->unsent != NULL);                         pcb->unsent != NULL);      
773          }          }
774                    
775          if(pcb->unsent != NULL) {          if (pcb->unsent != NULL) {
776            pcb->snd_nxt = htonl(pcb->unsent->tcphdr->seqno);            pcb->snd_nxt = htonl(pcb->unsent->tcphdr->seqno);
777          }          }
778        }        }
# Line 785  tcp_receive(struct tcp_pcb *pcb) Line 785  tcp_receive(struct tcp_pcb *pcb)
785      /* RTT estimation calculations. This is done by checking if the      /* RTT estimation calculations. This is done by checking if the
786         incoming segment acknowledges the segment we use to take a         incoming segment acknowledges the segment we use to take a
787         round-trip time measurement. */         round-trip time measurement. */
788      if(pcb->rttest && TCP_SEQ_LT(pcb->rtseq, ackno)) {      if (pcb->rttest && TCP_SEQ_LT(pcb->rtseq, ackno)) {
789        m = tcp_ticks - pcb->rttest;        m = tcp_ticks - pcb->rttest;
790    
791        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 794  tcp_receive(struct tcp_pcb *pcb) Line 794  tcp_receive(struct tcp_pcb *pcb)
794        /* This is taken directly from VJs original code in his paper */              /* This is taken directly from VJs original code in his paper */      
795        m = m - (pcb->sa >> 3);        m = m - (pcb->sa >> 3);
796        pcb->sa += m;        pcb->sa += m;
797        if(m < 0) {        if (m < 0) {
798          m = -m;          m = -m;
799        }        }
800        m = m - (pcb->sv >> 2);        m = m - (pcb->sv >> 2);
# Line 810  tcp_receive(struct tcp_pcb *pcb) Line 810  tcp_receive(struct tcp_pcb *pcb)
810        
811    /* If the incoming segment contains data, we must process it    /* If the incoming segment contains data, we must process it
812       further. */       further. */
813    if(tcplen > 0) {    if (tcplen > 0) {
814      /* This code basically does three things:      /* This code basically does three things:
815    
816       +) If the incoming segment contains data that is the next       +) If the incoming segment contains data that is the next
# Line 839  tcp_receive(struct tcp_pcb *pcb) Line 839  tcp_receive(struct tcp_pcb *pcb)
839         this if the sequence number of the incoming segment is less         this if the sequence number of the incoming segment is less
840         than rcv_nxt, and the sequence number plus the length of the         than rcv_nxt, and the sequence number plus the length of the
841         segment is larger than rcv_nxt. */         segment is larger than rcv_nxt. */
842      if(TCP_SEQ_LT(seqno, pcb->rcv_nxt)){      if (TCP_SEQ_LT(seqno, pcb->rcv_nxt)){
843        if(TCP_SEQ_LT(pcb->rcv_nxt, seqno + tcplen)) {        if (TCP_SEQ_LT(pcb->rcv_nxt, seqno + tcplen)) {
844          /* Trimming the first edge is done by pushing the payload          /* Trimming the first edge is done by pushing the payload
845             pointer in the pbuf downwards. This is somewhat tricky since             pointer in the pbuf downwards. This is somewhat tricky since
846             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 861  tcp_receive(struct tcp_pcb *pcb) Line 861  tcp_receive(struct tcp_pcb *pcb)
861             adjust the ->data pointer in the seg and the segment             adjust the ->data pointer in the seg and the segment
862             length.*/             length.*/
863          off = pcb->rcv_nxt - seqno;          off = pcb->rcv_nxt - seqno;
864          if(inseg.p->len < off) {          if (inseg.p->len < off) {
865            p = inseg.p;            p = inseg.p;
866            while(p->len < off) {            while (p->len < off) {
867              off -= p->len;              off -= p->len;
868              inseg.p->tot_len -= p->len;              inseg.p->tot_len -= p->len;
869              p->len = 0;              p->len = 0;
# Line 889  tcp_receive(struct tcp_pcb *pcb) Line 889  tcp_receive(struct tcp_pcb *pcb)
889      /* The sequence number must be within the window (above rcv_nxt      /* The sequence number must be within the window (above rcv_nxt
890         and below rcv_nxt + rcv_wnd) in order to be further         and below rcv_nxt + rcv_wnd) in order to be further
891         processed. */         processed. */
892      if(TCP_SEQ_GEQ(seqno, pcb->rcv_nxt) &&      if (TCP_SEQ_GEQ(seqno, pcb->rcv_nxt) &&
893         TCP_SEQ_LT(seqno, pcb->rcv_nxt + pcb->rcv_wnd)) {         TCP_SEQ_LT(seqno, pcb->rcv_nxt + pcb->rcv_wnd)) {
894        if(pcb->rcv_nxt == seqno) {                              if (pcb->rcv_nxt == seqno) {                      
895          /* The incoming segment is the next in sequence. We check if          /* The incoming segment is the next in sequence. We check if
896             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
897             and pass the data to the application. */             and pass the data to the application. */
898  #if TCP_QUEUE_OOSEQ  #if TCP_QUEUE_OOSEQ
899          if(pcb->ooseq != NULL &&          if (pcb->ooseq != NULL &&
900             TCP_SEQ_LEQ(pcb->ooseq->tcphdr->seqno, seqno + inseg.len)) {             TCP_SEQ_LEQ(pcb->ooseq->tcphdr->seqno, seqno + inseg.len)) {
901            /* We have to trim the second edge of the incoming            /* We have to trim the second edge of the incoming
902               segment. */               segment. */
# Line 910  tcp_receive(struct tcp_pcb *pcb) Line 910  tcp_receive(struct tcp_pcb *pcb)
910          pcb->rcv_nxt += tcplen;          pcb->rcv_nxt += tcplen;
911                    
912          /* Update the receiver's (our) window. */          /* Update the receiver's (our) window. */
913          if(pcb->rcv_wnd < tcplen) {          if (pcb->rcv_wnd < tcplen) {
914            pcb->rcv_wnd = 0;            pcb->rcv_wnd = 0;
915          } else {          } else {
916            pcb->rcv_wnd -= tcplen;            pcb->rcv_wnd -= tcplen;
# Line 925  tcp_receive(struct tcp_pcb *pcb) Line 925  tcp_receive(struct tcp_pcb *pcb)
925             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
926             be used to indicate to the application that the remote side has             be used to indicate to the application that the remote side has
927             closed its end of the connection. */                   closed its end of the connection. */      
928          if(inseg.p->tot_len > 0) {          if (inseg.p->tot_len > 0) {
929            recv_data = inseg.p;            recv_data = inseg.p;
930            /* Since this pbuf now is the responsibility of the            /* Since this pbuf now is the responsibility of the
931               application, we delete our reference to it so that we won't               application, we delete our reference to it so that we won't
932               (mistakingly) deallocate it. */               (mistakingly) deallocate it. */
933            inseg.p = NULL;            inseg.p = NULL;
934          }          }
935          if(TCPH_FLAGS(inseg.tcphdr) & TCP_FIN) {          if (TCPH_FLAGS(inseg.tcphdr) & TCP_FIN) {
936            DEBUGF(TCP_INPUT_DEBUG, ("tcp_receive: received FIN."));            DEBUGF(TCP_INPUT_DEBUG, ("tcp_receive: received FIN."));
937            recv_flags = TF_GOT_FIN;            recv_flags = TF_GOT_FIN;
938          }          }
# Line 940  tcp_receive(struct tcp_pcb *pcb) Line 940  tcp_receive(struct tcp_pcb *pcb)
940  #if TCP_QUEUE_OOSEQ  #if TCP_QUEUE_OOSEQ
941          /* We now check if we have segments on the ->ooseq queue that          /* We now check if we have segments on the ->ooseq queue that
942             is now in sequence. */             is now in sequence. */
943          while(pcb->ooseq != NULL &&          while (pcb->ooseq != NULL &&
944                pcb->ooseq->tcphdr->seqno == pcb->rcv_nxt) {                pcb->ooseq->tcphdr->seqno == pcb->rcv_nxt) {
945    
946            cseg = pcb->ooseq;            cseg = pcb->ooseq;
947            seqno = pcb->ooseq->tcphdr->seqno;            seqno = pcb->ooseq->tcphdr->seqno;
948                        
949            pcb->rcv_nxt += TCP_TCPLEN(cseg);            pcb->rcv_nxt += TCP_TCPLEN(cseg);
950            if(pcb->rcv_wnd < TCP_TCPLEN(cseg)) {            if (pcb->rcv_wnd < TCP_TCPLEN(cseg)) {
951              pcb->rcv_wnd = 0;              pcb->rcv_wnd = 0;
952            } else {            } else {
953              pcb->rcv_wnd -= TCP_TCPLEN(cseg);              pcb->rcv_wnd -= TCP_TCPLEN(cseg);
954            }            }
955            if(cseg->p->tot_len > 0) {            if (cseg->p->tot_len > 0) {
956              /* Chain this pbuf onto the pbuf that we will pass to              /* Chain this pbuf onto the pbuf that we will pass to
957                 the application. */                 the application. */
958              if(recv_data) {              if (recv_data) {
959                pbuf_chain(recv_data, cseg->p);                pbuf_chain(recv_data, cseg->p);
960                pbuf_free(cseg->p);                pbuf_free(cseg->p);
961              } else {              } else {
# Line 963  tcp_receive(struct tcp_pcb *pcb) Line 963  tcp_receive(struct tcp_pcb *pcb)
963              }              }
964              cseg->p = NULL;              cseg->p = NULL;
965            }            }
966            if(flags & TCP_FIN) {            if (flags & TCP_FIN) {
967              DEBUGF(TCP_INPUT_DEBUG, ("tcp_receive: dequeued FIN."));              DEBUGF(TCP_INPUT_DEBUG, ("tcp_receive: dequeued FIN."));
968              recv_flags = TF_GOT_FIN;              recv_flags = TF_GOT_FIN;
969            }                    }        
# Line 983  tcp_receive(struct tcp_pcb *pcb) Line 983  tcp_receive(struct tcp_pcb *pcb)
983          tcp_ack_now(pcb);          tcp_ack_now(pcb);
984  #if TCP_QUEUE_OOSEQ  #if TCP_QUEUE_OOSEQ
985          /* We queue the segment on the ->ooseq queue. */          /* We queue the segment on the ->ooseq queue. */
986          if(pcb->ooseq == NULL) {          if (pcb->ooseq == NULL) {
987            pcb->ooseq = tcp_seg_copy(&inseg);            pcb->ooseq = tcp_seg_copy(&inseg);
988          } else {          } else {
989            /* 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 1000  tcp_receive(struct tcp_pcb *pcb) Line 1000  tcp_receive(struct tcp_pcb *pcb)
1000    
1001            prev = NULL;            prev = NULL;
1002            for(next = pcb->ooseq; next != NULL; next = next->next) {            for(next = pcb->ooseq; next != NULL; next = next->next) {
1003              if(seqno == next->tcphdr->seqno) {              if (seqno == next->tcphdr->seqno) {
1004                /* The sequence number of the incoming segment is the                /* The sequence number of the incoming segment is the
1005                   same as the sequence number of the segment on                   same as the sequence number of the segment on
1006                   ->ooseq. We check the lengths to see which one to                   ->ooseq. We check the lengths to see which one to
1007                   discard. */                   discard. */
1008                if(inseg.len > next->len) {                if (inseg.len > next->len) {
1009                  /* The incoming segment is larger than the old                  /* The incoming segment is larger than the old
1010                     segment. We replace the old segment with the new                     segment. We replace the old segment with the new
1011                     one. */                     one. */
1012                  cseg = tcp_seg_copy(&inseg);                  cseg = tcp_seg_copy(&inseg);
1013                  if(cseg != NULL) {                  if (cseg != NULL) {
1014                    cseg->next = next->next;                    cseg->next = next->next;
1015                    if(prev != NULL) {                    if (prev != NULL) {
1016                      prev->next = cseg;                      prev->next = cseg;
1017                    } else {                    } else {
1018                      pcb->ooseq = cseg;                      pcb->ooseq = cseg;
# Line 1026  tcp_receive(struct tcp_pcb *pcb) Line 1026  tcp_receive(struct tcp_pcb *pcb)
1026                  break;                  break;
1027                }                }
1028              } else {              } else {
1029                if(prev == NULL) {                if (prev == NULL) {
1030                  if(TCP_SEQ_LT(seqno, next->tcphdr->seqno)) {                  if (TCP_SEQ_LT(seqno, next->tcphdr->seqno)) {
1031                    /* The sequence number of the incoming segment is lower                    /* The sequence number of the incoming segment is lower
1032                       than the sequence number of the first segment on the                       than the sequence number of the first segment on the
1033                       queue. We put the incoming segment first on the                       queue. We put the incoming segment first on the
1034                       queue. */                       queue. */
1035                                        
1036                    if(TCP_SEQ_GT(seqno + inseg.len, next->tcphdr->seqno)) {                    if (TCP_SEQ_GT(seqno + inseg.len, next->tcphdr->seqno)) {
1037                      /* We need to trim the incoming segment. */                      /* We need to trim the incoming segment. */
1038                      inseg.len = next->tcphdr->seqno - seqno;                      inseg.len = next->tcphdr->seqno - seqno;
1039                      pbuf_realloc(inseg.p, inseg.len);                      pbuf_realloc(inseg.p, inseg.len);
1040                    }                    }
1041                    cseg = tcp_seg_copy(&inseg);                    cseg = tcp_seg_copy(&inseg);
1042                    if(cseg != NULL) {                    if (cseg != NULL) {
1043                      cseg->next = next;                      cseg->next = next;
1044                      pcb->ooseq = cseg;                      pcb->ooseq = cseg;
1045                    }                    }
1046                    break;                    break;
1047                  }                  }
1048                } else if(TCP_SEQ_LT(prev->tcphdr->seqno, seqno) &&                } else if (TCP_SEQ_LT(prev->tcphdr->seqno, seqno) &&
1049                   TCP_SEQ_LT(seqno, next->tcphdr->seqno)) {                   TCP_SEQ_LT(seqno, next->tcphdr->seqno)) {
1050                  /* The sequence number of the incoming segment is in                  /* The sequence number of the incoming segment is in
1051                     between the sequence numbers of the previous and                     between the sequence numbers of the previous and
1052                     the next segment on ->ooseq. We trim and insert the                     the next segment on ->ooseq. We trim and insert the
1053                     incoming segment and trim the previous segment, if                     incoming segment and trim the previous segment, if
1054                     needed. */                     needed. */
1055                  if(TCP_SEQ_GT(seqno + inseg.len, next->tcphdr->seqno)) {                  if (TCP_SEQ_GT(seqno + inseg.len, next->tcphdr->seqno)) {
1056                    /* We need to trim the incoming segment. */                    /* We need to trim the incoming segment. */
1057                    inseg.len = next->tcphdr->seqno - seqno;                    inseg.len = next->tcphdr->seqno - seqno;
1058                    pbuf_realloc(inseg.p, inseg.len);                    pbuf_realloc(inseg.p, inseg.len);
1059                  }                  }
1060    
1061                  cseg = tcp_seg_copy(&inseg);                  cseg = tcp_seg_copy(&inseg);
1062                  if(cseg != NULL) {                                                  if (cseg != NULL) {                              
1063                    cseg->next = next;                    cseg->next = next;
1064                    prev->next = cseg;                    prev->next = cseg;
1065                    if(TCP_SEQ_GT(prev->tcphdr->seqno + prev->len, seqno)) {                    if (TCP_SEQ_GT(prev->tcphdr->seqno + prev->len, seqno)) {
1066                      /* We need to trim the prev segment. */                      /* We need to trim the prev segment. */
1067                      prev->len = seqno - prev->tcphdr->seqno;                      prev->len = seqno - prev->tcphdr->seqno;
1068                      pbuf_realloc(prev->p, prev->len);                      pbuf_realloc(prev->p, prev->len);
# Line 1073  tcp_receive(struct tcp_pcb *pcb) Line 1073  tcp_receive(struct tcp_pcb *pcb)
1073                /* If the "next" segment is the last segment on the                /* If the "next" segment is the last segment on the
1074                   ooseq queue, we add the incoming segment to the end                   ooseq queue, we add the incoming segment to the end
1075                   of the list. */                   of the list. */
1076                if(next->next == NULL &&                if (next->next == NULL &&
1077                   TCP_SEQ_GT(seqno, next->tcphdr->seqno)) {                   TCP_SEQ_GT(seqno, next->tcphdr->seqno)) {
1078                  next->next = tcp_seg_copy(&inseg);                  next->next = tcp_seg_copy(&inseg);
1079                  if(next->next != NULL) {                                  if (next->next != NULL) {              
1080                    if(TCP_SEQ_GT(next->tcphdr->seqno + next->len, seqno)) {                    if (TCP_SEQ_GT(next->tcphdr->seqno + next->len, seqno)) {
1081                      /* We need to trim the last segment. */                      /* We need to trim the last segment. */
1082                      next->len = seqno - next->tcphdr->seqno;                      next->len = seqno - next->tcphdr->seqno;
1083                      pbuf_realloc(next->p, next->len);                      pbuf_realloc(next->p, next->len);
# Line 1096  tcp_receive(struct tcp_pcb *pcb) Line 1096  tcp_receive(struct tcp_pcb *pcb)
1096    } else {    } else {
1097      /* Segments with length 0 is taken care of here. Segments that      /* Segments with length 0 is taken care of here. Segments that
1098         fall out of the window are ACKed. */         fall out of the window are ACKed. */
1099      if(TCP_SEQ_GT(pcb->rcv_nxt, seqno) ||      if (TCP_SEQ_GT(pcb->rcv_nxt, seqno) ||
1100         TCP_SEQ_GEQ(seqno, pcb->rcv_nxt + pcb->rcv_wnd)) {         TCP_SEQ_GEQ(seqno, pcb->rcv_nxt + pcb->rcv_wnd)) {
1101        tcp_ack_now(pcb);        tcp_ack_now(pcb);
1102      }            }      
# Line 1121  tcp_parseopt(struct tcp_pcb *pcb) Line 1121  tcp_parseopt(struct tcp_pcb *pcb)
1121    opts = (u8_t *)tcphdr + TCP_HLEN;    opts = (u8_t *)tcphdr + TCP_HLEN;
1122        
1123    /* Parse the TCP MSS option, if present. */    /* Parse the TCP MSS option, if present. */
1124    if((TCPH_OFFSET(tcphdr) & 0xf0) > 0x50) {    if ((TCPH_OFFSET(tcphdr) & 0xf0) > 0x50) {
1125      for(c = 0; c < ((TCPH_OFFSET(tcphdr) >> 4) - 5) << 2 ;) {      for(c = 0; c < ((TCPH_OFFSET(tcphdr) >> 4) - 5) << 2 ;) {
1126        opt = opts[c];        opt = opts[c];
1127        if(opt == 0x00) {        if (opt == 0x00) {
1128          /* End of options. */            /* End of options. */  
1129          break;          break;
1130        } else if(opt == 0x01) {        } else if (opt == 0x01) {
1131          ++c;          ++c;
1132          /* NOP option. */          /* NOP option. */
1133        } else if(opt == 0x02 &&        } else if (opt == 0x02 &&
1134                  opts[c + 1] == 0x04) {                  opts[c + 1] == 0x04) {
1135          /* An MSS option with the right option length. */                /* An MSS option with the right option length. */      
1136          mss = (opts[c + 2] << 8) | opts[c + 3];          mss = (opts[c + 2] << 8) | opts[c + 3];
# Line 1139  tcp_parseopt(struct tcp_pcb *pcb) Line 1139  tcp_parseopt(struct tcp_pcb *pcb)
1139          /* And we are done processing options. */          /* And we are done processing options. */
1140          break;          break;
1141        } else {        } else {
1142          if(opts[c + 1] == 0) {          if (opts[c + 1] == 0) {
1143            /* If the length field is zero, the options are malformed            /* If the length field is zero, the options are malformed
1144               and we don't process them further. */               and we don't process them further. */
1145            break;            break;

Legend:
Removed from v.1.24  
changed lines
  Added in v.1.25

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