lwip-devel
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[lwip-devel] [task #7525] Implement TCP listen backlog


From: Frédéric Bernon
Subject: [lwip-devel] [task #7525] Implement TCP listen backlog
Date: Mon, 17 Dec 2007 10:39:13 +0000
User-agent: Mozilla/5.0 (Windows; U; Windows NT 5.1; fr; rv:1.8.1.11) Gecko/20071127 Firefox/2.0.0.11

Follow-up Comment #4, task #7525 (project lwip):

>Doing it in accept_callback is definitively wrong, because for the client,
connect succeeds but a send after that fails! 
...
>but with the current code, this is done at the wrong time (after the new
connection is already established).

It's not a so big problem, since the client should also process this case.
But if it's not so "nice", it's more "lightweight" :)

Other solution (perhaps it's what jifl suggested): and if we use do_recv in
the same spirit than "netconn_recv" for tcp part? In netconn_accept, we could
do a do_recv to inform tcp raw api we fetch one of new connections. Checking
the state in do_recv will allow to know if we inform that we read data or
accept a new netconn ? Like this, we put new fields only in tcp_pcb_listen (a
"u8_t backlog" and a "u8_t to_accept"):

struct tcp_pcb_listen {  
/* Common members of all PCB types */
  IP_PCB;
/* Protocol specific PCB members */
  TCP_PCB_COMMON(struct tcp_pcb_listen);

#if LWIP_CALLBACK_API
  /* Function to call when a listener has been connected.
   * @param arg user-supplied argument (tcp_pcb.callback_arg)
   * @param pcb a new tcp_pcb that now is connected
   * @param err an error argument (TODO: that is current always ERR_OK?)
   * @return ERR_OK: accept the new connection,
   *                 any other err_t abortsthe new connection
   */
  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 to_accept;
#endif /* LWIP_LISTEN_BACKLOG */
};


void
do_recv(struct api_msg_msg *msg)
{
#if LWIP_TCP
  if (!ERR_IS_FATAL(msg->conn->err)) {
    if (msg->conn->pcb.tcp != NULL) {
      if (msg->conn->type == NETCONN_TCP) {
        if (conn->pcb.tcp->state == LISTEN) {
#if LWIP_LISTEN_BACKLOG
          tcp_accepted((struct tcp_pcb_listen *)(msg->conn->pcb.tcp));
<<<<<<<< NEW
#endif /* LWIP_LISTEN_BACKLOG */
        } else {
          tcp_recved(msg->conn->pcb.tcp, msg->msg.r.len);
        }
      }
    }
  }
#endif /* LWIP_TCP */
  TCPIP_APIMSG_ACK(msg);
}

#if LWIP_LISTEN_BACKLOG
void
tcp_accepted(struct tcp_pcb_listen *pcb)
{ pcb->to_accept--;
}
#endif /* LWIP_LISTEN_BACKLOG */

static err_t
tcp_listen_input(struct tcp_pcb_listen *pcb)
{ ...
  } 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->to_accept>=pcb->backlog) {
      return ERR_ABRT;
    }
#endif /* LWIP_LISTEN_BACKLOG */    
  ...
}



    _______________________________________________________

Reply to this item at:

  <http://savannah.nongnu.org/task/?7525>

_______________________________________________
  Message posté via/par Savannah
  http://savannah.nongnu.org/





reply via email to

[Prev in Thread] Current Thread [Next in Thread]