Changed tcp_pcb->snd_queuelen from u8_t to u16_t to prevent overflowing when sending many small packets with big send buffer, added assertions and oveflow checks for snd_queuelen.

This commit is contained in:
goldsimon 2007-07-01 15:56:04 +00:00
parent d7c50f56d7
commit 9abbb581c5
3 changed files with 12 additions and 9 deletions

View File

@ -513,6 +513,7 @@ tcp_process(struct tcp_pcb *pcb)
pcb->snd_wl1 = seqno - 1; /* initialise to seqno - 1 to force window update */
pcb->state = ESTABLISHED;
pcb->cwnd = pcb->mss;
LWIP_ASSERT("pcb->snd_queuelen > 0", (pcb->snd_queuelen > 0));
--pcb->snd_queuelen;
LWIP_DEBUGF(TCP_QLEN_DEBUG, ("tcp_process: SYN-SENT --queuelen %"U16_F"\n", (u16_t)pcb->snd_queuelen));
rseg = pcb->unacked;
@ -790,6 +791,7 @@ tcp_receive(struct tcp_pcb *pcb)
pcb->unacked = pcb->unacked->next;
LWIP_DEBUGF(TCP_QLEN_DEBUG, ("tcp_receive: queuelen %"U16_F" ... ", (u16_t)pcb->snd_queuelen));
LWIP_ASSERT("pcb->snd_queuelen >= pbuf_clen(next->p)", (pcb->snd_queuelen >= pbuf_clen(next->p)));
pcb->snd_queuelen -= pbuf_clen(next->p);
tcp_seg_free(next);
@ -828,6 +830,7 @@ tcp_receive(struct tcp_pcb *pcb)
next = pcb->unsent;
pcb->unsent = pcb->unsent->next;
LWIP_DEBUGF(TCP_QLEN_DEBUG, ("tcp_receive: queuelen %"U16_F" ... ", (u16_t)pcb->snd_queuelen));
LWIP_ASSERT("pcb->snd_queuelen >= pbuf_clen(next->p)", (pcb->snd_queuelen >= pbuf_clen(next->p)));
pcb->snd_queuelen -= pbuf_clen(next->p);
tcp_seg_free(next);
LWIP_DEBUGF(TCP_QLEN_DEBUG, ("%"U16_F" (after freeing unsent)\n", (u16_t)pcb->snd_queuelen));

View File

@ -133,7 +133,7 @@ tcp_enqueue(struct tcp_pcb *pcb, void *arg, u16_t len,
u32_t seqno;
u16_t left, seglen;
void *ptr;
u8_t queuelen;
u16_t queuelen;
LWIP_DEBUGF(TCP_OUTPUT_DEBUG, ("tcp_enqueue(pcb=%p, arg=%p, len=%"U16_F", flags=%"X16_F", copy=%"U16_F")\n",
(void *)pcb, arg, len, (u16_t)flags, (u16_t)copy));
@ -158,8 +158,8 @@ tcp_enqueue(struct tcp_pcb *pcb, void *arg, u16_t len,
/* If total number of pbufs on the unsent/unacked queues exceeds the
* configured maximum, return an error */
queuelen = pcb->snd_queuelen;
/* check for configured max queuelen and possible overflow of u8_t */
if ((queuelen >= TCP_SND_QUEUELEN) || (queuelen > 253)) {
/* check for configured max queuelen and possible overflow */
if ((queuelen >= TCP_SND_QUEUELEN) || (queuelen > TCP_SNDQUEUELEN_OVERFLOW)) {
LWIP_DEBUGF(TCP_OUTPUT_DEBUG | 3, ("tcp_enqueue: too long queue %"U16_F" (max %"U16_F")\n", queuelen, TCP_SND_QUEUELEN));
TCP_STATS_INC(tcp.memerr);
return ERR_MEM;
@ -261,9 +261,8 @@ tcp_enqueue(struct tcp_pcb *pcb, void *arg, u16_t len,
}
/* Now that there are more segments queued, we check again if the
length of the queue exceeds the configured maximum. */
/* check for configured max queuelen and possible overflow of u8_t */
if ((queuelen > TCP_SND_QUEUELEN) || (queuelen > 253)) {
length of the queue exceeds the configured maximum or overflows. */
if ((queuelen > TCP_SND_QUEUELEN) || (queuelen > TCP_SNDQUEUELEN_OVERFLOW)) {
LWIP_DEBUGF(TCP_OUTPUT_DEBUG | 2, ("tcp_enqueue: queue too long %"U16_F" (%"U16_F")\n", queuelen, TCP_SND_QUEUELEN));
goto memerr;
}

View File

@ -118,8 +118,8 @@ void tcp_rexmit_rto (struct tcp_pcb *pcb);
* unacknowledged.
*/
#define tcp_output_nagle(tpcb) ((((tpcb)->unacked == NULL) || \
((tpcb)->flags & TF_NODELAY) || \
(((tpcb)->unsent != NULL) && ((tpcb)->unsent->next != NULL))) ? \
((tpcb)->flags & TF_NODELAY) || \
(((tpcb)->unsent != NULL) && ((tpcb)->unsent->next != NULL))) ? \
tcp_output(tpcb) : ERR_OK)
@ -302,7 +302,8 @@ struct tcp_pcb {
u16_t acked;
u16_t snd_buf; /* Available buffer space for sending (in bytes). */
u8_t snd_queuelen; /* Available buffer space for sending (in tcp_segs). */
#define TCP_SNDQUEUELEN_OVERFLOW (0xffff-3)
u16_t snd_queuelen; /* Available buffer space for sending (in tcp_segs). */
/* These are ordered by sequence number: */