- fixing channel functions
authorBart Polot <bart@net.in.tum.de>
Wed, 9 Oct 2013 14:42:15 +0000 (14:42 +0000)
committerBart Polot <bart@net.in.tum.de>
Wed, 9 Oct 2013 14:42:15 +0000 (14:42 +0000)
src/mesh/gnunet-service-mesh_channel.c
src/mesh/gnunet-service-mesh_channel.h
src/mesh/gnunet-service-mesh_connection.c
src/mesh/gnunet-service-mesh_local.c
src/mesh/gnunet-service-mesh_local.h
src/mesh/gnunet-service-mesh_tunnel.c
src/mesh/gnunet-service-mesh_tunnel.h

index 933949b1689ef91d76b887c88f53891ab45ca039..d280e336f8c614d76e1269e34859131cac9412ac 100644 (file)
@@ -33,6 +33,8 @@
 
 #define LOG(level, ...) GNUNET_log_from(level,"mesh-chn",__VA_ARGS__)
 
+#define MESH_RETRANSMIT_MARGIN  4
+
 /**
  * All the states a connection can be in.
  */
@@ -258,6 +260,16 @@ extern struct GNUNET_STATISTICS_Handle *stats;
 /********************************   STATIC  ***********************************/
 /******************************************************************************/
 
+/**
+ * Destroy a reliable message after it has been acknowledged, either by
+ * direct mid ACK or bitfield. Updates the appropriate data structures and
+ * timers and frees all memory.
+ *
+ * @param copy Message that is no longer needed: remote peer got it.
+ */
+static void
+rel_message_free (struct MeshReliableMessage *copy);
+
 /**
  * We have received a message out of order, or the client is not ready.
  * Buffer it until we receive an ACK from the client or the missing
@@ -624,7 +636,7 @@ channel_send_connections_ack (struct MeshChannel *ch,
 
   LOG (GNUNET_ERROR_TYPE_DEBUG,
                 "Channel send connection %s ack on %s:%X\n",
-                fwd ? "FWD" : "BCK", peer2s (ch->t->peer), ch->gid);
+                fwd ? "FWD" : "BCK", GMT_2s (ch->t), ch->gid);
   GNUNET_break (to_allow == 0);
 }
 
@@ -677,7 +689,7 @@ channel_confirm (struct MeshChannel *ch, int fwd)
 
   LOG (GNUNET_ERROR_TYPE_DEBUG,
               "  channel confirm %s %s:%X\n",
-              fwd ? "FWD" : "BCK", peer2s (ch->t->peer), ch->gid);
+              fwd ? "FWD" : "BCK", GMT_2s (ch->t), ch->gid);
   ch->state = MESH_CHANNEL_READY;
 
   rel = fwd ? ch->root_rel : ch->dest_rel;
@@ -817,34 +829,25 @@ channel_destroy (struct MeshChannel *ch)
     return;
 
   LOG (GNUNET_ERROR_TYPE_DEBUG, "destroying channel %s:%u\n",
-              peer2s (ch->t->peer), ch->gid);
+              GMT_2s (ch->t), ch->gid);
   GMCH_debug (ch);
 
   c = ch->root;
   if (NULL != c)
   {
-    if (GNUNET_YES != GNUNET_CONTAINER_multihashmap32_remove (c->own_channels,
-                                                              ch->lid_root, ch))
-    {
-      GNUNET_break (0);
-    }
+    GML_channel_remove (c, ch->lid_root, ch);
   }
 
   c = ch->dest;
   if (NULL != c)
   {
-    if (GNUNET_YES !=
-        GNUNET_CONTAINER_multihashmap32_remove (c->incoming_channels,
-                                                ch->lid_dest, ch))
-    {
-      GNUNET_break (0);
-    }
+    GML_channel_remove (c, ch->lid_dest, ch);
   }
 
   channel_rel_free_all (ch->root_rel);
   channel_rel_free_all (ch->dest_rel);
 
-  GNUNET_CONTAINER_DLL_remove (ch->t->channel_head, ch->t->channel_tail, ch);
+  GMT_remove_channel (ch->t, ch);
   GNUNET_STATISTICS_update (stats, "# channels", -1, GNUNET_NO);
 
   GNUNET_free (ch);
@@ -875,26 +878,10 @@ channel_new (struct MeshTunnel3 *t,
 
   if (NULL != owner)
   {
-    while (NULL != channel_get (t, t->next_chid))
-    {
-      LOG (GNUNET_ERROR_TYPE_DEBUG, "Channel %u exists (%p)...\n",
-                  t->next_chid, channel_get (t, t->next_chid));
-      t->next_chid = (t->next_chid + 1) & ~GNUNET_MESH_LOCAL_CHANNEL_ID_CLI;
-    }
-    ch->gid = t->next_chid;
-    t->next_chid = (t->next_chid + 1) & ~GNUNET_MESH_LOCAL_CHANNEL_ID_CLI;
-
-    if (GNUNET_OK !=
-        GNUNET_CONTAINER_multihashmap32_put (owner->own_channels, lid_root, ch,
-                                             GNUNET_CONTAINER_MULTIHASHMAPOPTION_UNIQUE_ONLY))
-    {
-      GNUNET_break (0);
-      channel_destroy (ch);
-      GNUNET_SERVER_receive_done (owner->handle, GNUNET_SYSERR);
-      return NULL;
-    }
+    ch->gid = GMT_get_next_chid (t);
+    GML_channel_add (owner, lid_root, ch);
   }
-  GNUNET_CONTAINER_DLL_insert (t->channel_head, t->channel_tail, ch);
+  GMT_add_channel (t, ch);
 
   return ch;
 }
@@ -932,7 +919,7 @@ channel_send_ack (struct MeshChannel *ch, int fwd)
   msg.header.type = htons (GNUNET_MESSAGE_TYPE_MESH_CHANNEL_ACK);
   LOG (GNUNET_ERROR_TYPE_DEBUG,
               "  sending channel %s ack for channel %s:%X\n",
-              fwd ? "FWD" : "BCK", peer2s (ch->t->peer),
+              fwd ? "FWD" : "BCK", GMT_2s (ch->t),
               ch->gid);
 
   msg.chid = htonl (ch->gid);
@@ -940,57 +927,6 @@ channel_send_ack (struct MeshChannel *ch, int fwd)
 }
 
 
-/**
- * Send a message to all clients (local and remote) of this channel
- * notifying that the channel is no longer valid.
- *
- * If some peer or client should not receive the message,
- * should be zero'ed out before calling this function.
- *
- * @param ch The channel whose clients to notify.
- */
-static void
-channel_send_destroy (struct MeshChannel *ch)
-{
-  struct GNUNET_MESH_ChannelManage msg;
-
-  msg.header.size = htons (sizeof (msg));
-  msg.header.type = htons (GNUNET_MESSAGE_TYPE_MESH_CHANNEL_DESTROY);
-  LOG (GNUNET_ERROR_TYPE_DEBUG,
-              "  sending channel destroy for channel %s:%X\n",
-              peer2s (ch->t->peer),
-              ch->gid);
-
-  if (GMCH_is_terminal (ch, GNUNET_NO))
-  {
-    if (NULL != ch->root && GNUNET_NO == ch->root->shutting_down)
-    {
-      msg.chid = htonl (ch->lid_root);
-      send_local_channel_destroy (ch, GNUNET_NO);
-    }
-  }
-  else
-  {
-    msg.chid = htonl (ch->gid);
-    GMCH_send_prebuilt_message (&msg.header, ch, GNUNET_NO);
-  }
-
-  if (GMCH_is_terminal (ch, GNUNET_YES))
-  {
-    if (NULL != ch->dest && GNUNET_NO == ch->dest->shutting_down)
-    {
-      msg.chid = htonl (ch->lid_dest);
-      send_local_channel_destroy (ch, GNUNET_YES);
-    }
-  }
-  else
-  {
-    msg.chid = htonl (ch->gid);
-    GMCH_send_prebuilt_message (&msg.header, ch, GNUNET_YES);
-  }
-}
-
-
 /**
  * Iterator for deleting each channel whose client endpoint disconnected.
  *
@@ -1010,29 +946,86 @@ channel_destroy_iterator (void *cls,
   struct MeshTunnel3 *t;
 
   LOG (GNUNET_ERROR_TYPE_DEBUG,
-              " Channel %X (%X / %X) destroy, due to client %u shutdown.\n",
-              ch->gid, ch->lid_root, ch->lid_dest, c->id);
-  channel_debug (ch);
+              " Channel %X (%X / %X) destroy, due to client %s shutdown.\n",
+              ch->gid, ch->lid_root, ch->lid_dest, GML_2s (c));
+  GMCH_debug (ch);
 
   if (c == ch->dest)
   {
-    LOG (GNUNET_ERROR_TYPE_DEBUG, " Client %u is destination.\n", c->id);
+    LOG (GNUNET_ERROR_TYPE_DEBUG, " Client %s is destination.\n", GML_2s (c));
   }
   if (c == ch->root)
   {
-    LOG (GNUNET_ERROR_TYPE_DEBUG, " Client %u is owner.\n", c->id);
+    LOG (GNUNET_ERROR_TYPE_DEBUG, " Client %s is owner.\n", GML_2s (c));
   }
 
   t = ch->t;
   GMCH_send_destroy (ch);
-  channel_send_destroy (ch);
   channel_destroy (ch);
-  tunnel_destroy_if_empty (t);
+  GMT_destroy_if_empty (t);
 
   return GNUNET_OK;
 }
 
 
+/**
+ * Handle a loopback message: call the appropriate handler for the message type.
+ *
+ * @param ch Channel this message is on.
+ * @param msgh Message header.
+ * @param fwd Is this FWD traffic?
+ */
+void
+handle_loopback (struct MeshChannel *ch,
+                 struct GNUNET_MessageHeader *msgh,
+                 int fwd)
+{
+  uint16_t type;
+
+  type = ntohs (msgh->type);
+  LOG (GNUNET_ERROR_TYPE_DEBUG,
+       "Loopback %s message!\n",
+       GNUNET_MESH_DEBUG_M2S (type));
+
+  switch (type)
+  {
+    case GNUNET_MESSAGE_TYPE_MESH_DATA:
+      /* Don't send hop ACK, wait for client to ACK */
+      GMCH_handle_data (ch, (struct GNUNET_MESH_Data *) msgh, fwd);
+      break;
+
+    case GNUNET_MESSAGE_TYPE_MESH_DATA_ACK:
+      GMCH_handle_data_ack (ch, (struct GNUNET_MESH_DataACK *) msgh, fwd);
+      break;
+
+    case GNUNET_MESSAGE_TYPE_MESH_CHANNEL_CREATE:
+       // FIXME store channel in loopback tunnel?
+      GMCH_handle_create ((struct GNUNET_MESH_ChannelCreate *) msgh,
+                          fwd);
+      break;
+
+    case GNUNET_MESSAGE_TYPE_MESH_CHANNEL_ACK:
+      GMCH_handle_ack (ch,
+                       (struct GNUNET_MESH_ChannelManage *) msgh,
+                       fwd);
+      break;
+
+    case GNUNET_MESSAGE_TYPE_MESH_CHANNEL_DESTROY:
+      GMCH_handle_destroy (ch,
+                           (struct GNUNET_MESH_ChannelManage *) msgh,
+                           fwd);
+      break;
+
+    default:
+      GNUNET_break_op (0);
+      LOG (GNUNET_ERROR_TYPE_DEBUG,
+           "end-to-end message not known (%u)\n",
+           ntohs (msgh->type));
+  }
+}
+
+
+
 /******************************************************************************/
 /********************************    API    ***********************************/
 /******************************************************************************/
@@ -1136,7 +1129,6 @@ void
 GMCH_send_create (struct MeshChannel *ch)
 {
   struct GNUNET_MESH_ChannelMessage msg;
-  struct MeshTunnel3 *t = ch->t;
   uint32_t opt;
 
   if (NULL == ch->dest)
@@ -1146,29 +1138,24 @@ GMCH_send_create (struct MeshChannel *ch)
   opt |= GNUNET_YES == ch->reliable ? GNUNET_MESH_OPTION_RELIABLE : 0;
   opt |= GNUNET_YES == ch->nobuffer ? GNUNET_MESH_OPTION_NOBUFFER : 0;
   GML_send_channel_create (ch->dest, ch->lid_dest, ch->port, opt,
-                           GNUNET_PEER_resolve2 (t->peer->id));
+                           GMT_get_destination (ch->t));
 
 }
 
 /**
  * Notify a client that the channel is no longer valid.
+ * FIXME send on tunnel if some client == NULL?
  *
  * @param ch Channel that is destroyed.
- * @param fwd Forward notification (owner->dest)?
  */
 void
-GMCH_send_destroy (struct MeshChannel *ch, int fwd)
+GMCH_send_destroy (struct MeshChannel *ch)
 {
-  struct GNUNET_MeshClient *c = fwd ? ch->dest : ch->root;
-  uint32_t id = fwd ? ch->lid_dest : ch->lid_root;
-
-  if (NULL == c)
-  {
-//     TODO: send on connection?
-    return;
-  }
+  if (NULL != ch->root)
+    GML_send_channel_destroy (ch->root, ch->lid_root);
 
-  GML_send_channel_destroy (c, id);
+  if (NULL != ch->dest)
+    GML_send_channel_destroy (ch->dest, ch->lid_dest);
 }
 
 
@@ -1198,7 +1185,7 @@ GMCH_send_data (struct MeshChannel *ch,
  * @param ch Channel this is about.
  * @param fwd Is for FWD traffic? (ACK dest->owner)
  */
-static void
+void
 GMCH_send_ack (struct MeshChannel *ch, int fwd)
 {
   struct GNUNET_MESH_DataACK msg;
@@ -1238,7 +1225,7 @@ GMCH_send_ack (struct MeshChannel *ch, int fwd)
   }
   LOG (GNUNET_ERROR_TYPE_DEBUG, " final futures %llX\n", msg.futures);
 
-  send_prebuilt_message_channel (&msg.header, ch, fwd);
+  GMCH_send_prebuilt_message (&msg.header, ch, fwd);
   LOG (GNUNET_ERROR_TYPE_DEBUG, "send_data_ack END\n");
 }
 
@@ -1257,12 +1244,12 @@ GMCH_debug (struct MeshChannel *ch)
     return;
   }
   LOG (GNUNET_ERROR_TYPE_DEBUG, "Channel %s:%X (%p)\n",
-              peer2s (ch->t->peer), ch->gid, ch);
+              GMT_2s (ch->t), ch->gid, ch);
   LOG (GNUNET_ERROR_TYPE_DEBUG, "  root %p/%p\n",
               ch->root, ch->root_rel);
   if (NULL != ch->root)
   {
-    LOG (GNUNET_ERROR_TYPE_DEBUG, "  cli %u\n", ch->root->id);
+    LOG (GNUNET_ERROR_TYPE_DEBUG, "  cli %s\n", GML_2s (ch->root));
     LOG (GNUNET_ERROR_TYPE_DEBUG, "  ready %s\n",
                 ch->root_rel->client_ready ? "YES" : "NO");
     LOG (GNUNET_ERROR_TYPE_DEBUG, "  id %X\n", ch->lid_root);
@@ -1271,7 +1258,7 @@ GMCH_debug (struct MeshChannel *ch)
               ch->dest, ch->dest_rel);
   if (NULL != ch->dest)
   {
-    LOG (GNUNET_ERROR_TYPE_DEBUG, "  cli %u\n", ch->dest->id);
+    LOG (GNUNET_ERROR_TYPE_DEBUG, "  cli %s\n", GML_2s (ch->dest));
     LOG (GNUNET_ERROR_TYPE_DEBUG, "  ready %s\n",
                 ch->dest_rel->client_ready ? "YES" : "NO");
     LOG (GNUNET_ERROR_TYPE_DEBUG, "  id %X\n", ch->lid_dest);
@@ -1439,7 +1426,6 @@ GMCH_handle_data_ack (struct MeshChannel *ch,
 /**
  * Handler for channel create messages.
  *
- * @param t Tunnel this channel is to be created in.
  * @param msg Message.
  * @param fwd Is this FWD traffic? GNUNET_YES : GNUNET_NO;
  */
@@ -1452,7 +1438,6 @@ GMCH_handle_create (const struct GNUNET_MESH_ChannelCreate *msg,
   struct MeshClient *c;
   uint32_t port;
 
-  /* Check if channel exists */
   chid = ntohl (msg->chid);
 
   /* Create channel */
@@ -1522,14 +1507,13 @@ GMCH_handle_destroy (struct MeshChannel *ch,
     return;
   }
 
-  GMCH_send_destroy (ch, fwd);
+  GMCH_send_destroy (ch);
   channel_destroy (ch);
 }
 
 
 /**
- * Sends an already built message on a channel, properly registering
- * all used resources and encrypting the message with the tunnel's key.
+ * Sends an already built message on a channel.
  *
  * @param message Message to send. Function makes a copy of it.
  * @param ch Channel on which this message is transmitted.
@@ -1539,30 +1523,18 @@ void
 GMCH_send_prebuilt_message (const struct GNUNET_MessageHeader *message,
                             struct MeshChannel *ch, int fwd)
 {
-  struct GNUNET_MESH_Encrypted *msg;
   size_t size = ntohs (message->size);
-  char *cbuf[sizeof (struct GNUNET_MESH_Encrypted) + size];
-  uint16_t type;
-  uint64_t iv;
-  
+
   LOG (GNUNET_ERROR_TYPE_DEBUG, "Send on Channel %s:%X %s\n",
-       peer2s (ch->t->peer), ch->gid, fwd ? "FWD" : "BCK");
+       GMT_2s (ch->t), ch->gid, fwd ? "FWD" : "BCK");
   LOG (GNUNET_ERROR_TYPE_DEBUG, "  %s\n",
        GNUNET_MESH_DEBUG_M2S (ntohs (message->type)));
-  
-  if (GMCH_is_terminal (ch, fwd) || ch->t->peer->id == myid)
+
+  if (GMT_is_loopback (ch->t))
   {
-    GMT_handle_decrypted (ch->t, message, fwd);
+    handle_loopback (ch->t, message, fwd);
     return;
   }
-  
-    type = fwd ? GNUNET_MESSAGE_TYPE_MESH_FWD : GNUNET_MESSAGE_TYPE_MESH_BCK;
-    iv = GNUNET_CRYPTO_random_u64 (GNUNET_CRYPTO_QUALITY_NONCE, UINT64_MAX);
-    
-    msg = (struct GNUNET_MESH_Encrypted *) cbuf;
-    msg->header.type = htons (type);
-    msg->header.size = htons (sizeof (struct GNUNET_MESH_Encrypted) + size);
-    msg->iv = GNUNET_htonll (iv);
-    GMT_encrypt (ch->t, &msg[1], message, size, iv, fwd);
-    GMT_send_prebuilt_message (msg, ch->t, ch, fwd);
+
+  GMT_send_prebuilt_message (message, ch->t, ch, fwd);
 }
index 48f3e897d153793da85eae64141128e16045721a..a6f844290bccff4f4ca9916b0cad3534c2547461 100644 (file)
@@ -141,10 +141,9 @@ GMCH_send_create (struct MeshChannel *ch);
  * Notify a client that the channel is no longer valid.
  *
  * @param ch Channel that is destroyed.
- * @param fwd Forward notification (owner->dest)?
  */
 void
-GMCH_send_destroy (struct MeshChannel *ch, int fwd);
+GMCH_send_destroy (struct MeshChannel *ch);
 
 
 /**
index edcb7995313ce500bcad058b52cb9eb12efad122..776690a76ab39e5256861426b72339f1abc74afc 100644 (file)
@@ -41,7 +41,6 @@
                                   GNUNET_TIME_UNIT_MINUTES,\
                                   10)
 #define MESH_RETRANSMIT_TIME    GNUNET_TIME_UNIT_SECONDS
-#define MESH_RETRANSMIT_MARGIN  4
 
 #define LOG(level, ...) GNUNET_log_from (level,"mesh-con",__VA_ARGS__)
 
index 9d7db28bc1d753dfaa8159a3fdde16b580df9f02..3fea3a7143db370ec3304a3d5b16a970a73bc16b 100644 (file)
@@ -848,6 +848,7 @@ GML_shutdown (void)
   }
 }
 
+
 /**
  * Get a chennel from a client
  *
@@ -870,6 +871,49 @@ GML_channel_get (struct MeshClient *c, MESH_ChannelNumber chid)
   return GNUNET_CONTAINER_multihashmap32_get (c->own_channels, chid);
 }
 
+
+/**
+ * Add a channel to a client
+ *
+ * @param client Client.
+ * @param chid Channel ID.
+ * @param ch Channel.
+ */
+void
+GML_channel_add (struct MeshClient *client,
+                 uint32_t chid,
+                 struct MeshChannel *ch)
+{
+  if (chid >= GNUNET_MESH_LOCAL_CHANNEL_ID_SERV)
+    GNUNET_CONTAINER_multihashmap32_put (client->incoming_channels, chid, ch,
+                                         GNUNET_CONTAINER_MULTIHASHMAPOPTION_UNIQUE_ONLY);
+  else if (chid >= GNUNET_MESH_LOCAL_CHANNEL_ID_CLI)
+    GNUNET_CONTAINER_multihashmap32_put (client->own_channels, chid, ch,
+                                         GNUNET_CONTAINER_MULTIHASHMAPOPTION_UNIQUE_ONLY);
+  else
+    GNUNET_break (0);
+}
+
+/**
+ * Remove a channel from a client
+ *
+ * @param client Client.
+ * @param chid Channel ID.
+ * @param ch Channel.
+ */
+void
+GML_channel_remove (struct MeshClient *client,
+                    uint32_t chid,
+                    struct MeshChannel *ch)
+{
+  if (chid >= GNUNET_MESH_LOCAL_CHANNEL_ID_SERV)
+    GNUNET_CONTAINER_multihashmap32_remove (c->incoming_channels, chid, ch);
+  else if (chid >= GNUNET_MESH_LOCAL_CHANNEL_ID_CLI)
+    GNUNET_CONTAINER_multihashmap32_remove (c->own_channels, chid, ch);
+  else
+    GNUNET_break (0);
+}
+
 /**
  * Check if client has registered with the service and has not disconnected
  *
@@ -1056,4 +1100,18 @@ GML_send_data (struct MeshClient *c,
 }
 
 
+/**
+ * Get the static string to represent a client.
+ *
+ * @param c Client.
+ *
+ * @return Static string for the client.
+ */
+const char *
+GML_2s (const struct MeshClient *c)
+{
+  static char buf[32];
 
+  sprintf (buf, "%u", c->id);
+  return buf;
+}
index 22a8f8e6d5809941325ee1e9bf326f079f2f23cf..637a87aeb7501d1dbcf32b773bf800376ecc265a 100644 (file)
@@ -82,6 +82,30 @@ GML_shutdown (void);
 struct MeshChannel *
 GML_channel_get (struct MeshClient *client, uint32_t chid);
 
+/**
+ * Add a channel to a client
+ *
+ * @param client Client.
+ * @param chid Channel ID.
+ * @param ch Channel.
+ */
+void
+GML_channel_add (struct MeshClient *client,
+                 uint32_t chid,
+                 struct MeshChannel *ch);
+
+/**
+ * Remove a channel from a client
+ *
+ * @param client Client.
+ * @param chid Channel ID.
+ * @param ch Channel.
+ */
+void
+GML_channel_remove (struct MeshClient *client,
+                    uint32_t chid,
+                    struct MeshChannel *ch);
+
 /**
  * Check if client has registered with the service and has not disconnected
  *
@@ -155,6 +179,16 @@ GML_send_data (struct MeshChannel *ch,
                const struct GNUNET_MESH_Data *msg,
                struct MeshClient *c, MESH_ChannelNumber id);
 
+/**
+ * Get the static string to represent a client.
+ *
+ * @param c Client.
+ *
+ * @return Static string for the client.
+ */
+const char *
+GML_2s (const struct MeshClient *c);
+
 
 #if 0                           /* keep Emacsens' auto-indent happy */
 {
index e709a0be544e2c4d58153a3d4c9f6943b61de418..362ce7e74e55c621c255bd1d31699f49977d1711 100644 (file)
@@ -224,33 +224,6 @@ GMT_state2s (enum MeshTunnelState s)
   }
 }
 
-
-/**
- * Search for a channel by global ID using full PeerIdentities.
- *
- * @param t Tunnel containing the channel.
- * @param chid Public channel number.
- *
- * @return channel handler, NULL if doesn't exist
- */
-static struct MeshChannel *
-get_channel (struct MeshTunnel3 *t, MESH_ChannelNumber chid)
-{
-  struct MeshTChannel *iter;
-
-  if (NULL == t)
-    return NULL;
-
-  for (iter = t->channel_head; NULL != iter; iter = iter->next)
-  {
-    if (GMCH_get_id (iter->ch) == chid)
-      break;
-  }
-
-  return NULL == iter ? NULL : iter->ch;
-}
-
-
 /**
  * Pick a connection on which send the next data message.
  *
@@ -314,7 +287,7 @@ handle_data (struct MeshTunnel3 *t,
               GNUNET_MESH_DEBUG_M2S (ntohs (msg[1].header.type)));
 
   /* Check channel */
-  ch = get_channel (t, ntohl (msg->chid));
+  ch = GMT_get_channel (t, ntohl (msg->chid));
   if (NULL == ch)
   {
     GNUNET_STATISTICS_update (stats, "# data on unknown channel",
@@ -345,7 +318,7 @@ handle_data_ack (struct MeshTunnel3 *t,
   }
 
   /* Check channel */
-  ch = get_channel (t, ntohl (msg->chid));
+  ch = GMT_get_channel (t, ntohl (msg->chid));
   if (NULL == ch)
   {
     GNUNET_STATISTICS_update (stats, "# data ack on unknown channel",
@@ -376,7 +349,7 @@ handle_ch_create (struct MeshTunnel3 *t,
   }
 
   /* Check channel */
-  ch = get_channel (t, ntohl (msg->chid));
+  ch = GMT_get_channel (t, ntohl (msg->chid));
   if (NULL != ch)
   {
     /* Probably a retransmission, safe to ignore */
@@ -409,7 +382,7 @@ handle_ch_ack (struct MeshTunnel3 *t,
   }
 
   /* Check channel */
-  ch = get_channel (t, ntohl (msg->chid));
+  ch = GMT_get_channel (t, ntohl (msg->chid));
   if (NULL == ch)
   {
     GNUNET_STATISTICS_update (stats, "# channel ack on unknown channel",
@@ -439,7 +412,7 @@ handle_ch_destroy (struct MeshTunnel3 *t,
   }
 
   /* Check channel */
-  ch = get_channel (t, ntohl (msg->chid));
+  ch = GMT_get_channel (t, ntohl (msg->chid));
   if (NULL == ch)
   {
     /* Probably a retransmission, safe to ignore */
@@ -710,6 +683,74 @@ GMT_remove_connection (struct MeshTunnel3 *t, struct MeshConnection *c)
 }
 
 
+/**
+ * Add a channel to a tunnel.
+ *
+ * @param t Tunnel.
+ * @param ch Channel.
+ */
+void
+GMT_add_channel (struct MeshTunnel3 *t, struct MeshChannel *ch)
+{
+  struct MeshTChannel *aux;
+
+  for (aux = t->channel_head; aux != NULL; aux = aux->next)
+    if (aux->ch == ch)
+      return;
+
+  aux = GNUNET_new (struct MeshTChannel);
+  aux->ch = ch;
+  GNUNET_CONTAINER_DLL_insert_tail (t->channel_head, t->channel_tail, aux);
+}
+
+
+/**
+ * Remove a channel from a tunnel.
+ *
+ * @param t Tunnel.
+ * @param ch Channel.
+ */
+void
+GMT_remove_channel (struct MeshTunnel3 *t, struct MeshChannel *ch)
+{
+  struct MeshTChannel *aux;
+
+  for (aux = t->channel_head; aux != NULL; aux = aux->next)
+    if (aux->ch == ch)
+    {
+      GNUNET_CONTAINER_DLL_remove (t->channel_head, t->channel_tail, aux);
+      GNUNET_free (aux);
+      return;
+    }
+}
+
+
+/**
+ * Search for a channel by global ID.
+ *
+ * @param t Tunnel containing the channel.
+ * @param chid Public channel number.
+ *
+ * @return channel handler, NULL if doesn't exist
+ */
+struct MeshChannel *
+GMT_get_channel (struct MeshTunnel3 *t, MESH_ChannelNumber chid)
+{
+  struct MeshTChannel *iter;
+
+  if (NULL == t)
+    return NULL;
+
+  for (iter = t->channel_head; NULL != iter; iter = iter->next)
+  {
+    if (GMCH_get_id (iter->ch) == chid)
+      break;
+  }
+
+  return NULL == iter ? NULL : iter->ch;
+}
+
+
 /**
  * Tunnel is empty: destroy it.
  *
@@ -874,6 +915,7 @@ GMT_use_path (struct MeshTunnel3 *t, struct MeshPeerPath *p)
 /**
  * FIXME FIXME FIXME FIXME FIXME FIXME FIXME FIXME FIXME FIXME FIXME
  * Encrypt data with the tunnel key.
+ * Make static?
  *
  * @param t Tunnel whose key to use.
  * @param dst Destination for the encrypted data.
@@ -894,6 +936,7 @@ GMT_encrypt (struct MeshTunnel3 *t,
 /**
  * FIXME FIXME FIXME FIXME FIXME FIXME FIXME FIXME FIXME FIXME FIXME
  * Decrypt data with the tunnel key.
+ * Make static?
  *
  * @param t Tunnel whose key to use.
  * @param dst Destination for the plaintext.
@@ -1016,8 +1059,49 @@ GMT_get_buffer (struct MeshTunnel3 *t, int fwd)
   return buffer;
 }
 
+
+/**
+ * Get the tunnel's destination.
+ *
+ * @param t Tunnel.
+ *
+ * @return ID of the destination peer.
+ */
+const struct GNUNET_PeerIdentity *
+GMT_get_destination (struct MeshTunnel3 *t)
+{
+  return GMP_get_id (t->peer);
+}
+
+
+
 /**
- * Sends an already built message on a tunnel, choosing the best connection.
+ * Get the tunnel's next free Channel ID.
+ *
+ * @param t Tunnel.
+ *
+ * @return ID of a channel free to use.
+ */
+MESH_ChannelNumber
+GMT_get_next_chid (struct MeshTunnel3 *t)
+{
+  MESH_ChannelNumber chid;
+
+  while (NULL != GMT_get_channel (t, t->next_chid))
+  {
+    LOG (GNUNET_ERROR_TYPE_DEBUG, "Channel %u exists...\n", t->next_chid);
+    t->next_chid = (t->next_chid + 1) & ~GNUNET_MESH_LOCAL_CHANNEL_ID_CLI;
+  }
+  chid = t->next_chid;
+  t->next_chid = (t->next_chid + 1) & ~GNUNET_MESH_LOCAL_CHANNEL_ID_CLI;
+
+  return chid;
+}
+
+
+/**
+ * Sends an already built message on a tunnel, encrypting it and
+ * choosing the best connection.
  *
  * @param message Message to send. Function modifies it.
  * @param t Tunnel on which this message is transmitted.
@@ -1025,22 +1109,33 @@ GMT_get_buffer (struct MeshTunnel3 *t, int fwd)
  * @param fwd Is this a fwd message?
  */
 void
-GMT_send_prebuilt_message (struct GNUNET_MESH_Encrypted *msg,
+GMT_send_prebuilt_message (const struct GNUNET_MessageHeader *message,
                            struct MeshTunnel3 *t,
                            struct MeshChannel *ch,
                            int fwd)
 {
   struct MeshConnection *c;
+  struct GNUNET_MESH_Encrypted *msg;
+  size_t size = ntohs (message->size);
+  char *cbuf[sizeof (struct GNUNET_MESH_Encrypted) + size];
+  uint64_t iv;
   uint16_t type;
 
   LOG (GNUNET_ERROR_TYPE_DEBUG, "Send on Tunnel %s\n", GMP_2s (t->peer));
+
+  iv = GNUNET_CRYPTO_random_u64 (GNUNET_CRYPTO_QUALITY_NONCE, UINT64_MAX);
+  msg = (struct GNUNET_MESH_Encrypted *) cbuf;
+  msg->header.type = htons (GNUNET_MESSAGE_TYPE_MESH_ENCRYPTED);
+  msg->header.size = htons (sizeof (struct GNUNET_MESH_Encrypted) + size);
+  msg->iv = GNUNET_htonll (iv);
+  GMT_encrypt (t, &msg[1], message, size, iv, fwd);
   c = tunnel_get_connection (t, fwd);
   if (NULL == c)
   {
     GNUNET_break (GNUNET_YES == t->destroy);
     return;
   }
-  type = ntohs (msg->header.type);
+  type = ntohs (message->type);
   switch (type)
   {
     case GNUNET_MESSAGE_TYPE_MESH_FWD:
@@ -1059,3 +1154,30 @@ GMT_send_prebuilt_message (struct GNUNET_MESH_Encrypted *msg,
 
   GMC_send_prebuilt_message (&msg->header, c, ch, fwd);
 }
+
+/**
+ * Is the tunnel directed towards the local peer?
+ *
+ * @param t Tunnel.
+ *
+ * @return GNUNET_YES if it is loopback.
+ */
+int
+GMT_is_loopback (const struct MeshTunnel3 *t)
+{
+  return (my_short_id == GMP_get_short_id(t->peer));
+}
+
+
+/**
+ * Get the static string for the peer this tunnel is directed.
+ *
+ * @param t Tunnel.
+ *
+ * @return Static string the destination peer's ID.
+ */
+const char *
+GMT_2s (const struct MeshTunnel3 *t)
+{
+  return GMP_2s (t->peer);
+}
\ No newline at end of file
index 49e4ce4b2147efbef5841e1bf0e7f1b4f634e994..242d2c318e6a33fc5d3729c9fa399e0987e8fc55 100644 (file)
@@ -153,7 +153,6 @@ GMT_change_state (struct MeshTunnel3* t, enum MeshTunnelState state);
 void
 GMT_add_connection (struct MeshTunnel3 *t, struct MeshConnection *c);
 
-
 /**
  * Remove a connection from a tunnel.
  *
@@ -163,6 +162,36 @@ GMT_add_connection (struct MeshTunnel3 *t, struct MeshConnection *c);
 void
 GMT_remove_connection (struct MeshTunnel3 *t, struct MeshConnection *c);
 
+/**
+ * Add a channel to a tunnel.
+ *
+ * @param t Tunnel.
+ * @param ch Channel.
+ */
+void
+GMT_add_channel (struct MeshTunnel3 *t, struct MeshChannel *ch);
+
+/**
+ * Remove a channel from a tunnel.
+ *
+ * @param t Tunnel.
+ * @param ch Channel.
+ */
+void
+GMT_remove_channel (struct MeshTunnel3 *t, struct MeshChannel *ch);
+
+/**
+ * Search for a channel by global ID.
+ *
+ * @param t Tunnel containing the channel.
+ * @param chid Public channel number.
+ *
+ * @return channel handler, NULL if doesn't exist
+ */
+struct MeshChannel *
+GMT_get_channel (struct MeshTunnel3 *t, MESH_ChannelNumber chid);
+
+
 /**
  * Cache a message to be sent once tunnel is online.
  *
@@ -227,6 +256,61 @@ GMT_get_state (struct MeshTunnel3 *t);
 unsigned int
 GMT_get_buffer (struct MeshTunnel3 *t, int fwd);
 
+/**
+ * Get the tunnel's destination.
+ *
+ * @param t Tunnel.
+ *
+ * @return ID of the destination peer.
+ */
+const struct GNUNET_PeerIdentity *
+GMT_get_destination (struct MeshTunnel3 *t);
+
+/**
+ * Get the tunnel's next free Channel ID.
+ *
+ * @param t Tunnel.
+ *
+ * @return ID of a channel free to use.
+ */
+MESH_ChannelNumber
+GMT_get_next_chid (struct MeshTunnel3 *t);
+
+/**
+ * Sends an already built message on a tunnel, encrypting it and
+ * choosing the best connection.
+ *
+ * @param message Message to send. Function modifies it.
+ * @param t Tunnel on which this message is transmitted.
+ * @param ch Channel on which this message is transmitted.
+ * @param fwd Is this a fwd message?
+ */
+void
+GMT_send_prebuilt_message (const struct GNUNET_MessageHeader *message,
+                           struct MeshTunnel3 *t,
+                           struct MeshChannel *ch,
+                           int fwd);
+
+/**
+ * Is the tunnel directed towards the local peer?
+ *
+ * @param t Tunnel.
+ *
+ * @return GNUNET_YES if it is loopback.
+ */
+int
+GMT_is_loopback (const struct MeshTunnel3 *t);
+
+/**
+ * Get the static string for the peer this tunnel is directed.
+ *
+ * @param t Tunnel.
+ *
+ * @return Static string the destination peer's ID.
+ */
+const char *
+GMT_2s (const struct MeshTunnel3 *t);
+
 #if 0                           /* keep Emacsens' auto-indent happy */
 {
 #endif