/**
* Struct containing information about a client of the service
*
- * TODO: add a list of 'waiting' types
+ * TODO: add a list of 'waiting' ports
*/
struct MeshClient
{
struct GNUNET_SERVER_Client *handle;
/**
- * Messages that this client has declared interest in.
+ * Ports that this client has declared interest in.
* Indexed by a GMC_hash32 (type), contains *Client.
*/
- struct GNUNET_CONTAINER_MultiHashMap *types;
+ struct GNUNET_CONTAINER_MultiHashMap *ports;
/**
* Whether the client is active or shutting down (don't send confirmations
static MESH_TunnelNumber next_local_tid;
/**
- * All message types clients of this peer are interested in.
+ * All ports clients of this peer have opened.
*/
-static struct GNUNET_CONTAINER_MultiHashMap *types;
+static struct GNUNET_CONTAINER_MultiHashMap *ports;
/**
* Task to periodically announce itself in the network.
}
}
+/**
+ * Notify the appropiate client that a new incoming tunnel was created.
+ *
+ * @param t Tunnel that was created.
+ */
+static void
+send_client_tunnel_create (struct MeshTunnel *t)
+{
+ struct GNUNET_MESH_TunnelMessage msg;
+
+ if (NULL == t->client)
+ return;
+ msg.header.size = htons (sizeof (msg));
+ msg.header.type = htons (GNUNET_MESSAGE_TYPE_MESH_LOCAL_TUNNEL_CREATE);
+ msg.tunnel_id = htonl (t->local_tid_dest);
+ msg.port = htonl (t->port);
+ GNUNET_SERVER_notification_context_unicast (nc, t->client->handle,
+ &msg.header, GNUNET_NO);
+}
+
/**
- * Notify all clients (not depending on registration status) that the incoming
- * tunnel is no longer valid.
+ * Notify dest client that the incoming tunnel is no longer valid.
*
* @param t Tunnel that was destroyed.
*/
GNUNET_break (0);
return GNUNET_OK;
}
+ t->port = ntohl (msg->port);
opt = ntohl (msg->opt);
if (0 != (opt & MESH_TUNNEL_OPT_NOBUFFER))
{
return GNUNET_OK;
}
}
+ else
+ {
+ GNUNET_break_op (0);
+ }
t->state = MESH_TUNNEL_WAITING;
dest_peer_info =
GNUNET_CONTAINER_multihashmap_get (peers, &pi[size - 1].hashPubKey);
GNUNET_PEER_change_rc (t->prev_hop, 1);
if (own_pos == size - 1)
{
- /* It is for us! Send ack. */
- // TODO: check port number / client registration
+ struct MeshClient *c;
+ struct GNUNET_HashCode hc;
+
+ /* Find target client */
+ GMC_hash32 (t->port, &hc);
+ c = GNUNET_CONTAINER_multihashmap_get (ports, &hc);
+ if (NULL == c)
+ {
+ /* TODO send reject */
+ return GNUNET_OK;
+ }
+ t->client = c;
+
GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, " It's for us!\n");
- peer_info_add_path_to_origin (orig_peer_info, path, GNUNET_NO);
+ peer_info_add_path_to_origin (orig_peer_info, path, GNUNET_YES);
t->dest = myid;
+ /* Assign local tid */
while (NULL != tunnel_get_incoming (next_local_tid))
next_local_tid = (next_local_tid + 1) | GNUNET_MESH_LOCAL_TUNNEL_ID_SERV;
t->local_tid_dest = next_local_tid++;
next_local_tid = next_local_tid | GNUNET_MESH_LOCAL_TUNNEL_ID_SERV;
+ send_client_tunnel_create (t);
send_path_ack (t);
}
else
GNUNET_CONTAINER_multihashmap_destroy (c->own_tunnels);
GNUNET_CONTAINER_multihashmap_destroy (c->incoming_tunnels);
- if (NULL != c->types)
- GNUNET_CONTAINER_multihashmap_destroy (c->types);
+ if (NULL != c->ports)
+ GNUNET_CONTAINER_multihashmap_destroy (c->ports);
next = c->next;
GNUNET_CONTAINER_DLL_remove (clients_head, clients_tail, c);
GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, " CLIENT FREE at %p\n", c);
struct GNUNET_MESH_ClientConnect *cc_msg;
struct MeshClient *c;
unsigned int size;
- uint16_t ntypes;
- uint16_t *t;
- uint16_t i;
+ uint32_t *p;
+ unsigned int i;
GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "new client connected\n");
/* Check data sanity */
size = ntohs (message->size) - sizeof (struct GNUNET_MESH_ClientConnect);
cc_msg = (struct GNUNET_MESH_ClientConnect *) message;
- ntypes = ntohs (cc_msg->types);
- if (size != ntypes * sizeof (uint16_t))
+ if (0 != (size % sizeof (uint32_t)))
{
GNUNET_break (0);
GNUNET_SERVER_receive_done (client, GNUNET_SYSERR);
return;
}
+ size /= sizeof (uint32_t);
/* Create new client structure */
c = GNUNET_malloc (sizeof (struct MeshClient));
c->id = next_client_id++; /* overflow not important: just for debug */
- GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, " CLIENT NEW %u\n", c->id);
- GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, " client has %u types\n", ntypes);
+ GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, " client id %u\n", c->id);
+ GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, " client has %u ports\n", size);
c->handle = client;
GNUNET_SERVER_client_keep (client);
- if (ntypes > 0)
+ if (size > 0)
{
- uint16_t u16;
+ uint32_t u32;
struct GNUNET_HashCode hc;
- t = (uint16_t *) &cc_msg[1];
- c->types = GNUNET_CONTAINER_multihashmap_create (ntypes, GNUNET_NO);
- for (i = 0; i < ntypes; i++)
+ p = (uint32_t *) &cc_msg[1];
+ c->ports = GNUNET_CONTAINER_multihashmap_create (size, GNUNET_NO);
+ for (i = 0; i < size; i++)
{
- u16 = ntohs (t[i]);
- GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, " msg type: %u\n", u16);
- GMC_hash32 ((uint32_t) u16, &hc);
+ u32 = ntohl (p[i]);
+ GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, " port: %u\n", u32);
+ GMC_hash32 (u32, &hc);
- /* store in clients hashmap */
- GNUNET_CONTAINER_multihashmap_put (c->types, &hc, c,
+ /* store in client's hashmap */
+ GNUNET_CONTAINER_multihashmap_put (c->ports, &hc, c,
GNUNET_CONTAINER_MULTIHASHMAPOPTION_UNIQUE_FAST);
/* store in global hashmap */
- GNUNET_CONTAINER_multihashmap_put (types, &hc, c,
+ /* FIXME only allow one client to have the port open,
+ * have a backup hashmap with waiting clients */
+ GNUNET_CONTAINER_multihashmap_put (ports, &hc, c,
GNUNET_CONTAINER_MULTIHASHMAPOPTION_MULTIPLE);
}
}
tunnels = GNUNET_CONTAINER_multihashmap_create (32, GNUNET_NO);
incoming_tunnels = GNUNET_CONTAINER_multihashmap_create (32, GNUNET_NO);
peers = GNUNET_CONTAINER_multihashmap_create (32, GNUNET_NO);
- types = GNUNET_CONTAINER_multihashmap_create (32, GNUNET_NO);
+ ports = GNUNET_CONTAINER_multihashmap_create (32, GNUNET_NO);
dht_handle = GNUNET_DHT_connect (c, 64);
if (NULL == dht_handle)