92 |
/*-----------------------------------------------------------------------------------*/ |
/*-----------------------------------------------------------------------------------*/ |
93 |
err_t |
err_t |
94 |
tcp_enqueue(struct tcp_pcb *pcb, void *arg, u16_t len, |
tcp_enqueue(struct tcp_pcb *pcb, void *arg, u16_t len, |
95 |
u8_t flags, u8_t copy, |
u8_t flags, u8_t copy, |
96 |
u8_t *optdata, u8_t optlen) |
u8_t *optdata, u8_t optlen) |
97 |
{ |
{ |
98 |
struct pbuf *p; |
struct pbuf *p; |
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 | 2, ("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; |
191 |
* instead of PBUF_REF here. |
* instead of PBUF_REF here. |
192 |
*/ |
*/ |
193 |
if ((p = pbuf_alloc(PBUF_TRANSPORT, seglen, PBUF_ROM)) == NULL) { |
if ((p = pbuf_alloc(PBUF_TRANSPORT, seglen, PBUF_ROM)) == NULL) { |
194 |
DEBUGF(TCP_OUTPUT_DEBUG | 2, ("tcp_enqueue: could not allocate memory for zero-copy pbuf\n")); |
DEBUGF(TCP_OUTPUT_DEBUG | 2, ("tcp_enqueue: could not allocate memory for zero-copy pbuf\n")); |
195 |
goto memerr; |
goto memerr; |
196 |
} |
} |
197 |
++queuelen; |
++queuelen; |
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; |
208 |
} |
} |
209 |
++queuelen; |
++queuelen; |
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 | 2, ("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 |
|
|
400 |
|
|
401 |
tcphdr->chksum = 0; |
tcphdr->chksum = 0; |
402 |
tcphdr->chksum = inet_chksum_pseudo(p, &(pcb->local_ip), &(pcb->remote_ip), |
tcphdr->chksum = inet_chksum_pseudo(p, &(pcb->local_ip), &(pcb->remote_ip), |
403 |
IP_PROTO_TCP, p->tot_len); |
IP_PROTO_TCP, p->tot_len); |
404 |
|
|
405 |
ip_output(p, &(pcb->local_ip), &(pcb->remote_ip), TCP_TTL, |
ip_output(p, &(pcb->local_ip), &(pcb->remote_ip), TCP_TTL, |
406 |
IP_PROTO_TCP); |
IP_PROTO_TCP); |
407 |
pbuf_free(p); |
pbuf_free(p); |
408 |
|
|
409 |
return ERR_OK; |
return ERR_OK; |
428 |
#endif /* TCP_CWND_DEBUG */ |
#endif /* TCP_CWND_DEBUG */ |
429 |
|
|
430 |
while (seg != NULL && |
while (seg != NULL && |
431 |
ntohl(seg->tcphdr->seqno) - pcb->lastack + seg->len <= wnd) { |
ntohl(seg->tcphdr->seqno) - pcb->lastack + seg->len <= wnd) { |
432 |
#if TCP_CWND_DEBUG |
#if TCP_CWND_DEBUG |
433 |
DEBUGF(TCP_CWND_DEBUG, ("tcp_output: snd_wnd %lu, cwnd %lu, wnd %lu, effwnd %lu, seq %lu, ack %lu, i%d\n", |
DEBUGF(TCP_CWND_DEBUG, ("tcp_output: snd_wnd %lu, cwnd %lu, wnd %lu, effwnd %lu, seq %lu, ack %lu, i%d\n", |
434 |
pcb->snd_wnd, pcb->cwnd, wnd, |
pcb->snd_wnd, pcb->cwnd, wnd, |
455 |
seg->next = NULL; |
seg->next = NULL; |
456 |
if (pcb->unacked == NULL) { |
if (pcb->unacked == NULL) { |
457 |
pcb->unacked = seg; |
pcb->unacked = seg; |
458 |
|
|
459 |
|
|
460 |
} else { |
} else { |
461 |
for (useg = pcb->unacked; useg->next != NULL; useg = useg->next); |
for (useg = pcb->unacked; useg->next != NULL; useg = useg->next); |
462 |
useg->next = seg; |
useg->next = seg; |
506 |
DEBUGF(TCP_RTO_DEBUG, ("tcp_output_segment: rtseq %lu\n", pcb->rtseq)); |
DEBUGF(TCP_RTO_DEBUG, ("tcp_output_segment: rtseq %lu\n", pcb->rtseq)); |
507 |
} |
} |
508 |
DEBUGF(TCP_OUTPUT_DEBUG, ("tcp_output_segment: %lu:%lu\n", |
DEBUGF(TCP_OUTPUT_DEBUG, ("tcp_output_segment: %lu:%lu\n", |
509 |
htonl(seg->tcphdr->seqno), htonl(seg->tcphdr->seqno) + |
htonl(seg->tcphdr->seqno), htonl(seg->tcphdr->seqno) + |
510 |
seg->len)); |
seg->len)); |
511 |
|
|
512 |
len = (u16_t)((u8_t *)seg->tcphdr - (u8_t *)seg->p->payload); |
len = (u16_t)((u8_t *)seg->tcphdr - (u8_t *)seg->p->payload); |
513 |
|
|
518 |
|
|
519 |
seg->tcphdr->chksum = 0; |
seg->tcphdr->chksum = 0; |
520 |
seg->tcphdr->chksum = inet_chksum_pseudo(seg->p, |
seg->tcphdr->chksum = inet_chksum_pseudo(seg->p, |
521 |
&(pcb->local_ip), |
&(pcb->local_ip), |
522 |
&(pcb->remote_ip), |
&(pcb->remote_ip), |
523 |
IP_PROTO_TCP, seg->p->tot_len); |
IP_PROTO_TCP, seg->p->tot_len); |
524 |
#ifdef TCP_STATS |
#ifdef TCP_STATS |
525 |
++lwip_stats.tcp.xmit; |
++lwip_stats.tcp.xmit; |
526 |
#endif /* TCP_STATS */ |
#endif /* TCP_STATS */ |
527 |
|
|
528 |
ip_output(seg->p, &(pcb->local_ip), &(pcb->remote_ip), TCP_TTL, |
ip_output(seg->p, &(pcb->local_ip), &(pcb->remote_ip), TCP_TTL, |
529 |
IP_PROTO_TCP); |
IP_PROTO_TCP); |
530 |
} |
} |
531 |
/*-----------------------------------------------------------------------------------*/ |
/*-----------------------------------------------------------------------------------*/ |
532 |
void |
void |
533 |
tcp_rst(u32_t seqno, u32_t ackno, |
tcp_rst(u32_t seqno, u32_t ackno, |
534 |
struct ip_addr *local_ip, struct ip_addr *remote_ip, |
struct ip_addr *local_ip, struct ip_addr *remote_ip, |
535 |
u16_t local_port, u16_t remote_port) |
u16_t local_port, u16_t remote_port) |
536 |
{ |
{ |
537 |
struct pbuf *p; |
struct pbuf *p; |
538 |
struct tcp_hdr *tcphdr; |
struct tcp_hdr *tcphdr; |
554 |
|
|
555 |
tcphdr->chksum = 0; |
tcphdr->chksum = 0; |
556 |
tcphdr->chksum = inet_chksum_pseudo(p, local_ip, remote_ip, |
tcphdr->chksum = inet_chksum_pseudo(p, local_ip, remote_ip, |
557 |
IP_PROTO_TCP, p->tot_len); |
IP_PROTO_TCP, p->tot_len); |
558 |
|
|
559 |
#ifdef TCP_STATS |
#ifdef TCP_STATS |
560 |
++lwip_stats.tcp.xmit; |
++lwip_stats.tcp.xmit; |