- backport fix to mesh_new
[oweals/gnunet.git] / src / mesh / gnunet-service-mesh.c
index 8db18caf68d700cef762372f5a9629afeb1ed3ab..1f7f14b7ec8983f9ca05f15ad81cc49126f981dd 100644 (file)
@@ -170,6 +170,22 @@ struct MeshPeerQueue
 };
 
 
+/**
+ * Struct to store regex information announced by clients.
+ */
+struct MeshRegexDescriptor
+{
+    /**
+     * Regular expression itself.
+     */
+  char *regex;
+
+    /**
+     * How many characters per edge can we squeeze?
+     */
+  uint16_t compression;
+};
+
 /**
  * Struct containing all info possibly needed to build a package when called
  * back by core.
@@ -691,7 +707,7 @@ struct MeshClient
     /**
      * Regular expressions describing the services offered by this client.
      */
-  char **regexes; // FIXME add timeout? API to remove a regex?
+  struct MeshRegexDescriptor *regexes; // FIXME regex add timeout? API to remove a regex?
 
     /**
      * Number of regular expressions in regexes.
@@ -1287,6 +1303,8 @@ regex_result_iterator (void *cls,
   }
   regex_next_edge(block, SIZE_MAX, ctx);
 
+  GNUNET_STATISTICS_update (stats, "# regex mesh blocks iterated", 1, GNUNET_NO);
+
   return GNUNET_YES;
 }
 
@@ -1312,6 +1330,8 @@ regex_edge_iterator (void *cls,
   char *current;
   size_t current_len;
 
+  GNUNET_STATISTICS_update (stats, "# regex edges iterated", 1, GNUNET_NO);
+
   GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "*    Start of regex edge iterator\n");
   GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "*     descr : %s\n", info->description);
   GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "*     posit : %u\n", ctx->position);
@@ -1397,6 +1417,8 @@ regex_next_edge (const struct MeshRegexBlock *block,
     return; // We are already looking for it
   }
 
+  GNUNET_STATISTICS_update (stats, "# regex nodes traversed", 1, GNUNET_NO);
+
   /* Start search in DHT */
   get_h = 
       GNUNET_DHT_get_start (dht_handle,    /* handle */
@@ -1580,12 +1602,14 @@ regex_iterator (void *cls,
  * @param regex The regular expresion.
  */
 static void
-regex_put (const char *regex)
+regex_put (const struct MeshRegexDescriptor *regex)
 {
   struct GNUNET_REGEX_Automaton *dfa;
 
-  DEBUG_DHT ("  regex_put (%s) start\n", regex);
-  dfa = GNUNET_REGEX_construct_dfa (regex, strlen(regex));
+  DEBUG_DHT ("  regex_put (%s) start\n", regex->regex);
+  dfa = GNUNET_REGEX_construct_dfa (regex->regex,
+                                    strlen(regex->regex),
+                                    regex->compression);
   GNUNET_REGEX_iterate_all_edges (dfa, &regex_iterator, NULL);
   GNUNET_REGEX_automaton_destroy (dfa);
   DEBUG_DHT ("  regex_put (%s) end\n", regex);
@@ -1779,7 +1803,7 @@ announce_regex (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc)
 
   for (i = 0; i < c->n_regex; i++)
   {
-    regex_put (c->regexes[i]);
+    regex_put (&c->regexes[i]);
   }
   c->regex_announce_task = GNUNET_SCHEDULER_add_delayed (app_announce_time,
                                                          &announce_regex,
@@ -3994,23 +4018,25 @@ tunnel_send_child_bck_ack (void *cls,
   struct MeshTunnel *t = cls;
   struct MeshTunnelChildInfo *cinfo;
   struct GNUNET_PeerIdentity peer;
+  uint32_t ack;
 
   GNUNET_PEER_resolve (id, &peer);
   cinfo = tunnel_get_neighbor_fc (t, &peer);
+  ack = cinfo->bck_pid + t->bck_queue_max - t->bck_queue_n;
 
-  if (cinfo->bck_ack != cinfo->bck_pid &&
-      GNUNET_NO == GMC_is_pid_bigger (cinfo->bck_ack, cinfo->bck_pid))
+  if (cinfo->bck_ack == ack)
   {
+    // FIXME fc allow force on poll
     GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
                 "    Not sending ACK, not needed\n");
     return;
   }
+  cinfo->bck_ack = ack;
 
-  cinfo->bck_ack = t->bck_queue_max - t->bck_queue_n + cinfo->bck_pid;
   GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
-              "    Sending BCK ACK %u\n",
-              cinfo->bck_ack);
-  send_ack (t, &peer, cinfo->bck_ack);
+              "    Sending BCK ACK %u (last sent: %u)\n",
+              ack, cinfo->bck_ack);
+  send_ack (t, &peer, ack);
 }
 
 
@@ -4900,6 +4926,9 @@ queue_send (void *cls, size_t size, void *buf)
     GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "*********   not empty\n");
 
     GNUNET_PEER_resolve (peer->id, &dst_id);
+    GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
+                "*********   towards %s\n",
+                GNUNET_i2s(&dst_id));
     /* Check if buffer size is enough for the message */
     if (queue->size > size)
     {
@@ -6517,6 +6546,8 @@ handle_local_client_disconnect (void *cls, struct GNUNET_SERVER_Client *client)
     GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "   (SERVER DOWN)\n");
     return;
   }
+
+//   return; uncomment for regex_profiler
   c = clients;
   while (NULL != c)
   {
@@ -6558,7 +6589,7 @@ handle_local_client_disconnect (void *cls, struct GNUNET_SERVER_Client *client)
       GNUNET_CONTAINER_multihashmap_destroy (c->types);
     for (i = 0; i < c->n_regex; i++)
     {
-      GNUNET_free (c->regexes[i]);
+      GNUNET_free (c->regexes[i].regex);
     }
     GNUNET_free_non_null (c->regexes);
     if (GNUNET_SCHEDULER_NO_TASK != c->regex_announce_task)
@@ -6686,6 +6717,8 @@ static void
 handle_local_announce_regex (void *cls, struct GNUNET_SERVER_Client *client,
                              const struct GNUNET_MessageHeader *message)
 {
+  struct GNUNET_MESH_RegexAnnounce *msg;
+  struct MeshRegexDescriptor rd;
   struct MeshClient *c;
   char *regex;
   size_t len;
@@ -6701,18 +6734,24 @@ handle_local_announce_regex (void *cls, struct GNUNET_SERVER_Client *client,
   }
   GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "  by client %u\n", c->id);
 
-  len = ntohs (message->size) - sizeof(struct GNUNET_MessageHeader);
+  msg = (struct GNUNET_MESH_RegexAnnounce *) message;
+  len = ntohs (message->size) - sizeof(struct GNUNET_MESH_RegexAnnounce);
   regex = GNUNET_malloc (len + 1);
-  memcpy (regex, &message[1], len);
+  memcpy (regex, &msg[1], len);
   regex[len] = '\0';
-  GNUNET_array_append (c->regexes, c->n_regex, regex);
+  rd.regex = regex;
+  rd.compression = ntohs (msg->compression_characters);
+  GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "  length %u\n", len);
+  GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "  regex %s\n", regex);
+  GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "  cm %u\n", ntohs(rd.compression));
+  GNUNET_array_append (c->regexes, c->n_regex, rd);
   if (GNUNET_SCHEDULER_NO_TASK == c->regex_announce_task)
   {
     c->regex_announce_task = GNUNET_SCHEDULER_add_now(&announce_regex, c);
   }
   else
   {
-    regex_put(regex);
+    regex_put(&rd);
   }
   GNUNET_SERVER_receive_done (client, GNUNET_OK);
   GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "announce regex processed\n");
@@ -7674,11 +7713,11 @@ handle_local_to_origin (void *cls, struct GNUNET_SERVER_Client *client,
     GNUNET_SERVER_receive_done (client, GNUNET_SYSERR);
     return;
   }
+  clinfo->bck_pid++;
 
   /* Ok, everything is correct, send the message
    * (pretend we got it from a mesh peer)
    */
-  clinfo->bck_pid++;
   {
     char buf[ntohs (message->size)] GNUNET_ALIGN;
     struct GNUNET_MESH_ToOrigin *copy;
@@ -7689,15 +7728,8 @@ handle_local_to_origin (void *cls, struct GNUNET_SERVER_Client *client,
     GNUNET_PEER_resolve (t->id.oid, &copy->oid);
     copy->tid = htonl (t->id.tid);
     copy->ttl = htonl (default_ttl);
-    if (ntohl (copy->pid) != (t->bck_pid + 1))
-    {
-      GNUNET_break (0);
-      GNUNET_log (GNUNET_ERROR_TYPE_WARNING,
-                  "To Origin PID, expected %u, got %u\n",
-                  t->bck_pid + 1,
-                  ntohl (copy->pid));
-      return;
-    }
+    copy->pid = htonl (t->bck_pid + 1);
+
     copy->sender = my_full_id;
     GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
                 "  calling generic handler...\n");