- implementation of configurable regex compression
[oweals/gnunet.git] / src / mesh / mesh_api.c
index 1162f99808ebbb6c04a3348adb0e6ce4d3e157b9..479203f451ab01e9e19949ad10ba5cc67544b8f6 100644 (file)
@@ -467,6 +467,7 @@ create_tunnel (struct GNUNET_MESH_Handle *h, MESH_TunnelNumber tid)
   }
   t->max_send_pid = INITIAL_WINDOW_SIZE - 1;
   t->last_recv_pid = (uint32_t) -1;
+  t->buffering = GNUNET_YES;
   return t;
 }
 
@@ -653,7 +654,7 @@ timeout_transmission (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc)
 
 
 /**
- * Add a transmit handle to the transmission queue by priority and set the
+ * Add a transmit handle to the transmission queue and set the
  * timeout if needed.
  *
  * @param h mesh handle with the queue head and tail
@@ -663,16 +664,7 @@ static void
 add_to_queue (struct GNUNET_MESH_Handle *h,
               struct GNUNET_MESH_TransmitHandle *th)
 {
-  struct GNUNET_MESH_TransmitHandle *p;
-
-  p = h->th_head;
-  while ((NULL != p))
-    p = p->next;
-  if (NULL == p)
-    p = h->th_tail;
-  else
-    p = p->prev;
-  GNUNET_CONTAINER_DLL_insert_after (h->th_head, h->th_tail, p, th);
+  GNUNET_CONTAINER_DLL_insert_tail (h->th_head, h->th_tail, th);
   if (GNUNET_TIME_UNIT_FOREVER_ABS.abs_value == th->timeout.abs_value)
     return;
   th->timeout_task =
@@ -716,7 +708,10 @@ send_ack (struct GNUNET_MESH_Handle *h, struct GNUNET_MESH_Tunnel *t)
          t->tid, t->max_recv_pid, t->last_recv_pid, delta);
     return;
   }
-  t->max_recv_pid = t->last_recv_pid + INITIAL_WINDOW_SIZE;
+  if (GNUNET_YES == t->buffering)
+    t->max_recv_pid = t->last_recv_pid + INITIAL_WINDOW_SIZE;
+  else
+    t->max_recv_pid = t->last_recv_pid + 1;
   LOG (GNUNET_ERROR_TYPE_DEBUG,
        "Sending ACK on tunnel %X: %u\n",
        t->tid, t->max_recv_pid);
@@ -837,8 +832,10 @@ do_reconnect (struct GNUNET_MESH_Handle *h)
         GNUNET_TIME_relative_min (GNUNET_TIME_UNIT_SECONDS,
                                   GNUNET_TIME_relative_multiply
                                   (h->reconnect_time, 2));
-    LOG (GNUNET_ERROR_TYPE_DEBUG, "  Next retry in %sms\n",
-         GNUNET_TIME_relative_to_string (h->reconnect_time));
+    LOG (GNUNET_ERROR_TYPE_DEBUG, 
+        "Next retry in %s\n",
+         GNUNET_STRINGS_relative_time_to_string (h->reconnect_time,
+                                                GNUNET_NO));
     GNUNET_break (0);
     return GNUNET_NO;
   }
@@ -977,6 +974,12 @@ process_tunnel_created (struct GNUNET_MESH_Handle *h,
     GNUNET_PEER_change_rc (t->owner, 1);
     t->mesh = h;
     t->tid = tid;
+    if ((msg->opt & MESH_TUNNEL_OPT_NOBUFFER) != 0)
+      t->buffering = GNUNET_NO;
+    else
+      t->buffering = GNUNET_YES;
+    if ((msg->opt & MESH_TUNNEL_OPT_SPEED_MIN) != 0)
+      t->speed_min = GNUNET_YES;
     atsi.type = 0;
     atsi.value = 0;
     LOG (GNUNET_ERROR_TYPE_DEBUG, "  created tunnel %p\n", t);
@@ -1153,11 +1156,13 @@ process_incoming_data (struct GNUNET_MESH_Handle *h,
     LOG (GNUNET_ERROR_TYPE_DEBUG, "  ignored!\n");
     return GNUNET_YES;
   }
-    if (GNUNET_YES ==
-        GMC_is_pid_bigger(pid, t->max_recv_pid))
+  if (GNUNET_YES ==
+      GMC_is_pid_bigger(pid, t->max_recv_pid))
   {
     GNUNET_break (0);
-    LOG (GNUNET_ERROR_TYPE_WARNING, "  unauthorized message!\n");
+    LOG (GNUNET_ERROR_TYPE_WARNING,
+         "  unauthorized message! (%u, max %u)\n",
+         pid, t->max_recv_pid);
     // FIXME fc what now? accept? reject?
     return GNUNET_YES;
   }
@@ -1372,6 +1377,7 @@ send_callback (void *cls, size_t size, void *buf)
           to.header.type = htons (GNUNET_MESSAGE_TYPE_MESH_TO_ORIGIN);
           to.tid = htonl (t->tid);
           to.pid = htonl (t->next_send_pid);
+          to.ttl = 0;
           memset (&to.oid, 0, sizeof (struct GNUNET_PeerIdentity));
           memset (&to.sender, 0, sizeof (struct GNUNET_PeerIdentity));
           memcpy (cbuf, &to, sizeof (to));
@@ -1420,6 +1426,7 @@ send_callback (void *cls, size_t size, void *buf)
           uc.header.type = htons (GNUNET_MESSAGE_TYPE_MESH_UNICAST);
           uc.tid = htonl (t->tid);
           uc.pid = htonl (t->next_send_pid);
+          uc.ttl = 0;
           memset (&uc.oid, 0, sizeof (struct GNUNET_PeerIdentity));
           GNUNET_PEER_resolve (th->target, &uc.destination);
           memcpy (cbuf, &uc, sizeof (uc));
@@ -1659,27 +1666,35 @@ GNUNET_MESH_disconnect (struct GNUNET_MESH_Handle *handle)
  * (for instance 'gnunet://'). If you put a variable part in there (*, +. ()),
  * all matching strings will be stored in the DHT.
  *
- * @param h handle to mesh.
- * @param regex string with the regular expression describing local services.
+ * @param h Handle to mesh.
+ * @param regex String with the regular expression describing local services.
+ * @param compression_characters How many characters can be assigned to one
+ *                               edge of the graph. The bigger the variability
+ *                               of the data, the smaller this parameter should
+ *                               be (down to 1).
+ *                               For maximum compression, use strlen (regex)
+ *                               or 0 (special value). Use with care!
  */
 void
 GNUNET_MESH_announce_regex (struct GNUNET_MESH_Handle *h,
-                            const char *regex)
+                            const char *regex,
+                            unsigned int compression_characters)
 {
-  struct GNUNET_MessageHeader *msg;
+  struct GNUNET_MESH_RegexAnnounce *msg;
   size_t len;
   size_t msgsize;
 
   len = strlen (regex);
-  msgsize = sizeof(struct GNUNET_MessageHeader) + len;
+  msgsize = sizeof(struct GNUNET_MESH_RegexAnnounce) + len;
   GNUNET_assert (UINT16_MAX > msgsize);
 
   {
     char buffer[msgsize];
 
-    msg = (struct GNUNET_MessageHeader *) buffer;
-    msg->size = htons (msgsize);
-    msg->type = htons (GNUNET_MESSAGE_TYPE_MESH_LOCAL_ANNOUNCE_REGEX);
+    msg = (struct GNUNET_MESH_RegexAnnounce *) buffer;
+    msg->header.size = htons (msgsize);
+    msg->header.type = htons (GNUNET_MESSAGE_TYPE_MESH_LOCAL_ANNOUNCE_REGEX);
+    msg->compression_characters = htons (compression_characters);
     memcpy (&msg[1], regex, len);
 
     send_packet(h, msg, NULL);
@@ -1822,6 +1837,7 @@ GNUNET_MESH_tunnel_buffer (struct GNUNET_MESH_Tunnel *tunnel, int buffer)
 
   h = tunnel->mesh;
   tunnel->buffering = buffer;
+  tunnel->max_send_pid = tunnel->next_send_pid;
 
   if (GNUNET_YES == buffer)
     msg.header.type = htons (GNUNET_MESSAGE_TYPE_MESH_LOCAL_TUNNEL_BUFFER);