- stop using message types of payload on service side
[oweals/gnunet.git] / src / mesh / gnunet-service-mesh-new.c
index 49b70319a56d8de778e65193e0a445bd6b1cf2a7..6a1eb8b33e17b1a44e5d8bb23bf9cac8f30bb63a 100644 (file)
@@ -398,7 +398,7 @@ struct MeshTunnel
 /**
  * Struct containing information about a client of the service
  * 
- * TODO: add a list of 'waiting' types
+ * TODO: add a list of 'waiting' ports
  */
 struct MeshClient
 {
@@ -428,10 +428,10 @@ struct MeshClient
   struct GNUNET_SERVER_Client *handle;
 
     /**
-     * Messages that this client has declared interest in.
+     * Ports that this client has declared interest in.
      * Indexed by a GMC_hash32 (type), contains *Client.
      */
-  struct GNUNET_CONTAINER_MultiHashMap *types;
+  struct GNUNET_CONTAINER_MultiHashMap *ports;
 
     /**
      * Whether the client is active or shutting down (don't send confirmations
@@ -626,9 +626,9 @@ static MESH_TunnelNumber next_tid;
 static MESH_TunnelNumber next_local_tid;
 
 /**
- * All message types clients of this peer are interested in.
+ * All ports clients of this peer have opened.
  */
-static struct GNUNET_CONTAINER_MultiHashMap *types;
+static struct GNUNET_CONTAINER_MultiHashMap *ports;
 
 /**
  * Task to periodically announce itself in the network.
@@ -919,10 +919,29 @@ client_delete_tunnel (struct MeshClient *c, struct MeshTunnel *t)
   }
 }
 
+/**
+ * Notify the appropiate client that a new incoming tunnel was created.
+ *
+ * @param t Tunnel that was created.
+ */
+static void
+send_client_tunnel_create (struct MeshTunnel *t)
+{
+  struct GNUNET_MESH_TunnelMessage msg;
+
+  if (NULL == t->client)
+    return;
+  msg.header.size = htons (sizeof (msg));
+  msg.header.type = htons (GNUNET_MESSAGE_TYPE_MESH_LOCAL_TUNNEL_CREATE);
+  msg.tunnel_id = htonl (t->local_tid_dest);
+  msg.port = htonl (t->port);
+  GNUNET_SERVER_notification_context_unicast (nc, t->client->handle,
+                                              &msg.header, GNUNET_NO);
+}
+
 
 /**
- * Notify all clients (not depending on registration status) that the incoming
- * tunnel is no longer valid.
+ * Notify dest client that the incoming tunnel is no longer valid.
  *
  * @param t Tunnel that was destroyed.
  */
@@ -2925,6 +2944,7 @@ handle_mesh_path_create (void *cls, const struct GNUNET_PeerIdentity *peer,
       GNUNET_break (0);
       return GNUNET_OK;
     }
+    t->port = ntohl (msg->port);
     opt = ntohl (msg->opt);
     if (0 != (opt & MESH_TUNNEL_OPT_NOBUFFER))
     {
@@ -2946,6 +2966,10 @@ handle_mesh_path_create (void *cls, const struct GNUNET_PeerIdentity *peer,
       return GNUNET_OK;
     }
   }
+  else
+  {
+    GNUNET_break_op (0);
+  }
   t->state = MESH_TUNNEL_WAITING;
   dest_peer_info =
       GNUNET_CONTAINER_multihashmap_get (peers, &pi[size - 1].hashPubKey);
@@ -2995,17 +3019,30 @@ handle_mesh_path_create (void *cls, const struct GNUNET_PeerIdentity *peer,
   GNUNET_PEER_change_rc (t->prev_hop, 1);
   if (own_pos == size - 1)
   {
-    /* It is for us! Send ack. */
-    // TODO: check port number / client registration
+    struct MeshClient *c;
+    struct GNUNET_HashCode hc;
+
+    /* Find target client */
+    GMC_hash32 (t->port, &hc);
+    c = GNUNET_CONTAINER_multihashmap_get (ports, &hc);
+    if (NULL == c)
+    {
+      /* TODO send reject */
+      return GNUNET_OK;
+    }
+    t->client = c;
+
     GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "  It's for us!\n");
-    peer_info_add_path_to_origin (orig_peer_info, path, GNUNET_NO);
+    peer_info_add_path_to_origin (orig_peer_info, path, GNUNET_YES);
     t->dest = myid;
 
+    /* Assign local tid */
     while (NULL != tunnel_get_incoming (next_local_tid))
       next_local_tid = (next_local_tid + 1) | GNUNET_MESH_LOCAL_TUNNEL_ID_SERV;
     t->local_tid_dest = next_local_tid++;
     next_local_tid = next_local_tid | GNUNET_MESH_LOCAL_TUNNEL_ID_SERV;
 
+    send_client_tunnel_create (t);
     send_path_ack (t);
   }
   else
@@ -3775,8 +3812,8 @@ handle_local_client_disconnect (void *cls, struct GNUNET_SERVER_Client *client)
     GNUNET_CONTAINER_multihashmap_destroy (c->own_tunnels);
     GNUNET_CONTAINER_multihashmap_destroy (c->incoming_tunnels);
 
-    if (NULL != c->types)
-      GNUNET_CONTAINER_multihashmap_destroy (c->types);
+    if (NULL != c->ports)
+      GNUNET_CONTAINER_multihashmap_destroy (c->ports);
     next = c->next;
     GNUNET_CONTAINER_DLL_remove (clients_head, clients_tail, c);
     GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "  CLIENT FREE at %p\n", c);
@@ -3803,48 +3840,49 @@ handle_local_new_client (void *cls, struct GNUNET_SERVER_Client *client,
   struct GNUNET_MESH_ClientConnect *cc_msg;
   struct MeshClient *c;
   unsigned int size;
-  uint16_t ntypes;
-  uint16_t *t;
-  uint16_t i;
+  uint32_t *p;
+  unsigned int i;
 
   GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "new client connected\n");
 
   /* Check data sanity */
   size = ntohs (message->size) - sizeof (struct GNUNET_MESH_ClientConnect);
   cc_msg = (struct GNUNET_MESH_ClientConnect *) message;
-  ntypes = ntohs (cc_msg->types);
-  if (size != ntypes * sizeof (uint16_t))
+  if (0 != (size % sizeof (uint32_t)))
   {
     GNUNET_break (0);
     GNUNET_SERVER_receive_done (client, GNUNET_SYSERR);
     return;
   }
+  size /= sizeof (uint32_t);
 
   /* Create new client structure */
   c = GNUNET_malloc (sizeof (struct MeshClient));
   c->id = next_client_id++; /* overflow not important: just for debug */
-  GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "  CLIENT NEW %u\n", c->id);
-  GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "  client has %u types\n", ntypes);
+  GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "  client id %u\n", c->id);
+  GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "  client has %u ports\n", size);
   c->handle = client;
   GNUNET_SERVER_client_keep (client);
-  if (ntypes > 0)
+  if (size > 0)
   {
-    uint16_t u16;
+    uint32_t u32;
     struct GNUNET_HashCode hc;
 
-    t = (uint16_t *) &cc_msg[1];
-    c->types = GNUNET_CONTAINER_multihashmap_create (ntypes, GNUNET_NO);
-    for (i = 0; i < ntypes; i++)
+    p = (uint32_t *) &cc_msg[1];
+    c->ports = GNUNET_CONTAINER_multihashmap_create (size, GNUNET_NO);
+    for (i = 0; i < size; i++)
     {
-      u16 = ntohs (t[i]);
-      GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "    msg type: %u\n", u16);
-      GMC_hash32 ((uint32_t) u16, &hc);
+      u32 = ntohl (p[i]);
+      GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "    port: %u\n", u32);
+      GMC_hash32 (u32, &hc);
 
-      /* store in clients hashmap */
-      GNUNET_CONTAINER_multihashmap_put (c->types, &hc, c,
+      /* store in client's hashmap */
+      GNUNET_CONTAINER_multihashmap_put (c->ports, &hc, c,
                                          GNUNET_CONTAINER_MULTIHASHMAPOPTION_UNIQUE_FAST);
       /* store in global hashmap */
-      GNUNET_CONTAINER_multihashmap_put (types, &hc, c,
+      /* FIXME only allow one client to have the port open,
+       *       have a backup hashmap with waiting clients */
+      GNUNET_CONTAINER_multihashmap_put (ports, &hc, c,
                                          GNUNET_CONTAINER_MULTIHASHMAPOPTION_MULTIPLE);
     }
   }
@@ -4909,7 +4947,7 @@ run (void *cls, struct GNUNET_SERVER_Handle *server,
   tunnels = GNUNET_CONTAINER_multihashmap_create (32, GNUNET_NO);
   incoming_tunnels = GNUNET_CONTAINER_multihashmap_create (32, GNUNET_NO);
   peers = GNUNET_CONTAINER_multihashmap_create (32, GNUNET_NO);
-  types = GNUNET_CONTAINER_multihashmap_create (32, GNUNET_NO);
+  ports = GNUNET_CONTAINER_multihashmap_create (32, GNUNET_NO);
 
   dht_handle = GNUNET_DHT_connect (c, 64);
   if (NULL == dht_handle)