gnunet-svn
[Top][All Lists]
Advanced

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

[GNUnet-SVN] r11857 - in gnunet/src: include util


From: gnunet
Subject: [GNUnet-SVN] r11857 - in gnunet/src: include util
Date: Mon, 21 Jun 2010 23:42:07 +0200

Author: grothoff
Date: 2010-06-21 23:42:07 +0200 (Mon, 21 Jun 2010)
New Revision: 11857

Added:
   gnunet/src/util/server_mst.c
Modified:
   gnunet/src/include/gnunet_server_lib.h
   gnunet/src/util/Makefile.am
Log:
yay spagetti

Modified: gnunet/src/include/gnunet_server_lib.h
===================================================================
--- gnunet/src/include/gnunet_server_lib.h      2010-06-21 21:06:48 UTC (rev 
11856)
+++ gnunet/src/include/gnunet_server_lib.h      2010-06-21 21:42:07 UTC (rev 
11857)
@@ -637,19 +637,30 @@
  *    GNUNET_SERVER_MAX_MESSAGE_SIZE)
  * @param client_identity ID of client for which this is a buffer,
  *        can be NULL (will be passed back to 'cb')
+ * @param cb function to call on completed messages
+ * @param cb_cls closure for cb
  * @return handle to tokenizer
  */
 struct GNUNET_SERVER_MessageStreamTokenizer *
 GNUNET_SERVER_mst_create (size_t maxbuf,
                          void *client_identity,
                          GNUNET_SERVER_MessageTokenizerCallback cb,
-                         void *cls);
+                         void *cb_cls);
 
 
 /**
+ * Add incoming data to the receive buffer and call the
+ * callback for all complete messages.
  *
+ * @param mst tokenizer to use
+ * @param buf input data to add
+ * @param size number of bytes in buf
+ * @param purge should any excess bytes in the buffer be discarded 
+ *       (i.e. for packet-based services like UDP)
+ * @return GNUNET_NO if the data stream is corrupt 
+ *         GNUNET_SYSERR if the data stream is corrupt beyond repair
  */
-void
+int
 GNUNET_SERVER_mst_receive (struct GNUNET_SERVER_MessageStreamTokenizer *mst,
                           const char *buf,
                           size_t size,

Modified: gnunet/src/util/Makefile.am
===================================================================
--- gnunet/src/util/Makefile.am 2010-06-21 21:06:48 UTC (rev 11856)
+++ gnunet/src/util/Makefile.am 2010-06-21 21:42:07 UTC (rev 11857)
@@ -60,6 +60,7 @@
   resolver_api.c resolver.h \
   scheduler.c \
   server.c \
+  server_mst.c \
   server_nc.c \
   server_tc.c \
   service.c \

Added: gnunet/src/util/server_mst.c
===================================================================
--- gnunet/src/util/server_mst.c                                (rev 0)
+++ gnunet/src/util/server_mst.c        2010-06-21 21:42:07 UTC (rev 11857)
@@ -0,0 +1,212 @@
+/*
+     This file is part of GNUnet.
+     (C) 2009 Christian Grothoff (and other contributing authors)
+
+     GNUnet is free software; you can redistribute it and/or modify
+     it under the terms of the GNU General Public License as published
+     by the Free Software Foundation; either version 2, or (at your
+     option) any later version.
+
+     GNUnet is distributed in the hope that it will be useful, but
+     WITHOUT ANY WARRANTY; without even the implied warranty of
+     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+     General Public License for more details.
+
+     You should have received a copy of the GNU General Public License
+     along with GNUnet; see the file COPYING.  If not, write to the
+     Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+     Boston, MA 02111-1307, USA.
+*/
+
+/**
+ * @file util/server_mst.c
+ * @brief convenience functions for handling inbound message buffers
+ * @author Christian Grothoff
+ */
+
+#include "platform.h"
+#include "gnunet_common.h"
+#include "gnunet_connection_lib.h"
+#include "gnunet_scheduler_lib.h"
+#include "gnunet_server_lib.h"
+#include "gnunet_time_lib.h"
+
+
+/**
+ * Handle to a message stream tokenizer.
+ */
+struct GNUNET_SERVER_MessageStreamTokenizer
+{
+
+  size_t maxbuf;
+
+  size_t off;
+
+  void *client_identity;
+
+  GNUNET_SERVER_MessageTokenizerCallback cb;
+
+  void *cb_cls;
+
+  /**
+   * Beginning of the buffer.
+   */
+  struct GNUNET_MessageHeader hdr;
+
+};
+
+
+
+/**
+ * Create a message stream tokenizer.
+ *
+ * @param maxbuf maximum message size to support (typically
+ *    GNUNET_SERVER_MAX_MESSAGE_SIZE)
+ * @param client_identity ID of client for which this is a buffer,
+ *        can be NULL (will be passed back to 'cb')
+ * @return handle to tokenizer
+ */
+struct GNUNET_SERVER_MessageStreamTokenizer *
+GNUNET_SERVER_mst_create (size_t maxbuf,
+                         void *client_identity,
+                         GNUNET_SERVER_MessageTokenizerCallback cb,
+                         void *cb_cls)
+{
+  struct GNUNET_SERVER_MessageStreamTokenizer *ret;
+
+  ret = GNUNET_malloc (maxbuf + sizeof (struct 
GNUNET_SERVER_MessageStreamTokenizer));
+  ret->maxbuf = maxbuf;
+  ret->client_identity = client_identity;
+  ret->cb = cb;
+  ret->cb_cls = cb_cls;
+  return ret;
+}
+
+
+/**
+ * Add incoming data to the receive buffer and call the
+ * callback for all complete messages.
+ *
+ * @param mst tokenizer to use
+ * @param buf input data to add
+ * @param size number of bytes in buf
+ * @param purge should any excess bytes in the buffer be discarded 
+ *       (i.e. for packet-based services like UDP)
+ * @return GNUNET_NO if the data stream is corrupt 
+ *         GNUNET_SYSERR if the data stream is corrupt beyond repair
+ */
+int
+GNUNET_SERVER_mst_receive (struct GNUNET_SERVER_MessageStreamTokenizer *mst,
+                          const char *buf,
+                          size_t size,
+                          int purge)
+{
+  const struct GNUNET_MessageHeader *hdr;
+  size_t delta;
+  size_t want;
+  char *ibuf;
+  int need_align;
+  unsigned long offset;
+
+  ibuf = (char*) &mst->hdr;
+  if (mst->off > 0)
+    {
+    do_align:
+      if (mst->off < sizeof (struct GNUNET_MessageHeader))
+       {
+         delta = GNUNET_MIN (sizeof (struct GNUNET_MessageHeader) - mst->off,
+                             size);
+         memcpy (&ibuf[mst->off],
+                 buf,
+                 delta);
+         mst->off += delta;
+         buf += delta;
+         size -= delta;
+       }
+      if (mst->off < sizeof (struct GNUNET_MessageHeader))
+       {
+         if (purge)
+           mst->off = 0;    
+         return GNUNET_OK;
+       }
+      want = ntohs (mst->hdr.size);
+      if (want < sizeof (struct GNUNET_MessageHeader))
+       {
+         GNUNET_break_op (0);
+         if (purge)
+           return GNUNET_NO;
+         return GNUNET_SYSERR;
+       }
+      if (want < mst->off)
+       {
+         delta = GNUNET_MIN (want - mst->off,
+                             size);
+         memcpy (&ibuf[mst->off],
+                 buf,
+                 delta);
+         mst->off += delta;
+         buf += delta;
+         size -= delta;
+       }
+      if (want < mst->off)
+       {
+         if (purge)
+           mst->off = 0;    
+         return GNUNET_OK;
+       }
+      mst->cb (mst->cb_cls, mst->client_identity, &mst->hdr);
+      mst->off = 0;
+    }
+  while (size > 0)
+    {
+      if (size < sizeof (struct GNUNET_MessageHeader))
+       break;
+      offset = (unsigned long) buf;
+#if HAVE_UNALIGNED_64_ACCESS
+      need_align = (0 != offset % 4) ? GNUNET_YES : GNUNET_NO;
+#else
+      need_align = (0 != offset % 8) ? GNUNET_YES : GNUNET_NO;
+#endif
+      if (GNUNET_NO == need_align)
+       {
+         /* can try to do zero-copy */
+         hdr = (const struct GNUNET_MessageHeader *) buf;
+         want = ntohs (hdr->size);
+         if (size < want)
+           break; /* or not, buffer incomplete... */
+         mst->cb (mst->cb_cls, mst->client_identity, hdr);
+         buf += want;
+         size -= want;
+       }
+      else
+       {
+         /* yes, we go a bit more spagetti than usual here */
+         goto do_align;
+       }
+    }
+  if ( (size > 0) && (! purge) )
+    {
+      memcpy (&mst->hdr, buf, size);
+      mst->off = size;
+      size = 0;
+    }
+  if (purge)
+    mst->off = 0;    
+  return GNUNET_OK;
+}
+
+
+/**
+ * Destroys a tokenizer.
+ *
+ * @param mst tokenizer to destroy
+ */
+void
+GNUNET_SERVER_mst_destroy (struct GNUNET_SERVER_MessageStreamTokenizer *mst)
+{
+  GNUNET_free (mst);
+}
+
+
+
+/* end of server_mst.c */




reply via email to

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