mirror of
https://github.com/lwip-tcpip/lwip.git
synced 2024-11-04 14:29:39 +00:00
tcp.h, opt.h, api.h, api_msg.h, tcp.c, tcp_in.c, api_lib.c, api_msg.c, sockets.c, init.c: task #7252: Implement TCP listen backlog: Warning: raw API applications have to call 'tcp_accepted(pcb)' in their accept callback to keep accepting new connections.
This commit is contained in:
parent
48e62e25e9
commit
1ed34774c8
@ -19,6 +19,12 @@ HISTORY
|
||||
|
||||
++ New features:
|
||||
|
||||
2007-12-21 Frédéric Bernon, Simon Goldschmidt, Jonathan Larmour
|
||||
* tcp.h, opt.h, api.h, api_msg.h, tcp.c, tcp_in.c, api_lib.c, api_msg.c,
|
||||
sockets.c, init.c: task #7252: Implement TCP listen backlog: Warning: raw API
|
||||
applications have to call 'tcp_accepted(pcb)' in their accept callback to
|
||||
keep accepting new connections.
|
||||
|
||||
2007-12-13 Frédéric Bernon
|
||||
* api_msg.c, err.h, err.c, sockets.c, dns.c, dns.h: replace "enum dns_result"
|
||||
by err_t type. Add a new err_t code "ERR_INPROGRESS".
|
||||
|
@ -261,16 +261,23 @@ netconn_disconnect(struct netconn *conn)
|
||||
* Set a TCP netconn into listen mode
|
||||
*
|
||||
* @param conn the tcp netconn to set to listen mode
|
||||
* @param backlog the listen backlog (0 = max), only used if LWIP_LISTEN_BACKLOG==1
|
||||
* @return ERR_OK if the netconn was set to listen (UDP and RAW netconns
|
||||
* don't return any error (yet?))
|
||||
*/
|
||||
err_t
|
||||
netconn_listen(struct netconn *conn)
|
||||
netconn_listen_with_backlog(struct netconn *conn, u8_t backlog)
|
||||
{
|
||||
struct api_msg msg;
|
||||
|
||||
/* This does no harm. If LWIP_LISTEN_BACKLOG is off, backlog is unused. */
|
||||
LWIP_UNUSED_ARG(backlog);
|
||||
|
||||
LWIP_ERROR("netconn_listen: invalid conn", (conn != NULL), return ERR_ARG;);
|
||||
|
||||
#if LWIP_LISTEN_BACKLOG
|
||||
msg.msg.msg.lb.backlog = backlog;
|
||||
#endif /* LWIP_LISTEN_BACKLOG */
|
||||
msg.function = do_listen;
|
||||
msg.msg.conn = conn;
|
||||
TCPIP_APIMSG(&msg);
|
||||
@ -292,15 +299,26 @@ netconn_accept(struct netconn *conn)
|
||||
LWIP_ERROR("netconn_accept: invalid acceptmbox", (conn->acceptmbox != SYS_MBOX_NULL), return NULL;);
|
||||
|
||||
#if LWIP_SO_RCVTIMEO
|
||||
if (sys_arch_mbox_fetch(conn->acceptmbox, (void *)&newconn, conn->recv_timeout)==SYS_ARCH_TIMEOUT) {
|
||||
if (sys_arch_mbox_fetch(conn->acceptmbox, (void *)&newconn, conn->recv_timeout) == SYS_ARCH_TIMEOUT) {
|
||||
newconn = NULL;
|
||||
}
|
||||
} else
|
||||
#else
|
||||
sys_arch_mbox_fetch(conn->acceptmbox, (void *)&newconn, 0);
|
||||
#endif /* LWIP_SO_RCVTIMEO*/
|
||||
{
|
||||
/* Register event with callback */
|
||||
API_EVENT(conn, NETCONN_EVT_RCVMINUS, 0);
|
||||
|
||||
/* Register event with callback */
|
||||
API_EVENT(conn, NETCONN_EVT_RCVMINUS, 0);
|
||||
#if LWIP_LISTEN_BACKLOG
|
||||
if (newconn != NULL) {
|
||||
/* Let the stack know that we have accepted the connection. */
|
||||
struct api_msg msg;
|
||||
msg.function = do_recv;
|
||||
msg.msg.conn = conn;
|
||||
TCPIP_APIMSG(&msg);
|
||||
}
|
||||
#endif /* LWIP_LISTEN_BACKLOG */
|
||||
}
|
||||
|
||||
return newconn;
|
||||
}
|
||||
|
@ -735,6 +735,9 @@ do_listen(struct api_msg_msg *msg)
|
||||
if (msg->conn->err == ERR_OK) {
|
||||
msg->conn->state = NETCONN_LISTEN;
|
||||
msg->conn->pcb.tcp = lpcb;
|
||||
#if LWIP_LISTEN_BACKLOG
|
||||
tcp_backlog(lpcb, msg->msg.lb.backlog);
|
||||
#endif /* LWIP_LISTEN_BACKLOG */
|
||||
tcp_arg(msg->conn->pcb.tcp, msg->conn);
|
||||
tcp_accept(msg->conn->pcb.tcp, accept_function);
|
||||
}
|
||||
@ -800,7 +803,14 @@ do_recv(struct api_msg_msg *msg)
|
||||
if (!ERR_IS_FATAL(msg->conn->err)) {
|
||||
if (msg->conn->pcb.tcp != NULL) {
|
||||
if (msg->conn->type == NETCONN_TCP) {
|
||||
tcp_recved(msg->conn->pcb.tcp, msg->msg.r.len);
|
||||
#if LWIP_LISTEN_BACKLOG
|
||||
if (msg->conn->pcb.tcp->state == LISTEN) {
|
||||
tcp_accepted(msg->conn->pcb.tcp);
|
||||
} else
|
||||
#endif /* LWIP_LISTEN_BACKLOG */
|
||||
{
|
||||
tcp_recved(msg->conn->pcb.tcp, msg->msg.r.len);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -430,15 +430,15 @@ lwip_listen(int s, int backlog)
|
||||
struct lwip_socket *sock;
|
||||
err_t err;
|
||||
|
||||
/* This does no harm. If debugging is off, backlog is unused. */
|
||||
LWIP_UNUSED_ARG(backlog);
|
||||
|
||||
LWIP_DEBUGF(SOCKETS_DEBUG, ("lwip_listen(%d, backlog=%d)\n", s, backlog));
|
||||
LWIP_ASSERT("backlog must be between 0 and 255", backlog > 0);
|
||||
LWIP_ASSERT("backlog must be between 0 and 255", backlog <= 0xff);
|
||||
|
||||
sock = get_socket(s);
|
||||
if (!sock)
|
||||
return -1;
|
||||
|
||||
err = netconn_listen(sock->conn);
|
||||
err = netconn_listen_with_backlog(sock->conn, backlog);
|
||||
|
||||
if (err != ERR_OK) {
|
||||
LWIP_DEBUGF(SOCKETS_DEBUG, ("lwip_listen(%d) failed, err=%d\n", s, err));
|
||||
|
@ -152,6 +152,10 @@
|
||||
#if (MEM_USE_POOLS && !MEMP_USE_CUSTOM_POOLS)
|
||||
#error "MEM_USE_POOLS requires custom pools (MEMP_USE_CUSTOM_POOLS) to be enabled in your lwipopts.h"
|
||||
#endif
|
||||
#if (LWIP_DEFAULT_LISTEN_BACKLOG < 0) || (LWIP_DEFAULT_LISTEN_BACKLOG > 255)
|
||||
#error "LWIP_DEFAULT_LISTEN_BACKLOG must fit into an u8_t"
|
||||
#endif
|
||||
|
||||
|
||||
/* Compile-time checks for deprecated options.
|
||||
*/
|
||||
|
@ -368,6 +368,10 @@ tcp_listen(struct tcp_pcb *pcb)
|
||||
#if LWIP_CALLBACK_API
|
||||
lpcb->accept = tcp_accept_null;
|
||||
#endif /* LWIP_CALLBACK_API */
|
||||
#if LWIP_LISTEN_BACKLOG
|
||||
lpcb->accepts_pending = 0;
|
||||
lpcb->backlog = LWIP_DEFAULT_LISTEN_BACKLOG;
|
||||
#endif /* LWIP_LISTEN_BACKLOG */
|
||||
TCP_REG(&tcp_listen_pcbs.listen_pcbs, lpcb);
|
||||
return (struct tcp_pcb *)lpcb;
|
||||
}
|
||||
|
@ -381,6 +381,11 @@ tcp_listen_input(struct tcp_pcb_listen *pcb)
|
||||
tcphdr->dest, tcphdr->src);
|
||||
} else if (flags & TCP_SYN) {
|
||||
LWIP_DEBUGF(TCP_DEBUG, ("TCP connection request %"U16_F" -> %"U16_F".\n", tcphdr->src, tcphdr->dest));
|
||||
#if LWIP_LISTEN_BACKLOG
|
||||
if (pcb->accepts_pending >= pcb->backlog) {
|
||||
return ERR_ABRT;
|
||||
}
|
||||
#endif /* LWIP_LISTEN_BACKLOG */
|
||||
npcb = tcp_alloc(pcb->prio);
|
||||
/* If a new PCB could not be created (probably due to lack of memory),
|
||||
we don't do anything, but rely on the sender will retransmit the
|
||||
@ -390,6 +395,9 @@ tcp_listen_input(struct tcp_pcb_listen *pcb)
|
||||
TCP_STATS_INC(tcp.memerr);
|
||||
return ERR_MEM;
|
||||
}
|
||||
#if LWIP_LISTEN_BACKLOG
|
||||
pcb->accepts_pending++;
|
||||
#endif /* LWIP_LISTEN_BACKLOG */
|
||||
/* Set up the new PCB. */
|
||||
ip_addr_set(&(npcb->local_ip), &(iphdr->dest));
|
||||
npcb->local_port = pcb->local_port;
|
||||
|
@ -179,7 +179,8 @@ err_t netconn_connect (struct netconn *conn,
|
||||
struct ip_addr *addr,
|
||||
u16_t port);
|
||||
err_t netconn_disconnect (struct netconn *conn);
|
||||
err_t netconn_listen (struct netconn *conn);
|
||||
err_t netconn_listen_with_backlog(struct netconn *conn, u8_t backlog);
|
||||
#define netconn_listen(conn) netconn_listen_with_backlog(conn, LWIP_DEFAULT_LISTEN_BACKLOG);
|
||||
struct netconn * netconn_accept (struct netconn *conn);
|
||||
struct netbuf * netconn_recv (struct netconn *conn);
|
||||
err_t netconn_sendto (struct netconn *conn,
|
||||
|
@ -93,6 +93,11 @@ struct api_msg_msg {
|
||||
enum netconn_igmp join_or_leave;
|
||||
} jl;
|
||||
#endif /* LWIP_IGMP */
|
||||
#if LWIP_LISTEN_BACKLOG
|
||||
struct {
|
||||
u8_t backlog;
|
||||
} lb;
|
||||
#endif /* LWIP_LISTEN_BACKLOG */
|
||||
} msg;
|
||||
};
|
||||
|
||||
|
@ -728,6 +728,23 @@
|
||||
#define LWIP_CALLBACK_API 0
|
||||
#endif
|
||||
|
||||
/**
|
||||
* LWIP_LISTEN_BACKLOG: Enable the backlog option for tcp listen pcb.
|
||||
*/
|
||||
#ifndef LWIP_LISTEN_BACKLOG
|
||||
#define LWIP_LISTEN_BACKLOG 1
|
||||
#endif
|
||||
|
||||
/**
|
||||
* The maximum allowed backlog for TCP listen netconns.
|
||||
* This backlog is used unless another is explicitly specified.
|
||||
* 0xff is the maximum (u8_t).
|
||||
*/
|
||||
#ifndef LWIP_DEFAULT_LISTEN_BACKLOG
|
||||
#define LWIP_DEFAULT_LISTEN_BACKLOG 0xff
|
||||
#endif
|
||||
|
||||
|
||||
/*
|
||||
----------------------------------
|
||||
---------- Pbuf options ----------
|
||||
|
@ -79,6 +79,11 @@ void tcp_err (struct tcp_pcb *pcb,
|
||||
#define tcp_mss(pcb) ((pcb)->mss)
|
||||
#define tcp_sndbuf(pcb) ((pcb)->snd_buf)
|
||||
|
||||
#if LWIP_LISTEN_BACKLOG
|
||||
#define tcp_accepted(pcb) (((struct tcp_pcb_listen *)(pcb))->accepts_pending--)
|
||||
#define tcp_backlog(pcb, bklog) (((struct tcp_pcb_listen *)(pcb))->backlog = bklog)
|
||||
#endif /* LWIP_LISTEN_BACKLOG */
|
||||
|
||||
void tcp_recved (struct tcp_pcb *pcb, u16_t len);
|
||||
err_t tcp_bind (struct tcp_pcb *pcb, struct ip_addr *ipaddr,
|
||||
u16_t port);
|
||||
@ -412,6 +417,10 @@ struct tcp_pcb_listen {
|
||||
*/
|
||||
err_t (* accept)(void *arg, struct tcp_pcb *newpcb, err_t err);
|
||||
#endif /* LWIP_CALLBACK_API */
|
||||
#if LWIP_LISTEN_BACKLOG
|
||||
u8_t backlog;
|
||||
u8_t accepts_pending;
|
||||
#endif /* LWIP_LISTEN_BACKLOG */
|
||||
};
|
||||
|
||||
#if LWIP_EVENT_API
|
||||
|
Loading…
Reference in New Issue
Block a user