struct MeshPeer *peer = cls;
struct MeshConnection *c = value;
+ LOG (GNUNET_ERROR_TYPE_DEBUG, " notifying %s due to %s\n",
+ GMC_2s (c), GMP_2s (peer));
GMC_notify_broken (c, peer);
return GNUNET_YES;
}
+/**
+ * Remove the direct path to the peer.
+ *
+ * @param peer Peer to remove the direct path from.
+ *
+ */
+static struct MeshPeerPath *
+pop_direct_path (struct MeshPeer *peer)
+{
+ struct MeshPeerPath *iter;
+
+ for (iter = peer->path_head; NULL != iter; iter = iter->next)
+ {
+ if (2 <= iter->length)
+ {
+ GNUNET_CONTAINER_DLL_remove (peer->path_head, peer->path_tail, iter);
+ return iter;
+ }
+ }
+ return NULL;
+}
+
+
+
/**
* Method called whenever a given peer connects.
*
core_disconnect (void *cls, const struct GNUNET_PeerIdentity *peer)
{
struct MeshPeer *p;
+ struct MeshPeerPath *direct_path;
LOG (GNUNET_ERROR_TYPE_DEBUG, "Peer disconnected\n");
p = GNUNET_CONTAINER_multipeermap_get (peers, peer);
return;
}
if (myid == p->id)
- LOG (GNUNET_ERROR_TYPE_DEBUG, " (self)\n");
+ LOG (GNUNET_ERROR_TYPE_DEBUG, " (self: %s)\n", GMP_2s (p));
else
LOG (GNUNET_ERROR_TYPE_DEBUG, " %s\n", GMP_2s (p));
-
+ direct_path = pop_direct_path (p);
GNUNET_CONTAINER_multihashmap_iterate (p->connections, ¬ify_broken, p);
GNUNET_CONTAINER_multihashmap_destroy (p->connections);
p->connections = NULL;
}
GNUNET_STATISTICS_update (stats, "# peers", -1, GNUNET_NO);
+ path_destroy (direct_path);
return;
}
if (GNUNET_YES == GMT_is_path_used (peer->tunnel, p))
continue; /* If path is already in use, skip it. */
+ if (GNUNET_NO == path_is_valid (p))
+ continue; /* Don't use invalid paths. */
+
if ((cost = GMT_get_path_cost (peer->tunnel, p)) < best_cost)
{
best_cost = cost;
{
case GNUNET_MESSAGE_TYPE_MESH_ACK:
case GNUNET_MESSAGE_TYPE_MESH_POLL:
+ case GNUNET_MESSAGE_TYPE_MESH_KX:
+ case GNUNET_MESSAGE_TYPE_MESH_CONNECTION_CREATE:
+ case GNUNET_MESSAGE_TYPE_MESH_CONNECTION_ACK:
+ case GNUNET_MESSAGE_TYPE_MESH_CONNECTION_DESTROY:
+ case GNUNET_MESSAGE_TYPE_MESH_CONNECTION_BROKEN:
+ case GNUNET_MESSAGE_TYPE_MESH_KEEPALIVE:
return GNUNET_YES;
+
+ case GNUNET_MESSAGE_TYPE_MESH_ENCRYPTED:
+ break;
+
+ default:
+ GNUNET_break (0);
}
if (GMC_is_sendable (q->c, q->fwd))
* @param buf Where the to write the message.
*
* @return number of bytes written to buf
- *
- * FIXME add GNUNET_MESSAGE_TYPE_MESH_KEEPALIVE
*/
static size_t
queue_send (void *cls, size_t size, void *buf)
size_t data_size;
peer->core_transmit = NULL;
- LOG (GNUNET_ERROR_TYPE_DEBUG, "* Queue send (max %u)\n", size);
+ LOG (GNUNET_ERROR_TYPE_DEBUG, "* Queue send towards %s (max %u)\n",
+ GMP_2s (peer), size);
if (NULL == buf || 0 == size)
{
c = queue->c;
dst_id = GNUNET_PEER_resolve2 (peer->id);
- LOG (GNUNET_ERROR_TYPE_DEBUG, "* towards %s\n", GNUNET_i2s (dst_id));
LOG (GNUNET_ERROR_TYPE_DEBUG, "* on connection %s\n", GMC_2s (c));
/* Check if buffer size is enough for the message */
if (queue->size > size)
case GNUNET_MESSAGE_TYPE_MESH_CONNECTION_ACK:
case GNUNET_MESSAGE_TYPE_MESH_CONNECTION_CREATE:
case GNUNET_MESSAGE_TYPE_MESH_CONNECTION_BROKEN:
+ case GNUNET_MESSAGE_TYPE_MESH_KEEPALIVE:
case GNUNET_MESSAGE_TYPE_MESH_KX:
case GNUNET_MESSAGE_TYPE_MESH_ENCRYPTED:
case GNUNET_MESSAGE_TYPE_MESH_ACK:
if (NULL == peer->connections)
{
/* We are not connected to this peer, ignore request. */
- GNUNET_break_op (0);
+ LOG (GNUNET_ERROR_TYPE_DEBUG, "WARNING %s not a neighbor\n", GMP_2s (peer));
+ GNUNET_STATISTICS_update (stats, "# messages dropped due to wrong hop", 1,
+ GNUNET_NO);
return NULL;
}
prev = q->prev;
if (q->c == c)
{
- LOG (GNUNET_ERROR_TYPE_DEBUG,
- "GMP_cancel_queue %s\n",
- GM_m2s (q->type));
+ LOG (GNUNET_ERROR_TYPE_DEBUG, "GMP_cancel_queue %s\n", GM_m2s (q->type));
GMP_queue_destroy (q, GNUNET_YES);
/* Get next from prev, q->next might be already freed:
if (NULL != peer->path_head)
{
- LOG (GNUNET_ERROR_TYPE_DEBUG, "path exists\n");
+ LOG (GNUNET_ERROR_TYPE_DEBUG, " some path exists\n");
p = peer_get_best_path (peer);
if (NULL != p)
{
* path.
*
* Re-running the DHT GET should give core time to callback.
+ *
+ * GMT_use_path -> GMC_new -> register_neighbors takes care of
+ * updating statistics about this issue.
*/
- GNUNET_break(0);
rerun_search = GNUNET_YES;
}
else
}
else
{
- LOG (GNUNET_ERROR_TYPE_DEBUG, "but is NULL!!\n");
- GNUNET_break (0);
+ LOG (GNUNET_ERROR_TYPE_DEBUG, " but is NULL, all paths are in use\n");
}
}
GMP_add_connection (struct MeshPeer *peer,
struct MeshConnection *c)
{
+ int result;
+ LOG (GNUNET_ERROR_TYPE_DEBUG, "adding connection %s\n", GMC_2s (c));
+ LOG (GNUNET_ERROR_TYPE_DEBUG, "to peer %s\n", GMP_2s (peer));
+
if (NULL == peer->connections)
{
GNUNET_break (0);
+ LOG (GNUNET_ERROR_TYPE_DEBUG,
+ "Peer %s is not a neighbor!\n",
+ GMP_2s (peer));
return GNUNET_SYSERR;
}
- return GNUNET_CONTAINER_multihashmap_put (peer->connections,
- GMC_get_id (c),
- c,
- GNUNET_CONTAINER_MULTIHASHMAPOPTION_UNIQUE_FAST);
+ LOG (GNUNET_ERROR_TYPE_DEBUG,
+ "peer %s ok, has %u connections.\n",
+ GMP_2s (peer), GNUNET_CONTAINER_multihashmap_size (peer->connections));
+ result = GNUNET_CONTAINER_multihashmap_put (peer->connections,
+ GMC_get_id (c),
+ c,
+ GNUNET_CONTAINER_MULTIHASHMAPOPTION_UNIQUE_FAST);
+ LOG (GNUNET_ERROR_TYPE_DEBUG,
+ " now has %u connections.\n",
+ GNUNET_CONTAINER_multihashmap_size (peer->connections));
+ LOG (GNUNET_ERROR_TYPE_DEBUG, "result %u\n", result);
+
+ return result;
}
}
+/**
+ * Remove any path to the peer that has the extact same peers as the one given.
+ *
+ * @param peer Peer to remove the path from.
+ * @param path Path to remove. Is always destroyed .
+ */
+void
+GMP_remove_path (struct MeshPeer *peer, struct MeshPeerPath *path)
+{
+ struct MeshPeerPath *iter;
+ struct MeshPeerPath *next;
+
+ GNUNET_assert (myid == path->peers[0]);
+ GNUNET_assert (peer->id == path->peers[path->length - 1]);
+
+ for (iter = peer->path_head; NULL != iter; iter = next)
+ {
+ next = iter->next;
+ if (0 == memcmp (path->peers, iter->peers,
+ sizeof (GNUNET_PEER_Id) * path->length))
+ {
+ GNUNET_CONTAINER_DLL_remove (peer->path_head, peer->path_tail, iter);
+ path_destroy (iter);
+ if (path == iter)
+ return;
+ }
+ }
+ path_destroy (path);
+}
+
+
/**
* Remove a connection from a neighboring peer.
*
GMP_remove_connection (struct MeshPeer *peer,
const struct MeshConnection *c)
{
+ LOG (GNUNET_ERROR_TYPE_DEBUG, "removing connection %s\n", GMC_2s (c));
+ LOG (GNUNET_ERROR_TYPE_DEBUG, "from peer %s\n", GMP_2s (peer));
+
if (NULL == peer || NULL == peer->connections)
{
LOG (GNUNET_ERROR_TYPE_DEBUG,
GMP_2s (peer));
return GNUNET_SYSERR;
}
+ LOG (GNUNET_ERROR_TYPE_DEBUG,
+ "peer %s ok, has %u connections.\n",
+ GMP_2s (peer), GNUNET_CONTAINER_multihashmap_size (peer->connections));
+
return GNUNET_CONTAINER_multihashmap_remove (peer->connections,
GMC_get_id (c),
c);
struct MeshTunnel3 *
GMP_get_tunnel (const struct MeshPeer *peer)
{
+ GNUNET_assert (NULL != peer->tunnel);
return peer->tunnel;
}