diff --git a/CHANGELOG b/CHANGELOG index 28d8cbcb..14c6cbe0 100644 --- a/CHANGELOG +++ b/CHANGELOG @@ -117,6 +117,10 @@ HISTORY ++ Bugfixes: + 2014-09-02: Simon Goldschmidt + * err.h/.c, sockets.c, api_msg.c: fixed bug #43110 call getpeername() before + listen() will cause a error + 2014-09-02: Simon Goldschmidt * sockets.c: fixed bug #42117 lwip_fcntl does not set errno diff --git a/src/api/api_msg.c b/src/api/api_msg.c index f3e4f9a3..d497ed5c 100644 --- a/src/api/api_msg.c +++ b/src/api/api_msg.c @@ -1074,7 +1074,7 @@ lwip_netconn_do_disconnect(struct api_msg_msg *msg) void lwip_netconn_do_listen(struct api_msg_msg *msg) { - if (ERR_IS_FATAL(msg->conn->last_err)) { + if (ERR_IS_FATAL_LISTENCONNECT(msg->conn->last_err)) { msg->err = msg->conn->last_err; } else { msg->err = ERR_CONN; @@ -1082,45 +1082,50 @@ lwip_netconn_do_listen(struct api_msg_msg *msg) if (NETCONNTYPE_GROUP(msg->conn->type) == NETCONN_TCP) { if (msg->conn->state == NETCONN_NONE) { struct tcp_pcb* lpcb; -#if LWIP_IPV6 - if ((msg->conn->flags & NETCONN_FLAG_IPV6_V6ONLY) == 0) { -#if TCP_LISTEN_BACKLOG - lpcb = tcp_listen_dual_with_backlog(msg->conn->pcb.tcp, msg->msg.lb.backlog); -#else /* TCP_LISTEN_BACKLOG */ - lpcb = tcp_listen_dual(msg->conn->pcb.tcp); -#endif /* TCP_LISTEN_BACKLOG */ - } else -#endif /* LWIP_IPV6 */ - { -#if TCP_LISTEN_BACKLOG - lpcb = tcp_listen_with_backlog(msg->conn->pcb.tcp, msg->msg.lb.backlog); -#else /* TCP_LISTEN_BACKLOG */ - lpcb = tcp_listen(msg->conn->pcb.tcp); -#endif /* TCP_LISTEN_BACKLOG */ - } - if (lpcb == NULL) { - /* in this case, the old pcb is still allocated */ - msg->err = ERR_MEM; + if (msg->conn->pcb.tcp->state != CLOSED) { + /* connection is not closed, cannot listen */ + msg->err = ERR_VAL; } else { - /* delete the recvmbox and allocate the acceptmbox */ - if (sys_mbox_valid(&msg->conn->recvmbox)) { - /** @todo: should we drain the recvmbox here? */ - sys_mbox_free(&msg->conn->recvmbox); - sys_mbox_set_invalid(&msg->conn->recvmbox); +#if LWIP_IPV6 + if ((msg->conn->flags & NETCONN_FLAG_IPV6_V6ONLY) == 0) { +#if TCP_LISTEN_BACKLOG + lpcb = tcp_listen_dual_with_backlog(msg->conn->pcb.tcp, msg->msg.lb.backlog); +#else /* TCP_LISTEN_BACKLOG */ + lpcb = tcp_listen_dual(msg->conn->pcb.tcp); +#endif /* TCP_LISTEN_BACKLOG */ + } else +#endif /* LWIP_IPV6 */ + { +#if TCP_LISTEN_BACKLOG + lpcb = tcp_listen_with_backlog(msg->conn->pcb.tcp, msg->msg.lb.backlog); +#else /* TCP_LISTEN_BACKLOG */ + lpcb = tcp_listen(msg->conn->pcb.tcp); +#endif /* TCP_LISTEN_BACKLOG */ } - msg->err = ERR_OK; - if (!sys_mbox_valid(&msg->conn->acceptmbox)) { - msg->err = sys_mbox_new(&msg->conn->acceptmbox, DEFAULT_ACCEPTMBOX_SIZE); - } - if (msg->err == ERR_OK) { - msg->conn->state = NETCONN_LISTEN; - msg->conn->pcb.tcp = lpcb; - tcp_arg(msg->conn->pcb.tcp, msg->conn); - tcp_accept(msg->conn->pcb.tcp, accept_function); + if (lpcb == NULL) { + /* in this case, the old pcb is still allocated */ + msg->err = ERR_MEM; } else { - /* since the old pcb is already deallocated, free lpcb now */ - tcp_close(lpcb); - msg->conn->pcb.tcp = NULL; + /* delete the recvmbox and allocate the acceptmbox */ + if (sys_mbox_valid(&msg->conn->recvmbox)) { + /** @todo: should we drain the recvmbox here? */ + sys_mbox_free(&msg->conn->recvmbox); + sys_mbox_set_invalid(&msg->conn->recvmbox); + } + msg->err = ERR_OK; + if (!sys_mbox_valid(&msg->conn->acceptmbox)) { + msg->err = sys_mbox_new(&msg->conn->acceptmbox, DEFAULT_ACCEPTMBOX_SIZE); + } + if (msg->err == ERR_OK) { + msg->conn->state = NETCONN_LISTEN; + msg->conn->pcb.tcp = lpcb; + tcp_arg(msg->conn->pcb.tcp, msg->conn); + tcp_accept(msg->conn->pcb.tcp, accept_function); + } else { + /* since the old pcb is already deallocated, free lpcb now */ + tcp_close(lpcb); + msg->conn->pcb.tcp = NULL; + } } } } diff --git a/src/api/err.c b/src/api/err.c index 92fa8b7d..e9701018 100644 --- a/src/api/err.c +++ b/src/api/err.c @@ -51,10 +51,10 @@ static const char *err_strerr[] = { "Operation would block.", /* ERR_WOULDBLOCK -7 */ "Address in use.", /* ERR_USE -8 */ "Already connected.", /* ERR_ISCONN -9 */ - "Connection aborted.", /* ERR_ABRT -10 */ - "Connection reset.", /* ERR_RST -11 */ - "Connection closed.", /* ERR_CLSD -12 */ - "Not connected.", /* ERR_CONN -13 */ + "Not connected.", /* ERR_CONN -10 */ + "Connection aborted.", /* ERR_ABRT -11 */ + "Connection reset.", /* ERR_RST -12 */ + "Connection closed.", /* ERR_CLSD -13 */ "Illegal argument.", /* ERR_ARG -14 */ "Low-level netif error.", /* ERR_IF -15 */ }; diff --git a/src/api/sockets.c b/src/api/sockets.c index cbdb4009..14718170 100644 --- a/src/api/sockets.c +++ b/src/api/sockets.c @@ -208,10 +208,10 @@ static const int err_to_errno_table[] = { EWOULDBLOCK, /* ERR_WOULDBLOCK -7 Operation would block. */ EADDRINUSE, /* ERR_USE -8 Address in use. */ EALREADY, /* ERR_ISCONN -9 Already connected. */ - ECONNABORTED, /* ERR_ABRT -10 Connection aborted. */ - ECONNRESET, /* ERR_RST -11 Connection reset. */ - ENOTCONN, /* ERR_CLSD -12 Connection closed. */ - ENOTCONN, /* ERR_CONN -13 Not connected. */ + ENOTCONN, /* ERR_CONN -10 Not connected. */ + ECONNABORTED, /* ERR_ABRT -11 Connection aborted. */ + ECONNRESET, /* ERR_RST -12 Connection reset. */ + ENOTCONN, /* ERR_CLSD -13 Connection closed. */ EIO, /* ERR_ARG -14 Illegal argument. */ -1, /* ERR_IF -15 Low-level netif error */ }; diff --git a/src/include/lwip/err.h b/src/include/lwip/err.h index d12d5894..a48430d2 100644 --- a/src/include/lwip/err.h +++ b/src/include/lwip/err.h @@ -62,10 +62,12 @@ typedef s8_t err_t; #define ERR_IS_FATAL(e) ((e) < ERR_ISCONN) -#define ERR_ABRT -10 /* Connection aborted. */ -#define ERR_RST -11 /* Connection reset. */ -#define ERR_CLSD -12 /* Connection closed. */ -#define ERR_CONN -13 /* Not connected. */ +#define ERR_CONN -10 /* Not connected. */ +#define ERR_IS_FATAL_LISTENCONNECT(e) ((e) < ERR_CONN) + +#define ERR_ABRT -11 /* Connection aborted. */ +#define ERR_RST -12 /* Connection reset. */ +#define ERR_CLSD -13 /* Connection closed. */ #define ERR_ARG -14 /* Illegal argument. */