tcp: fixed bug #50418: LWIP_EVENT_API: fix invalid calbacks for SYN_RCVD pcb

This commit is contained in:
goldsimon 2017-02-28 12:13:26 +01:00
parent d3fc398580
commit f85eed0ab3
4 changed files with 19 additions and 9 deletions

View File

@ -26,6 +26,9 @@ HISTORY
++ Bugfixes:
2017-02-28: David van Moolenbroek/Simon Goldschmidt
tcp: fixed bug #50418: LWIP_EVENT_API: fix invalid calbacks for SYN_RCVD pcb
2017-02-24: Simon Goldschmidt
* sockets.c: fixed close race conditions in lwip_select (for LWIP_NETCONN_FULLDUPLEX)

View File

@ -482,6 +482,7 @@ tcp_abandon(struct tcp_pcb *pcb, int reset)
} else {
int send_rst = 0;
u16_t local_port = 0;
enum tcp_state last_state;
seqno = pcb->snd_nxt;
ackno = pcb->rcv_nxt;
#if LWIP_CALLBACK_API
@ -514,8 +515,9 @@ tcp_abandon(struct tcp_pcb *pcb, int reset)
LWIP_DEBUGF(TCP_RST_DEBUG, ("tcp_abandon: sending RST\n"));
tcp_rst(seqno, ackno, &pcb->local_ip, &pcb->remote_ip, local_port, pcb->remote_port);
}
last_state = pcb->state;
memp_free(MEMP_TCP_PCB, pcb);
TCP_EVENT_ERR(errf, errf_arg, ERR_ABRT);
TCP_EVENT_ERR(last_state, errf, errf_arg, ERR_ABRT);
}
}
@ -1179,6 +1181,7 @@ tcp_slowtmr_start:
tcp_err_fn err_fn = pcb->errf;
#endif /* LWIP_CALLBACK_API */
void *err_arg;
enum tcp_state last_state;
tcp_pcb_purge(pcb);
/* Remove PCB from tcp_active_pcbs list. */
if (prev != NULL) {
@ -1196,12 +1199,13 @@ tcp_slowtmr_start:
}
err_arg = pcb->callback_arg;
last_state = pcb->state;
pcb2 = pcb;
pcb = pcb->next;
memp_free(MEMP_TCP_PCB, pcb2);
tcp_active_pcbs_changed = 0;
TCP_EVENT_ERR(err_fn, err_arg, ERR_ABRT);
TCP_EVENT_ERR(last_state, err_fn, err_arg, ERR_ABRT);
if (tcp_active_pcbs_changed) {
goto tcp_slowtmr_start;
}

View File

@ -378,7 +378,7 @@ tcp_input(struct pbuf *p, struct netif *inp)
end. We then call the error callback to inform the
application that the connection is dead before we
deallocate the PCB. */
TCP_EVENT_ERR(pcb->errf, pcb->callback_arg, ERR_RST);
TCP_EVENT_ERR(pcb->state, pcb->errf, pcb->callback_arg, ERR_RST);
tcp_pcb_remove(&tcp_active_pcbs, pcb);
memp_free(MEMP_TCP_PCB, pcb);
} else {
@ -413,7 +413,7 @@ tcp_input(struct pbuf *p, struct netif *inp)
/* Connection closed although the application has only shut down the
tx side: call the PCB's err callback and indicate the closure to
ensure the application doesn't continue using the PCB. */
TCP_EVENT_ERR(pcb->errf, pcb->callback_arg, ERR_CLSD);
TCP_EVENT_ERR(pcb->state, pcb->errf, pcb->callback_arg, ERR_CLSD);
}
tcp_pcb_remove(&tcp_active_pcbs, pcb);
memp_free(MEMP_TCP_PCB, pcb);

View File

@ -170,10 +170,12 @@ err_t tcp_process_refused_data(struct tcp_pcb *pcb);
LWIP_EVENT_RECV, NULL, 0, ERR_OK)
#define TCP_EVENT_CONNECTED(pcb,err,ret) ret = lwip_tcp_event((pcb)->callback_arg, (pcb),\
LWIP_EVENT_CONNECTED, NULL, 0, (err))
#define TCP_EVENT_POLL(pcb,ret) ret = lwip_tcp_event((pcb)->callback_arg, (pcb),\
LWIP_EVENT_POLL, NULL, 0, ERR_OK)
#define TCP_EVENT_ERR(errf,arg,err) lwip_tcp_event((arg), NULL, \
LWIP_EVENT_ERR, NULL, 0, (err))
#define TCP_EVENT_POLL(pcb,ret) do { if ((pcb)->state != SYN_RCVD) { \
ret = lwip_tcp_event((pcb)->callback_arg, (pcb), LWIP_EVENT_POLL, NULL, 0, ERR_OK); \
} else { \
ret = ERR_ARG; } } while(0)
#define TCP_EVENT_ERR(last_state,errf,arg,err) do { if (last_state != SYN_RCVD) { \
lwip_tcp_event((arg), NULL, LWIP_EVENT_ERR, NULL, 0, (err)); } } while(0)
#else /* LWIP_EVENT_API */
@ -223,8 +225,9 @@ err_t tcp_process_refused_data(struct tcp_pcb *pcb);
else (ret) = ERR_OK; \
} while (0)
#define TCP_EVENT_ERR(errf,arg,err) \
#define TCP_EVENT_ERR(last_state,errf,arg,err) \
do { \
LWIP_UNUSED_ARG(last_state); \
if((errf) != NULL) \
(errf)((arg),(err)); \
} while (0)