mirror of
https://github.com/lwip-tcpip/lwip.git
synced 2024-10-02 12:52:10 +00:00
added function tcp_listen_with_backlog_and_err() to get the error reason when listening fails (bug #49861)
This commit is contained in:
parent
1884c7e83f
commit
98fc82fa71
@ -6,8 +6,12 @@ HISTORY
|
|||||||
|
|
||||||
++ New features:
|
++ New features:
|
||||||
|
|
||||||
|
2016-12-31: Simon Goldschmidt
|
||||||
|
* tcp.h/.c: added function tcp_listen_with_backlog_and_err() to get the error
|
||||||
|
reason when listening fails (bug #49861)
|
||||||
|
|
||||||
2016-12-14: Jan Breuer:
|
2016-12-14: Jan Breuer:
|
||||||
opt.h, ndc.h/.c: add support for RDNSS option (as per RFC 6106)
|
* opt.h, ndc.h/.c: add support for RDNSS option (as per RFC 6106)
|
||||||
|
|
||||||
2016-12-14: David van Moolenbroek
|
2016-12-14: David van Moolenbroek
|
||||||
* opt.h, nd6.c: Added LWIP_HOOK_ND6_GET_GW()
|
* opt.h, nd6.c: Added LWIP_HOOK_ND6_GET_GW()
|
||||||
|
@ -1307,6 +1307,13 @@ lwip_netconn_do_listen(void *m)
|
|||||||
/* connection is not closed, cannot listen */
|
/* connection is not closed, cannot listen */
|
||||||
msg->err = ERR_VAL;
|
msg->err = ERR_VAL;
|
||||||
} else {
|
} else {
|
||||||
|
err_t err;
|
||||||
|
u8_t backlog;
|
||||||
|
#if TCP_LISTEN_BACKLOG
|
||||||
|
backlog = msg->msg.lb.backlog;
|
||||||
|
#else /* TCP_LISTEN_BACKLOG */
|
||||||
|
backlog = TCP_DEFAULT_LISTEN_BACKLOG;
|
||||||
|
#endif /* TCP_LISTEN_BACKLOG */
|
||||||
#if LWIP_IPV4 && LWIP_IPV6
|
#if LWIP_IPV4 && LWIP_IPV6
|
||||||
/* "Socket API like" dual-stack support: If IP to listen to is IP6_ADDR_ANY,
|
/* "Socket API like" dual-stack support: If IP to listen to is IP6_ADDR_ANY,
|
||||||
* and NETCONN_FLAG_IPV6_V6ONLY is NOT set, use IP_ANY_TYPE to listen
|
* and NETCONN_FLAG_IPV6_V6ONLY is NOT set, use IP_ANY_TYPE to listen
|
||||||
@ -1319,15 +1326,11 @@ lwip_netconn_do_listen(void *m)
|
|||||||
}
|
}
|
||||||
#endif /* LWIP_IPV4 && LWIP_IPV6 */
|
#endif /* LWIP_IPV4 && LWIP_IPV6 */
|
||||||
|
|
||||||
#if TCP_LISTEN_BACKLOG
|
lpcb = tcp_listen_with_backlog_and_err(msg->conn->pcb.tcp, backlog, &err);
|
||||||
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) {
|
if (lpcb == NULL) {
|
||||||
/* in this case, the old pcb is still allocated */
|
/* in this case, the old pcb is still allocated */
|
||||||
msg->err = ERR_MEM;
|
msg->err = err;
|
||||||
} else {
|
} else {
|
||||||
/* delete the recvmbox and allocate the acceptmbox */
|
/* delete the recvmbox and allocate the acceptmbox */
|
||||||
if (sys_mbox_valid(&msg->conn->recvmbox)) {
|
if (sys_mbox_valid(&msg->conn->recvmbox)) {
|
||||||
|
@ -636,19 +636,44 @@ tcp_accept_null(void *arg, struct tcp_pcb *pcb, err_t err)
|
|||||||
*
|
*
|
||||||
* @note The original tcp_pcb is freed. This function therefore has to be
|
* @note The original tcp_pcb is freed. This function therefore has to be
|
||||||
* called like this:
|
* called like this:
|
||||||
* tpcb = tcp_listen(tpcb);
|
* tpcb = tcp_listen_with_backlog(tpcb, backlog);
|
||||||
*/
|
*/
|
||||||
struct tcp_pcb *
|
struct tcp_pcb *
|
||||||
tcp_listen_with_backlog(struct tcp_pcb *pcb, u8_t backlog)
|
tcp_listen_with_backlog(struct tcp_pcb *pcb, u8_t backlog)
|
||||||
{
|
{
|
||||||
struct tcp_pcb_listen *lpcb;
|
return tcp_listen_with_backlog_and_err(pcb, backlog, NULL);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @ingroup tcp_raw
|
||||||
|
* Set the state of the connection to be LISTEN, which means that it
|
||||||
|
* is able to accept incoming connections. The protocol control block
|
||||||
|
* is reallocated in order to consume less memory. Setting the
|
||||||
|
* connection to LISTEN is an irreversible process.
|
||||||
|
*
|
||||||
|
* @param pcb the original tcp_pcb
|
||||||
|
* @param backlog the incoming connections queue limit
|
||||||
|
* @param err when NULL is returned, this contains the error reason
|
||||||
|
* @return tcp_pcb used for listening, consumes less memory.
|
||||||
|
*
|
||||||
|
* @note The original tcp_pcb is freed. This function therefore has to be
|
||||||
|
* called like this:
|
||||||
|
* tpcb = tcp_listen_with_backlog_and_err(tpcb, backlog, &err);
|
||||||
|
*/
|
||||||
|
struct tcp_pcb *
|
||||||
|
tcp_listen_with_backlog_and_err(struct tcp_pcb *pcb, u8_t backlog, err_t *err)
|
||||||
|
{
|
||||||
|
struct tcp_pcb_listen *lpcb = NULL;
|
||||||
|
err_t res;
|
||||||
|
|
||||||
LWIP_UNUSED_ARG(backlog);
|
LWIP_UNUSED_ARG(backlog);
|
||||||
LWIP_ERROR("tcp_listen: pcb already connected", pcb->state == CLOSED, return NULL);
|
LWIP_ERROR("tcp_listen: pcb already connected", pcb->state == CLOSED, res = ERR_CLSD; goto done);
|
||||||
|
|
||||||
/* already listening? */
|
/* already listening? */
|
||||||
if (pcb->state == LISTEN) {
|
if (pcb->state == LISTEN) {
|
||||||
return pcb;
|
lpcb = (struct tcp_pcb_listen*)pcb;
|
||||||
|
res = ERR_ALREADY;
|
||||||
|
goto done;
|
||||||
}
|
}
|
||||||
#if SO_REUSE
|
#if SO_REUSE
|
||||||
if (ip_get_option(pcb, SOF_REUSEADDR)) {
|
if (ip_get_option(pcb, SOF_REUSEADDR)) {
|
||||||
@ -659,14 +684,16 @@ tcp_listen_with_backlog(struct tcp_pcb *pcb, u8_t backlog)
|
|||||||
if ((lpcb->local_port == pcb->local_port) &&
|
if ((lpcb->local_port == pcb->local_port) &&
|
||||||
ip_addr_cmp(&lpcb->local_ip, &pcb->local_ip)) {
|
ip_addr_cmp(&lpcb->local_ip, &pcb->local_ip)) {
|
||||||
/* this address/port is already used */
|
/* this address/port is already used */
|
||||||
return NULL;
|
res = ERR_USE;
|
||||||
|
goto done;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
#endif /* SO_REUSE */
|
#endif /* SO_REUSE */
|
||||||
lpcb = (struct tcp_pcb_listen *)memp_malloc(MEMP_TCP_PCB_LISTEN);
|
lpcb = (struct tcp_pcb_listen *)memp_malloc(MEMP_TCP_PCB_LISTEN);
|
||||||
if (lpcb == NULL) {
|
if (lpcb == NULL) {
|
||||||
return NULL;
|
res = ERR_MEM;
|
||||||
|
goto done;
|
||||||
}
|
}
|
||||||
lpcb->callback_arg = pcb->callback_arg;
|
lpcb->callback_arg = pcb->callback_arg;
|
||||||
lpcb->local_port = pcb->local_port;
|
lpcb->local_port = pcb->local_port;
|
||||||
@ -691,6 +718,11 @@ tcp_listen_with_backlog(struct tcp_pcb *pcb, u8_t backlog)
|
|||||||
tcp_backlog_set(lpcb, backlog);
|
tcp_backlog_set(lpcb, backlog);
|
||||||
#endif /* TCP_LISTEN_BACKLOG */
|
#endif /* TCP_LISTEN_BACKLOG */
|
||||||
TCP_REG(&tcp_listen_pcbs.pcbs, (struct tcp_pcb *)lpcb);
|
TCP_REG(&tcp_listen_pcbs.pcbs, (struct tcp_pcb *)lpcb);
|
||||||
|
res = ERR_OK;
|
||||||
|
done:
|
||||||
|
if (err != NULL) {
|
||||||
|
*err = res;
|
||||||
|
}
|
||||||
return (struct tcp_pcb *)lpcb;
|
return (struct tcp_pcb *)lpcb;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -387,6 +387,7 @@ err_t tcp_bind (struct tcp_pcb *pcb, const ip_addr_t *ipaddr,
|
|||||||
err_t tcp_connect (struct tcp_pcb *pcb, const ip_addr_t *ipaddr,
|
err_t tcp_connect (struct tcp_pcb *pcb, const ip_addr_t *ipaddr,
|
||||||
u16_t port, tcp_connected_fn connected);
|
u16_t port, tcp_connected_fn connected);
|
||||||
|
|
||||||
|
struct tcp_pcb * tcp_listen_with_backlog_and_err(struct tcp_pcb *pcb, u8_t backlog, err_t *err);
|
||||||
struct tcp_pcb * tcp_listen_with_backlog(struct tcp_pcb *pcb, u8_t backlog);
|
struct tcp_pcb * tcp_listen_with_backlog(struct tcp_pcb *pcb, u8_t backlog);
|
||||||
/** @ingroup tcp_raw */
|
/** @ingroup tcp_raw */
|
||||||
#define tcp_listen(pcb) tcp_listen_with_backlog(pcb, TCP_DEFAULT_LISTEN_BACKLOG)
|
#define tcp_listen(pcb) tcp_listen_with_backlog(pcb, TCP_DEFAULT_LISTEN_BACKLOG)
|
||||||
|
Loading…
Reference in New Issue
Block a user