Returns now GNUNET_SYSERR
[oweals/gnunet.git] / src / util / server_mst.c
index d7a109f3b91b135e1ae59c5a538c9fc9ce143bc7..835d8eebaaa0a874f8857f43d7abf368c10cc6ef 100644 (file)
@@ -61,11 +61,6 @@ struct GNUNET_SERVER_MessageStreamTokenizer
    */
   size_t curr_buf;
 
-  /**
-   * Maximum size of the buffer.
-   */
-  size_t maxbuf;
-
   /**
    * How many bytes in buffer have we already processed?
    */
@@ -88,15 +83,12 @@ struct GNUNET_SERVER_MessageStreamTokenizer
 /**
  * Create a message stream tokenizer.
  *
- * @param maxbuf maximum message size to support (typically
- *    GNUNET_SERVER_MAX_MESSAGE_SIZE - 1)
  * @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,
-                         GNUNET_SERVER_MessageTokenizerCallback cb,
+GNUNET_SERVER_mst_create (GNUNET_SERVER_MessageTokenizerCallback cb,
                          void *cb_cls)
 {
   struct GNUNET_SERVER_MessageStreamTokenizer *ret;
@@ -104,7 +96,6 @@ GNUNET_SERVER_mst_create (size_t maxbuf,
   ret = GNUNET_malloc (sizeof (struct GNUNET_SERVER_MessageStreamTokenizer));
   ret->hdr = GNUNET_malloc(GNUNET_SERVER_MIN_BUFFER_SIZE);
   ret->curr_buf = GNUNET_SERVER_MIN_BUFFER_SIZE;
-  ret->maxbuf = maxbuf;
   ret->cb = cb;
   ret->cb_cls = cb_cls;
   return ret;
@@ -141,7 +132,6 @@ GNUNET_SERVER_mst_receive (struct GNUNET_SERVER_MessageStreamTokenizer *mst,
   int need_align;
   unsigned long offset;
   int ret;
-  size_t newsize;
 
 #if DEBUG_SERVER_MST
   GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
@@ -149,16 +139,6 @@ GNUNET_SERVER_mst_receive (struct GNUNET_SERVER_MessageStreamTokenizer *mst,
              (unsigned int) size,
              (unsigned int) (mst->pos - mst->off));
 #endif
-  if ((size > mst->curr_buf) && (size < mst->maxbuf)) /* Received bigger message than we can currently handle! */
-    {
-      newsize = mst->curr_buf + size; /* How much space do we need? */
-      if (newsize > mst->maxbuf)
-        newsize = mst->maxbuf; /* Check it's not bigger than maxbuf */
-
-      mst->hdr = GNUNET_realloc(mst->hdr, newsize);
-      mst->curr_buf = newsize;
-    }
-
   ret = GNUNET_OK;
   ibuf = (char*)mst->hdr;
   while (mst->pos > 0)
@@ -210,6 +190,13 @@ GNUNET_SERVER_mst_receive (struct GNUNET_SERVER_MessageStreamTokenizer *mst,
                   mst->pos);
          mst->off = 0;
        }
+      if (want > mst->curr_buf)
+       {
+         mst->hdr = GNUNET_realloc(mst->hdr, want);
+         ibuf = (char*)mst->hdr;         
+         mst->curr_buf = want;
+       }
+      hdr = (const struct GNUNET_MessageHeader*) &ibuf[mst->off];
       if (mst->pos - mst->off < want)
        {
          delta = GNUNET_MIN (want - (mst->pos - mst->off),
@@ -264,6 +251,12 @@ GNUNET_SERVER_mst_receive (struct GNUNET_SERVER_MessageStreamTokenizer *mst,
          /* can try to do zero-copy and process directly from original buffer */
          hdr = (const struct GNUNET_MessageHeader *) buf;
          want = ntohs (hdr->size);
+         if (want < sizeof (struct GNUNET_MessageHeader))
+           {
+             GNUNET_break_op (0);
+             mst->off = 0;
+             return GNUNET_SYSERR;
+           }
          if (size < want)
            break; /* or not, buffer incomplete, so copy to private buffer... */
          if (one_shot == GNUNET_SYSERR)
@@ -289,6 +282,12 @@ GNUNET_SERVER_mst_receive (struct GNUNET_SERVER_MessageStreamTokenizer *mst,
  copy:
   if ( (size > 0) && (! purge) )
     {
+      if (size + mst->pos > mst->curr_buf)
+       {
+         mst->hdr = GNUNET_realloc(mst->hdr, size + mst->pos);
+         ibuf = (char*)mst->hdr;         
+         mst->curr_buf = size + mst->pos;
+       }
       GNUNET_assert (mst->pos + size <= mst->curr_buf);
       memcpy (&ibuf[mst->pos], buf, size);
       mst->pos += size;
@@ -312,6 +311,7 @@ GNUNET_SERVER_mst_receive (struct GNUNET_SERVER_MessageStreamTokenizer *mst,
 void
 GNUNET_SERVER_mst_destroy (struct GNUNET_SERVER_MessageStreamTokenizer *mst)
 {
+  GNUNET_free (mst->hdr);
   GNUNET_free (mst);
 }