summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorBart Polot <bart@net.in.tum.de>2015-10-02 03:37:42 +0000
committerBart Polot <bart@net.in.tum.de>2015-10-02 03:37:42 +0000
commit341704937b8b07b415376f8f0bd13bbc7d26d44c (patch)
treeba9be1884b709e99aa481d54c62238ac7d0138c4 /src
parent7df0c2bc1d40a7d98d590dc796f5b429455a23a7 (diff)
Fixed usage of known broken paths. If a connection was destroyed
while handling a neighbor disconnection, cadet tried to reconnect to peers using paths containing the disconnecting peer.
Diffstat (limited to 'src')
-rw-r--r--src/cadet/gnunet-service-cadet_connection.c59
-rw-r--r--src/cadet/gnunet-service-cadet_dht.c1
-rw-r--r--src/cadet/gnunet-service-cadet_peer.c23
-rw-r--r--src/cadet/gnunet-service-cadet_peer.h4
4 files changed, 48 insertions, 39 deletions
diff --git a/src/cadet/gnunet-service-cadet_connection.c b/src/cadet/gnunet-service-cadet_connection.c
index b82c788e9..8c25a46b7 100644
--- a/src/cadet/gnunet-service-cadet_connection.c
+++ b/src/cadet/gnunet-service-cadet_connection.c
@@ -1354,7 +1354,12 @@ connection_cancel_queues (struct CadetConnection *c,
{
GNUNET_SCHEDULER_cancel (fc->poll_task);
fc->poll_task = NULL;
- LOG (GNUNET_ERROR_TYPE_DEBUG, "Cancel POLL in ccq for fc %p\n", fc);
+ LOG (GNUNET_ERROR_TYPE_DEBUG, " cancelled POLL task for fc %p\n", fc);
+ }
+ if (NULL != fc->poll_msg)
+ {
+ GCC_cancel (fc->poll_msg);
+ LOG (GNUNET_ERROR_TYPE_DEBUG, " cancelled POLL msg for fc %p\n", fc);
}
peer = get_hop (c, fwd);
GCP_queue_cancel (peer, c);
@@ -1852,6 +1857,30 @@ unregister_neighbors (struct CadetConnection *c)
/**
+ * Invalidates all paths towards all peers that comprise the connection which
+ * rely on the disconnected peer.
+ *
+ * ~O(n^3) (peers in connection * paths/peer * links/path)
+ *
+ * @param c Connection whose peers' paths to clean.
+ * @param disconnected Peer that disconnected.
+ */
+static void
+invalidate_paths (struct CadetConnection *c, struct CadetPeer *disconnected)
+{
+ struct CadetPeer *peer;
+ unsigned int i;
+
+ for (i = 0; i < c->path->length; i++)
+ {
+ peer = GCP_get_short (c->path->peers[i], GNUNET_NO);
+ if (NULL != peer)
+ GCP_notify_broken_link (peer, &my_full_id, GCP_get_id (disconnected));
+ }
+}
+
+
+/**
* Bind the connection to the peer and the tunnel to that peer.
*
* If the peer has no tunnel, create one. Update tunnel and connection
@@ -3045,20 +3074,6 @@ GCC_destroy (struct CadetConnection *c)
path_destroy (c->path);
c->path = NULL;
- /* Cancel maintainance task (keepalive/timeout) */
- if (NULL != c->fwd_fc.poll_msg)
- {
- GCC_cancel (c->fwd_fc.poll_msg);
- LOG (GNUNET_ERROR_TYPE_DEBUG,
- " POLL msg FWD canceled\n");
- }
- if (NULL != c->bck_fc.poll_msg)
- {
- GCC_cancel (c->bck_fc.poll_msg);
- LOG (GNUNET_ERROR_TYPE_DEBUG,
- " POLL msg BCK canceled\n");
- }
-
/* Delete from tunnel */
if (NULL != c->t)
GCT_remove_connection (c->t, c);
@@ -3069,16 +3084,7 @@ GCC_destroy (struct CadetConnection *c)
GNUNET_SCHEDULER_cancel (c->fwd_maintenance_task);
if (NULL != c->bck_maintenance_task)
GNUNET_SCHEDULER_cancel (c->bck_maintenance_task);
- if (NULL != c->fwd_fc.poll_task)
- {
- GNUNET_SCHEDULER_cancel (c->fwd_fc.poll_task);
- LOG (GNUNET_ERROR_TYPE_DEBUG, " POLL task FWD canceled\n");
- }
- if (NULL != c->bck_fc.poll_task)
- {
- GNUNET_SCHEDULER_cancel (c->bck_fc.poll_task);
- LOG (GNUNET_ERROR_TYPE_DEBUG, " POLL task BCK canceled\n");
- }
+
if (GNUNET_NO == c->was_removed)
{
GNUNET_break (GNUNET_YES ==
@@ -3289,6 +3295,9 @@ GCC_neighbor_disconnected (struct CadetConnection *c, struct CadetPeer *peer)
LOG (GNUNET_ERROR_TYPE_DEBUG,
"shutting down %s, %s disconnected\n",
GCC_2s (c), peer_name);
+
+ invalidate_paths (c, peer);
+
hop = get_prev_hop (c);
if (NULL == hop)
{
diff --git a/src/cadet/gnunet-service-cadet_dht.c b/src/cadet/gnunet-service-cadet_dht.c
index cdc1f5a7f..e4ae52da3 100644
--- a/src/cadet/gnunet-service-cadet_dht.c
+++ b/src/cadet/gnunet-service-cadet_dht.c
@@ -187,6 +187,7 @@ dht_get_id_handler (void *cls, struct GNUNET_TIME_Absolute exp,
s = path_2s (p);
LOG (GNUNET_ERROR_TYPE_INFO, "Got path from DHT: %s\n", s);
GNUNET_free_non_null (s);
+
peer = GCP_get_short (p->peers[p->length - 1], GNUNET_YES);
LOG (GNUNET_ERROR_TYPE_DEBUG, "Got HELLO for %s\n", GCP_2s (peer));
h->callback (h->cls, p);
diff --git a/src/cadet/gnunet-service-cadet_peer.c b/src/cadet/gnunet-service-cadet_peer.c
index d60858321..9d80336bd 100644
--- a/src/cadet/gnunet-service-cadet_peer.c
+++ b/src/cadet/gnunet-service-cadet_peer.c
@@ -358,9 +358,8 @@ notify_broken (void *cls,
struct CadetConnection *c = value;
LOG (GNUNET_ERROR_TYPE_DEBUG,
- "Notifying %s due to %s\n",
- GCC_2s (c),
- GCP_2s (peer));
+ "Notifying %s due to %s disconnect\n",
+ GCC_2s (c), GCP_2s (peer));
GCC_neighbor_disconnected (c, peer);
return GNUNET_YES;
}
@@ -1016,8 +1015,8 @@ peer_get_first_message (const struct CadetPeer *peer)
* paths form the initial tunnel, which can be optimized later.
* Called on each result obtained for the DHT search.
*
- * @param cls closure
- * @param path
+ * @param cls Closure (peer towards a path has been found).
+ * @param path Path created from the DHT query. Will be freed afterwards.
*/
static void
search_handler (void *cls, const struct CadetPeerPath *path)
@@ -1537,7 +1536,7 @@ GCP_queue_cancel (struct CadetPeer *peer,
LOG (GNUNET_ERROR_TYPE_DEBUG,
"GMP queue cancel %s\n",
GC_m2s (q->type));
- GNUNET_break (GNUNET_NO == connection_destroyed);
+ GNUNET_assert (GNUNET_NO == connection_destroyed);
if (GNUNET_MESSAGE_TYPE_CADET_CONNECTION_DESTROY == q->type)
{
q->c = NULL;
@@ -2066,7 +2065,7 @@ GCP_add_connection (struct CadetPeer *peer,
* is the shortest.
*
* @param peer Destination peer to add the path to.
- * @param path New path to add. Last peer must be the peer in arg 1.
+ * @param path New path to add. Last peer must be @c peer.
* Path will be either used of freed if already known.
* @param trusted Do we trust that this path is real?
*
@@ -2206,13 +2205,13 @@ GCP_add_path_to_all (const struct CadetPeerPath *p, int confirmed)
for (i = 0; i < p->length && p->peers[i] != myid; i++) /* skip'em */ ;
for (i++; i < p->length; i++)
{
- struct CadetPeer *aux;
+ struct CadetPeer *peer;
struct CadetPeerPath *copy;
- aux = GCP_get_short (p->peers[i], GNUNET_YES);
+ peer = GCP_get_short (p->peers[i], GNUNET_YES);
copy = path_duplicate (p);
copy->length = i + 1;
- GCP_add_path (aux, copy, p->length < 3 ? GNUNET_NO : confirmed);
+ GCP_add_path (peer, copy, 3 > p->length ? GNUNET_NO : confirmed);
}
GCC_check_connections ();
}
@@ -2531,8 +2530,8 @@ GCP_try_connect (struct CadetPeer *peer)
*/
void
GCP_notify_broken_link (struct CadetPeer *peer,
- struct GNUNET_PeerIdentity *peer1,
- struct GNUNET_PeerIdentity *peer2)
+ const struct GNUNET_PeerIdentity *peer1,
+ const struct GNUNET_PeerIdentity *peer2)
{
struct CadetPeerPath *iter;
struct CadetPeerPath *next;
diff --git a/src/cadet/gnunet-service-cadet_peer.h b/src/cadet/gnunet-service-cadet_peer.h
index 7a60b33bd..65704f9c4 100644
--- a/src/cadet/gnunet-service-cadet_peer.h
+++ b/src/cadet/gnunet-service-cadet_peer.h
@@ -450,8 +450,8 @@ GCP_try_connect (struct CadetPeer *peer);
*/
void
GCP_notify_broken_link (struct CadetPeer *peer,
- struct GNUNET_PeerIdentity *peer1,
- struct GNUNET_PeerIdentity *peer2);
+ const struct GNUNET_PeerIdentity *peer1,
+ const struct GNUNET_PeerIdentity *peer2);
/**