[patch #5780] Implement SO_RCVTIMEO on UDP sockets/netconn

classic Classic list List threaded Threaded
6 messages Options
Reply | Threaded
Open this post in threaded view
|

[patch #5780] Implement SO_RCVTIMEO on UDP sockets/netconn

Ashley Duncan

URL:
  <http://savannah.nongnu.org/patch/?5780>

                 Summary: Implement SO_RCVTIMEO on UDP sockets/netconn
                 Project: lwIP - A Lightweight TCP/IP stack
            Submitted by: fbernon
            Submitted on: dimanche 04.03.2007 à 14:56
                Category: None
                Priority: 5 - Normal
                  Status: In Progress
                 Privacy: Public
             Assigned to: fbernon
        Originator Email:
             Open/Closed: Open
         Discussion Lock: Any

    _______________________________________________________

Details:

I propose to add the possibility to use the socket's option name SO_RCVTIMEO
on UDP sockets. It's very usefull in some UDP protocols, like SNTP or DNS,
where you have to wait an answer which can never arrived (packet lost, server
shutdown...). SO_RCVTIMEO is a very generic parameter. It allow to give a code
very simple (you can do something like that with select, but it's not the
simplest solution).


The patch is very simple, and need to add a "timeout" parameter in
sys_mbox_fetch (in sys.h/.c):

void sys_mbox_fetch(sys_mbox_t mbox, void **msg, u32_t timeout);

In the sys.c implementation, the only thing to do is the give this new
parameter to sys_arch_mbox_fetch.

Most of calling functions have to set it to 0, but in netconn_recv, we can
pass the different values, initialize with SO_RCVTIMEO, and register in a
netconn member.

To handle the timeout, in netconn_recv (see below), we just return a NULL
value, like this :

struct netbuf *
netconn_recv(struct netconn *conn)
{
  struct api_msg _msg;
  struct api_msg *msg = &_msg;
  struct netbuf *buf = NULL;
  struct pbuf *p;
  u16_t len;
     
  if (conn == NULL) {
    return NULL;
  }
 
  if (conn->recvmbox == SYS_MBOX_NULL) {
    conn->err = ERR_CONN;
    return NULL;
  }

  if (conn->err != ERR_OK) {
    return NULL;
  }

  if (conn->type == NETCONN_TCP) {
    if (conn->pcb.tcp->state == LISTEN) {
      conn->err = ERR_CONN;
      return NULL;
    }


    buf = memp_malloc(MEMP_NETBUF);

    if (buf == NULL) {
      conn->err = ERR_MEM;
      return NULL;
    }
   
    sys_mbox_fetch(conn->recvmbox, (void *)&p, 0);

    if (p != NULL)
    {
        len = p->tot_len;
        conn->recv_avail -= len;
    }
    else
        len = 0;
   
    /* Register event with callback */
      if (conn->callback)
        (*conn->callback)(conn, NETCONN_EVT_RCVMINUS, len);

    /* If we are closed, we indicate that we no longer wish to receive
       data by setting conn->recvmbox to SYS_MBOX_NULL. */
    if (p == NULL) {
      memp_free(MEMP_NETBUF, buf);
      sys_mbox_free(conn->recvmbox);
      conn->recvmbox = SYS_MBOX_NULL;
      return NULL;
    }

    buf->p = p;
    buf->ptr = p;
    buf->fromport = 0;
    buf->fromaddr = NULL;

    /* Let the stack know that we have taken the data. */
    msg->type = API_MSG_RECV;
    msg->msg.conn = conn;
    if (buf != NULL) {
      msg->msg.msg.len = buf->p->tot_len;
    } else {
      msg->msg.msg.len = 1;
    }
    api_msg_post(msg);

    sys_mbox_fetch(conn->mbox, NULL, 0);
  } else {
    sys_mbox_fetch(conn->recvmbox, (void *)&buf, conn->recv_timeout);
    if (buf!=NULL)
     { conn->recv_avail -= buf->p->tot_len;
       /* Register event with callback */
       if (conn->callback)
           (*conn->callback)(conn, NETCONN_EVT_RCVMINUS, buf->p->tot_len);
     }
  }

 

   
  LWIP_DEBUGF(API_LIB_DEBUG, ("netconn_recv: received %p (err %d)\n", (void
*)buf, conn->err));


  return buf;
}

In sockets.c, we change only in lwip_recvfrom (ETIMEDOUT is this new error
code):

     //...
     /* No data was left from the previous operation, so we try to get
     some from the network. */
     buf = netconn_recv(sock->conn);
     
     if (!buf) {
        /* We should really do some error checking here. */
        LWIP_DEBUGF(SOCKETS_DEBUG, ("lwip_recvfrom(%d): buf == NULL!\n", s));
       
        sock_set_errno(sock, (sock->conn->type==NETCONN_UDP)?ETIMEDOUT:0);
        return 0;
      }
     //...


Is it good for you?






    _______________________________________________________

Reply to this item at:

  <http://savannah.nongnu.org/patch/?5780>

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



_______________________________________________
lwip-devel mailing list
[hidden email]
http://lists.nongnu.org/mailman/listinfo/lwip-devel
Reply | Threaded
Open this post in threaded view
|

[patch #5780] Implement SO_RCVTIMEO on UDP sockets/netconn

Ashley Duncan

Follow-up Comment #1, patch #5780 (project lwip):

Implementing such general socket options (derived from linux etc.) is fine
for me, as long as you can turn it off to save code space if you don't need
it.
But rather than changing the mbox api for this purpose, I would like to
introduce a new function for this (sys_mbox_fetch_timeout or something) which
returns int instead of void to let the caller know if it worked. You have it
this way with most embedded operating systems, anyway.
In sys.c, sys_mbox_fetch can simply call the new function with timeout=0.

I can't read the source code in this post though, since it is not formatted.

    _______________________________________________________

Reply to this item at:

  <http://savannah.nongnu.org/patch/?5780>

_______________________________________________
  Nachricht geschickt von/durch Savannah
  http://savannah.nongnu.org/



_______________________________________________
lwip-devel mailing list
[hidden email]
http://lists.nongnu.org/mailman/listinfo/lwip-devel
Reply | Threaded
Open this post in threaded view
|

[patch #5780] Implement SO_RCVTIMEO on UDP sockets/netconn

Ashley Duncan

Follow-up Comment #2, patch #5780 (project lwip):

I join the SO_RCVTIMO.patch file. About last remarks from Simon, I found that
- in this case - adding a new sys_mbox_fetch_timeout will only increase source
code size and footprint. This patch is very "small & simple". But, before
commit that, I let you and others give me your comments.

SO_RCVTIMO is generic options, already defined in sockets.h, but not
implemented. So, I think it's better to be directly integrate in the standard
core, than be turn off by a configuration option.

I wait your comments...

(file #12127)
    _______________________________________________________

Additional Item Attachment:

File name: SO_RCVTIMEO.patch              Size:20 KB


    _______________________________________________________

Reply to this item at:

  <http://savannah.nongnu.org/patch/?5780>

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



_______________________________________________
lwip-devel mailing list
[hidden email]
http://lists.nongnu.org/mailman/listinfo/lwip-devel
Reply | Threaded
Open this post in threaded view
|

[patch #5780] Implement SO_RCVTIMEO on UDP sockets/netconn

Ashley Duncan

Follow-up Comment #3, patch #5780 (project lwip):

Looks OK to me.  There are a number of other changes in the patch -
whitespace mods, formatting, that sort of thing - which normally I'd prefer
to see as a separate change, but I know how it is easier to clean these
things up while you're working on something.

    _______________________________________________________

Reply to this item at:

  <http://savannah.nongnu.org/patch/?5780>

_______________________________________________
  Message sent via/by Savannah
  http://savannah.nongnu.org/



_______________________________________________
lwip-devel mailing list
[hidden email]
http://lists.nongnu.org/mailman/listinfo/lwip-devel
Reply | Threaded
Open this post in threaded view
|

[patch #5780] Implement SO_RCVTIMEO on UDP sockets/netconn

Ashley Duncan

Update of patch #5780 (project lwip):

                  Status:             In Progress => Done                  
             Open/Closed:                    Open => Closed                


    _______________________________________________________

Reply to this item at:

  <http://savannah.nongnu.org/patch/?5780>

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



_______________________________________________
lwip-devel mailing list
[hidden email]
http://lists.nongnu.org/mailman/listinfo/lwip-devel
Reply | Threaded
Open this post in threaded view
|

[patch #5780] Implement SO_RCVTIMEO on UDP sockets/netconn

Ashley Duncan

Follow-up Comment #4, patch #5780 (project lwip):

I know I'm a bit late on this bug, since it is closed for over one month now,
but shouldn't sys_mbox_fetch_timeout() return something like SYS_ARCH_TIMEOUT
on timeout (no message) instead of setting *msg=NULL?

    _______________________________________________________

Reply to this item at:

  <http://savannah.nongnu.org/patch/?5780>

_______________________________________________
  Nachricht geschickt von/durch Savannah
  http://savannah.nongnu.org/



_______________________________________________
lwip-devel mailing list
[hidden email]
http://lists.nongnu.org/mailman/listinfo/lwip-devel