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

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

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

revision 1.17.2.3 by likewise, Wed Jun 4 10:18:38 2003 UTC revision 1.17.2.4 by likewise, Wed Jun 4 10:30:00 2003 UTC
# Line 59  Line 59 
59  #include "lwip/stats.h"  #include "lwip/stats.h"
60    
61  #if LWIP_TCP  #if LWIP_TCP
 #define MIN(x,y) (x) < (y)? (x): (y)  
   
   
62    
63  /* Forward declarations.*/  /* Forward declarations.*/
64  static void tcp_output_segment(struct tcp_seg *seg, struct tcp_pcb *pcb);  static void tcp_output_segment(struct tcp_seg *seg, struct tcp_pcb *pcb);
# Line 115  tcp_enqueue(struct tcp_pcb *pcb, void *a Line 112  tcp_enqueue(struct tcp_pcb *pcb, void *a
112    }    }
113    
114    /* seqno will be the sequence number of the first segment enqueued    /* seqno will be the sequence number of the first segment enqueued
115    by the call to this function. */     * by the call to this function. */
116    seqno = pcb->snd_lbb;    seqno = pcb->snd_lbb;
117    
118      queue = NULL;    queue = NULL;
119    DEBUGF(TCP_QLEN_DEBUG, ("tcp_enqueue: queuelen: %d\n", pcb->snd_queuelen));    DEBUGF(TCP_QLEN_DEBUG, ("tcp_enqueue: queuelen: %d\n", pcb->snd_queuelen));
120    
121    /* Check if the queue length exceeds the configured maximum queue    /* Check if the queue length exceeds the configured maximum queue
122    length. If so, we return an error. */     * length. If so, we return an error. */
123    queuelen = pcb->snd_queuelen;    queuelen = pcb->snd_queuelen;
124    if (queuelen >= TCP_SND_QUEUELEN) {    if (queuelen >= TCP_SND_QUEUELEN) {
125      DEBUGF(TCP_OUTPUT_DEBUG, ("tcp_enqueue: too long queue %d (max %d)\n", queuelen, TCP_SND_QUEUELEN));      DEBUGF(TCP_OUTPUT_DEBUG | 3, ("tcp_enqueue: too long queue %d (max %d)\n", queuelen, TCP_SND_QUEUELEN));
126      goto memerr;      goto memerr;
127    }      }  
128    
# Line 138  tcp_enqueue(struct tcp_pcb *pcb, void *a Line 135  tcp_enqueue(struct tcp_pcb *pcb, void *a
135    seglen = 0;    seglen = 0;
136    
137    /* First, break up the data into segments and tuck them together in    /* First, break up the data into segments and tuck them together in
138    the local "queue" variable. */     * the local "queue" variable. */
139    while (queue == NULL || left > 0) {    while (queue == NULL || left > 0) {
140    
141      /* The segment length should be the MSS if the data to be enqueued      /* The segment length should be the MSS if the data to be enqueued
142      is larger than the MSS. */       * is larger than the MSS. */
143      seglen = left > pcb->mss? pcb->mss: left;      seglen = left > pcb->mss? pcb->mss: left;
144    
145      /* Allocate memory for tcp_seg, and fill in fields. */      /* Allocate memory for tcp_seg, and fill in fields. */
146      seg = memp_malloc(MEMP_TCP_SEG);      seg = memp_malloc(MEMP_TCP_SEG);
147      if (seg == NULL) {      if (seg == NULL) {
148        DEBUGF(TCP_OUTPUT_DEBUG, ("tcp_enqueue: could not allocate memory for tcp_seg\n"));        DEBUGF(TCP_OUTPUT_DEBUG | 2, ("tcp_enqueue: could not allocate memory for tcp_seg\n"));
149        goto memerr;        goto memerr;
150      }      }
151      seg->next = NULL;      seg->next = NULL;
# Line 159  tcp_enqueue(struct tcp_pcb *pcb, void *a Line 156  tcp_enqueue(struct tcp_pcb *pcb, void *a
156      }      }
157      else {      else {
158        /* Attach the segment to the end of the queued segments. */        /* Attach the segment to the end of the queued segments. */
159        for(useg = queue; useg->next != NULL; useg = useg->next);        for (useg = queue; useg->next != NULL; useg = useg->next);
160        useg->next = seg;        useg->next = seg;
161      }      }
162    
163      /* If copy is set, memory should be allocated      /* If copy is set, memory should be allocated
164      and data copied into pbuf, otherwise data comes from       * and data copied into pbuf, otherwise data comes from
165      ROM or other static memory, and need not be copied. If       * ROM or other static memory, and need not be copied. If
166      optdata is != NULL, we have options instead of data. */       * optdata is != NULL, we have options instead of data. */
167      if (optdata != NULL) {      if (optdata != NULL) {
168        if ((seg->p = pbuf_alloc(PBUF_TRANSPORT, optlen, PBUF_RAM)) == NULL) {        if ((seg->p = pbuf_alloc(PBUF_TRANSPORT, optlen, PBUF_RAM)) == NULL) {
169          goto memerr;          goto memerr;
# Line 176  tcp_enqueue(struct tcp_pcb *pcb, void *a Line 173  tcp_enqueue(struct tcp_pcb *pcb, void *a
173      }      }
174      else if (copy) {      else if (copy) {
175        if ((seg->p = pbuf_alloc(PBUF_TRANSPORT, seglen, PBUF_RAM)) == NULL) {        if ((seg->p = pbuf_alloc(PBUF_TRANSPORT, seglen, PBUF_RAM)) == NULL) {
176          DEBUGF(TCP_OUTPUT_DEBUG, ("tcp_enqueue: could not allocate memory for pbuf copy size %u\n", seglen));              DEBUGF(TCP_OUTPUT_DEBUG | 2, ("tcp_enqueue: could not allocate memory for pbuf copy size %u\n", seglen));        
177          goto memerr;          goto memerr;
178        }        }
179        ++queuelen;        ++queuelen;
# Line 204  tcp_enqueue(struct tcp_pcb *pcb, void *a Line 201  tcp_enqueue(struct tcp_pcb *pcb, void *a
201        /* Second, allocate a pbuf for the headers. */        /* Second, allocate a pbuf for the headers. */
202        if ((seg->p = pbuf_alloc(PBUF_TRANSPORT, 0, PBUF_RAM)) == NULL) {        if ((seg->p = pbuf_alloc(PBUF_TRANSPORT, 0, PBUF_RAM)) == NULL) {
203          /* If allocation fails, we have to deallocate the data pbuf as          /* If allocation fails, we have to deallocate the data pbuf as
204             well. */           * well. */
205          pbuf_free(p);          pbuf_free(p);
206          DEBUGF(TCP_OUTPUT_DEBUG | 2, ("tcp_enqueue: could not allocate memory for header pbuf\n"));                        DEBUGF(TCP_OUTPUT_DEBUG | 2, ("tcp_enqueue: could not allocate memory for header pbuf\n"));              
207          goto memerr;          goto memerr;
# Line 214  tcp_enqueue(struct tcp_pcb *pcb, void *a Line 211  tcp_enqueue(struct tcp_pcb *pcb, void *a
211        /* Chain the headers and data pbufs together. */        /* Chain the headers and data pbufs together. */
212        pbuf_chain(seg->p, p);        pbuf_chain(seg->p, p);
213        pbuf_free(p);        pbuf_free(p);
214          p = NULL;
215      }      }
216    
217      /* Now that there are more segments queued, we check again if the      /* Now that there are more segments queued, we check again if the
218      length of the queue exceeds the configured maximum. */      length of the queue exceeds the configured maximum. */
219      if (queuelen > TCP_SND_QUEUELEN) {      if (queuelen > TCP_SND_QUEUELEN) {
220        DEBUGF(TCP_OUTPUT_DEBUG, ("tcp_enqueue: queue too long %d (%d)\n", queuelen, TCP_SND_QUEUELEN));          DEBUGF(TCP_OUTPUT_DEBUG | 2, ("tcp_enqueue: queue too long %d (%d)\n", queuelen, TCP_SND_QUEUELEN));      
221        goto memerr;        goto memerr;
222      }      }
223    
# Line 275  tcp_enqueue(struct tcp_pcb *pcb, void *a Line 273  tcp_enqueue(struct tcp_pcb *pcb, void *a
273      useg = NULL;      useg = NULL;
274    }    }
275    else {    else {
276      for(useg = pcb->unsent; useg->next != NULL; useg = useg->next);      for (useg = pcb->unsent; useg->next != NULL; useg = useg->next);
277    }    }
278    
279    /* If there is room in the last pbuf on the unsent queue,    /* If there is room in the last pbuf on the unsent queue,
# Line 367  tcp_output(struct tcp_pcb *pcb) Line 365  tcp_output(struct tcp_pcb *pcb)
365      return ERR_OK;      return ERR_OK;
366    }    }
367        
368    wnd = MIN(pcb->snd_wnd, pcb->cwnd);    wnd = LWIP_MIN(pcb->snd_wnd, pcb->cwnd);
369    
370        
371    seg = pcb->unsent;    seg = pcb->unsent;
# Line 459  tcp_output(struct tcp_pcb *pcb) Line 457  tcp_output(struct tcp_pcb *pcb)
457                    
458                    
459        } else {        } else {
460          for(useg = pcb->unacked; useg->next != NULL; useg = useg->next);          for (useg = pcb->unacked; useg->next != NULL; useg = useg->next);
461          useg->next = seg;          useg->next = seg;
462        }        }
463      } else {      } else {
# Line 575  tcp_rexmit(struct tcp_pcb *pcb) Line 573  tcp_rexmit(struct tcp_pcb *pcb)
573    }    }
574        
575    /* Move all unacked segments to the unsent queue. */    /* Move all unacked segments to the unsent queue. */
576    for(seg = pcb->unacked; seg->next != NULL; seg = seg->next);    for (seg = pcb->unacked; seg->next != NULL; seg = seg->next);
577        
578    seg->next = pcb->unsent;    seg->next = pcb->unsent;
579    pcb->unsent = pcb->unacked;    pcb->unsent = pcb->unacked;

Legend:
Removed from v.1.17.2.3  
changed lines
  Added in v.1.17.2.4

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