aboutsummaryrefslogtreecommitdiff
path: root/src/mesh/gnunet-service-mesh-new.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/mesh/gnunet-service-mesh-new.c')
-rw-r--r--src/mesh/gnunet-service-mesh-new.c91
1 files 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
@@ -434,6 +434,12 @@ struct MeshClient
434 struct GNUNET_CONTAINER_MultiHashMap *types; 434 struct GNUNET_CONTAINER_MultiHashMap *types;
435 435
436 /** 436 /**
437 * Ports that this client has declared interest in.
438 * Indexed by a GMC_hash32 (type), contains *Client.
439 */
440 struct GNUNET_CONTAINER_MultiHashMap *ports;
441
442 /**
437 * Whether the client is active or shutting down (don't send confirmations 443 * Whether the client is active or shutting down (don't send confirmations
438 * to a client that is shutting down. 444 * to a client that is shutting down.
439 */ 445 */
@@ -631,6 +637,11 @@ static MESH_TunnelNumber next_local_tid;
631static struct GNUNET_CONTAINER_MultiHashMap *types; 637static struct GNUNET_CONTAINER_MultiHashMap *types;
632 638
633/** 639/**
640 * All ports clients of this peer have opened.
641 */
642static struct GNUNET_CONTAINER_MultiHashMap *ports;
643
644/**
634 * Task to periodically announce itself in the network. 645 * Task to periodically announce itself in the network.
635 */ 646 */
636GNUNET_SCHEDULER_TaskIdentifier announce_id_task; 647GNUNET_SCHEDULER_TaskIdentifier announce_id_task;
@@ -919,10 +930,29 @@ client_delete_tunnel (struct MeshClient *c, struct MeshTunnel *t)
919 } 930 }
920} 931}
921 932
933/**
934 * Notify the appropiate client that a new incoming tunnel was created.
935 *
936 * @param t Tunnel that was created.
937 */
938static void
939send_client_tunnel_create (struct MeshTunnel *t)
940{
941 struct GNUNET_MESH_TunnelMessage msg;
942
943 if (NULL == t->client)
944 return;
945 msg.header.size = htons (sizeof (msg));
946 msg.header.type = htons (GNUNET_MESSAGE_TYPE_MESH_LOCAL_TUNNEL_CREATE);
947 msg.tunnel_id = htonl (t->local_tid_dest);
948 msg.port = htonl (t->port);
949 GNUNET_SERVER_notification_context_unicast (nc, t->client->handle,
950 &msg.header, GNUNET_NO);
951}
952
922 953
923/** 954/**
924 * Notify all clients (not depending on registration status) that the incoming 955 * Notify dest client that the incoming tunnel is no longer valid.
925 * tunnel is no longer valid.
926 * 956 *
927 * @param t Tunnel that was destroyed. 957 * @param t Tunnel that was destroyed.
928 */ 958 */
@@ -2925,6 +2955,7 @@ handle_mesh_path_create (void *cls, const struct GNUNET_PeerIdentity *peer,
2925 GNUNET_break (0); 2955 GNUNET_break (0);
2926 return GNUNET_OK; 2956 return GNUNET_OK;
2927 } 2957 }
2958 t->port = ntohl (msg->port);
2928 opt = ntohl (msg->opt); 2959 opt = ntohl (msg->opt);
2929 if (0 != (opt & MESH_TUNNEL_OPT_NOBUFFER)) 2960 if (0 != (opt & MESH_TUNNEL_OPT_NOBUFFER))
2930 { 2961 {
@@ -2946,6 +2977,10 @@ handle_mesh_path_create (void *cls, const struct GNUNET_PeerIdentity *peer,
2946 return GNUNET_OK; 2977 return GNUNET_OK;
2947 } 2978 }
2948 } 2979 }
2980 else
2981 {
2982 GNUNET_break_op (0);
2983 }
2949 t->state = MESH_TUNNEL_WAITING; 2984 t->state = MESH_TUNNEL_WAITING;
2950 dest_peer_info = 2985 dest_peer_info =
2951 GNUNET_CONTAINER_multihashmap_get (peers, &pi[size - 1].hashPubKey); 2986 GNUNET_CONTAINER_multihashmap_get (peers, &pi[size - 1].hashPubKey);
@@ -2995,17 +3030,30 @@ handle_mesh_path_create (void *cls, const struct GNUNET_PeerIdentity *peer,
2995 GNUNET_PEER_change_rc (t->prev_hop, 1); 3030 GNUNET_PEER_change_rc (t->prev_hop, 1);
2996 if (own_pos == size - 1) 3031 if (own_pos == size - 1)
2997 { 3032 {
2998 /* It is for us! Send ack. */ 3033 struct MeshClient *c;
2999 // TODO: check port number / client registration 3034 struct GNUNET_HashCode hc;
3035
3036 /* Find target client */
3037 GMC_hash32 (t->port, &hc);
3038 c = GNUNET_CONTAINER_multihashmap_get (ports, &hc);
3039 if (NULL == c)
3040 {
3041 /* TODO send reject */
3042 return GNUNET_OK;
3043 }
3044 t->client = c;
3045
3000 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, " It's for us!\n"); 3046 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, " It's for us!\n");
3001 peer_info_add_path_to_origin (orig_peer_info, path, GNUNET_NO); 3047 peer_info_add_path_to_origin (orig_peer_info, path, GNUNET_YES);
3002 t->dest = myid; 3048 t->dest = myid;
3003 3049
3050 /* Assign local tid */
3004 while (NULL != tunnel_get_incoming (next_local_tid)) 3051 while (NULL != tunnel_get_incoming (next_local_tid))
3005 next_local_tid = (next_local_tid + 1) | GNUNET_MESH_LOCAL_TUNNEL_ID_SERV; 3052 next_local_tid = (next_local_tid + 1) | GNUNET_MESH_LOCAL_TUNNEL_ID_SERV;
3006 t->local_tid_dest = next_local_tid++; 3053 t->local_tid_dest = next_local_tid++;
3007 next_local_tid = next_local_tid | GNUNET_MESH_LOCAL_TUNNEL_ID_SERV; 3054 next_local_tid = next_local_tid | GNUNET_MESH_LOCAL_TUNNEL_ID_SERV;
3008 3055
3056 send_client_tunnel_create (t);
3009 send_path_ack (t); 3057 send_path_ack (t);
3010 } 3058 }
3011 else 3059 else
@@ -3804,8 +3852,10 @@ handle_local_new_client (void *cls, struct GNUNET_SERVER_Client *client,
3804 struct MeshClient *c; 3852 struct MeshClient *c;
3805 unsigned int size; 3853 unsigned int size;
3806 uint16_t ntypes; 3854 uint16_t ntypes;
3855 uint16_t nports;
3807 uint16_t *t; 3856 uint16_t *t;
3808 uint16_t i; 3857 uint32_t *p;
3858 unsigned int i;
3809 3859
3810 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "new client connected\n"); 3860 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "new client connected\n");
3811 3861
@@ -3813,6 +3863,7 @@ handle_local_new_client (void *cls, struct GNUNET_SERVER_Client *client,
3813 size = ntohs (message->size) - sizeof (struct GNUNET_MESH_ClientConnect); 3863 size = ntohs (message->size) - sizeof (struct GNUNET_MESH_ClientConnect);
3814 cc_msg = (struct GNUNET_MESH_ClientConnect *) message; 3864 cc_msg = (struct GNUNET_MESH_ClientConnect *) message;
3815 ntypes = ntohs (cc_msg->types); 3865 ntypes = ntohs (cc_msg->types);
3866 nports = ntohs (cc_msg->ports);
3816 if (size != ntypes * sizeof (uint16_t)) 3867 if (size != ntypes * sizeof (uint16_t))
3817 { 3868 {
3818 GNUNET_break (0); 3869 GNUNET_break (0);
@@ -3827,12 +3878,12 @@ handle_local_new_client (void *cls, struct GNUNET_SERVER_Client *client,
3827 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, " client has %u types\n", ntypes); 3878 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, " client has %u types\n", ntypes);
3828 c->handle = client; 3879 c->handle = client;
3829 GNUNET_SERVER_client_keep (client); 3880 GNUNET_SERVER_client_keep (client);
3881 t = (uint16_t *) &cc_msg[1];
3830 if (ntypes > 0) 3882 if (ntypes > 0)
3831 { 3883 {
3832 uint16_t u16; 3884 uint16_t u16;
3833 struct GNUNET_HashCode hc; 3885 struct GNUNET_HashCode hc;
3834 3886
3835 t = (uint16_t *) &cc_msg[1];
3836 c->types = GNUNET_CONTAINER_multihashmap_create (ntypes, GNUNET_NO); 3887 c->types = GNUNET_CONTAINER_multihashmap_create (ntypes, GNUNET_NO);
3837 for (i = 0; i < ntypes; i++) 3888 for (i = 0; i < ntypes; i++)
3838 { 3889 {
@@ -3840,7 +3891,7 @@ handle_local_new_client (void *cls, struct GNUNET_SERVER_Client *client,
3840 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, " msg type: %u\n", u16); 3891 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, " msg type: %u\n", u16);
3841 GMC_hash32 ((uint32_t) u16, &hc); 3892 GMC_hash32 ((uint32_t) u16, &hc);
3842 3893
3843 /* store in clients hashmap */ 3894 /* store in client's hashmap */
3844 GNUNET_CONTAINER_multihashmap_put (c->types, &hc, c, 3895 GNUNET_CONTAINER_multihashmap_put (c->types, &hc, c,
3845 GNUNET_CONTAINER_MULTIHASHMAPOPTION_UNIQUE_FAST); 3896 GNUNET_CONTAINER_MULTIHASHMAPOPTION_UNIQUE_FAST);
3846 /* store in global hashmap */ 3897 /* store in global hashmap */
@@ -3848,6 +3899,29 @@ handle_local_new_client (void *cls, struct GNUNET_SERVER_Client *client,
3848 GNUNET_CONTAINER_MULTIHASHMAPOPTION_MULTIPLE); 3899 GNUNET_CONTAINER_MULTIHASHMAPOPTION_MULTIPLE);
3849 } 3900 }
3850 } 3901 }
3902 if (nports > 0)
3903 {
3904 uint32_t u32;
3905 struct GNUNET_HashCode hc;
3906
3907 p = (uint32_t *) &t[ntypes];
3908 c->ports = GNUNET_CONTAINER_multihashmap_create (nports, GNUNET_NO);
3909 for (i = 0; i < nports; i++)
3910 {
3911 u32 = ntohl (p[i]);
3912 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, " port: %u\n", u32);
3913 GMC_hash32 (u32, &hc);
3914
3915 /* store in client's hashmap */
3916 GNUNET_CONTAINER_multihashmap_put (c->ports, &hc, c,
3917 GNUNET_CONTAINER_MULTIHASHMAPOPTION_UNIQUE_FAST);
3918 /* store in global hashmap */
3919 /* FIXME only allow one client to have the port open,
3920 * have a backup hashmap with waiting clients */
3921 GNUNET_CONTAINER_multihashmap_put (ports, &hc, c,
3922 GNUNET_CONTAINER_MULTIHASHMAPOPTION_MULTIPLE);
3923 }
3924 }
3851 3925
3852 GNUNET_CONTAINER_DLL_insert (clients_head, clients_tail, c); 3926 GNUNET_CONTAINER_DLL_insert (clients_head, clients_tail, c);
3853 c->own_tunnels = GNUNET_CONTAINER_multihashmap_create (32, GNUNET_NO); 3927 c->own_tunnels = GNUNET_CONTAINER_multihashmap_create (32, GNUNET_NO);
@@ -4910,6 +4984,7 @@ run (void *cls, struct GNUNET_SERVER_Handle *server,
4910 incoming_tunnels = GNUNET_CONTAINER_multihashmap_create (32, GNUNET_NO); 4984 incoming_tunnels = GNUNET_CONTAINER_multihashmap_create (32, GNUNET_NO);
4911 peers = GNUNET_CONTAINER_multihashmap_create (32, GNUNET_NO); 4985 peers = GNUNET_CONTAINER_multihashmap_create (32, GNUNET_NO);
4912 types = GNUNET_CONTAINER_multihashmap_create (32, GNUNET_NO); 4986 types = GNUNET_CONTAINER_multihashmap_create (32, GNUNET_NO);
4987 ports = GNUNET_CONTAINER_multihashmap_create (32, GNUNET_NO);
4913 4988
4914 dht_handle = GNUNET_DHT_connect (c, 64); 4989 dht_handle = GNUNET_DHT_connect (c, 64);
4915 if (NULL == dht_handle) 4990 if (NULL == dht_handle)