process inbound type map messages:
authorChristian Grothoff <christian@grothoff.org>
Tue, 11 Oct 2011 08:56:00 +0000 (08:56 +0000)
committerChristian Grothoff <christian@grothoff.org>
Tue, 11 Oct 2011 08:56:00 +0000 (08:56 +0000)
src/core/gnunet-service-core_clients.c
src/core/gnunet-service-core_clients.h
src/core/gnunet-service-core_kx.c
src/core/gnunet-service-core_sessions.c
src/core/gnunet-service-core_sessions.h
src/core/gnunet-service-core_typemap.c
src/core/gnunet-service-core_typemap.h

index 0b1616c9795455c62a5affffe5babafa9bc8e47f..9b442bf30ec3b97995cc3414f3934fcd6531b0a4 100644 (file)
@@ -578,7 +578,7 @@ GSC_CLIENTS_reject_request (struct GSC_ClientActiveRequest *car)
  * @param tmap_new updated type map for the neighbour, NULL for disconnect
  */
 void
-GDS_CLIENTS_notify_client_about_neighbour (struct GSC_Client *client,
+GSC_CLIENTS_notify_client_about_neighbour (struct GSC_Client *client,
                                           const struct GNUNET_PeerIdentity *neighbour,
                                           const struct GNUNET_TRANSPORT_ATS_Information *atsi,
                                           unsigned int atsi_count,
@@ -651,7 +651,7 @@ GDS_CLIENTS_notify_client_about_neighbour (struct GSC_Client *client,
  * @param tmap_new updated type map for the neighbour, NULL for disconnect
  */
 void
-GDS_CLIENTS_notify_clients_about_neighbour (const struct GNUNET_PeerIdentity *neighbour,
+GSC_CLIENTS_notify_clients_about_neighbour (const struct GNUNET_PeerIdentity *neighbour,
                                            const struct GNUNET_TRANSPORT_ATS_Information *atsi,
                                            unsigned int atsi_count,
                                            const struct GSC_TypeMap *tmap_old,
@@ -660,7 +660,7 @@ GDS_CLIENTS_notify_clients_about_neighbour (const struct GNUNET_PeerIdentity *ne
   struct GSC_Client *c;
 
   for (c = client_head; c != NULL; c = c->next)
-    GDS_CLIENTS_notify_client_about_neighbour (c, neighbour, atsi,
+    GSC_CLIENTS_notify_client_about_neighbour (c, neighbour, atsi,
                                               atsi_count, 
                                               tmap_old, tmap_new);
 }
@@ -713,6 +713,7 @@ GSC_CLIENTS_deliver_message (const struct GNUNET_PeerIdentity *sender,
               GNUNET_i2s (sender),
               (unsigned int) ntohs (msg->type));
 #endif
+  GSC_SESSIONS_add_to_typemap (sender, ntohs (msg->type));
   ntm = (struct NotifyTrafficMessage *) buf;
   ntm->header.size = htons (size);
   ntm->header.type = htons (GNUNET_MESSAGE_TYPE_CORE_NOTIFY_INBOUND);
index 7e316d90ff6763658e05768b36eabd9106cedfa3..9774292c08415829e9afb5f02b48c00fd8c7188e 100644 (file)
@@ -58,7 +58,7 @@ GSC_CLIENTS_send_to_client (struct GNUNET_SERVER_Client *client,
  * @param tmap_new updated type map for the neighbour, NULL for disconnect
  */
 void
-GDS_CLIENTS_notify_client_about_neighbour (struct GSC_Client *client,
+GSC_CLIENTS_notify_client_about_neighbour (struct GSC_Client *client,
                                           const struct GNUNET_PeerIdentity *neighbour,
                                           const struct GNUNET_TRANSPORT_ATS_Information *atsi,
                                           unsigned int atsi_count,
@@ -78,7 +78,7 @@ GDS_CLIENTS_notify_client_about_neighbour (struct GSC_Client *client,
  * @param tmap_new updated type map for the neighbour, NULL for disconnect
  */
 void
-GDS_CLIENTS_notify_clients_about_neighbour (const struct GNUNET_PeerIdentity *neighbour,
+GSC_CLIENTS_notify_clients_about_neighbour (const struct GNUNET_PeerIdentity *neighbour,
                                            const struct GNUNET_TRANSPORT_ATS_Information *atsi,
                                            unsigned int atsi_count,
                                            const struct GSC_TypeMap *tmap_old,
index 8daf49826663417b8313e90f10f2bf0b4ee45003..19b692ab945581c4d54760ea4464011064f04e2e 100644 (file)
@@ -1418,16 +1418,25 @@ deliver_message (void *cls, void *client, const struct GNUNET_MessageHeader *m)
 {
   struct DeliverMessageContext *dmc = client;
 
-  GSC_CLIENTS_deliver_message (dmc->peer,
-                              dmc->atsi, dmc->atsi_count,
-                              m,
-                              ntohs (m->size),
-                              GNUNET_CORE_OPTION_SEND_FULL_INBOUND);
-  GSC_CLIENTS_deliver_message (dmc->peer,
-                              dmc->atsi, dmc->atsi_count,
-                              m,
-                              sizeof (struct GNUNET_MessageHeader),
-                              GNUNET_CORE_OPTION_SEND_HDR_INBOUND);
+  switch (ntohs (m->type))
+  {
+  case GNUNET_MESSAGE_TYPE_CORE_BINARY_TYPE_MAP:
+  case GNUNET_MESSAGE_TYPE_CORE_COMPRESSED_TYPE_MAP:
+    GSC_SESSIONS_set_typemap (dmc->peer,
+                             m); 
+    return;
+  default:
+    GSC_CLIENTS_deliver_message (dmc->peer,
+                                dmc->atsi, dmc->atsi_count,
+                                m,
+                                ntohs (m->size),
+                                GNUNET_CORE_OPTION_SEND_FULL_INBOUND);
+    GSC_CLIENTS_deliver_message (dmc->peer,
+                                dmc->atsi, dmc->atsi_count,
+                                m,
+                                sizeof (struct GNUNET_MessageHeader),
+                                GNUNET_CORE_OPTION_SEND_HDR_INBOUND);
+  }
 }
 
 
index 7b159022cc7d8c9bcee7f758943f1d8562cb1387..4808576423a7398523222832b404f26eabe4e355 100644 (file)
@@ -188,6 +188,11 @@ GSC_SESSIONS_end (const struct GNUNET_PeerIdentity *pid)
                         gettext_noop ("# established sessions"),
                         GNUNET_CONTAINER_multihashmap_size (sessions), 
                         GNUNET_NO);
+  if (NULL != session->tmap)
+  {
+    GSC_TYPEMAP_destroy (session->tmap);
+    session->tmap = NULL;
+  }
   GNUNET_free (session);
 }
 
@@ -247,7 +252,7 @@ notify_client_about_session (void *cls,
   struct GSC_Client *client = cls;
   struct Session *session = value;
 
-  GDS_CLIENTS_notify_client_about_neighbour (client,
+  GSC_CLIENTS_notify_client_about_neighbour (client,
                                             &session->peer,
                                             NULL, 0, /* FIXME: ATS!? */
                                             NULL, /* old TMAP: none */
@@ -689,6 +694,66 @@ GSC_SESSIONS_handle_client_have_peer (void *cls, struct GNUNET_SERVER_Client *cl
 }
 
 
+/**
+ * We've received a typemap message from a peer, update ours.
+ * Notifies clients about the session.
+ *
+ * @param peer peer this is about
+ * @param msg typemap update message
+ */
+void
+GSC_SESSIONS_set_typemap (const struct GNUNET_PeerIdentity *peer,
+                         const struct GNUNET_MessageHeader *msg)
+{
+  struct Session *session;
+  struct GSC_TypeMap *nmap;
+
+  nmap = GSC_TYPEMAP_get_from_message (msg);
+  if (NULL == nmap)
+    return; /* malformed */
+  session = find_session (peer);
+  GSC_CLIENTS_notify_clients_about_neighbour (peer,
+                                             NULL, 0, /* FIXME: ATS */
+                                             session->tmap,
+                                             nmap);
+  if (NULL != session->tmap)
+    GSC_TYPEMAP_destroy (session->tmap);
+  session->tmap = nmap;
+}
+
+
+/**
+ * The given peer send a message of the specified type.  Make sure the
+ * respective bit is set in its type-map and that clients are notified
+ * about the session.
+ *
+ * @param peer peer this is about
+ * @param type type of the message
+ */
+void
+GSC_SESSIONS_add_to_typemap (const struct GNUNET_PeerIdentity *peer,
+                            uint16_t type)
+{
+  struct Session *session;
+  struct GSC_TypeMap *nmap;
+
+  session = find_session (peer);
+  if (GNUNET_YES ==
+      GSC_TYPEMAP_test_match (session->tmap,
+                             &type, 1))
+    return; /* already in it */
+  nmap = GSC_TYPEMAP_extend (session->tmap,
+                            &type, 1);
+  GSC_CLIENTS_notify_clients_about_neighbour (peer,
+                                             NULL, 0, /* FIXME: ATS */
+                                             session->tmap,
+                                             nmap);
+  if (NULL != session->tmap)
+    GSC_TYPEMAP_destroy (session->tmap);
+  session->tmap = nmap;
+}
+
+
 /**
  * Initialize sessions subsystem.
  */
index a795c417c8964daaf6d392f22adc8425d062cb33..b70bd59fdc8e874a951b4c4e86cd41a83ed10e17 100644 (file)
@@ -116,6 +116,30 @@ GSC_SESSIONS_broadcast (const struct GNUNET_MessageHeader *msg);
 void
 GSC_SESSIONS_notify_client_about_sessions (struct GSC_Client *client);
 
+/**
+ * We've received a typemap message from a peer, update ours.
+ * Notifies clients about the session.
+ *
+ * @param peer peer this is about
+ * @param msg typemap update message
+ */
+void
+GSC_SESSIONS_set_typemap (const struct GNUNET_PeerIdentity *peer,
+                         const struct GNUNET_MessageHeader *msg);
+
+
+/**
+ * The given peer send a message of the specified type.  Make sure the
+ * respective bit is set in its type-map and that clients are notified
+ * about the session.
+ *
+ * @param peer peer this is about
+ * @param type type of the message
+ */
+void
+GSC_SESSIONS_add_to_typemap (const struct GNUNET_PeerIdentity *peer,
+                            uint16_t type);
+
 
 /**
  * Handle CORE_ITERATE_PEERS request.  For this request type, the client
index 78dfc2bb901eb15ff87dce0957fbd88c72ce66f8..db9b2a1362add3ca7827a7b978223de26f04d210 100644 (file)
@@ -72,7 +72,6 @@ GSC_TYPEMAP_compute_type_map_message ()
    * should be able to overshoot by more to be safe */
 #endif
   hdr = GNUNET_malloc (dlen + sizeof (struct GNUNET_MessageHeader));
-  hdr->size = htons ((uint16_t) dlen + sizeof (struct GNUNET_MessageHeader));
   tmp = (char *) &hdr[1];
   if ((Z_OK !=
        compress2 ((Bytef *) tmp, &dlen, (const Bytef *) &my_type_map,
@@ -86,10 +85,56 @@ GSC_TYPEMAP_compute_type_map_message ()
   {
     hdr->type = htons (GNUNET_MESSAGE_TYPE_CORE_COMPRESSED_TYPE_MAP);
   }
+  hdr->size = htons ((uint16_t) dlen + sizeof (struct GNUNET_MessageHeader));
   return hdr;
 }
 
 
+/**
+ * Extract a type map from a TYPE_MAP message.
+ *
+ * @param msg a type map message
+ * @return NULL on error
+ */
+struct GSC_TypeMap *
+GSC_TYPEMAP_get_from_message (const struct GNUNET_MessageHeader *msg)
+{
+  struct GSC_TypeMap *ret;
+  uint16_t size;
+  uLongf dlen;
+
+  size = ntohs (msg->size);
+  switch (msg->type)
+  {
+  case GNUNET_MESSAGE_TYPE_CORE_BINARY_TYPE_MAP:
+    if (size != sizeof (struct GSC_TypeMap))
+    {
+      GNUNET_break_op (0);
+      return NULL;
+    }
+    ret = GNUNET_malloc (sizeof (struct GSC_TypeMap));
+    memcpy (ret, &msg[1], sizeof (struct GSC_TypeMap));
+    return ret;
+  case GNUNET_MESSAGE_TYPE_CORE_COMPRESSED_TYPE_MAP:
+    ret = GNUNET_malloc (sizeof (struct GSC_TypeMap));
+    dlen = sizeof (struct GSC_TypeMap);
+    if ( (Z_OK !=
+         uncompress ((Bytef*) ret, &dlen,
+                     (const Bytef*) &msg[1], (uLong) size)) ||
+        (dlen != sizeof (struct GSC_TypeMap) ) )
+    {
+      GNUNET_break_op (0);
+      GNUNET_free (ret);
+      return NULL;
+    }
+    return ret;
+  default:
+    GNUNET_break (0);
+    return NULL;
+  }
+}
+
+
 /**
  * Send my type map to all connected peers (it got changed).
  */
@@ -169,12 +214,49 @@ GSC_TYPEMAP_test_match (const struct GSC_TypeMap *tmap,
   unsigned int i;
 
   for (i=0;i<tcnt;i++) 
-    if (0 != (my_type_map.bits[types[i] / 32] & (1 << (types[i] % 32))))
+    if (0 != (tmap->bits[types[i] / 32] & (1 << (types[i] % 32))))
       return GNUNET_YES;
   return GNUNET_NO;
 }
 
 
+/**
+ * Add additional types to a given typemap.
+ *
+ * @param map map to extend (not changed)
+ * @param types array of types to add
+ * @param tcnt number of entries in types
+ * @return updated type map (fresh copy)
+ */ 
+struct GSC_TypeMap *
+GSC_TYPEMAP_extend (const struct GSC_TypeMap *tmap,
+                   const uint16_t *types,
+                   unsigned int tcnt)
+{
+  struct GSC_TypeMap *ret;
+  unsigned int i;
+
+  ret = GNUNET_malloc (sizeof (struct GSC_TypeMap));
+  if (NULL != tmap)
+    memcpy (ret, tmap, sizeof (struct GSC_TypeMap));
+  for (i=0;i<tcnt;i++)
+    ret->bits[types[i] / 32] |= (1 << (types[i] % 32));
+  return ret;
+}
+
+
+/**
+ * Free the given type map.
+ *
+ * @param map a type map
+ */
+void
+GSC_TYPEMAP_destroy (struct GSC_TypeMap *tmap)
+{
+  GNUNET_free (tmap);
+}
+
+
 /**
  * Initialize typemap subsystem.
  */
index 10c614a852018c7e75647ff8c6d48454521210ad..72eb5b566713e2dd394a7b3e5e775e55099400e2 100644 (file)
@@ -60,6 +60,16 @@ struct GNUNET_MessageHeader *
 GSC_TYPEMAP_compute_type_map_message (void);
 
 
+/**
+ * Extract a type map from a TYPE_MAP message.
+ *
+ * @param msg a type map message
+ * @return NULL on error
+ */
+struct GSC_TypeMap *
+GSC_TYPEMAP_get_from_message (const struct GNUNET_MessageHeader *msg);
+
+
 /**
  * Test if any of the types from the types array is in the
  * given type map.
@@ -75,6 +85,29 @@ GSC_TYPEMAP_test_match (const struct GSC_TypeMap *tmap,
                        unsigned int tcnt);
 
 
+/**
+ * Add additional types to a given typemap.
+ *
+ * @param map map to extend (not changed)
+ * @param types array of types to add
+ * @param tcnt number of entries in types
+ * @return updated type map (fresh copy)
+ */ 
+struct GSC_TypeMap *
+GSC_TYPEMAP_extend (const struct GSC_TypeMap *tmap,
+                   const uint16_t *types,
+                   unsigned int tcnt);
+
+
+/**
+ * Free the given type map.
+ *
+ * @param map a type map
+ */
+void
+GSC_TYPEMAP_destroy (struct GSC_TypeMap *tmap);
+
+
 /**
  * Initialize typemap subsystem.
  */