Fixed possible problems with tcp_backlog_delayed/tcp_backlog_accepted

This commit is contained in:
sg 2016-03-25 16:19:39 +01:00
parent 5b0a47ca87
commit 27f03798b9
4 changed files with 39 additions and 28 deletions

View File

@ -512,8 +512,6 @@ accept_function(void *arg, struct tcp_pcb *newpcb, err_t err)
sys_mbox_free(&newconn->recvmbox);
sys_mbox_set_invalid(&newconn->recvmbox);
netconn_free(newconn);
/* handle backlog counter */
tcp_backlog_accepted(newpcb);
return ERR_MEM;
} else {
/* Register event with callback */
@ -774,9 +772,6 @@ netconn_drain(struct netconn *conn)
struct netconn *newconn = (struct netconn *)mem;
/* Only tcp pcbs have an acceptmbox, so no need to check conn->type */
/* pcb might be set to NULL already by err_tcp() */
if (newconn->pcb.tcp != NULL) {
tcp_backlog_accepted(newconn->pcb.tcp);
}
/* drain recvmbox */
netconn_drain(newconn);
if (newconn->pcb.tcp != NULL) {

View File

@ -194,9 +194,12 @@ void
tcp_backlog_delayed(struct tcp_pcb* pcb)
{
LWIP_ASSERT("pcb != NULL", pcb != NULL);
if (pcb->listener != NULL) {
pcb->listener->accepts_pending++;
LWIP_ASSERT("accepts_pending != 0", pcb->listener->accepts_pending != 0);
if ((pcb->flags & TF_BACKLOGPEND) == 0) {
if (pcb->listener != NULL) {
pcb->listener->accepts_pending++;
LWIP_ASSERT("accepts_pending != 0", pcb->listener->accepts_pending != 0);
pcb->flags |= TF_BACKLOGPEND;
}
}
}
@ -212,9 +215,12 @@ void
tcp_backlog_accepted(struct tcp_pcb* pcb)
{
LWIP_ASSERT("pcb != NULL", pcb != NULL);
if (pcb->listener != NULL) {
LWIP_ASSERT("accepts_pending != 0", pcb->listener->accepts_pending != 0);
pcb->listener->accepts_pending--;
if ((pcb->flags & TF_BACKLOGPEND) != 0) {
if (pcb->listener != NULL) {
LWIP_ASSERT("accepts_pending != 0", pcb->listener->accepts_pending != 0);
pcb->listener->accepts_pending--;
pcb->flags &= ~TF_BACKLOGPEND;
}
}
}
#endif /* TCP_LISTEN_BACKLOG */
@ -470,6 +476,7 @@ tcp_abandon(struct tcp_pcb *pcb, int reset)
tcp_segs_free(pcb->ooseq);
}
#endif /* TCP_QUEUE_OOSEQ */
tcp_backlog_accepted(pcb);
if (send_rst) {
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);
@ -1599,7 +1606,9 @@ tcp_arg(struct tcp_pcb *pcb, void *arg)
{
/* This function is allowed to be called for both listen pcbs and
connection pcbs. */
pcb->callback_arg = arg;
if (pcb != NULL) {
pcb->callback_arg = arg;
}
}
#if LWIP_CALLBACK_API
@ -1613,8 +1622,10 @@ tcp_arg(struct tcp_pcb *pcb, void *arg)
void
tcp_recv(struct tcp_pcb *pcb, tcp_recv_fn recv)
{
LWIP_ASSERT("invalid socket state for recv callback", pcb->state != LISTEN);
pcb->recv = recv;
if (pcb != NULL) {
LWIP_ASSERT("invalid socket state for recv callback", pcb->state != LISTEN);
pcb->recv = recv;
}
}
/**
@ -1627,8 +1638,10 @@ tcp_recv(struct tcp_pcb *pcb, tcp_recv_fn recv)
void
tcp_sent(struct tcp_pcb *pcb, tcp_sent_fn sent)
{
LWIP_ASSERT("invalid socket state for sent callback", pcb->state != LISTEN);
pcb->sent = sent;
if (pcb != NULL) {
LWIP_ASSERT("invalid socket state for sent callback", pcb->state != LISTEN);
pcb->sent = sent;
}
}
/**
@ -1642,8 +1655,10 @@ tcp_sent(struct tcp_pcb *pcb, tcp_sent_fn sent)
void
tcp_err(struct tcp_pcb *pcb, tcp_err_fn err)
{
LWIP_ASSERT("invalid socket state for err callback", pcb->state != LISTEN);
pcb->errf = err;
if (pcb != NULL) {
LWIP_ASSERT("invalid socket state for err callback", pcb->state != LISTEN);
pcb->errf = err;
}
}
/**
@ -1657,7 +1672,7 @@ tcp_err(struct tcp_pcb *pcb, tcp_err_fn err)
void
tcp_accept(struct tcp_pcb *pcb, tcp_accept_fn accept)
{
if (pcb->state == LISTEN) {
if ((pcb != NULL) && (pcb->state == LISTEN)) {
struct tcp_pcb_listen *lpcb = (struct tcp_pcb_listen*)pcb;
lpcb->accept = accept;
}
@ -1698,14 +1713,7 @@ tcp_pcb_purge(struct tcp_pcb *pcb)
LWIP_DEBUGF(TCP_DEBUG, ("tcp_pcb_purge\n"));
#if TCP_LISTEN_BACKLOG
if (pcb->state == SYN_RCVD) {
tcp_backlog_accepted(pcb);
/* prevent executing this again: */
pcb->listener = NULL;
}
#endif /* TCP_LISTEN_BACKLOG */
tcp_backlog_accepted(pcb);
if (pcb->refused_data != NULL) {
LWIP_DEBUGF(TCP_DEBUG, ("tcp_pcb_purge: data left on ->refused_data\n"));

View File

@ -571,6 +571,7 @@ tcp_listen_input(struct tcp_pcb_listen *pcb)
}
#if TCP_LISTEN_BACKLOG
pcb->accepts_pending++;
npcb->flags |= TF_BACKLOGPEND;
#endif /* TCP_LISTEN_BACKLOG */
/* Set up the new PCB. */
ip_addr_copy(npcb->local_ip, *ip_current_dest_addr());

View File

@ -131,13 +131,17 @@ typedef err_t (*tcp_connected_fn)(void *arg, struct tcp_pcb *tpcb, err_t err);
#define TCPWND16(x) ((u16_t)LWIP_MIN((x), 0xFFFF))
#define TCP_WND_MAX(pcb) ((tcpwnd_size_t)(((pcb)->flags & TF_WND_SCALE) ? TCP_WND : TCPWND16(TCP_WND)))
typedef u32_t tcpwnd_size_t;
typedef u16_t tcpflags_t;
#else
#define RCV_WND_SCALE(pcb, wnd) (wnd)
#define SND_WND_SCALE(pcb, wnd) (wnd)
#define TCPWND16(x) (x)
#define TCP_WND_MAX(pcb) TCP_WND
typedef u16_t tcpwnd_size_t;
#endif
#if LWIP_WND_SCALE || TCP_LISTEN_BACKLOG
typedef u16_t tcpflags_t;
#else
typedef u8_t tcpflags_t;
#endif
@ -207,6 +211,9 @@ struct tcp_pcb {
#define TF_NAGLEMEMERR 0x80U /* nagle enabled, memerr, try to output to prevent delayed ACK to happen */
#if LWIP_WND_SCALE
#define TF_WND_SCALE 0x0100U /* Window Scale option enabled */
#endif
#if TCP_LISTEN_BACKLOG
#define TF_BACKLOGPEND 0x0200U /* If this is set, a connection pcb has increased the backlog on its listener */
#endif
/* the rest of the fields are in host byte order