From 7721b20179dad3ae9c51bbcabc4dbb3ad82b6ff5 Mon Sep 17 00:00:00 2001 From: sg Date: Wed, 23 Mar 2016 21:57:38 +0100 Subject: [PATCH] call accept-callback with ERR_MEM when allocating a pcb fails on passive open to inform the application about this error; ATTENTION: applications have to handle NULL pcb in accept callback! --- CHANGELOG | 5 +++++ src/api/api_msg.c | 8 ++++++++ src/apps/httpd/httpd.c | 4 ++++ src/core/tcp_in.c | 4 +++- src/include/lwip/priv/tcp_priv.h | 12 ++++++------ 5 files changed, 26 insertions(+), 7 deletions(-) diff --git a/CHANGELOG b/CHANGELOG index 24fd8f00..962850af 100644 --- a/CHANGELOG +++ b/CHANGELOG @@ -6,6 +6,11 @@ HISTORY ++ New features: + 2016-03-23: Simon Goldschmidt + * tcp: call accept-callback with ERR_MEM when allocating a pcb fails on + passive open to inform the application about this error + ATTENTION: applications have to handle NULL pcb in accept callback! + 2016-02-22: Ivan Delamer * Initial 6LoWPAN support diff --git a/src/api/api_msg.c b/src/api/api_msg.c index 6a1060b3..96a4023c 100644 --- a/src/api/api_msg.c +++ b/src/api/api_msg.c @@ -468,6 +468,14 @@ accept_function(void *arg, struct tcp_pcb *newpcb, err_t err) LWIP_DEBUGF(API_MSG_DEBUG, ("accept_function: newpcb->tate: %s\n", tcp_debug_state_str(newpcb->state))); + if ((err != ERR_OK) || (arg == NULL)) { + return ERR_VAL; + } + if (newpcb == NULL) { + /* @todo: out-of-pcbs during connect: pass on this error to the application */ + return ERR_VAL; + } + if (!sys_mbox_valid(&conn->acceptmbox)) { LWIP_DEBUGF(API_MSG_DEBUG, ("accept_function: acceptmbox already deleted\n")); return ERR_VAL; diff --git a/src/apps/httpd/httpd.c b/src/apps/httpd/httpd.c index 97c393e2..832dd18f 100644 --- a/src/apps/httpd/httpd.c +++ b/src/apps/httpd/httpd.c @@ -2290,6 +2290,10 @@ http_accept(void *arg, struct tcp_pcb *pcb, err_t err) LWIP_UNUSED_ARG(err); LWIP_DEBUGF(HTTPD_DEBUG, ("http_accept %p / %p\n", (void*)pcb, arg)); + if ((err != ERR_OK) || (pcb == NULL)) { + return ERR_VAL; + } + /* Set priority */ tcp_setprio(pcb, HTTPD_TCP_PRIO); diff --git a/src/core/tcp_in.c b/src/core/tcp_in.c index 3d5cfa0f..be935ccc 100644 --- a/src/core/tcp_in.c +++ b/src/core/tcp_in.c @@ -562,8 +562,10 @@ tcp_listen_input(struct tcp_pcb_listen *pcb) we don't do anything, but rely on the sender will retransmit the SYN at a time when we have more memory available. */ if (npcb == NULL) { + err_t err; LWIP_DEBUGF(TCP_DEBUG, ("tcp_listen_input: could not allocate PCB\n")); TCP_STATS_INC(tcp.memerr); + TCP_EVENT_ACCEPT(pcb, NULL, pcb->callback_arg, ERR_MEM, err); return ERR_MEM; } #if TCP_LISTEN_BACKLOG @@ -794,7 +796,7 @@ tcp_process(struct tcp_pcb *pcb) { tcp_backlog_accepted(pcb); /* Call the accept function. */ - TCP_EVENT_ACCEPT(pcb, ERR_OK, err); + TCP_EVENT_ACCEPT(pcb->listener, pcb, pcb->callback_arg, ERR_OK, err); } if (err != ERR_OK) { /* If the accept function returns with an error, we abort diff --git a/src/include/lwip/priv/tcp_priv.h b/src/include/lwip/priv/tcp_priv.h index 183cee2b..b14e944e 100644 --- a/src/include/lwip/priv/tcp_priv.h +++ b/src/include/lwip/priv/tcp_priv.h @@ -199,7 +199,7 @@ PACK_STRUCT_END #if LWIP_EVENT_API -#define TCP_EVENT_ACCEPT(pcb,err,ret) ret = lwip_tcp_event((pcb)->callback_arg, (pcb),\ +#define TCP_EVENT_ACCEPT(lpcb,pcb,arg,err,ret) ret = lwip_tcp_event(arg, (pcb),\ LWIP_EVENT_ACCEPT, NULL, 0, err) #define TCP_EVENT_SENT(pcb,space,ret) ret = lwip_tcp_event((pcb)->callback_arg, (pcb),\ LWIP_EVENT_SENT, NULL, space, ERR_OK) @@ -216,11 +216,11 @@ PACK_STRUCT_END #else /* LWIP_EVENT_API */ -#define TCP_EVENT_ACCEPT(pcb,err,ret) \ - do { \ - if(((pcb)->listener != NULL) && ((pcb)->listener->accept != NULL)) \ - (ret) = (pcb)->listener->accept((pcb)->callback_arg,(pcb),(err)); \ - else (ret) = ERR_ARG; \ +#define TCP_EVENT_ACCEPT(lpcb,pcb,arg,err,ret) \ + do { \ + if((lpcb != NULL) && ((lpcb)->accept != NULL)) \ + (ret) = (lpcb)->accept((arg),(pcb),(err)); \ + else (ret) = ERR_ARG; \ } while (0) #define TCP_EVENT_SENT(pcb,space,ret) \