enum MeshConnectionState state;
/**
- * Path being used for the tunnel.
+ * Path being used for the tunnel. At the origin of the connection
+ * it's a pointer to the destination's path pool, otherwise just a copy.
*/
struct MeshPeerPath *path;
{
GNUNET_PEER_Id id;
- LOG (GNUNET_ERROR_TYPE_DEBUG, "Get prev hop, own pos %u\n", c->own_pos);
if (0 == c->own_pos || c->path->length < 2)
id = c->path->peers[0];
else
|| GNUNET_NO == GMP_is_neighbor (prev_peer))
{
if (GMC_is_origin (c, GNUNET_YES))
- GNUNET_break (0);
- else
- GNUNET_break_op (0);
+ GNUNET_STATISTICS_update (stats, "# local bad paths", 1, GNUNET_NO);
+ GNUNET_STATISTICS_update (stats, "# bad paths", 1, GNUNET_NO);
+
LOG (GNUNET_ERROR_TYPE_DEBUG, " register neighbors failed\n");
- LOG (GNUNET_ERROR_TYPE_DEBUG, " prev: %s, %d\n",
+ LOG (GNUNET_ERROR_TYPE_DEBUG, " prev: %s, neighbor: %d\n",
GMP_2s (prev_peer), GMP_is_neighbor (prev_peer));
- LOG (GNUNET_ERROR_TYPE_DEBUG, " next: %s, %d\n",
+ LOG (GNUNET_ERROR_TYPE_DEBUG, " next: %s, neighbor: %d\n",
GMP_2s (next_peer), GMP_is_neighbor (next_peer));
return GNUNET_SYSERR;
}
struct MeshPeer *peer;
peer = get_next_hop (c);
- GMP_remove_connection (peer, c);
+ if (GNUNET_OK != GMP_remove_connection (peer, c))
+ {
+ GNUNET_break (MESH_CONNECTION_NEW == c->state);
+ LOG (GNUNET_ERROR_TYPE_ERROR, " cstate: %u\n", c->state);
+ }
peer = get_prev_hop (c);
- GMP_remove_connection (peer, c);
-
+ if (GNUNET_OK != GMP_remove_connection (peer, c))
+ {
+ GNUNET_break (MESH_CONNECTION_NEW == c->state);
+ LOG (GNUNET_ERROR_TYPE_ERROR, " cstate: %u\n", c->state);
+ }
}
}
LOG (GNUNET_ERROR_TYPE_DEBUG, " Own position: %u\n", own_pos);
GMP_add_path_to_all (path, GNUNET_NO);
- LOG (GNUNET_ERROR_TYPE_DEBUG, " Creating connection\n");
+ LOG (GNUNET_ERROR_TYPE_DEBUG, " Creating connection\n");
c = GMC_new (cid, NULL, path_duplicate (path), own_pos);
if (NULL == c)
{
type = ntohs (msg->header.type);
LOG (GNUNET_ERROR_TYPE_DEBUG, "\n\n");
LOG (GNUNET_ERROR_TYPE_DEBUG, "got a %s message from %s\n",
- GM_m2s (type), GNUNET_i2s (peer));
+ GM_m2s (type), GNUNET_i2s (peer));
/* Check connection */
c = connection_get (&msg->cid);
LOG (GNUNET_ERROR_TYPE_DEBUG, "WARNING connection unknown\n");
return GNUNET_OK;
}
+ LOG (GNUNET_ERROR_TYPE_DEBUG, " on connection %s\n", GMC_2s (c));
/* Check if origin is as expected */
neighbor = get_prev_hop (c);
c = GNUNET_new (struct MeshConnection);
c->id = *cid;
- GNUNET_CONTAINER_multihashmap_put (connections, &c->id, c,
- GNUNET_CONTAINER_MULTIHASHMAPOPTION_UNIQUE_FAST);
+ GNUNET_assert (GNUNET_OK ==
+ GNUNET_CONTAINER_multihashmap_put (connections,
+ &c->id, c,
+ GNUNET_CONTAINER_MULTIHASHMAPOPTION_UNIQUE_ONLY));
fc_init (&c->fwd_fc);
fc_init (&c->bck_fc);
c->fwd_fc.c = c;
c->bck_fc.c = c;
c->t = t;
- if (own_pos > p->length - 1)
+ GNUNET_assert (own_pos <= p->length - 1);
+ c->own_pos = own_pos;
+ c->path = p;
+
+ if (GNUNET_OK != register_neighbors (c))
{
- GNUNET_break (0);
+ if (0 == own_pos)
+ {
+ GMT_remove_path (c->t, p);
+ c->t = NULL;
+ c->path = NULL;
+ }
GMC_destroy (c);
return NULL;
}
- c->own_pos = own_pos;
- c->path = p;
if (0 == own_pos)
{
GNUNET_SCHEDULER_add_delayed (create_connection_time,
&connection_fwd_keepalive, c);
}
- if (GNUNET_OK != register_neighbors (c))
- {
- GMC_destroy (c);
- return NULL;
- }
return c;
}
GMC_destroy (struct MeshConnection *c)
{
if (NULL == c)
+ {
+ GNUNET_break (0);
return;
+ }
if (2 == c->destroy) /* cancel queues -> GMP_queue_cancel -> q_destroy -> */
return; /* -> message_sent -> GMC_destroy. Don't loop. */
c->fwd_fc.poll_task, c->bck_fc.poll_task);
/* Cancel all traffic */
- connection_cancel_queues (c, GNUNET_YES);
- connection_cancel_queues (c, GNUNET_NO);
+ if (NULL != c->path)
+ {
+ connection_cancel_queues (c, GNUNET_YES);
+ connection_cancel_queues (c, GNUNET_NO);
+ unregister_neighbors (c);
+ }
LOG (GNUNET_ERROR_TYPE_DEBUG, " fc tasks f: %u, b: %u\n",
c->fwd_fc.poll_task, c->bck_fc.poll_task);
LOG (GNUNET_ERROR_TYPE_DEBUG, " *** POLL msg BCK canceled\n");
}
- /* Unregister from neighbors */
- unregister_neighbors (c);
-
- /* Delete */
- GNUNET_STATISTICS_update (stats, "# connections", -1, GNUNET_NO);
+ /* Delete from tunnel */
if (NULL != c->t)
GMT_remove_connection (c->t, c);
- if (GNUNET_NO == GMC_is_origin (c, GNUNET_YES))
+ if (GNUNET_NO == GMC_is_origin (c, GNUNET_YES) && NULL != c->path)
path_destroy (c->path);
if (GNUNET_SCHEDULER_NO_TASK != c->fwd_maintenance_task)
GNUNET_SCHEDULER_cancel (c->fwd_maintenance_task);
GNUNET_break (GNUNET_YES ==
GNUNET_CONTAINER_multihashmap_remove (connections, &c->id, c));
+ GNUNET_STATISTICS_update (stats, "# connections", -1, GNUNET_NO);
GNUNET_free (c);
}