reduce buffer size for all connections, and for mst processing
authorNathan S. Evans <evans@in.tum.de>
Fri, 2 Jul 2010 10:42:03 +0000 (10:42 +0000)
committerNathan S. Evans <evans@in.tum.de>
Fri, 2 Jul 2010 10:42:03 +0000 (10:42 +0000)
src/util/connection.c
src/util/server_mst.c
src/util/service.c

index 6c53bdef7ba38e23d0af5efb21bc8a9ba07bbb6d..34c9fa62be5ed55fe9bc0486c21895a6af3916a9 100644 (file)
@@ -214,7 +214,12 @@ struct GNUNET_CONNECTION_Handle
   char *write_buffer;
 
   /**
-   * Size of our write buffer.
+   * Max size of our write buffer.
+   */
+  size_t max_write_buffer_size;
+
+  /**
+   * Current size of our write buffer.
    */
   size_t write_buffer_size;
 
@@ -226,7 +231,7 @@ struct GNUNET_CONNECTION_Handle
 
   /**
    * Current read-offset in write buffer (how many
-   * bytes have already been send).
+   * bytes have already been sent).
    */
   size_t write_buffer_pos;
 
@@ -325,10 +330,11 @@ GNUNET_CONNECTION_create_from_existing (struct GNUNET_SCHEDULER_Handle
                                         *osSocket, size_t maxbuf)
 {
   struct GNUNET_CONNECTION_Handle *ret;
-  ret = GNUNET_malloc (sizeof (struct GNUNET_CONNECTION_Handle) + maxbuf);
-  ret->write_buffer = (char *) &ret[1];
+  ret = GNUNET_malloc (sizeof (struct GNUNET_CONNECTION_Handle));
   GNUNET_assert (maxbuf < GNUNET_SERVER_MAX_MESSAGE_SIZE);
-  ret->write_buffer_size = maxbuf;
+  ret->write_buffer_size = GNUNET_SERVER_MIN_BUFFER_SIZE;
+  ret->max_write_buffer_size = maxbuf;
+  ret->write_buffer = GNUNET_malloc(ret->write_buffer_size);
   ret->sock = osSocket;
   ret->sched = sched;
   return ret;
@@ -416,10 +422,12 @@ GNUNET_CONNECTION_create_from_accept (struct GNUNET_SCHEDULER_Handle
       GNUNET_free (uaddr);
       return NULL;
     }
-  ret = GNUNET_malloc (sizeof (struct GNUNET_CONNECTION_Handle) + maxbuf);
-  ret->write_buffer = (char *) &ret[1];
+  ret = GNUNET_malloc (sizeof (struct GNUNET_CONNECTION_Handle));
+
   GNUNET_assert (maxbuf < GNUNET_SERVER_MAX_MESSAGE_SIZE);
-  ret->write_buffer_size = maxbuf;
+  ret->write_buffer_size = GNUNET_SERVER_MIN_BUFFER_SIZE;
+  ret->max_write_buffer_size = maxbuf;
+  ret->write_buffer = GNUNET_malloc(ret->write_buffer_size);
   ret->addr = uaddr;
   ret->addrlen = addrlen;
   ret->sock = sock;
@@ -588,6 +596,7 @@ transmit_ready (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc);
 static void
 connect_fail_continuation (struct GNUNET_CONNECTION_Handle *h)
 {
+#if DEBUG_CONNECTION
   GNUNET_log ((0 != strncmp (h->hostname, 
                             "localhost:",
                             10)) 
@@ -595,6 +604,7 @@ connect_fail_continuation (struct GNUNET_CONNECTION_Handle *h)
              : GNUNET_ERROR_TYPE_WARNING,
               _("Failed to establish TCP connection to `%s:%u', no further addresses to try.\n"),
               h->hostname, h->port);
+#endif
   /* connect failed / timed out */
   GNUNET_break (h->ap_head == NULL);
   GNUNET_break (h->ap_tail == NULL);
@@ -819,9 +829,11 @@ try_connect_using_address (void *cls,
       GNUNET_free (ap);
       return;                   /* not supported by OS */
     }
+#if DEBUG_CONNECTION
   GNUNET_log (GNUNET_ERROR_TYPE_INFO,
               _("Trying to connect to `%s' (%p)\n"),
               GNUNET_a2s (ap->addr, ap->addrlen), h);
+#endif
   if ((GNUNET_OK != GNUNET_NETWORK_socket_connect (ap->sock,
                                                    ap->addr,
                                                    ap->addrlen)) &&
@@ -872,12 +884,14 @@ GNUNET_CONNECTION_create_from_connect (struct GNUNET_SCHEDULER_Handle *sched,
   struct GNUNET_CONNECTION_Handle *ret;
 
   GNUNET_assert (0 < strlen (hostname));        /* sanity check */
-  ret = GNUNET_malloc (sizeof (struct GNUNET_CONNECTION_Handle) + maxbuf);
+  ret = GNUNET_malloc (sizeof (struct GNUNET_CONNECTION_Handle));
   ret->cfg = cfg;
   ret->sched = sched;
-  ret->write_buffer = (char *) &ret[1];
+
   GNUNET_assert (maxbuf < GNUNET_SERVER_MAX_MESSAGE_SIZE);
-  ret->write_buffer_size = maxbuf;
+  ret->write_buffer_size = GNUNET_SERVER_MIN_BUFFER_SIZE;
+  ret->max_write_buffer_size = maxbuf;
+  ret->write_buffer = GNUNET_malloc(ret->write_buffer_size);
   ret->port = port;
   ret->hostname = GNUNET_strdup (hostname);
   ret->dns_active = GNUNET_RESOLVER_ip_get (sched,
@@ -929,12 +943,13 @@ GNUNET_CONNECTION_create_from_connect_to_unixpath (struct GNUNET_SCHEDULER_Handl
   un->sun_path[0] = '\0';
   slen = sizeof (struct sockaddr_un);
 #endif
-  ret = GNUNET_malloc (sizeof (struct GNUNET_CONNECTION_Handle) + maxbuf);
+  ret = GNUNET_malloc (sizeof (struct GNUNET_CONNECTION_Handle));
   ret->cfg = cfg;
   ret->sched = sched;
-  ret->write_buffer = (char *) &ret[1];
   GNUNET_assert (maxbuf < GNUNET_SERVER_MAX_MESSAGE_SIZE);
-  ret->write_buffer_size = maxbuf;
+  ret->write_buffer_size = GNUNET_SERVER_MIN_BUFFER_SIZE;
+  ret->max_write_buffer_size = maxbuf;
+  ret->write_buffer = GNUNET_malloc(ret->write_buffer_size);
   ret->port = 0;
   ret->hostname = NULL;
   ret->addr = (struct sockaddr*) un;
@@ -1596,9 +1611,19 @@ GNUNET_CONNECTION_notify_transmit_ready (struct GNUNET_CONNECTION_Handle
                                          GNUNET_CONNECTION_TransmitReadyNotify
                                          notify, void *notify_cls)
 {
+  size_t temp_size;
   if (sock->nth.notify_ready != NULL)
     return NULL;
   GNUNET_assert (notify != NULL);
+  if ((sock->write_buffer_size < size) && (size < sock->max_write_buffer_size))
+    {
+      temp_size = sock->write_buffer_size + size;
+      if (temp_size > sock->max_write_buffer_size)
+        temp_size = sock->max_write_buffer_size;
+
+      sock->write_buffer = GNUNET_realloc(sock->write_buffer, temp_size);
+      sock->write_buffer_size = temp_size;
+    }
   GNUNET_assert (sock->write_buffer_size >= size);
   GNUNET_assert (sock->write_buffer_off <= sock->write_buffer_size);
   GNUNET_assert (sock->write_buffer_pos <= sock->write_buffer_size);
index 9dc47e94b4dd7840baf2f7e3d6c8a25c6c2135cd..d7a109f3b91b135e1ae59c5a538c9fc9ce143bc7 100644 (file)
@@ -59,6 +59,11 @@ struct GNUNET_SERVER_MessageStreamTokenizer
   /**
    * Size of the buffer (starting at 'hdr').
    */
+  size_t curr_buf;
+
+  /**
+   * Maximum size of the buffer.
+   */
   size_t maxbuf;
 
   /**
@@ -74,7 +79,7 @@ struct GNUNET_SERVER_MessageStreamTokenizer
   /**
    * Beginning of the buffer.  Typed like this to force alignment.
    */
-  struct GNUNET_MessageHeader hdr;
+  struct GNUNET_MessageHeader *hdr;
 
 };
 
@@ -96,7 +101,9 @@ GNUNET_SERVER_mst_create (size_t maxbuf,
 {
   struct GNUNET_SERVER_MessageStreamTokenizer *ret;
 
-  ret = GNUNET_malloc (maxbuf + sizeof (struct GNUNET_SERVER_MessageStreamTokenizer));
+  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;
@@ -134,6 +141,7 @@ 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,
@@ -141,12 +149,22 @@ 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;
+  ibuf = (char*)mst->hdr;
   while (mst->pos > 0)
     {
     do_align:
-      if ( (mst->maxbuf - mst->off < sizeof (struct GNUNET_MessageHeader)) ||
+      if ( (mst->curr_buf - mst->off < sizeof (struct GNUNET_MessageHeader)) ||
           (0 != (mst->off % ALIGN_FACTOR)) )
        {
          /* need to align or need more space */
@@ -183,7 +201,7 @@ GNUNET_SERVER_mst_receive (struct GNUNET_SERVER_MessageStreamTokenizer *mst,
          GNUNET_break_op (0);
          return GNUNET_SYSERR;
        }
-      if (mst->maxbuf - mst->off < want)
+      if (mst->curr_buf - mst->off < want)
        {
          /* need more space */
          mst->pos -= mst->off;
@@ -271,7 +289,7 @@ GNUNET_SERVER_mst_receive (struct GNUNET_SERVER_MessageStreamTokenizer *mst,
  copy:
   if ( (size > 0) && (! purge) )
     {
-      GNUNET_assert (mst->pos + size <= mst->maxbuf);
+      GNUNET_assert (mst->pos + size <= mst->curr_buf);
       memcpy (&ibuf[mst->pos], buf, size);
       mst->pos += size;
     }
index 46a01a098fe49df3e7bf8cc0bacae8b0c2861b76..c34c5aa32c11925ca4403e4d7e0f1452e37ba079 100644 (file)
@@ -1656,7 +1656,7 @@ GNUNET_SERVICE_start (const char *serviceName,
   sctx->ready_confirm_fd = -1;  /* no daemonizing */
   sctx->ret = GNUNET_OK;
   sctx->timeout = GNUNET_TIME_UNIT_FOREVER_REL;
-  sctx->maxbuf = GNUNET_SERVER_MAX_MESSAGE_SIZE - 1;
+  sctx->maxbuf = GNUNET_SERVER_MAX_MESSAGE_SIZE;
   sctx->serviceName = serviceName;
   sctx->cfg = cfg;
   sctx->sched = sched;