Index: CHANGELOG
===================================================================
RCS file: /sources/lwip/lwip/CHANGELOG,v
retrieving revision 1.123
diff -w -b -u -3 -p -B -r1.123 CHANGELOG
--- CHANGELOG	23 Apr 2007 20:00:29 -0000	1.123
+++ CHANGELOG	3 May 2007 18:21:36 -0000
@@ -23,6 +23,12 @@ HISTORY
 
   ++ New features:
 
+  2007-05-03 Frédéric Bernon
+  * sockets.c, api_lib.c, api_msg.h, api_msg.c: Fix bug #19162 "lwip_sento: a possible to
+    corrupt remote addr/port connection state". Reduce problems "not enought memory" with
+    netbuf (if we receive lot of datagrams). Improve lwip_sendto (only one exchange between
+    sockets api and api_msg which run in tcpip_thread context).
+
   2007-04-11 Jonathan Larmour
   * sys.h, api_lib.c: Provide new sys_mbox_tryfetch function. Require ports to provide new
     sys_arch_mbox_tryfetch function to get a message if one is there, otherwise return


Index: src/api/api_lib.c
===================================================================
RCS file: /sources/lwip/lwip/src/api/api_lib.c,v
retrieving revision 1.35
diff -w -b -u -3 -p -B -r1.35 api_lib.c
--- src/api/api_lib.c	11 Apr 2007 15:41:04 -0000	1.35
+++ src/api/api_lib.c	3 May 2007 18:23:26 -0000
@@ -49,6 +49,7 @@ netbuf *netbuf_new(void)
   if (buf != NULL) {
     buf->p = NULL;
     buf->ptr = NULL;
+    buf->fromaddr = NULL;
     return buf;
   } else {
     return NULL;
@@ -487,9 +486,11 @@ netconn_recv(struct netconn *conn)
   }
   
   if (conn->recvmbox == SYS_MBOX_NULL) {
+    if ((conn->recvmbox = sys_mbox_new()) == SYS_MBOX_NULL) {
     conn->err = ERR_CONN;
     return NULL;
   }
+  }
 
   if (conn->err != ERR_OK) {
     return NULL;
@@ -580,7 +581,7 @@ netconn_send(struct netconn *conn, struc
   LWIP_DEBUGF(API_LIB_DEBUG, ("netconn_send: sending %d bytes\n", buf->p->tot_len));
   msg.type = API_MSG_SEND;
   msg.msg.conn = conn;
-  msg.msg.msg.p = buf->p;
+  msg.msg.msg.b = buf;
   api_msg_post(&msg);
   return conn->err;
 }


Index: src/api/api_msg.c
===================================================================
RCS file: /sources/lwip/lwip/src/api/api_msg.c,v
retrieving revision 1.34
diff -w -b -u -3 -p -B -r1.34 api_msg.c
--- src/api/api_msg.c	5 Apr 2007 21:11:16 -0000	1.34
+++ src/api/api_msg.c	3 May 2007 18:24:11 -0000
@@ -581,7 +581,11 @@ do_send(struct api_msg_msg *msg)
       switch (msg->conn->type) {
 #if LWIP_RAW
       case NETCONN_RAW:
-        raw_send(msg->conn->pcb.raw, msg->msg.p);
+        if (msg->msg.b->fromaddr==NULL) {
+          raw_send(msg->conn->pcb.raw, msg->msg.b->p);
+        } else {
+          raw_sendto(msg->conn->pcb.raw, msg->msg.b->p, msg->msg.b->fromaddr);
+        }
         break;
 #endif
 #if LWIP_UDP
@@ -590,7 +594,11 @@ do_send(struct api_msg_msg *msg)
       case NETCONN_UDPNOCHKSUM:
         /* FALLTHROUGH */
       case NETCONN_UDP:
-        udp_send(msg->conn->pcb.udp, msg->msg.p);
+        if (msg->msg.b->fromaddr==NULL) {
+          udp_send(msg->conn->pcb.udp, msg->msg.b->p);
+        } else {
+          udp_sendto(msg->conn->pcb.udp, msg->msg.b->p, msg->msg.b->fromaddr, msg->msg.b->fromport);
+        }
         break;
 #endif /* LWIP_UDP */
       case NETCONN_TCP:


Index: src/api/sockets.c
===================================================================
RCS file: /sources/lwip/lwip/src/api/sockets.c,v
retrieving revision 1.42
diff -w -b -u -3 -p -B -r1.42 sockets.c
--- src/api/sockets.c	5 Apr 2007 16:49:33 -0000	1.42
+++ src/api/sockets.c	3 May 2007 18:25:28 -0000
@@ -461,7 +461,6 @@ int
 lwip_send(int s, const void *data, int size, unsigned int flags)
 {
   struct lwip_socket *sock;
-  struct netbuf *buf;
   err_t err;
 
   LWIP_DEBUGF(SOCKETS_DEBUG, ("lwip_send(%d, data=%p, size=%d, flags=0x%x)\n", s, data, size, flags));
@@ -470,45 +469,14 @@ lwip_send(int s, const void *data, int s
   if (!sock)
     return -1;
 
-  switch (netconn_type(sock->conn)) {
-  case NETCONN_RAW:
-  case NETCONN_UDP:
-  case NETCONN_UDPLITE:
-  case NETCONN_UDPNOCHKSUM:
-    /* create a buffer */
-    buf = netbuf_new();
-
-    if (!buf) {
-      LWIP_DEBUGF(SOCKETS_DEBUG, ("lwip_send(%d) ENOBUFS\n", s));
-      sock_set_errno(sock, ENOBUFS);
-      return -1;
-    }
-
-    /* make the buffer point to the data that should be sent */
-    if ((err = netbuf_ref(buf, data, size))==ERR_OK) {
-      /* send the data */
-      err = netconn_send(sock->conn, buf);
-    }
+  if (sock->conn->type!=NETCONN_TCP)     
+    return lwip_sendto( s, data, size, flags, NULL, 0);
 
-    /* deallocated the buffer */
-    netbuf_delete(buf);
-    break;
-  case NETCONN_TCP:
     err = netconn_write(sock->conn, data, size, NETCONN_COPY);
-    break;
-  default:
-    err = ERR_ARG;
-    break;
-  }
-  if (err != ERR_OK) {
-    LWIP_DEBUGF(SOCKETS_DEBUG, ("lwip_send(%d) err=%d\n", s, err));
-    sock_set_errno(sock, err_to_errno(err));
-    return -1;
-  }
 
-  LWIP_DEBUGF(SOCKETS_DEBUG, ("lwip_send(%d) ok size=%d\n", s, size));
-  sock_set_errno(sock, 0);
-  return size;
+  LWIP_DEBUGF(SOCKETS_DEBUG, ("lwip_send(%d) err=%d size=%d\n", s, err, size));
+  sock_set_errno(sock, err_to_errno(err));
+  return (err==ERR_OK?size:-1);
 }
 
 int
@@ -516,37 +484,51 @@ lwip_sendto(int s, const void *data, int
        struct sockaddr *to, socklen_t tolen)
 {
   struct lwip_socket *sock;
-  struct ip_addr remote_addr, addr;
-  u16_t remote_port, port;
-  int err,connected;
+  struct netbuf buf;
+  struct ip_addr remote_addr;
+  u16_t remote_port;
+  int err;
 
   sock = get_socket(s);
   if (!sock)
     return -1;
 
-  LWIP_ASSERT("lwip_sendto: invalid address", (tolen == sizeof(struct sockaddr_in)) && ((((struct sockaddr_in *)to)->sin_family) == AF_INET));
+  if (sock->conn->type==NETCONN_TCP)
+    return lwip_send( s, data, size, flags);
 
-  /* get the peer if currently connected */
-  connected = (netconn_peer(sock->conn, &addr, &port) == ERR_OK);
+  LWIP_ASSERT("lwip_sendto: invalid address", (((to==NULL) && (tolen==0)) || ((tolen == sizeof(struct sockaddr_in)) && ((((struct sockaddr_in *)to)->sin_family) == AF_INET))) );
 
+  /* initialize a buffer */
+  buf.p = buf.ptr = NULL;
+  if (to) {
   remote_addr.addr = ((struct sockaddr_in *)to)->sin_addr.s_addr;
-  remote_port = ((struct sockaddr_in *)to)->sin_port;
+    remote_port      = ntohs(((struct sockaddr_in *)to)->sin_port);
+    buf.fromaddr     = &remote_addr;
+    buf.fromport     = remote_port;
+  } else {
+    remote_addr.addr = 0;
+    remote_port      = 0;
+    buf.fromaddr     = NULL;
+    buf.fromport     = 0;
+  }
 
   LWIP_DEBUGF(SOCKETS_DEBUG, ("lwip_sendto(%d, data=%p, size=%d, flags=0x%x to=", s, data, size, flags));
   ip_addr_debug_print(SOCKETS_DEBUG, &remote_addr);
-  LWIP_DEBUGF(SOCKETS_DEBUG, (" port=%u\n", ntohs(remote_port)));
+  LWIP_DEBUGF(SOCKETS_DEBUG, (" port=%u\n", remote_port));
 
-  netconn_connect(sock->conn, &remote_addr, ntohs(remote_port));
+  /* make the buffer point to the data that should be sent */
+  if ((err = netbuf_ref(&buf, data, size))==ERR_OK) {
+    /* send the data */
+    err = netconn_send(sock->conn, &buf);
+  }
 
-  err = lwip_send(s, data, size, flags);
+  /* deallocated the buffer */
+  if (buf.p != NULL) {
+    pbuf_free(buf.p);
+  }
 
-  /* reset the remote address and port number
-     of the connection */
-  if (connected)
-    netconn_connect(sock->conn, &addr, port);
-  else
-    netconn_disconnect(sock->conn);
-  return err;
+  sock_set_errno(sock, err_to_errno(err));
+  return (err==ERR_OK?size:-1);
 }
 
 int


Index: src/include/lwip/api_msg.h
===================================================================
RCS file: /sources/lwip/lwip/src/include/lwip/api_msg.h,v
retrieving revision 1.9
diff -w -b -u -3 -p -B -r1.9 api_msg.h
--- src/include/lwip/api_msg.h	22 Mar 2007 09:34:18 -0000	1.9
+++ src/include/lwip/api_msg.h	3 May 2007 18:22:08 -0000
@@ -71,6 +71,7 @@ struct api_msg_msg {
   enum netconn_type conntype;
   union {
     struct pbuf *p;   
+    struct netbuf *b;
     struct  {
       struct ip_addr *ipaddr;
       u16_t port;
