- log wrong TID
[oweals/gnunet.git] / src / mesh / gnunet-service-mesh.c
index 6a56f605b7ac0dfa6ce1ca46eadb5d091a647290..e1ddb559c6467cc3d3789b78b6d41936164472af 100644 (file)
@@ -836,6 +836,16 @@ static struct MeshTunnel *
 tunnel_get (const struct GNUNET_PeerIdentity *oid, MESH_TunnelNumber tid);
 
 
+/**
+ * Change the tunnel state.
+ *
+ * @param t Tunnel whose ttate to change.
+ * @param state New state.
+ */
+static void
+tunnel_change_state (struct MeshTunnel *t, enum MeshTunnelState state);
+
+
 /**
  * Notify a tunnel that a connection has broken that affects at least
  * some of its peers.
@@ -959,6 +969,45 @@ void
 __mesh_divider______________________________________________________________();
 
 
+static const char *
+GNUNET_MESH_DEBUG_S2S (enum MeshTunnelState s)
+{
+  static char buf[128];
+
+  switch (s)
+  {
+    /**
+     * Uninitialized status, should never appear in operation.
+     */
+    case MESH_TUNNEL_NEW: return "MESH_TUNNEL_NEW";
+
+    /**
+     * Path to the peer not known yet
+     */
+    case MESH_TUNNEL_SEARCHING: return "MESH_TUNNEL_SEARCHING";
+
+    /**
+     * Request sent, not yet answered.
+     */
+    case MESH_TUNNEL_WAITING: return "MESH_TUNNEL_WAITING";
+
+    /**
+     * Peer connected and ready to accept data
+     */
+    case MESH_TUNNEL_READY: return "MESH_TUNNEL_READY";
+
+    /**
+     * Peer connected previosly but not responding
+     */
+    case MESH_TUNNEL_RECONNECTING: return "MESH_TUNNEL_RECONNECTING";
+
+    default:
+      sprintf (buf, "%u (UNKNOWN STATE)", s);
+      return buf;
+  }
+}
+
+
 /******************************************************************************/
 /************************    PERIODIC FUNCTIONS    ****************************/
 /******************************************************************************/
@@ -1236,7 +1285,7 @@ send_path_create (struct MeshTunnel *t)
                 (t->path->length * sizeof (struct GNUNET_PeerIdentity)),
              neighbor,
              t);
-  t->state = MESH_TUNNEL_WAITING;
+  tunnel_change_state (t, MESH_TUNNEL_WAITING);
 }
 
 
@@ -1248,16 +1297,16 @@ send_path_create (struct MeshTunnel *t)
 static void
 send_path_ack (struct MeshTunnel *t) 
 {
-  struct MeshPeerInfo *peer;
-
-  peer = peer_get_short (t->prev_hop);
-  t->state = MESH_TUNNEL_WAITING;
+  struct MeshPeerInfo *neighbor;
 
+  GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Send path ack\n");
+  neighbor = peer_get_short (t->prev_hop);
   queue_add (t,
              GNUNET_MESSAGE_TYPE_MESH_PATH_ACK,
              sizeof (struct GNUNET_MESH_PathACK),
-             peer,
+             neighbor,
              t);
+  tunnel_change_state (t, MESH_TUNNEL_WAITING);
 }
 
 
@@ -1574,7 +1623,7 @@ peer_connect (struct MeshPeerInfo *peer, struct MeshTunnel *t)
                                          NULL,       /* xquery */
                                          0,     /* xquery bits */
                                          &dht_get_id_handler, peer);
-    t->state = MESH_TUNNEL_SEARCHING;
+    tunnel_change_state (t, MESH_TUNNEL_SEARCHING);
   }
   else
   {
@@ -2112,13 +2161,18 @@ tunnel_get_incoming (MESH_TunnelNumber tid)
 static struct MeshTunnel *
 tunnel_get_by_local_id (struct MeshClient *c, MESH_TunnelNumber tid)
 {
+  if (0 == (tid & GNUNET_MESH_LOCAL_TUNNEL_ID_CLI))
+  {
+    GNUNET_break_op (0);
+    GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "TID %X not a local tid\n", tid);
+    return NULL;
+  }
   if (tid >= GNUNET_MESH_LOCAL_TUNNEL_ID_SERV)
   {
     return tunnel_get_incoming (tid);
   }
   else
   {
-    GNUNET_assert (tid >= GNUNET_MESH_LOCAL_TUNNEL_ID_CLI);
     return GNUNET_CONTAINER_multihashmap32_get (c->own_tunnels, tid);
   }
 }
@@ -2161,6 +2215,28 @@ tunnel_get (const struct GNUNET_PeerIdentity *oid, MESH_TunnelNumber tid)
 }
 
 
+/**
+ * Change the tunnel state.
+ *
+ * @param t Tunnel whose ttate to change.
+ * @param state New state.
+ */
+static void
+tunnel_change_state (struct MeshTunnel *t, enum MeshTunnelState state)
+{
+  GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
+              "Tunnel %s[%X] state was %s\n",
+              GNUNET_i2s (GNUNET_PEER_resolve2 (t->id.oid)), t->id.tid,
+              GNUNET_MESH_DEBUG_S2S (t->state));
+  GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
+              "Tunnel %s[%X] state is now %s\n",
+              GNUNET_i2s (GNUNET_PEER_resolve2 (t->id.oid)), t->id.tid,
+              GNUNET_MESH_DEBUG_S2S (state));
+  t->state = state;
+}
+
+
+
 /**
  * Add a client to a tunnel, initializing all needed data structures.
  * 
@@ -3107,6 +3183,8 @@ tunnel_new (GNUNET_PEER_Id owner,
   t->owner = client;
   fc_init (&t->next_fc);
   fc_init (&t->prev_fc);
+  t->next_fc.t = t;
+  t->prev_fc.t = t;
   t->local_tid = local;
   n_tunnels++;
   GNUNET_STATISTICS_update (stats, "# tunnels", 1, GNUNET_NO);
@@ -3595,7 +3673,6 @@ queue_send (void *cls, size_t size, void *buf)
       GNUNET_log (GNUNET_ERROR_TYPE_INFO,
                   "*   %s starting poll timeout\n",
                   GNUNET_i2s (&my_full_id));
-      fc->t = t;
       fc->poll_task = GNUNET_SCHEDULER_add_delayed (fc->poll_time,
                                                     &tunnel_poll, fc);
     }
@@ -3810,7 +3887,7 @@ handle_mesh_path_create (void *cls, const struct GNUNET_PeerIdentity *peer,
     GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "  nobuffer:%d\n", t->nobuffer);
   }
   tunnel_reset_timeout (t, GNUNET_YES);
-  t->state = MESH_TUNNEL_WAITING;
+  tunnel_change_state (t,  MESH_TUNNEL_WAITING);
   dest_peer_info =
       GNUNET_CONTAINER_multihashmap_get (peers, &pi[size - 1].hashPubKey);
   if (NULL == dest_peer_info)
@@ -3964,7 +4041,7 @@ handle_mesh_path_ack (void *cls, const struct GNUNET_PeerIdentity *peer,
   {
     GNUNET_break (0);
   }
-  t->state = MESH_TUNNEL_READY;
+  tunnel_change_state (t, MESH_TUNNEL_READY);
   tunnel_reset_timeout (t, GNUNET_NO);
   t->next_fc.last_ack_recv = (NULL == t->client) ? ntohl (msg->ack) : 0;
   t->prev_fc.last_ack_sent = ntohl (msg->ack);
@@ -3990,7 +4067,6 @@ handle_mesh_path_ack (void *cls, const struct GNUNET_PeerIdentity *peer,
 
   GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
               "  not for us, retransmitting...\n");
-  peer_info = peer_get (&msg->oid);
   send_prebuilt_message (message, t->prev_hop, t);
   return GNUNET_OK;
 }
@@ -4170,7 +4246,7 @@ handle_mesh_data (const struct GNUNET_PeerIdentity *peer,
     return GNUNET_OK;
   }
   if (NULL != c)
-    t->state = MESH_TUNNEL_READY;
+    tunnel_change_state (t, MESH_TUNNEL_READY);
   tunnel_reset_timeout (t, fwd);
   if (NULL != c)
   {
@@ -4472,7 +4548,7 @@ handle_mesh_ack (void *cls, const struct GNUNET_PeerIdentity *peer,
 
   fc->last_ack_recv = ack;
   peer_unlock_queue (id);
-  t->state = MESH_TUNNEL_READY;
+  tunnel_change_state (t, MESH_TUNNEL_READY);
 
   tunnel_send_ack (t, GNUNET_MESSAGE_TYPE_MESH_ACK, t->next_hop == id);
 
@@ -4589,7 +4665,7 @@ handle_mesh_keepalive (void *cls, const struct GNUNET_PeerIdentity *peer,
   hop = fwd ? t->next_hop : t->prev_hop;
 
   if (NULL != c)
-    t->state = MESH_TUNNEL_READY;
+    tunnel_change_state (t, MESH_TUNNEL_READY);
   tunnel_reset_timeout (t, fwd);
   if (NULL != c || 0 == hop || myid == hop)
     return GNUNET_OK;
@@ -4879,14 +4955,7 @@ handle_local_tunnel_create (void *cls, struct GNUNET_SERVER_Client *client,
   t_msg = (struct GNUNET_MESH_TunnelMessage *) message;
   GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "  towards %s\n",
               GNUNET_i2s (&t_msg->peer));
-  /* Sanity check for tunnel numbering */
   tid = ntohl (t_msg->tunnel_id);
-  if (0 == (tid & GNUNET_MESH_LOCAL_TUNNEL_ID_CLI))
-  {
-    GNUNET_break (0);
-    GNUNET_SERVER_receive_done (client, GNUNET_SYSERR);
-    return;
-  }
   /* Sanity check for duplicate tunnel IDs */
   if (NULL != tunnel_get_by_local_id (c, tid))
   {
@@ -4968,7 +5037,7 @@ handle_local_tunnel_destroy (void *cls, struct GNUNET_SERVER_Client *client,
 
   /* Retrieve tunnel */
   tid = ntohl (tunnel_msg->tunnel_id);
-  t = tunnel_get_by_local_id(c, tid);
+  t = tunnel_get_by_local_id (c, tid);
   if (NULL == t)
   {
     GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "  tunnel %X not found\n", tid);
@@ -4979,15 +5048,22 @@ handle_local_tunnel_destroy (void *cls, struct GNUNET_SERVER_Client *client,
 
   /* Cleanup after the tunnel */
   client_delete_tunnel (c, t);
-  if (c == t->client)
+  if (c == t->client && GNUNET_MESH_LOCAL_TUNNEL_ID_SERV >= tid)
   {
     t->client = NULL;
   }
-  if (c == t->owner)
+  else if (c == t->owner && GNUNET_MESH_LOCAL_TUNNEL_ID_SERV < tid)
   {
     peer_info_remove_tunnel (peer_get_short (t->dest), t);
     t->owner = NULL;
   }
+  else 
+  {
+    GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
+                "  tunnel %X client %p (%p, %p)\n",
+                tid, c, t->owner, t->client);
+    GNUNET_break (0);
+  }
 
   /* The tunnel will be destroyed when the last message is transmitted. */
   tunnel_destroy_empty (t);
@@ -5040,12 +5116,6 @@ handle_local_data (void *cls, struct GNUNET_SERVER_Client *client,
 
   /* Tunnel exists? */
   tid = ntohl (data_msg->tid);
-  if (tid < GNUNET_MESH_LOCAL_TUNNEL_ID_CLI)
-  {
-    GNUNET_break (0);
-    GNUNET_SERVER_receive_done (client, GNUNET_SYSERR);
-    return;
-  }
   t = tunnel_get_by_local_id (c, tid);
   if (NULL == t)
   {