/[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.6 by likewise, Wed Jan 8 10:09:42 2003 UTC revision 1.7 by adamdunkels, Wed Jan 8 14:11:24 2003 UTC
# Line 108  tcp_enqueue(struct tcp_pcb *pcb, void *a Line 108  tcp_enqueue(struct tcp_pcb *pcb, void *a
108      DEBUGF(TCP_OUTPUT_DEBUG, ("tcp_enqueue: too much data %d\n", len));      DEBUGF(TCP_OUTPUT_DEBUG, ("tcp_enqueue: too much data %d\n", len));
109      return ERR_MEM;      return ERR_MEM;
110    }    }
111      
112      /* seqno will be the sequence number of the first segment enqueued
113         by the call to this function. */
114    seqno = pcb->snd_lbb;    seqno = pcb->snd_lbb;
115        
116    queue = NULL;    queue = NULL;
117    DEBUGF(TCP_QLEN_DEBUG, ("tcp_enqueue: %d\n", pcb->snd_queuelen));    DEBUGF(TCP_QLEN_DEBUG, ("tcp_enqueue: %d\n", pcb->snd_queuelen));
118    
119      /* Check if the queue length exceeds the configured maximum queue
120         length. If so, we return an error. */
121    queuelen = pcb->snd_queuelen;    queuelen = pcb->snd_queuelen;
122    if(queuelen >= TCP_SND_QUEUELEN) {    if(queuelen >= TCP_SND_QUEUELEN) {
123      DEBUGF(TCP_OUTPUT_DEBUG, ("tcp_enqueue: too long queue %d (max %d)\n", queuelen, TCP_SND_QUEUELEN));      DEBUGF(TCP_OUTPUT_DEBUG, ("tcp_enqueue: too long queue %d (max %d)\n", queuelen, TCP_SND_QUEUELEN));
# Line 128  tcp_enqueue(struct tcp_pcb *pcb, void *a Line 133  tcp_enqueue(struct tcp_pcb *pcb, void *a
133        
134    seg = NULL;    seg = NULL;
135    seglen = 0;    seglen = 0;
136      
137      /* First, break up the data into segments and tuck them together in
138         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
142           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, ("tcp_enqueue: could not allocate memory for tcp_seg\n"));
# Line 142  tcp_enqueue(struct tcp_pcb *pcb, void *a Line 151  tcp_enqueue(struct tcp_pcb *pcb, void *a
151      seg->next = NULL;      seg->next = NULL;
152      seg->p = NULL;      seg->p = NULL;
153            
       
154      if(queue == NULL) {      if(queue == NULL) {
155        queue = seg;        queue = seg;
156      } else {      } else {
157          /* Attach the segment to the end of the queued segments. */
158        for(useg = queue; useg->next != NULL; useg = useg->next);        for(useg = queue; useg->next != NULL; useg = useg->next);
159        useg->next = seg;        useg->next = seg;
160      }      }
# Line 172  tcp_enqueue(struct tcp_pcb *pcb, void *a Line 181  tcp_enqueue(struct tcp_pcb *pcb, void *a
181        seg->dataptr = seg->p->payload;        seg->dataptr = seg->p->payload;
182      } else {      } else {
183        /* Do not copy the data. */        /* Do not copy the data. */
184    
185          /* First, allocate a pbuf for holding the data. */
186        if((p = pbuf_alloc(PBUF_TRANSPORT, seglen, PBUF_ROM)) == NULL) {        if((p = pbuf_alloc(PBUF_TRANSPORT, seglen, PBUF_ROM)) == NULL) {
187          DEBUGF(TCP_OUTPUT_DEBUG, ("tcp_enqueue: could not allocate memory for pbuf non-copy\n"));                          DEBUGF(TCP_OUTPUT_DEBUG, ("tcp_enqueue: could not allocate memory for pbuf non-copy\n"));                
188          goto memerr;          goto memerr;
# Line 179  tcp_enqueue(struct tcp_pcb *pcb, void *a Line 190  tcp_enqueue(struct tcp_pcb *pcb, void *a
190        ++queuelen;        ++queuelen;
191        p->payload = ptr;        p->payload = ptr;
192        seg->dataptr = ptr;        seg->dataptr = ptr;
193    
194          /* Second, allocate a pbuf for the headers. */
195        if((seg->p = pbuf_alloc(PBUF_TRANSPORT, 0, PBUF_RAM)) == NULL) {        if((seg->p = pbuf_alloc(PBUF_TRANSPORT, 0, PBUF_RAM)) == NULL) {
196            /* If allocation fails, we have to deallocate the data pbuf as
197               well. */
198          pbuf_free(p);          pbuf_free(p);
199          DEBUGF(TCP_OUTPUT_DEBUG, ("tcp_enqueue: could not allocate memory for header pbuf\n"));                    DEBUGF(TCP_OUTPUT_DEBUG, ("tcp_enqueue: could not allocate memory for header pbuf\n"));          
200          goto memerr;          goto memerr;
201        }        }
202        ++queuelen;        ++queuelen;
203    
204          /* Chain the headers and data pbufs together. */
205        pbuf_chain(seg->p, p);        pbuf_chain(seg->p, p);
206      }      }
207    
208        /* Now that there are more segments queued, we check again if the
209           length of the queue exceeds the configured maximum. */
210      if(queuelen > TCP_SND_QUEUELEN) {      if(queuelen > TCP_SND_QUEUELEN) {
211        DEBUGF(TCP_OUTPUT_DEBUG, ("tcp_enqueue: queue too long %d (%d)\n", queuelen, TCP_SND_QUEUELEN));          DEBUGF(TCP_OUTPUT_DEBUG, ("tcp_enqueue: queue too long %d (%d)\n", queuelen, TCP_SND_QUEUELEN));  
212        goto memerr;        goto memerr;
# Line 197  tcp_enqueue(struct tcp_pcb *pcb, void *a Line 217  tcp_enqueue(struct tcp_pcb *pcb, void *a
217        ++seg->len;        ++seg->len;
218        }*/        }*/
219                
220      /* build TCP header */      /* Build TCP header. */
221      if(pbuf_header(seg->p, TCP_HLEN)) {      if(pbuf_header(seg->p, TCP_HLEN)) {
222                    
223        DEBUGF(TCP_OUTPUT_DEBUG, ("tcp_enqueue: no room for TCP header in pbuf.\n"));        DEBUGF(TCP_OUTPUT_DEBUG, ("tcp_enqueue: no room for TCP header in pbuf.\n"));
# Line 214  tcp_enqueue(struct tcp_pcb *pcb, void *a Line 234  tcp_enqueue(struct tcp_pcb *pcb, void *a
234      seg->tcphdr->urgp = 0;      seg->tcphdr->urgp = 0;
235      TCPH_FLAGS_SET(seg->tcphdr, flags);      TCPH_FLAGS_SET(seg->tcphdr, flags);
236      /* don't fill in tcphdr->ackno and tcphdr->wnd until later */      /* don't fill in tcphdr->ackno and tcphdr->wnd until later */
237          
238        /* Copy the options into the header, if they are present. */
239      if(optdata == NULL) {      if(optdata == NULL) {
240        TCPH_OFFSET_SET(seg->tcphdr, 5 << 4);        TCPH_OFFSET_SET(seg->tcphdr, 5 << 4);
241      } else {      } else {
# Line 235  tcp_enqueue(struct tcp_pcb *pcb, void *a Line 256  tcp_enqueue(struct tcp_pcb *pcb, void *a
256    }    }
257    
258            
259    /* Go to the last segment on the ->unsent queue. */        /* Now that the data to be enqueued has been broken up into TCP
260         segments in the queue variable, we add them to the end of the
261         pcb->unsent queue. */    
262    if(pcb->unsent == NULL) {    if(pcb->unsent == NULL) {
263      useg = NULL;      useg = NULL;
264    } else {    } else {

Legend:
Removed from v.1.6  
changed lines
  Added in v.1.7

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