* Sends an already built message to a peer, properly registrating
* all used resources.
*
- * @param message Message to send.
+ * @param message Message to send. Fucntion makes a copy of it.
* @param peer Short ID of the neighbor whom to send the message.
*/
static void
static void
send_destroy_path (struct MeshTunnel *t, GNUNET_PEER_Id destination)
{
- struct GNUNET_MESH_ManipulatePath *msg;
- struct GNUNET_PeerIdentity *pi;
struct MeshPeerPath *p;
- unsigned int i;
size_t size;
p = tree_get_path_to_peer(t->tree, destination);
}
size = sizeof (struct GNUNET_MESH_ManipulatePath);
size += p->length * sizeof (struct GNUNET_PeerIdentity);
- msg = GNUNET_malloc (size);
- msg->header.size = htons (size);
- msg->header.type = htons (GNUNET_MESSAGE_TYPE_MESH_PATH_DESTROY);
- msg->tid = htonl (t->id.tid);
- pi = (struct GNUNET_PeerIdentity *) &msg[1];
- for (i = 0; i < p->length; i++)
{
- GNUNET_PEER_resolve(p->peers[i], &pi[i]);
+ struct GNUNET_MESH_ManipulatePath *msg;
+ struct GNUNET_PeerIdentity *pi;
+ char cbuf[size];
+ unsigned int i;
+
+ msg = (struct GNUNET_MESH_ManipulatePath *) cbuf;
+ msg->header.size = htons (size);
+ msg->header.type = htons (GNUNET_MESSAGE_TYPE_MESH_PATH_DESTROY);
+ msg->tid = htonl (t->id.tid);
+ pi = (struct GNUNET_PeerIdentity *) &msg[1];
+ for (i = 0; i < p->length; i++)
+ {
+ GNUNET_PEER_resolve(p->peers[i], &pi[i]);
+ }
+ send_message (&msg->header, path_get_first_hop(t->tree, destination));
}
- send_message (&msg->header, path_get_first_hop(t->tree, destination));
path_destroy (p);
}
if (NULL != peer->path_head)
{
p = tree_get_path_to_peer(t->tree, peer->id);
+ if (NULL == p)
+ {
+ GNUNET_break (0);
+ return;
+ }
+
if (p->length > 1)
{
send_create_path(peer, p, t);
}
+/**
+ * Task to delay the connection of a peer
+ *
+ * @param cls Closure (path info with tunnel and peer to connect).
+ * Will be free'd on exection.
+ * @param tc TaskContext
+ */
+static void
+peer_info_connect_task (void *cls,
+ const struct GNUNET_SCHEDULER_TaskContext *tc)
+{
+ struct MeshPathInfo *path_info = cls;
+
+ if (GNUNET_SCHEDULER_REASON_SHUTDOWN == tc->reason)
+ {
+ GNUNET_free (cls);
+ }
+ peer_info_connect (path_info->peer, path_info->t);
+ GNUNET_free (cls);
+}
+
+
/**
* Destroy the peer_info and free any allocated resources linked to it
*
notify_peer_disconnected (const struct MeshTunnelTreeNode *n)
{
struct MeshPeerInfo *peer;
+ struct MeshPathInfo *path_info;
if (NULL != n->t->client && NULL != nc)
{
&msg.header, GNUNET_NO);
}
peer = peer_info_get_short(n->peer);
- peer_info_connect(peer, n->t);
+ path_info = GNUNET_malloc (sizeof (struct MeshPathInfo));
+ path_info->peer = peer;
+ path_info->t = n->t;
+ GNUNET_SCHEDULER_add_now(&peer_info_connect_task, path_info);
}
GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
"MESH: It's for us!\n");
path_add_to_origin (orig_peer_info, path);
- t->peers = GNUNET_CONTAINER_multihashmap_create(4);
+ if (NULL == t->peers)
+ t->peers = GNUNET_CONTAINER_multihashmap_create(4);
GNUNET_break (GNUNET_OK == GNUNET_CONTAINER_multihashmap_put (
t->peers,
&my_full_id.hashPubKey,
if (own_pos < path->length - 1)
send_message (message, &pi[own_pos + 1]);
tunnel_delete_peer (t, path->peers[path->length - 1]);
+ path_destroy (path);
return GNUNET_OK;
}