Index: CHANGELOG
===================================================================
RCS file: /sources/lwip/lwip/CHANGELOG,v
retrieving revision 1.115
diff -w -b -u -3 -p -r1.115 CHANGELOG
--- CHANGELOG	6 Apr 2007 10:09:24 -0000	1.115
+++ CHANGELOG	9 Apr 2007 21:11:21 -0000
@@ -23,6 +23,12 @@ HISTORY
 
   ++ New features:
 
+  2007-04-09 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-06 Frédéric Bernon, Simon Goldschmidt
   * opt.h, tcpip.h, tcpip.c, netifapi.h, netifapi.c: New configuration option LWIP_NETIF_API
     allow to use thread-safe functions to add/remove netif in list, and to start/stop dhcp

Index: src/api/api_lib.c
===================================================================
RCS file: /sources/lwip/lwip/src/api/api_lib.c,v
retrieving revision 1.34
diff -w -b -u -3 -p -r1.34 api_lib.c
--- src/api/api_lib.c	28 Mar 2007 17:26:06 -0000	1.34
+++ src/api/api_lib.c	9 Apr 2007 21:04:15 -0000
@@ -580,7 +580,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 -r1.34 api_msg.c
--- src/api/api_msg.c	5 Apr 2007 21:11:16 -0000	1.34
+++ src/api/api_msg.c	9 Apr 2007 21:04:54 -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->fromport==0) {
+          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->fromport==0) {
+          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 -r1.42 sockets.c
--- src/api/sockets.c	5 Apr 2007 16:49:33 -0000	1.42
+++ src/api/sockets.c	9 Apr 2007 21:05:53 -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,16 @@ 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);
-    }
-
-    /* deallocated the buffer */
-    netbuf_delete(buf);
-    break;
-  case NETCONN_TCP:
+  if (sock->conn->type==NETCONN_TCP) {
     err = netconn_write(sock->conn, data, size, NETCONN_COPY);
-    break;
-  default:
-    err = ERR_ARG;
-    break;
+  } else {
+    struct sockaddr_in to = {0};
+    to.sin_family = AF_INET; /* Necessary to pass LWIP_ASSERT in lwip_sendto */
+    err = lwip_sendto( s, data, size, flags, (struct sockaddr *)&to, sizeof(to));
   }
-  if (err != ERR_OK) {
-    LWIP_DEBUGF(SOCKETS_DEBUG, ("lwip_send(%d) err=%d\n", s, err));
+  LWIP_DEBUGF(SOCKETS_DEBUG, ("lwip_send(%d) err=%d size=%d\n", s, err, size));
     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;
+  return ((err != ERR_OK)?-1:size);
 }
 
 int
@@ -516,36 +486,43 @@ 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)==size)?ERR_OK:sock->err);
 
-  /* get the peer if currently connected */
-  connected = (netconn_peer(sock->conn, &addr, &port) == ERR_OK);
+  LWIP_ASSERT("lwip_sendto: invalid address", (tolen == sizeof(struct sockaddr_in)) && ((((struct sockaddr_in *)to)->sin_family) == AF_INET));
 
   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);
 
   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));
+
+  /* initialize a buffer */
+  buf.p = buf.ptr = NULL;
+  buf.fromaddr = &remote_addr;
+  buf.fromport = remote_port; /*need or not ??*/
 
-  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;
 }
 

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 -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	9 Apr 2007 21:03:45 -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;
