lwip-users
[Top][All Lists]
Advanced

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

[lwip-users] [lwip] Sockets patch


From: Kieran Mansley
Subject: [lwip-users] [lwip] Sockets patch
Date: Thu, 09 Jan 2003 02:08:45 -0000

I've made a patch for the sockets code in lwip that changes the behaviour
of lwip_read().  The existing version drops data if there is more than it
can pass to the application in a single operation (ie. the application is
using small buffer to read from the socket).  The changes I've made
prevent this happening, and so ensure all the data that are written into
the socket reach the other application.

The patch doesn't alter lwip_recvfrom, but it would be a simple extension
to do this, and it could probably reuse much of the code in the new
function lwip_recv_copy().

Hopefully the code is clear enough to understand what is going on, but
should you need more documentation feel free to ask.

Adam, if you think this functionality is useful then you're welcome to add
it to the current cvs tree.  The patch is taken against lwip-cvs-20020131.
Let me know if the patch doesn't work for some reason, or I've obviously
forgotten to include a diff or something.

It could potentially increase the memory usage, and there is a slight
increase in code size, so it might not be ideal for everyone.

Cheers

Kieran


--- cvs-src/api/api_lib.c       Thu Jan 31 13:00:06 2002
+++ src/api/api_lib.c   Mon Feb  4 15:16:35 2002
@@ -151,8 +151,8 @@
   buf->ptr = buf->p;
 }
 
/*-----------------------------------------------------------------------------------*/
-void
-netbuf_copy(struct netbuf *buf, void *dataptr, u16_t len)
+void
+netbuf_copy_partial(struct netbuf *buf, void *dataptr, u16_t len, u16_t offset)
 {
   struct pbuf *p;
   u16_t i, left;
@@ -166,14 +166,26 @@
   /* This implementation is bad. It should use bcopy
      instead. */
   for(p = buf->p; left < len && p != NULL; p = p->next) {
-    for(i = 0; i < p->len; ++i) {
-      ((char *)dataptr)[left] = ((char *)p->payload)[i];
-      if(++left >= len) {
-       return;
+    if(offset && offset >= p->len){
+      offset -= p->len;
+    }
+    else{
+      for(i = offset; i < p->len; ++i) {
+       ((char *)dataptr)[left] = ((char *)p->payload)[i];
+       if(++left >= len) {
+         return;
+       }
       }
     }
   }
   return;
+
+}
+/*-----------------------------------------------------------------------------------*/
+void
+netbuf_copy(struct netbuf *buf, void *dataptr, u16_t len)
+{
+  netbuf_copy_partial(buf, dataptr, len, 0);
 }
 
/*-----------------------------------------------------------------------------------*/
 struct ip_addr *
--- cvs-src/api/sockets.c       Thu Jan 31 13:00:06 2002
+++ src/api/sockets.c   Mon Feb  4 15:26:08 2002
@@ -201,6 +201,57 @@
   return 0;
 }
 
/*-----------------------------------------------------------------------------------*/
+int lwip_recv_copy(struct netconn *conn, void *mem, int len)
+{
+  static struct netbuf *old_data=NULL;
+  static int remaining=0;
+  int amount_output=0;
+  struct netbuf *buf;
+  u16_t buflen;
+
+  if(old_data){
+    /* data left over from previous occasion */
+    if(remaining <= len){
+      DEBUGF(SOCKETS_DEBUG, ("lwip_recv_copy: complete old\n"));
+      netbuf_copy_partial(old_data, mem, remaining,
+                         netbuf_len(old_data)-remaining);
+      amount_output = remaining;
+      remaining = 0;
+      netbuf_delete(old_data);
+      old_data = NULL;
+    }
+    else{
+      DEBUGF(SOCKETS_DEBUG, ("lwip_recv_copy: partial old\n"));
+      netbuf_copy_partial(old_data, mem, len,
+                         netbuf_len(old_data)-remaining);
+      amount_output = len;
+      remaining -= len;
+      return amount_output;
+    }
+  }
+
+  buf = netconn_recv(conn);
+
+  if(buf){
+    buflen = netbuf_len(buf);
+
+    if(buflen <= len-amount_output){
+      DEBUGF(SOCKETS_DEBUG, ("lwip_recv_copy: complete new\n"));
+      netbuf_copy(buf, mem+amount_output, buflen);
+      amount_output += buflen;
+      netbuf_delete(buf);
+    }
+    else{
+      DEBUGF(SOCKETS_DEBUG, ("lwip_recv_copy: partial new\n"));
+      netbuf_copy(buf, mem+amount_output, (len-amount_output));
+      remaining = buflen-(len-amount_output);
+      amount_output += (len-amount_output);
+      old_data = buf;
+    }
+  }
+  return amount_output;
+}
+/*-----------------------------------------------------------------------------------*/
 int
 lwip_recv(int s, void *mem, int len, unsigned int flags)
 {
@@ -221,6 +272,7 @@
     return -1;
   }

+#if 0
   buf = netconn_recv(conn);

   if(buf == NULL) {
@@ -250,6 +302,9 @@
   } else {
     return len;
   }
+#else
+  return lwip_recv_copy(conn, mem, len);
+#endif
 }
 
/*-----------------------------------------------------------------------------------*/
 int
--- cvs-src/include/lwip/api.h  Thu Jan 31 13:00:06 2002
+++ src/include/lwip/api.h      Mon Feb  4 15:23:18 2002
@@ -102,6 +102,8 @@
 s8_t              netbuf_next     (struct netbuf *buf);
 void              netbuf_first    (struct netbuf *buf);

+void              netbuf_copy_partial(struct netbuf *buf, void *dataptr,
+                                     u16_t len, u16_t offset);
 void              netbuf_copy     (struct netbuf *buf,
                                   void *dataptr, u16_t len);
 struct ip_addr *  netbuf_fromaddr (struct netbuf *buf);

[This message was sent through the lwip discussion list.]




reply via email to

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