Skip to content

Commit

Permalink
lwip: Fix lwip bug #48476 found by me while looking at the code (TCP …
Browse files Browse the repository at this point in the history
…sent callback called wrongly due to picking up old pcb->acked).

The fix is to initialize acked to 0 before calling tcp_process. Also replacing pcb->acked with a static variable.
  • Loading branch information
ambrop72 committed Jul 11, 2016
1 parent caf68ac commit 4abf387
Show file tree
Hide file tree
Showing 2 changed files with 17 additions and 20 deletions.
35 changes: 17 additions & 18 deletions lwip/src/core/tcp_in.c
Expand Up @@ -80,6 +80,8 @@ static u16_t tcplen;
static u8_t recv_flags;
static struct pbuf *recv_data;

static tcpwnd_size_t tcp_acked;

struct tcp_pcb *tcp_input_pcb;

/* Forward declarations. */
Expand Down Expand Up @@ -354,6 +356,7 @@ tcp_input(struct pbuf *p, struct netif *inp)

recv_data = NULL;
recv_flags = 0;
tcp_acked = 0;

if (flags & TCP_PSH) {
p->flags |= PBUF_FLAG_PUSH;
Expand All @@ -368,14 +371,10 @@ tcp_input(struct pbuf *p, struct netif *inp)
/* If the application has registered a "sent" function to be
called when new send buffer space is available, we call it
now. */
if (pcb->acked > 0) {
u16_t acked;
{
acked = pcb->acked;
TCP_EVENT_SENT(pcb, (u16_t)acked, err);
if (err == ERR_ABRT) {
goto aborted;
}
if (tcp_acked > 0) {
TCP_EVENT_SENT(pcb, tcp_acked, err);
if (err == ERR_ABRT) {
goto aborted;
}
}
if (recv_flags & TF_CLOSED) {
Expand Down Expand Up @@ -781,8 +780,8 @@ tcp_process(struct tcp_pcb *pcb)
pcb->ssthresh = LWIP_TCP_INITIAL_SSTHRESH(pcb);

/* Prevent ACK for SYN to generate a sent event */
if (pcb->acked != 0) {
pcb->acked--;
if (tcp_acked != 0) {
tcp_acked--;
}

pcb->cwnd = LWIP_TCP_CALC_INITIAL_CWND(pcb->mss);
Expand Down Expand Up @@ -943,7 +942,7 @@ tcp_receive(struct tcp_pcb *pcb)

/* Clause 1 */
if (TCP_SEQ_LEQ(ackno, pcb->lastack)) {
pcb->acked = 0;
tcp_acked = 0;
/* Clause 2 */
if (tcplen == 0) {
/* Clause 3 */
Expand Down Expand Up @@ -994,9 +993,9 @@ tcp_receive(struct tcp_pcb *pcb)

/* Update the send buffer space. Diff between the two can never exceed 64K
unless window scaling is used. */
pcb->acked = (tcpwnd_size_t)(ackno - pcb->lastack);
tcp_acked = (tcpwnd_size_t)(ackno - pcb->lastack);

pcb->snd_buf += pcb->acked;
pcb->snd_buf += tcp_acked;

/* Reset the fast retransmit variables. */
pcb->dupacks = 0;
Expand Down Expand Up @@ -1041,8 +1040,8 @@ tcp_receive(struct tcp_pcb *pcb)
LWIP_DEBUGF(TCP_QLEN_DEBUG, ("tcp_receive: queuelen %"TCPWNDSIZE_F" ... ", (tcpwnd_size_t)pcb->snd_queuelen));
LWIP_ASSERT("pcb->snd_queuelen >= pbuf_clen(next->p)", (pcb->snd_queuelen >= pbuf_clen(next->p)));
/* Prevent ACK for FIN to generate a sent event */
if ((pcb->acked != 0) && ((TCPH_FLAGS(next->tcphdr) & TCP_FIN) != 0)) {
pcb->acked--;
if ((tcp_acked != 0) && ((TCPH_FLAGS(next->tcphdr) & TCP_FIN) != 0)) {
tcp_acked--;
}

pcb->snd_queuelen -= pbuf_clen(next->p);
Expand Down Expand Up @@ -1071,7 +1070,7 @@ tcp_receive(struct tcp_pcb *pcb)
#endif /* LWIP_IPV6 && LWIP_ND6_TCP_REACHABILITY_HINTS*/
} else {
/* Out of sequence ACK, didn't really ack anything */
pcb->acked = 0;
tcp_acked = 0;
tcp_send_empty_ack(pcb);
}

Expand All @@ -1093,8 +1092,8 @@ tcp_receive(struct tcp_pcb *pcb)
LWIP_DEBUGF(TCP_QLEN_DEBUG, ("tcp_receive: queuelen %"TCPWNDSIZE_F" ... ", (tcpwnd_size_t)pcb->snd_queuelen));
LWIP_ASSERT("pcb->snd_queuelen >= pbuf_clen(next->p)", (pcb->snd_queuelen >= pbuf_clen(next->p)));
/* Prevent ACK for FIN to generate a sent event */
if ((pcb->acked != 0) && ((TCPH_FLAGS(next->tcphdr) & TCP_FIN) != 0)) {
pcb->acked--;
if ((tcp_acked != 0) && ((TCPH_FLAGS(next->tcphdr) & TCP_FIN) != 0)) {
tcp_acked--;
}
pcb->snd_queuelen -= pbuf_clen(next->p);
tcp_seg_free(next);
Expand Down
2 changes: 0 additions & 2 deletions lwip/src/include/lwip/tcp.h
Expand Up @@ -237,8 +237,6 @@ struct tcp_pcb {
tcpwnd_size_t snd_wnd; /* sender window */
tcpwnd_size_t snd_wnd_max; /* the maximum sender window announced by the remote host */

tcpwnd_size_t acked;

tcpwnd_size_t snd_buf; /* Available buffer space for sending (in bytes). */
#define TCP_SNDQUEUELEN_OVERFLOW (0xffffU-3)
u16_t snd_queuelen; /* Available buffer space for sending (in pbufs). */
Expand Down

0 comments on commit 4abf387

Please sign in to comment.