/** FWD declaration */
struct MeshPeerInfo;
+
+/**
+ * Struct representing a piece of data being sent to other peers
+ */
+struct MeshData
+{
+ /** Tunnel it belongs to. */
+ struct MeshTunnel *t;
+
+ /** In case of a multicast, task to allow a client to send more data if
+ * some neighbor is too slow. */
+ GNUNET_SCHEDULER_TaskIdentifier *task;
+
+ /** How many remaining neighbors we need to send this to. */
+ unsigned int *reference_counter;
+
+ /** Size of the data. */
+ size_t data_len;
+
+ /** Data itself */
+ void *data;
+};
+
+
/**
* Struct containing all info possibly needed to build a package when called
* back by core.
*/
-struct MeshDataDescriptor
+struct MeshTransmissionDescriptor
{
/** ID of the tunnel this packet travels in */
struct MESH_TunnelID *origin;
- /** Data itself */
- void *data;
-
- /** Client that asked for the transmission, if any */
- struct GNUNET_SERVER_Client *client;
-
/** Who was this message being sent to */
struct MeshPeerInfo *peer;
/** Ultimate destination of the packet */
GNUNET_PEER_Id destination;
- /** Number of identical messages sent to different hops (multicast) */
- unsigned int *copies;
-
/** Which handler was used to request the transmission */
unsigned int handler_n;
- /** Size of the data */
- size_t size;
-
- /** Used to allow a client send more traffic to the service after a
- * previous packet was tried to be sent to a neighbor and couldn't */
- GNUNET_SCHEDULER_TaskIdentifier *timeout_task;
+ /** Data descriptor */
+ struct MeshData* mesh_data;
};
*/
MESH_TunnelNumber local_tid;
+ /**
+ * Local tunnel number for local destination clients
+ */
+ MESH_TunnelNumber local_tid_dest;
+
/**
* ID of the last multicast packet seen/sent.
*/
/************************ DEBUG FUNCTIONS ****************************/
/******************************************************************************/
-
+#if MESH_DEBUG
/**
* GNUNET_SCHEDULER_Task for printing a message after some operation is done
* @param cls string to print
}
GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "MESH: %s\n", s);
}
-
+#endif
/******************************************************************************/
/*********************** GLOBAL VARIABLES ****************************/
static void
client_allow_send (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc)
{
- struct MeshDataDescriptor *info = cls;
+ struct MeshData *mdata = cls;
if (GNUNET_SCHEDULER_REASON_SHUTDOWN == tc->reason)
return;
#if MESH_DEBUG
+ GNUNET_assert (NULL != mdata->reference_counter);
GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
"MESH: CLIENT ALLOW SEND DESPITE %u COPIES PENDING\n",
- *(info->copies));
+ mdata->reference_counter);
#endif
- *(info->timeout_task) = GNUNET_SCHEDULER_NO_TASK;
- GNUNET_SERVER_receive_done (info->client, GNUNET_OK);
+ *(mdata->task) = GNUNET_SCHEDULER_NO_TASK;
+ GNUNET_SERVER_receive_done (mdata->t->client->handle, GNUNET_OK);
}
* Send the message to all clients that have subscribed to its type
*
* @param msg Pointer to the message itself
+ * @param payload Pointer to the payload of the message.
* @return number of clients this message was sent to
*/
static unsigned int
uint16_t type;
char cbuf[htons (msg->size)];
+#if MESH_DEBUG
GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "MESH: Sending to clients...\n");
type = ntohs (payload->type);
GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "MESH: message of type %u\n", type);
+#endif
memcpy (cbuf, msg, sizeof (cbuf));
switch (htons (msg->type))
GNUNET_break (0);
return 0;
}
- *tid = htonl (t->local_tid);
+ // FIXME proper client differentiation mechanism required
+ if (htons (msg->type) == GNUNET_MESSAGE_TYPE_MESH_TO_ORIGIN)
+ *tid = htonl (t->local_tid);
+ else
+ *tid = htonl (t->local_tid_dest != 0 ? t->local_tid_dest : t->local_tid);
for (count = 0, c = clients; c != NULL; c = c->next)
{
+#if MESH_DEBUG
GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "MESH: client %u\n", c->id);
+#endif
if (client_is_subscribed (type, c))
{
count++;
/**
* Decrements the reference counter and frees all resources if needed
*
- * @param dd Data Descriptor used in a multicast message
+ * @param dd Data Descriptor used in a multicast message. Freed if needed.
*/
static void
-data_descriptor_decrement_multicast (struct MeshDataDescriptor *dd)
+data_descriptor_decrement_multicast (struct MeshData *mesh_data)
{
- if (0 == --(*(dd->copies)))
+ /* Make sure it's a multicast packet */
+ GNUNET_assert (NULL != mesh_data->reference_counter);
+
+ if (0 == --(*(mesh_data->reference_counter)))
{
GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "MESH: Last copy!\n");
- if (NULL != dd->client)
+ if (NULL != mesh_data->task)
{
- if (GNUNET_SCHEDULER_NO_TASK != *(dd->timeout_task))
+ if (GNUNET_SCHEDULER_NO_TASK != *(mesh_data->task))
{
- GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
- "MESH: cancelling client timeout (%u)...\n",
- *(dd->timeout_task));
- GNUNET_SCHEDULER_cancel (*(dd->timeout_task));
+ GNUNET_SCHEDULER_cancel (*(mesh_data->task));
GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "MESH: notifying client...\n");
- GNUNET_SERVER_receive_done (dd->client, GNUNET_OK);
+ GNUNET_SERVER_receive_done (mesh_data->t->client->handle, GNUNET_OK);
}
- GNUNET_free (dd->timeout_task);
+ GNUNET_free (mesh_data->task);
}
- GNUNET_free (dd->copies);
- GNUNET_free (dd->data);
+ GNUNET_free (mesh_data->reference_counter);
+ GNUNET_free (mesh_data->data);
+ GNUNET_free (mesh_data);
}
}
{
if (NULL != peer->core_transmit[i])
{
- struct MeshDataDescriptor *dd;
+ struct MeshTransmissionDescriptor *dd;
struct MeshPathInfo *path_info;
#if MESH_DEBUG
case GNUNET_MESSAGE_TYPE_MESH_TO_ORIGIN:
GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "MESH: type payload\n");
dd = peer->infos[i];
- data_descriptor_decrement_multicast (dd);
+ data_descriptor_decrement_multicast (dd->mesh_data);
break;
case GNUNET_MESSAGE_TYPE_MESH_PATH_CREATE:
GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "MESH: type create path\n");
/**
* Core callback to write a
*
- * @param cls Closure (MeshDataDescriptor with data in "data" member).
+ * @param cls Closure (MeshTransmissionDescriptor with data in "data" member).
* @param size Number of bytes available in buf.
* @param buf Where the to write the message.
*
static size_t
send_core_data_raw (void *cls, size_t size, void *buf)
{
- struct MeshDataDescriptor *info = cls;
+ struct MeshTransmissionDescriptor *info = cls;
struct GNUNET_MessageHeader *msg;
size_t total_size;
GNUNET_assert (NULL != info);
- GNUNET_assert (NULL != info->data);
- msg = (struct GNUNET_MessageHeader *) info->data;
+ GNUNET_assert (NULL != info->mesh_data);
+ msg = (struct GNUNET_MessageHeader *) info->mesh_data->data;
total_size = ntohs (msg->size);
if (total_size > size)
}
info->peer->core_transmit[info->handler_n] = NULL;
memcpy (buf, msg, total_size);
- GNUNET_free (info->data);
+ GNUNET_free (info->mesh_data);
GNUNET_free (info);
return total_size;
}
*
* @param message Message to send. Fucntion makes a copy of it.
* @param peer Short ID of the neighbor whom to send the message.
+ *
+ * FIXME tunnel?
*/
static void
send_message (const struct GNUNET_MessageHeader *message,
const struct GNUNET_PeerIdentity *peer)
{
- struct MeshDataDescriptor *info;
+ struct MeshTransmissionDescriptor *info;
struct MeshPeerInfo *neighbor;
struct MeshPeerPath *p;
unsigned int i;
// GNUNET_TRANSPORT_try_connect();
size = ntohs (message->size);
- info = GNUNET_malloc (sizeof (struct MeshDataDescriptor));
- info->data = GNUNET_malloc (size);
- memcpy (info->data, message, size);
+ info = GNUNET_malloc (sizeof (struct MeshTransmissionDescriptor));
+ info->mesh_data = GNUNET_malloc (sizeof (struct MeshData));
+ info->mesh_data->data = GNUNET_malloc (size);
+ memcpy (info->mesh_data->data, message, size);
+ info->mesh_data->data_len = size;
neighbor = peer_info_get (peer);
for (p = neighbor->path_head; NULL != p; p = p->next)
{
if (NULL == p)
{
GNUNET_break (0);
+ GNUNET_free (info->mesh_data->data);
+ GNUNET_free (info->mesh_data);
GNUNET_free (info);
return;
}
{
GNUNET_PEER_resolve (p->peers[i], &pi[i]);
}
- send_message (&msg->header, path_get_first_hop (t->tree, destination));
+ send_message (&msg->header, tree_get_first_hop (t->tree, destination));
}
path_destroy (p);
}
for (i = 0; i < peer->ntunnels; i++)
{
d = tunnel_notify_connection_broken (peer->tunnels[i], p1, p2);
- if (0 == d) continue;
+ if (0 == d)
+ continue;
/* TODO
* Problem: one or more peers have been deleted from the tunnel tree.
* We don't know who they are to try to add them again.
aux = NULL;
for (p = peer_d->path_head; NULL != p; p = p->next)
{
- if ((cost = path_get_cost (peer->tunnels[i]->tree, p)) < best)
+ if ((cost = tree_get_path_cost (peer->tunnels[i]->tree, p)) < best)
{
best = cost;
aux = p;
path_destroy (path);
return;
}
+ if (path->peers[path->length - 1] != peer_info->id)
+ {
+ GNUNET_break (0);
+ path_destroy (path);
+ return;
+ }
if (path->length <= 2 && GNUNET_NO == trusted)
{
/* Only allow CORE to tell us about direct paths */
}
+/**
+ * Adds a path to the peer_infos of all the peers in the path
+ *
+ * @param p Path to process.
+ * @param confirmed Whether we know if the path works or not. FIXME use
+ */
+static void
+path_add_to_peers (struct MeshPeerPath *p, int confirmed)
+{
+ unsigned int i;
+
+ /* TODO: invert and add */
+ for (i = 0; i < p->length && p->peers[i] != myid; i++) /* skip'em */ ;
+ for (i++; i < p->length; i++)
+ {
+ struct MeshPeerInfo *aux;
+ struct MeshPeerPath *copy;
+
+ aux = peer_info_get_short (p->peers[i]);
+ copy = path_duplicate (p);
+ copy->length = i + 1;
+ peer_info_add_path (aux, copy, GNUNET_NO);
+ }
+}
+
+
/**
* Send keepalive packets for a peer
*
if (NULL != (p = peer->path_head))
{
best_p = p;
- best_cost = path_get_cost (t->tree, p);
+ best_cost = tree_get_path_cost (t->tree, p);
while (NULL != p)
{
- if ((cost = path_get_cost (t->tree, p)) < best_cost)
+ if ((cost = tree_get_path_cost (t->tree, p)) < best_cost)
{
best_cost = cost;
best_p = p;
}
else
{
- /* Start a DHT get if necessary */
+ /* Start a DHT get */
peer_info_connect (peer, t);
}
}
GNUNET_assert (0 != own_pos);
tree_add_path (t->tree, p, NULL, NULL);
- if (tree_get_me (t->tree) == 0)
- tree_set_me (t->tree, p->peers[own_pos]);
if (own_pos < p->length - 1)
{
GNUNET_PEER_resolve (p->peers[own_pos + 1], &id);
- tree_update_first_hops (t->tree, tree_get_me (t->tree), &id);
+ tree_update_first_hops (t->tree, myid, &id);
}
}
}
-struct MeshMulticastData
-{
- struct MeshTunnel *t;
-
- GNUNET_SCHEDULER_TaskIdentifier *task;
-
- unsigned int *reference_counter;
-
- size_t data_len;
-
- void *data;
-};
-
-
/**
* Send a multicast packet to a neighbor.
+ *
+ * @param cls Closure (Info about the multicast packet)
+ * @param neighbor_id Short ID of the neighbor to send the packet to.
*/
static void
tunnel_send_multicast_iterator (void *cls, GNUNET_PEER_Id neighbor_id)
{
- struct MeshMulticastData *mdata = cls;
- struct MeshDataDescriptor *info;
+ struct MeshData *mdata = cls;
+ struct MeshTransmissionDescriptor *info;
struct GNUNET_PeerIdentity neighbor;
unsigned int i;
- info = GNUNET_malloc (sizeof (struct MeshDataDescriptor));
+ info = GNUNET_malloc (sizeof (struct MeshTransmissionDescriptor));
- info->data = mdata->data;
- info->size = mdata->data_len;
- info->copies = mdata->reference_counter;
- (*(mdata->reference_counter))++;
-
- if (NULL != mdata->t->client)
- {
- info->client = mdata->t->client->handle;
- info->timeout_task = mdata->task;
- }
+ info->mesh_data = mdata;
+ (*(mdata->reference_counter)) ++;
info->destination = neighbor_id;
GNUNET_PEER_resolve (neighbor_id, &neighbor);
#if MESH_DEBUG
info->peer->core_transmit[i] =
GNUNET_CORE_notify_transmit_ready (core_handle, 0, 0,
GNUNET_TIME_UNIT_FOREVER_REL,
- &neighbor, info->size,
+ &neighbor, info->mesh_data->data_len,
&send_core_data_multicast, info);
}
tunnel_send_multicast (struct MeshTunnel *t,
const struct GNUNET_MessageHeader *msg)
{
- struct MeshMulticastData *mdata;
+ struct MeshData *mdata;
#if MESH_DEBUG
GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
"MESH: sending a multicast packet...\n");
#endif
- GNUNET_assert (tree_get_me (t->tree) != 0);
- mdata = GNUNET_malloc (sizeof (struct MeshMulticastData));
+ mdata = GNUNET_malloc (sizeof (struct MeshData));
mdata->data_len = ntohs (msg->size);
mdata->reference_counter = GNUNET_malloc (sizeof (unsigned int));
mdata->t = t;
mcast = (struct GNUNET_MESH_Multicast *) mdata->data;
mcast->ttl = htonl (ntohl (mcast->ttl) - 1);
#if MESH_DEBUG
- GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
- "MESH: data packet, ttl: %u\n",
+ GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "MESH: data packet, ttl: %u\n",
ntohl (mcast->ttl));
}
else
{
- GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
- "MESH: not a data packet, no ttl\n");
+ GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "MESH: not a data packet, no ttl\n");
#endif
}
if (NULL != t->client)
{
mdata->task = GNUNET_malloc (sizeof (GNUNET_SCHEDULER_TaskIdentifier));
- *(mdata->task) =
+ (*(mdata->task)) =
GNUNET_SCHEDULER_add_delayed (UNACKNOWLEDGED_WAIT, &client_allow_send,
- t->client->handle);
+ mdata);
+ GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "MESH: timeout task %u\n",
+ *(mdata->task));
}
tree_iterate_children (t->tree, &tunnel_send_multicast_iterator, mdata);
GNUNET_free (mdata->reference_counter);
if (NULL != mdata->task)
{
+ GNUNET_SCHEDULER_cancel(*(mdata->task));
GNUNET_free (mdata->task);
+ GNUNET_SERVER_receive_done(t->client->handle, GNUNET_OK);
}
+ // FIXME change order?
+ GNUNET_free (mdata);
}
- GNUNET_free (mdata);
#if MESH_DEBUG
GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
"MESH: sending a multicast packet done\n");
* The tunnel itself is also destoyed if results in a remote empty tunnel.
*
* @param t Tunnel from which to remove the path.
- * @param p Peer which should be removed.
+ * @param peer Short id of the peer which should be removed.
*/
static void
tunnel_delete_peer (struct MeshTunnel *t, GNUNET_PEER_Id peer)
info->peer->core_transmit[info->pos] =
GNUNET_CORE_notify_transmit_ready (core_handle, 0, 0,
GNUNET_TIME_UNIT_FOREVER_REL,
- path_get_first_hop (t->tree,
+ tree_get_first_hop (t->tree,
peer->id),
size_needed, &send_core_create_path,
info);
static size_t
send_core_data_multicast (void *cls, size_t size, void *buf)
{
- struct MeshDataDescriptor *info = cls;
+ struct MeshTransmissionDescriptor *info = cls;
size_t total_size;
GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "MESH: Multicast callback.\n");
GNUNET_assert (NULL != info);
GNUNET_assert (NULL != info->peer);
- total_size = info->size;
+ total_size = info->mesh_data->data_len;
GNUNET_assert (total_size < GNUNET_SERVER_MAX_MESSAGE_SIZE);
if (total_size > size)
info->peer->core_transmit[info->handler_n] = NULL;
info->peer->infos[info->handler_n] = NULL;
GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "MESH: copying data...\n");
- memcpy (buf, info->data, total_size);
+ memcpy (buf, info->mesh_data->data, total_size);
#if MESH_DEBUG
{
struct GNUNET_MESH_Multicast *mc;
}
}
#endif
- data_descriptor_decrement_multicast (info);
+ data_descriptor_decrement_multicast (info->mesh_data);
GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "MESH: freeing info...\n");
GNUNET_free (info);
GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "MESH: return %u\n", total_size);
* NULL and "size" zero if the socket was closed for
* writing in the meantime.
*
- * @param cls closure (MeshDataDescriptor)
+ * @param cls closure (MeshTransmissionDescriptor)
* @param size number of bytes available in buf
* @param buf where the callee should write the message
* @return number of bytes written to buf
static size_t
send_core_path_ack (void *cls, size_t size, void *buf)
{
- struct MeshDataDescriptor *info = cls;
+ struct MeshTransmissionDescriptor *info = cls;
struct GNUNET_MESH_PathACK *msg = buf;
GNUNET_assert (NULL != info);
tid = ntohl (msg->tid);
pi = (struct GNUNET_PeerIdentity *) &msg[1];
- t = tunnel_get (pi, tid);
GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
"MESH: path is for tunnel %s [%X].\n", GNUNET_i2s (pi), tid);
+ t = tunnel_get (pi, tid);
if (NULL == t)
{
GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "MESH: Creating tunnel\n");
/* FIXME error. destroy tunnel? leave for timeout? */
return 0;
}
+ path_add_to_peers (path, GNUNET_NO);
tunnel_add_path (t, path, own_pos);
if (own_pos == size - 1)
{
/* It is for us! Send ack. */
- struct GNUNET_MESH_TunnelNotification cmsg;
- struct MeshDataDescriptor *info;
+ struct MeshTransmissionDescriptor *info;
unsigned int j;
GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "MESH: It's for us!\n");
peer_info_add_path_to_origin (orig_peer_info, path, GNUNET_NO);
if (NULL == t->peers)
+ {
+ /* New tunnel! Notify clients! */
+ struct GNUNET_MESH_TunnelNotification cmsg;
+
+ cmsg.header.size = htons (sizeof (cmsg));
+ cmsg.header.type = htons (GNUNET_MESSAGE_TYPE_MESH_LOCAL_TUNNEL_CREATE);
+ GNUNET_PEER_resolve (t->id.oid, &cmsg.peer);
+ cmsg.tunnel_id = htonl (t->local_tid);
+ GNUNET_SERVER_notification_context_broadcast (nc, &cmsg.header,
+ GNUNET_NO);
+
t->peers = GNUNET_CONTAINER_multihashmap_create (4);
+ }
GNUNET_break (GNUNET_OK ==
GNUNET_CONTAINER_multihashmap_put (t->peers,
&my_full_id.hashPubKey,
peer_info_get
(&my_full_id),
- GNUNET_CONTAINER_MULTIHASHMAPOPTION_UNIQUE_FAST));
+ GNUNET_CONTAINER_MULTIHASHMAPOPTION_REPLACE));
/* FIXME use send_message */
- info = GNUNET_malloc (sizeof (struct MeshDataDescriptor));
+ info = GNUNET_malloc (sizeof (struct MeshTransmissionDescriptor));
info->origin = &t->id;
info->peer = GNUNET_CONTAINER_multihashmap_get (peers, &peer->hashPubKey);
GNUNET_assert (NULL != info->peer);
GNUNET_TIME_UNIT_FOREVER_REL, peer,
sizeof (struct GNUNET_MESH_PathACK),
&send_core_path_ack, info);
- cmsg.header.size = htons (sizeof (cmsg));
- cmsg.header.type = htons (GNUNET_MESSAGE_TYPE_MESH_LOCAL_TUNNEL_CREATE);
- GNUNET_PEER_resolve (t->id.oid, &cmsg.peer);
- cmsg.tunnel_id = htonl (t->local_tid);
- GNUNET_SERVER_notification_context_broadcast (nc, &cmsg.header, GNUNET_NO);
}
else
{
}
GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
"MESH: not for us, retransmitting...\n");
- send_message (message, path_get_first_hop (t->tree, pid));
+ send_message (message, tree_get_first_hop (t->tree, pid));
return GNUNET_OK;
}
{
/* FIXME: already seen this packet, log dropping */
GNUNET_log (GNUNET_ERROR_TYPE_WARNING,
- "MESH: Already seen mid %u, DROPPING!\n",
- t->mid);
+ "MESH: Already seen mid %u, DROPPING!\n", t->mid);
return GNUNET_OK;
}
#if MESH_DEBUG
else
{
GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
- "MESH: mid %u not seen yet, forwarding\n",
- ntohl (msg->mid));
+ "MESH: mid %u not seen yet, forwarding\n", ntohl (msg->mid));
}
#endif
t->mid = ntohl (msg->mid);
send_subscribed_clients (message, &msg[1].header);
}
#if MESH_DEBUG
- GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
- "MESH: ttl: %u\n",
- ntohl (msg->ttl));
+ GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "MESH: ttl: %u\n", ntohl (msg->ttl));
#endif
if (ntohl (msg->ttl) == 0)
{
/* FIXME: ttl is 0, log dropping */
- GNUNET_log (GNUNET_ERROR_TYPE_WARNING,
- "MESH: TTL is 0, DROPPING!\n");
+ GNUNET_log (GNUNET_ERROR_TYPE_WARNING, "MESH: TTL is 0, DROPPING!\n");
return GNUNET_OK;
}
tunnel_send_multicast (t, message);
struct GNUNET_MESH_PathACK *msg;
struct GNUNET_PeerIdentity id;
struct MeshPeerInfo *peer_info;
+ struct MeshPeerPath *p;
struct MeshTunnel *t;
GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "MESH: Received a path ACK msg [%s]\n",
return GNUNET_OK;
}
+ peer_info = peer_info_get (&msg->peer_id);
+
+ /* Add paths to peers? */
+ p = tree_get_path_to_peer (t->tree, peer_info->id);
+ if (NULL != p)
+ {
+ path_add_to_peers (p, GNUNET_YES);
+ path_destroy (p);
+ }
+ else
+ {
+ GNUNET_break (0);
+ }
+
/* Message for us? */
if (0 == memcmp (&msg->oid, &my_full_id, sizeof (struct GNUNET_PeerIdentity)))
{
GNUNET_DHT_get_stop (t->dht_get_type);
t->dht_get_type = NULL;
}
- peer_info = peer_info_get (&msg->peer_id);
- tree_set_status (t->tree, peer_info->id, MESH_PEER_READY);
- send_client_peer_connected (t, peer_info->id);
+ if (tree_get_status (t->tree, peer_info->id) != MESH_PEER_READY)
+ {
+ tree_set_status (t->tree, peer_info->id, MESH_PEER_READY);
+ send_client_peer_connected (t, peer_info->id);
+ }
return GNUNET_OK;
}
* @param cls closure
* @param exp when will this value expire
* @param key key of the result
+ * @param get_path path of the get request
+ * @param get_path_length lenght of get_path
+ * @param put_path path of the put request
+ * @param put_path_length length of the put_path
* @param type type of the result
* @param size number of bytes in data
* @param data pointer to the result data
GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "MESH: Got results from DHT!\n");
GNUNET_PEER_resolve (path_info->peer->id, &pi);
GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "MESH: for %s\n", GNUNET_i2s (&pi));
-// GNUNET_DHT_get_stop(path_info->peer->dhtget);
-// path_info->peer->dhtget = NULL;
p = path_build_from_dht (get_path, get_path_length, put_path,
put_path_length);
- peer_info_add_path (path_info->peer, p, GNUNET_NO);
+ path_add_to_peers (p, GNUNET_NO);
+ path_destroy(p);
for (i = 0; i < path_info->peer->ntunnels; i++)
{
tunnel_add_peer (path_info->peer->tunnels[i], path_info->peer);
peer_info_connect (path_info->peer, path_info->t);
}
-// GNUNET_free (path_info);
return;
}
* @param cls closure
* @param exp when will this value expire
* @param key key of the result
+ * @param get_path path of the get request
+ * @param get_path_length lenght of get_path
+ * @param put_path path of the put request
+ * @param put_path_length length of the put_path
* @param type type of the result
* @param size number of bytes in data
* @param data pointer to the result data
p = path_build_from_dht (get_path, get_path_length, put_path,
put_path_length);
- peer_info_add_path (peer_info, p, GNUNET_NO);
+ path_add_to_peers (p, GNUNET_NO);
+ path_destroy(p);
tunnel_add_peer (t, peer_info);
peer_info_connect (peer_info, t);
}
c = GNUNET_malloc (sizeof (struct MeshClient));
#if MESH_DEBUG
c->id = next_client_id++;
-#endif
GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "MESH: CLIENT NEW %u at %p\n", c->id,
c);
+#endif
c->handle = client;
GNUNET_SERVER_client_keep (client);
a = (GNUNET_MESH_ApplicationType *) &cc_msg[1];
return;
}
t->tree = tree_new (myid);
- tree_set_me (t->tree, myid);
GNUNET_SERVER_receive_done (client, GNUNET_OK);
return;
GNUNET_YES)
{
/* Yes! Fast forward, add ourselves to the tunnel and send the
- * good news to the client
+ * good news to the client, and alert the destination client of
+ * an incoming tunnel.
*/
+ struct GNUNET_MESH_TunnelNotification cmsg;
+ struct MeshClient *c;
+
GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "MESH: available locally\n");
GNUNET_CONTAINER_multihashmap_put (t->peers, &my_full_id.hashPubKey,
peer_info_get (&my_full_id),
send_client_peer_connected (t, myid);
GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "MESH: Done\n");
GNUNET_SERVER_receive_done (client, GNUNET_OK);
+
+ /* FIXME implement a proper handling of this case,
+ a client differentiation mechanism */
+ cmsg.header.size = htons (sizeof (cmsg));
+ cmsg.header.type = htons (GNUNET_MESSAGE_TYPE_MESH_LOCAL_TUNNEL_CREATE);
+ cmsg.peer = my_full_id;
+ t->local_tid_dest = next_local_tid++;
+ cmsg.tunnel_id = htonl (t->local_tid_dest);
+ c = (struct MeshClient *) GNUNET_CONTAINER_multihashmap_get(applications,
+ &hash);
+ GNUNET_SERVER_notification_context_unicast (nc, c->handle, &cmsg.header,
+ GNUNET_NO);
+
+
return;
}
/* Ok, lets find a peer offering the service */
shutdown_task (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc)
{
GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "MESH: shutting down\n");
- /* TODO: destroy tunnels? */
+
if (core_handle != NULL)
{
GNUNET_CORE_disconnect (core_handle);