From 28ce81cd95b3942d30deb45c81fe9f961c4d3d3c Mon Sep 17 00:00:00 2001 From: Bart Polot Date: Wed, 15 May 2013 00:04:09 +0000 Subject: - use port for tunnel creation / notification --- src/mesh/gnunet-service-mesh-new.c | 91 ++++++++++++++++++++++++++++++++++---- 1 file changed, 83 insertions(+), 8 deletions(-) diff --git a/src/mesh/gnunet-service-mesh-new.c b/src/mesh/gnunet-service-mesh-new.c index 49b70319a..729b536a4 100644 --- a/src/mesh/gnunet-service-mesh-new.c +++ b/src/mesh/gnunet-service-mesh-new.c @@ -433,6 +433,12 @@ struct MeshClient */ struct GNUNET_CONTAINER_MultiHashMap *types; + /** + * Ports that this client has declared interest in. + * Indexed by a GMC_hash32 (type), contains *Client. + */ + struct GNUNET_CONTAINER_MultiHashMap *ports; + /** * Whether the client is active or shutting down (don't send confirmations * to a client that is shutting down. @@ -630,6 +636,11 @@ static MESH_TunnelNumber next_local_tid; */ static struct GNUNET_CONTAINER_MultiHashMap *types; +/** + * All ports clients of this peer have opened. + */ +static struct GNUNET_CONTAINER_MultiHashMap *ports; + /** * Task to periodically announce itself in the network. */ @@ -919,10 +930,29 @@ client_delete_tunnel (struct MeshClient *c, struct MeshTunnel *t) } } +/** + * 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. */ @@ -2925,6 +2955,7 @@ handle_mesh_path_create (void *cls, const struct GNUNET_PeerIdentity *peer, GNUNET_break (0); return GNUNET_OK; } + t->port = ntohl (msg->port); opt = ntohl (msg->opt); if (0 != (opt & MESH_TUNNEL_OPT_NOBUFFER)) { @@ -2946,6 +2977,10 @@ handle_mesh_path_create (void *cls, const struct GNUNET_PeerIdentity *peer, 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); @@ -2995,17 +3030,30 @@ handle_mesh_path_create (void *cls, const struct GNUNET_PeerIdentity *peer, 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 @@ -3804,8 +3852,10 @@ handle_local_new_client (void *cls, struct GNUNET_SERVER_Client *client, struct MeshClient *c; unsigned int size; uint16_t ntypes; + uint16_t nports; uint16_t *t; - uint16_t i; + uint32_t *p; + unsigned int i; GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "new client connected\n"); @@ -3813,6 +3863,7 @@ handle_local_new_client (void *cls, struct GNUNET_SERVER_Client *client, size = ntohs (message->size) - sizeof (struct GNUNET_MESH_ClientConnect); cc_msg = (struct GNUNET_MESH_ClientConnect *) message; ntypes = ntohs (cc_msg->types); + nports = ntohs (cc_msg->ports); if (size != ntypes * sizeof (uint16_t)) { GNUNET_break (0); @@ -3827,12 +3878,12 @@ handle_local_new_client (void *cls, struct GNUNET_SERVER_Client *client, GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, " client has %u types\n", ntypes); c->handle = client; GNUNET_SERVER_client_keep (client); + t = (uint16_t *) &cc_msg[1]; if (ntypes > 0) { uint16_t u16; 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++) { @@ -3840,7 +3891,7 @@ handle_local_new_client (void *cls, struct GNUNET_SERVER_Client *client, GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, " msg type: %u\n", u16); GMC_hash32 ((uint32_t) u16, &hc); - /* store in clients hashmap */ + /* store in client's hashmap */ GNUNET_CONTAINER_multihashmap_put (c->types, &hc, c, GNUNET_CONTAINER_MULTIHASHMAPOPTION_UNIQUE_FAST); /* store in global hashmap */ @@ -3848,6 +3899,29 @@ handle_local_new_client (void *cls, struct GNUNET_SERVER_Client *client, GNUNET_CONTAINER_MULTIHASHMAPOPTION_MULTIPLE); } } + if (nports > 0) + { + uint32_t u32; + struct GNUNET_HashCode hc; + + p = (uint32_t *) &t[ntypes]; + c->ports = GNUNET_CONTAINER_multihashmap_create (nports, GNUNET_NO); + for (i = 0; i < nports; i++) + { + u32 = ntohl (p[i]); + GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, " port: %u\n", u32); + GMC_hash32 (u32, &hc); + + /* store in client's hashmap */ + GNUNET_CONTAINER_multihashmap_put (c->ports, &hc, c, + GNUNET_CONTAINER_MULTIHASHMAPOPTION_UNIQUE_FAST); + /* store in global hashmap */ + /* 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); + } + } GNUNET_CONTAINER_DLL_insert (clients_head, clients_tail, c); c->own_tunnels = GNUNET_CONTAINER_multihashmap_create (32, GNUNET_NO); @@ -4910,6 +4984,7 @@ run (void *cls, struct GNUNET_SERVER_Handle *server, 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) -- cgit v1.2.3