#include "platform.h"
+#include "gnunet_util_lib.h"
+
+#include "gnunet_statistics_service.h"
+
#include "mesh_enc.h"
#include "mesh_protocol_enc.h" // GNUNET_MESH_Data is shared
#include "gnunet-service-mesh_local.h"
-#include "gnunet-service-mesh_tunnel.h"
+
+#define LOG(level, ...) GNUNET_log_from(level,"mesh-loc",__VA_ARGS__)
/******************************************************************************/
/******************************** STRUCTS **********************************/
*/
struct GNUNET_CONTAINER_MultiHashMap32 *own_channels;
- /**
+ /**
* Tunnels this client has accepted, indexed by incoming local id
*/
struct GNUNET_CONTAINER_MultiHashMap32 *incoming_channels;
+ /**
+ * Channel ID for the next incoming channel.
+ */
+ MESH_ChannelNumber next_chid;
+
/**
* Handle to communicate with the client
*/
/******************************* GLOBALS ***********************************/
/******************************************************************************/
+/**
+ * Global handle to the statistics service.
+ */
+extern struct GNUNET_STATISTICS_Handle *stats;
+
/**
* Handle to server lib.
*/
if (GNUNET_YES != res)
{
GNUNET_break (0);
- GNUNET_log (GNUNET_ERROR_TYPE_WARNING,
+ LOG (GNUNET_ERROR_TYPE_WARNING,
"Port %u by client %p was not registered.\n",
key, value);
}
{
struct MeshClient *c;
+ LOG (GNUNET_ERROR_TYPE_DEBUG, "client connected: %p\n", client);
if (NULL == client)
return;
- c = GNUNET_malloc (sizeof (struct MeshClient));
+ c = GNUNET_new (struct MeshClient);
c->handle = client;
c->id = next_client_id++; /* overflow not important: just for debug */
+ c->next_chid = GNUNET_MESH_LOCAL_CHANNEL_ID_SERV;
GNUNET_SERVER_client_keep (client);
GNUNET_SERVER_client_set_user_context (client, c);
GNUNET_CONTAINER_DLL_insert (clients_head, clients_tail, c);
}
+/**
+ * Iterator for deleting each channel whose client endpoint disconnected.
+ *
+ * @param cls Closure (client that has disconnected).
+ * @param key The local channel id (used to access the hashmap).
+ * @param value The value stored at the key (channel to destroy).
+ *
+ * @return GNUNET_OK, keep iterating.
+ */
+static int
+channel_destroy_iterator (void *cls,
+ uint32_t key,
+ void *value)
+{
+ struct MeshChannel *ch = value;
+ struct MeshClient *c = cls;
+
+ LOG (GNUNET_ERROR_TYPE_DEBUG,
+ " Channel %s destroy, due to client %s shutdown.\n",
+ GMCH_2s (ch), GML_2s (c));
+
+ GMCH_handle_local_destroy (ch, c);
+ return GNUNET_OK;
+}
+
/**
* Handler for client disconnection
*
{
struct MeshClient *c;
- GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "client disconnected: %p\n", client);
+ LOG (GNUNET_ERROR_TYPE_DEBUG, "client disconnected: %p\n", client);
if (client == NULL)
{
- GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, " (SERVER DOWN)\n");
+ LOG (GNUNET_ERROR_TYPE_DEBUG, " (SERVER DOWN)\n");
return;
}
- c = client_get (client);
+ c = GML_client_get (client);
if (NULL != c)
{
- GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "matching client found (%u, %p)\n",
+ LOG (GNUNET_ERROR_TYPE_DEBUG, "matching client found (%u, %p)\n",
c->id, c);
GNUNET_SERVER_client_drop (c->handle);
c->shutting_down = GNUNET_YES;
}
GNUNET_CONTAINER_DLL_remove (clients_head, clients_tail, c);
GNUNET_STATISTICS_update (stats, "# clients", -1, GNUNET_NO);
- GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, " client free (%p)\n", c);
+ LOG (GNUNET_ERROR_TYPE_DEBUG, " client free (%p)\n", c);
GNUNET_free (c);
}
else
{
- GNUNET_log (GNUNET_ERROR_TYPE_WARNING, " context NULL!\n");
+ LOG (GNUNET_ERROR_TYPE_WARNING, " context NULL!\n");
}
- GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "done!\n");
+ LOG (GNUNET_ERROR_TYPE_DEBUG, "done!\n");
return;
}
uint32_t *p;
unsigned int i;
- GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "new client connected %p\n", client);
+ LOG (GNUNET_ERROR_TYPE_DEBUG, "new client connected %p\n", client);
/* Check data sanity */
size = ntohs (message->size) - sizeof (struct GNUNET_MESH_ClientConnect);
/* Initialize new client structure */
c = GNUNET_SERVER_client_get_user_context (client, struct MeshClient);
- GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, " client id %u\n", c->id);
- GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, " client has %u ports\n", size);
+ LOG (GNUNET_ERROR_TYPE_DEBUG, " client id %u\n", c->id);
+ LOG (GNUNET_ERROR_TYPE_DEBUG, " client has %u ports\n", size);
if (size > 0)
{
uint32_t u32;
for (i = 0; i < size; i++)
{
u32 = ntohl (p[i]);
- GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, " port: %u\n", u32);
+ LOG (GNUNET_ERROR_TYPE_DEBUG, " port: %u\n", u32);
/* store in client's hashmap */
GNUNET_CONTAINER_multihashmap32_put (c->ports, u32, c,
GNUNET_STATISTICS_update (stats, "# clients", 1, GNUNET_NO);
GNUNET_SERVER_receive_done (client, GNUNET_OK);
- GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "new client processed\n");
+ LOG (GNUNET_ERROR_TYPE_DEBUG, "new client processed\n");
}
handle_channel_create (void *cls, struct GNUNET_SERVER_Client *client,
const struct GNUNET_MessageHeader *message)
{
- struct GNUNET_MESH_ChannelMessage *msg;
- struct MeshPeer *peer;
- struct MeshTunnel2 *t;
- struct MeshChannel *ch;
struct MeshClient *c;
- MESH_ChannelNumber chid;
- GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "new channel requested\n");
+ LOG (GNUNET_ERROR_TYPE_DEBUG, "new channel requested\n");
/* Sanity check for client registration */
- if (NULL == (c = client_get (client)))
+ if (NULL == (c = GML_client_get (client)))
{
GNUNET_break (0);
GNUNET_SERVER_receive_done (client, GNUNET_SYSERR);
return;
}
- GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, " by client %u\n", c->id);
+ LOG (GNUNET_ERROR_TYPE_DEBUG, " by client %u\n", c->id);
/* Message size sanity check */
if (sizeof (struct GNUNET_MESH_ChannelMessage) != ntohs (message->size))
return;
}
- msg = (struct GNUNET_MESH_ChannelMessage *) message;
- GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, " towards %s:%u\n",
- GNUNET_i2s (&msg->peer), ntohl (msg->port));
- chid = ntohl (msg->channel_id);
-
- /* Sanity check for duplicate channel IDs */
- if (NULL != channel_get_by_local_id (c, chid))
+ if (GNUNET_OK !=
+ GMCH_handle_local_create (c,
+ (struct GNUNET_MESH_ChannelMessage *) message))
{
- GNUNET_break (0);
GNUNET_SERVER_receive_done (client, GNUNET_SYSERR);
return;
}
- peer = peer_get (&msg->peer);
- if (NULL == peer->tunnel)
- {
- peer->tunnel = tunnel_new ();
- peer->tunnel->peer = peer;
- if (peer->id == myid)
- {
- tunnel_change_state (peer->tunnel, MESH_TUNNEL_READY);
- }
- else
- {
- peer_connect (peer);
- }
- }
- t = peer->tunnel;
-
- /* Create channel */
- ch = channel_new (t, c, chid);
- if (NULL == ch)
- {
- GNUNET_break (0);
- GNUNET_SERVER_receive_done (client, GNUNET_SYSERR);
- return;
- }
- ch->port = ntohl (msg->port);
- channel_set_options (ch, ntohl (msg->opt));
-
- /* In unreliable channels, we'll use the DLL to buffer BCK data */
- ch->root_rel = GNUNET_new (struct MeshChannelReliability);
- ch->root_rel->ch = ch;
- ch->root_rel->expected_delay = MESH_RETRANSMIT_TIME;
-
- GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "CREATED CHANNEL %s[%x]:%u (%x)\n",
- peer2s (t->peer), ch->gid, ch->port, ch->lid_root);
-
- /* Send create channel */
- {
- struct GNUNET_MESH_ChannelCreate msgcc;
-
- msgcc.header.size = htons (sizeof (msgcc));
- msgcc.header.type = htons (GNUNET_MESSAGE_TYPE_MESH_CHANNEL_CREATE);
- msgcc.chid = htonl (ch->gid);
- msgcc.port = msg->port;
- msgcc.opt = msg->opt;
-
- GMT_queue_data (t, ch, &msgcc.header, GNUNET_YES);
- }
-
GNUNET_SERVER_receive_done (client, GNUNET_OK);
return;
}
struct GNUNET_MESH_ChannelMessage *msg;
struct MeshClient *c;
struct MeshChannel *ch;
- struct MeshTunnel2 *t;
MESH_ChannelNumber chid;
- GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
+ LOG (GNUNET_ERROR_TYPE_DEBUG,
"Got a DESTROY CHANNEL from client!\n");
/* Sanity check for client registration */
- if (NULL == (c = client_get (client)))
+ if (NULL == (c = GML_client_get (client)))
{
GNUNET_break (0);
GNUNET_SERVER_receive_done (client, GNUNET_SYSERR);
return;
}
- GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, " by client %u\n", c->id);
+ LOG (GNUNET_ERROR_TYPE_DEBUG, " by client %u\n", c->id);
/* Message sanity check */
if (sizeof (struct GNUNET_MESH_ChannelMessage) != ntohs (message->size))
/* Retrieve tunnel */
chid = ntohl (msg->channel_id);
- ch = channel_get_by_local_id (c, chid);
+ ch = GML_channel_get (c, chid);
if (NULL == ch)
{
- GNUNET_log (GNUNET_ERROR_TYPE_ERROR, " channel %X not found\n", chid);
+ LOG (GNUNET_ERROR_TYPE_ERROR, " channel %X not found\n", chid);
GNUNET_break (0);
GNUNET_SERVER_receive_done (client, GNUNET_SYSERR);
return;
}
- /* Cleanup after the tunnel */
- client_delete_channel (c, ch);
- if (c == ch->dest && GNUNET_MESH_LOCAL_CHANNEL_ID_SERV <= chid)
- {
- ch->dest = NULL;
- }
- else if (c == ch->root && GNUNET_MESH_LOCAL_CHANNEL_ID_SERV > chid)
- {
- ch->root = NULL;
- }
- else
- {
- GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
- " channel %X client %p (%p, %p)\n",
- chid, c, ch->root, ch->dest);
- GNUNET_break (0);
- }
-
- t = ch->t;
- channel_destroy (ch);
- tunnel_destroy_if_empty (t);
+ GMCH_handle_local_destroy (ch, c);
GNUNET_SERVER_receive_done (client, GNUNET_OK);
return;
struct GNUNET_MESH_LocalData *msg;
struct MeshClient *c;
struct MeshChannel *ch;
- struct MeshChannelReliability *rel;
MESH_ChannelNumber chid;
size_t size;
int fwd;
- GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
+ LOG (GNUNET_ERROR_TYPE_DEBUG,
"Got data from a client!\n");
/* Sanity check for client registration */
- if (NULL == (c = client_get (client)))
+ if (NULL == (c = GML_client_get (client)))
{
GNUNET_break (0);
GNUNET_SERVER_receive_done (client, GNUNET_SYSERR);
return;
}
- GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, " by client %u\n", c->id);
+ LOG (GNUNET_ERROR_TYPE_DEBUG, " by client %u\n", c->id);
msg = (struct GNUNET_MESH_LocalData *) message;
/* Channel exists? */
chid = ntohl (msg->id);
fwd = chid < GNUNET_MESH_LOCAL_CHANNEL_ID_SERV;
- ch = channel_get_by_local_id (c, chid);
+ ch = GML_channel_get (c, chid);
if (NULL == ch)
{
GNUNET_break (0);
return;
}
- /* Is the client in the channel? */
- if ( !( (fwd &&
- ch->root &&
- ch->root->handle == client)
- ||
- (!fwd &&
- ch->dest &&
- ch->dest->handle == client) ) )
+ if (GNUNET_OK !=
+ GMCH_handle_local_data (ch, c,
+ (struct GNUNET_MessageHeader *)&msg[1], fwd))
{
- GNUNET_break (0);
GNUNET_SERVER_receive_done (client, GNUNET_SYSERR);
return;
}
- rel = fwd ? ch->root_rel : ch->dest_rel;
- rel->client_ready = GNUNET_NO;
-
- /* Ok, everything is correct, send the message. */
- {
- struct GNUNET_MESH_Data *payload;
- uint16_t p2p_size = sizeof(struct GNUNET_MESH_Data) + size;
- unsigned char cbuf[p2p_size];
-
- payload = (struct GNUNET_MESH_Data *) cbuf;
- payload->mid = htonl (rel->mid_send);
- rel->mid_send++;
- memcpy (&payload[1], &msg[1], size);
- payload->header.size = htons (p2p_size);
- payload->header.type = htons (GNUNET_MESSAGE_TYPE_MESH_DATA);
- payload->chid = htonl (ch->gid);
- GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, " sending on channel...\n");
- send_prebuilt_message_channel (&payload->header, ch, fwd);
-
- if (GNUNET_YES == ch->reliable)
- channel_save_copy (ch, &payload->header, fwd);
- }
- if (tunnel_get_buffer (ch->t, fwd) > 0)
- send_local_ack (ch, fwd);
- GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "receive done OK\n");
+ LOG (GNUNET_ERROR_TYPE_DEBUG, "receive done OK\n");
GNUNET_SERVER_receive_done (client, GNUNET_OK);
return;
const struct GNUNET_MessageHeader *message)
{
struct GNUNET_MESH_LocalAck *msg;
- struct MeshChannelReliability *rel;
struct MeshChannel *ch;
struct MeshClient *c;
MESH_ChannelNumber chid;
int fwd;
- GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Got a local ACK\n");
+ LOG (GNUNET_ERROR_TYPE_DEBUG, "Got a local ACK\n");
/* Sanity check for client registration */
- if (NULL == (c = client_get (client)))
+ if (NULL == (c = GML_client_get (client)))
{
GNUNET_break (0);
GNUNET_SERVER_receive_done (client, GNUNET_SYSERR);
return;
}
- GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, " by client %u\n", c->id);
+ LOG (GNUNET_ERROR_TYPE_DEBUG, " by client %u\n", c->id);
msg = (struct GNUNET_MESH_LocalAck *) message;
/* Channel exists? */
chid = ntohl (msg->channel_id);
- GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, " on channel %X\n", chid);
- ch = channel_get_by_local_id (c, chid);
- GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, " -- ch %p\n", ch);
+ LOG (GNUNET_ERROR_TYPE_DEBUG, " on channel %X\n", chid);
+ ch = GML_channel_get (c, chid);
+ LOG (GNUNET_ERROR_TYPE_DEBUG, " -- ch %p\n", ch);
if (NULL == ch)
{
GNUNET_break (0);
- GNUNET_log (GNUNET_ERROR_TYPE_WARNING, "Channel %X unknown.\n", chid);
- GNUNET_log (GNUNET_ERROR_TYPE_WARNING, " for client %u.\n", c->id);
+ LOG (GNUNET_ERROR_TYPE_WARNING, "Channel %X unknown.\n", chid);
+ LOG (GNUNET_ERROR_TYPE_WARNING, " for client %u.\n", c->id);
GNUNET_SERVER_receive_done (client, GNUNET_SYSERR);
return;
}
/* If client is root, the ACK is going FWD, therefore this is "BCK". */
/* If client is dest, the ACK is going BCK, therefore this is "FWD" */
fwd = chid >= GNUNET_MESH_LOCAL_CHANNEL_ID_SERV;
- rel = fwd ? ch->dest_rel : ch->root_rel;
-
- rel->client_ready = GNUNET_YES;
- channel_send_client_buffered_data (ch, c, fwd);
- send_ack (NULL, ch, fwd);
+ GMCH_handle_local_ack (ch, fwd);
GNUNET_SERVER_receive_done (client, GNUNET_OK);
return;
// msg->header.size = htons (sizeof (struct GNUNET_MESH_LocalMonitor));
// msg->header.type = htons (GNUNET_MESSAGE_TYPE_MESH_LOCAL_INFO_TUNNELS);
//
-// GNUNET_log (GNUNET_ERROR_TYPE_INFO,
+// LOG (GNUNET_ERROR_TYPE_INFO,
// "* sending info about tunnel %s\n",
// GNUNET_i2s (&msg->owner));
//
struct MeshClient *c;
/* Sanity check for client registration */
- if (NULL == (c = client_get (client)))
+ if (NULL == (c = GML_client_get (client)))
{
GNUNET_break (0);
GNUNET_SERVER_receive_done (client, GNUNET_SYSERR);
return;
}
- GNUNET_log (GNUNET_ERROR_TYPE_INFO,
+ LOG (GNUNET_ERROR_TYPE_INFO,
"Received get tunnels request from client %u\n",
c->id);
// GNUNET_CONTAINER_multihashmap_iterate (tunnels,
// monitor_all_tunnels_iterator,
// client);
- GNUNET_log (GNUNET_ERROR_TYPE_INFO,
+ LOG (GNUNET_ERROR_TYPE_INFO,
"Get tunnels request from client %u completed\n",
c->id);
GNUNET_SERVER_receive_done (client, GNUNET_OK);
struct MeshChannel *ch;
/* Sanity check for client registration */
- if (NULL == (c = client_get (client)))
+ if (NULL == (c = GML_client_get (client)))
{
GNUNET_break (0);
GNUNET_SERVER_receive_done (client, GNUNET_SYSERR);
}
msg = (struct GNUNET_MESH_LocalMonitor *) message;
- GNUNET_log (GNUNET_ERROR_TYPE_INFO,
+ LOG (GNUNET_ERROR_TYPE_INFO,
"Received tunnel info request from client %u for tunnel %s[%X]\n",
c->id,
&msg->owner,
&resp->header, GNUNET_NO);
GNUNET_free (resp);
- GNUNET_log (GNUNET_ERROR_TYPE_INFO,
+ LOG (GNUNET_ERROR_TYPE_INFO,
"Monitor tunnel request from client %u completed\n",
c->id);
GNUNET_SERVER_receive_done (client, GNUNET_OK);
void
GML_init (struct GNUNET_SERVER_Handle *handle)
{
+ LOG (GNUNET_ERROR_TYPE_DEBUG, "init\n");
server_handle = handle;
GNUNET_SERVER_suspend (server_handle);
ports = GNUNET_CONTAINER_multihashmap32_create (32);
}
+/**
+ * Get a chennel from a client
+ *
+ * @param c the client to check
+ * @param chid Channel ID, must be local (> 0x800...)
+ *
+ * @return non-NULL if channel exists in the clients lists
+ */
+struct MeshChannel *
+GML_channel_get (struct MeshClient *c, MESH_ChannelNumber chid)
+{
+ if (0 == (chid & GNUNET_MESH_LOCAL_CHANNEL_ID_CLI))
+ {
+ GNUNET_break_op (0);
+ LOG (GNUNET_ERROR_TYPE_DEBUG, "CHID %X not a local chid\n", chid);
+ return NULL;
+ }
+ if (chid >= GNUNET_MESH_LOCAL_CHANNEL_ID_SERV)
+ return GNUNET_CONTAINER_multihashmap32_get (c->incoming_channels, chid);
+ return GNUNET_CONTAINER_multihashmap32_get (c->own_channels, chid);
+}
+
+
+/**
+ * Add a channel to a client
+ *
+ * @param client Client.
+ * @param chid Channel ID.
+ * @param ch Channel.
+ */
+void
+GML_channel_add (struct MeshClient *client,
+ uint32_t chid,
+ struct MeshChannel *ch)
+{
+ if (chid >= GNUNET_MESH_LOCAL_CHANNEL_ID_SERV)
+ GNUNET_CONTAINER_multihashmap32_put (client->incoming_channels, chid, ch,
+ GNUNET_CONTAINER_MULTIHASHMAPOPTION_UNIQUE_ONLY);
+ else if (chid >= GNUNET_MESH_LOCAL_CHANNEL_ID_CLI)
+ GNUNET_CONTAINER_multihashmap32_put (client->own_channels, chid, ch,
+ GNUNET_CONTAINER_MULTIHASHMAPOPTION_UNIQUE_ONLY);
+ else
+ GNUNET_break (0);
+}
+
+
+/**
+ * Remove a channel from a client
+ *
+ * @param client Client.
+ * @param chid Channel ID.
+ * @param ch Channel.
+ */
+void
+GML_channel_remove (struct MeshClient *client,
+ uint32_t chid,
+ struct MeshChannel *ch)
+{
+ if (GNUNET_MESH_LOCAL_CHANNEL_ID_SERV <= chid)
+ GNUNET_CONTAINER_multihashmap32_remove (client->incoming_channels, chid, ch);
+ else if (GNUNET_MESH_LOCAL_CHANNEL_ID_CLI <= chid)
+ GNUNET_CONTAINER_multihashmap32_remove (client->own_channels, chid, ch);
+ else
+ GNUNET_break (0);
+}
+
+
+/**
+ * Get the tunnel's next free local channel ID.
+ *
+ * @param c Client.
+ *
+ * @return LID of a channel free to use.
+ */
+MESH_ChannelNumber
+GML_get_next_chid (struct MeshClient *c)
+{
+ MESH_ChannelNumber chid;
+
+ while (NULL != GML_channel_get (c, c->next_chid))
+ {
+ LOG (GNUNET_ERROR_TYPE_DEBUG, "Channel %u exists...\n", c->next_chid);
+ c->next_chid = (c->next_chid + 1) | GNUNET_MESH_LOCAL_CHANNEL_ID_SERV;
+ }
+ chid = c->next_chid;
+ c->next_chid = (c->next_chid + 1) | GNUNET_MESH_LOCAL_CHANNEL_ID_SERV;
+
+ return chid;
+}
+
+
/**
* Check if client has registered with the service and has not disconnected
*
return GNUNET_SERVER_client_get_user_context (client, struct MeshClient);
}
+/**
+ * Find a client that has opened a port
+ *
+ * @param port Port to check.
+ *
+ * @return non-NULL if a client has the port.
+ */
+struct MeshClient *
+GML_client_get_by_port (uint32_t port)
+{
+ return GNUNET_CONTAINER_multihashmap32_get (ports, port);
+}
+
/**
- * Deletes a tunnel from a client (either owner or destination).
+ * Deletes a channel from a client (either owner or destination).
*
* @param c Client whose tunnel to delete.
* @param ch Channel which should be deleted.
+ * @param id Channel ID.
*/
void
-GML_client_delete_channel (struct MeshClient *c, struct MeshChannel *ch)
+GML_client_delete_channel (struct MeshClient *c,
+ struct MeshChannel *ch,
+ MESH_ChannelNumber id)
{
int res;
- if (c == ch->root)
+ if (GNUNET_MESH_LOCAL_CHANNEL_ID_SERV <= id)
{
- res = GNUNET_CONTAINER_multihashmap32_remove (c->own_channels,
- ch->lid_root, ch);
+ res = GNUNET_CONTAINER_multihashmap32_remove (c->incoming_channels,
+ id, ch);
if (GNUNET_YES != res)
- GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "client_delete_channel owner KO\n");
+ LOG (GNUNET_ERROR_TYPE_DEBUG, "client_delete_channel dest KO\n");
}
- if (c == ch->dest)
+ else if (GNUNET_MESH_LOCAL_CHANNEL_ID_CLI <= id)
{
- res = GNUNET_CONTAINER_multihashmap32_remove (c->incoming_channels,
- ch->lid_dest, ch);
+ res = GNUNET_CONTAINER_multihashmap32_remove (c->own_channels,
+ id, ch);
if (GNUNET_YES != res)
- GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "client_delete_tunnel client KO\n");
+ LOG (GNUNET_ERROR_TYPE_DEBUG, "client_delete_tunnel root KO\n");
+ }
+ else
+ {
+ GNUNET_break (0);
}
}
*
* If the client was already allowed to send data, do nothing.
*
- * @param ch Channel on which to send the ACK.
* @param c Client to whom send the ACK.
- * @param fwd Set to GNUNET_YES for FWD ACK (dest->root)
+ * @param id Channel ID to use
*/
void
-GML_send_ack (struct MeshChannel *ch, int fwd)
+GML_send_ack (struct MeshClient *c, MESH_ChannelNumber id)
{
struct GNUNET_MESH_LocalAck msg;
- struct MeshChannelReliability *rel;
- struct MeshClient *c;
-
- c = fwd ? ch->root : ch->dest;
- rel = fwd ? ch->root_rel : ch->dest_rel;
- if (GNUNET_YES == rel->client_ready)
- return; /* don't send double ACKs to client */
+ LOG (GNUNET_ERROR_TYPE_DEBUG,
+ "send local %s ack on %X towards %p\n",
+ id < GNUNET_MESH_LOCAL_CHANNEL_ID_SERV ? "FWD" : "BCK", id, c);
- rel->client_ready = GNUNET_YES;
-
- GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
- "send local %s ack on %s:%X towards %p\n",
- fwd ? "FWD" : "BCK", peer2s (ch->t->peer), ch->gid, c);
-
- if (NULL == c
- || ( fwd && (0 == ch->lid_root || c != ch->root))
- || (!fwd && (0 == ch->lid_dest || c != ch->dest)) )
- {
- GNUNET_break (0);
- return;
- }
msg.header.size = htons (sizeof (msg));
msg.header.type = htons (GNUNET_MESSAGE_TYPE_MESH_LOCAL_ACK);
- msg.channel_id = htonl (fwd ? ch->lid_root : ch->lid_dest);
+ msg.channel_id = htonl (id);
GNUNET_SERVER_notification_context_unicast (nc,
c->handle,
&msg.header,
void
GML_send_channel_create (struct MeshClient *c,
uint32_t id, uint32_t port, uint32_t opt,
- struct GNUNET_PeerIdentity *peer)
+ const struct GNUNET_PeerIdentity *peer)
{
struct GNUNET_MESH_ChannelMessage msg;
/**
* Modify the mesh message ID from global to local and send to client.
*
- * @param msg Message to modify and send.
* @param c Client to send to.
- * @param tid Tunnel ID to use (c can be both owner and client).
+ * @param msg Message to modify and send.
+ * @param id Channel ID to use (c can be both owner and client).
*/
-static void
+void
GML_send_data (struct MeshClient *c,
const struct GNUNET_MESH_Data *msg,
MESH_ChannelNumber id)
}
+/**
+ * Get the static string to represent a client.
+ *
+ * @param c Client.
+ *
+ * @return Static string for the client.
+ */
+const char *
+GML_2s (const struct MeshClient *c)
+{
+ static char buf[32];
+ sprintf (buf, "%u", c->id);
+ return buf;
+}