aboutsummaryrefslogtreecommitdiff
path: root/src/mesh
diff options
context:
space:
mode:
authorBart Polot <bart@net.in.tum.de>2011-05-02 22:36:20 +0000
committerBart Polot <bart@net.in.tum.de>2011-05-02 22:36:20 +0000
commitb869c58f5e200d802f4f764d802e1569ca041b6a (patch)
treeb8071eae2d5faf4b6bf4b027712bf77b2568cf97 /src/mesh
parent4aea44167099630dd9e92166b8c319cffa3e7b31 (diff)
downloadgnunet-b869c58f5e200d802f4f764d802e1569ca041b6a.tar.gz
gnunet-b869c58f5e200d802f4f764d802e1569ca041b6a.zip
WiP
Diffstat (limited to 'src/mesh')
-rw-r--r--src/mesh/gnunet-service-mesh.c238
1 files changed, 216 insertions, 22 deletions
diff --git a/src/mesh/gnunet-service-mesh.c b/src/mesh/gnunet-service-mesh.c
index 6c70d9684..1ffcb848d 100644
--- a/src/mesh/gnunet-service-mesh.c
+++ b/src/mesh/gnunet-service-mesh.c
@@ -247,6 +247,11 @@ struct PeerInfo
247 GNUNET_PEER_Id id; 247 GNUNET_PEER_Id id;
248 248
249 /** 249 /**
250 * Tunnel this peer belongs to
251 */
252 struct MESH_tunnel *t;
253
254 /**
250 * Is the peer reachable? Is the peer even connected? 255 * Is the peer reachable? Is the peer even connected?
251 */ 256 */
252 enum PeerState state; 257 enum PeerState state;
@@ -265,10 +270,17 @@ struct PeerInfo
265 * Max data rate to this peer 270 * Max data rate to this peer
266 */ 271 */
267 uint32_t max_speed; 272 uint32_t max_speed;
273
274 /**
275 * Handle to stop the DHT search for a path to this peer
276 */
277 struct GNUNET_DHT_GetHandle *dhtget;
268}; 278};
269 279
270 280
271typedef uint32_t MESH_PathID; 281typedef uint32_t MESH_PathID;
282
283
272/** 284/**
273 * Information regarding a path 285 * Information regarding a path
274 */ 286 */
@@ -297,6 +309,9 @@ struct Path
297 int length; 309 int length;
298}; 310};
299 311
312/**
313 * Data scheduled to transmit (to local client or remote peer)
314 */
300struct MESH_queue 315struct MESH_queue
301{ 316{
302 /** 317 /**
@@ -448,6 +463,12 @@ static struct Client *clients_head;
448static struct Client *clients_tail; 463static struct Client *clients_tail;
449 464
450/** 465/**
466 * Tunnels not owned by this node
467 */
468// static struct MESH_Tunnel *tunnels_head;
469// static struct MESH_Tunnel *tunnels_tail;
470
471/**
451 * Handle to communicate with core 472 * Handle to communicate with core
452 */ 473 */
453static struct GNUNET_CORE_Handle *core_handle; 474static struct GNUNET_CORE_Handle *core_handle;
@@ -555,6 +576,41 @@ client_retrieve (struct GNUNET_SERVER_Client *client) {
555} 576}
556 577
557/** 578/**
579 * Iterator called on each result obtained for a DHT
580 * operation that expects a reply
581 *
582 * @param cls closure
583 * @param exp when will this value expire
584 * @param key key of the result
585 * @param get_path NULL-terminated array of pointers
586 * to the peers on reverse GET path (or NULL if not recorded)
587 * @param put_path NULL-terminated array of pointers
588 * to the peers on the PUT path (or NULL if not recorded)
589 * @param type type of the result
590 * @param size number of bytes in data
591 * @param data pointer to the result data
592 */
593void dht_get_response_handler(void *cls,
594 struct GNUNET_TIME_Absolute exp,
595 const GNUNET_HashCode * key,
596 const struct GNUNET_PeerIdentity * const *get_path,
597 const struct GNUNET_PeerIdentity * const *put_path,
598 enum GNUNET_BLOCK_Type type,
599 size_t size,
600 const void *data)
601{
602 struct PeerInfo *peer_info;
603 struct MESH_tunnel *t;
604 struct Path *p;
605
606 peer_info = (struct PeerInfo *)cls;
607 t = peer_info->t;
608 p = GNUNET_malloc(sizeof(struct Path));
609 GNUNET_CONTAINER_DLL_insert(t->paths_head, t->paths_tail, p);
610 return;
611}
612
613/**
558 * Handler for client disconnection 614 * Handler for client disconnection
559 * 615 *
560 * @param cls closure 616 * @param cls closure
@@ -567,11 +623,6 @@ handle_client_disconnect (void *cls, struct GNUNET_SERVER_Client *client)
567 struct Client *c, *next; 623 struct Client *c, *next;
568 struct MESH_tunnel *t; 624 struct MESH_tunnel *t;
569 625
570 /* If there are no clients registered, something is wrong... or is it?
571 * FIXME: what happens if a client connects, doesn't send a MESH_Connect
572 * and disconnects? Does the service get a disconnect notification anyway?
573 */
574 GNUNET_assert(NULL != clients_head);
575 c = clients_head; 626 c = clients_head;
576 while(NULL != c) { 627 while(NULL != c) {
577 if (c->handle == client) { 628 if (c->handle == client) {
@@ -788,6 +839,8 @@ handle_local_connect_add (void *cls,
788 MESH_TunnelID tid; 839 MESH_TunnelID tid;
789 struct PeerInfo *peer_info; 840 struct PeerInfo *peer_info;
790 841
842 GNUNET_HashCode key;
843
791 844
792 /* Sanity check for client registration */ 845 /* Sanity check for client registration */
793 if(NULL == (c = client_retrieve(client))) { 846 if(NULL == (c = client_retrieve(client))) {
@@ -834,9 +887,23 @@ handle_local_connect_add (void *cls,
834 peer_info = (struct PeerInfo *) GNUNET_malloc(sizeof(struct PeerInfo)); 887 peer_info = (struct PeerInfo *) GNUNET_malloc(sizeof(struct PeerInfo));
835 peer_info->id = GNUNET_PEER_intern(&peer_msg->peer); 888 peer_info->id = GNUNET_PEER_intern(&peer_msg->peer);
836 peer_info->state = MESH_PEER_WAITING; 889 peer_info->state = MESH_PEER_WAITING;
890 peer_info->t = t;
837 t->peers_total++; 891 t->peers_total++;
838 GNUNET_CONTAINER_DLL_insert(t->peers_head, t->peers_tail, peer_info); 892 GNUNET_CONTAINER_DLL_insert(t->peers_head, t->peers_tail, peer_info);
839 /* TODO MESH SEARCH FOR PEER */ 893 /* start dht search */
894 // FIXME key = hash (peerid + salt);
895 peer_info->dhtget = GNUNET_DHT_get_start(dht_handle,
896 GNUNET_TIME_relative_get_forever(),
897 GNUNET_BLOCK_TYPE_ANY,
898 &key,
899 4, /* replication level */
900 GNUNET_DHT_RO_RECORD_ROUTE,
901 NULL, /* bloom filter */
902 0, /* mutator */
903 NULL, /* xquery */
904 0, /* xquery bits */
905 dht_get_response_handler,
906 (void *)peer_info);
840 907
841 GNUNET_SERVER_receive_done(client, GNUNET_OK); 908 GNUNET_SERVER_receive_done(client, GNUNET_OK);
842 return; 909 return;
@@ -906,12 +973,12 @@ handle_local_connect_del (void *cls,
906 } 973 }
907 974
908 /* Ok, delete peer from tunnel */ 975 /* Ok, delete peer from tunnel */
909 p = t->paths_head;
910 peer_id = GNUNET_PEER_intern(&peer_msg->peer); 976 peer_id = GNUNET_PEER_intern(&peer_msg->peer);
911 977
912 /* Delete paths */ 978 /* Delete paths */
979 p = t->paths_head;
913 while(p != NULL) { 980 while(p != NULL) {
914 if(p->peers[p->length-1] == peer_id) { 981 if(p->peers[p->length-1] == peer_id) { /* one path per destination */
915 GNUNET_CONTAINER_DLL_remove(t->paths_head, t->paths_tail, p); 982 GNUNET_CONTAINER_DLL_remove(t->paths_head, t->paths_tail, p);
916 GNUNET_PEER_decrement_rcs(p->peers, p->length); 983 GNUNET_PEER_decrement_rcs(p->peers, p->length);
917 aux_path = p; 984 aux_path = p;
@@ -962,12 +1029,57 @@ handle_local_connect_by_type (void *cls,
962 struct GNUNET_SERVER_Client *client, 1029 struct GNUNET_SERVER_Client *client,
963 const struct GNUNET_MessageHeader *message) 1030 const struct GNUNET_MessageHeader *message)
964{ 1031{
1032 struct GNUNET_MESH_ConnectPeerByType *connect_msg;
1033 MESH_TunnelID tid;
1034 GNUNET_MESH_ApplicationType application;
1035 struct Client *c;
1036 struct MESH_tunnel *t;
1037
965 /* Sanity check for client registration */ 1038 /* Sanity check for client registration */
966 if(NULL == client_retrieve(client)) { 1039 if(NULL == (c = client_retrieve(client))) {
1040 GNUNET_break(0);
1041 GNUNET_SERVER_receive_done(client, GNUNET_SYSERR);
1042 return;
1043 }
1044
1045 connect_msg = (struct GNUNET_MESH_ConnectPeerByType *)message;
1046 /* Sanity check for message size */
1047 if(sizeof(struct GNUNET_MESH_PeerControl) != ntohs(connect_msg->header.size)) {
967 GNUNET_break(0); 1048 GNUNET_break(0);
968 GNUNET_SERVER_receive_done(client, GNUNET_SYSERR); 1049 GNUNET_SERVER_receive_done(client, GNUNET_SYSERR);
969 return; 1050 return;
970 } 1051 }
1052
1053 /* Tunnel exists? */
1054 tid = ntohl(connect_msg->tunnel_id);
1055 if(NULL == (t = c->tunnels_head)) {
1056 GNUNET_break(0);
1057 GNUNET_SERVER_receive_done(client, GNUNET_SYSERR);
1058 return;
1059 }
1060 while(NULL != t) {
1061 if(t->tid == tid) {
1062 break;
1063 }
1064 if(t == c->tunnels_tail) {
1065 GNUNET_break(0);
1066 GNUNET_SERVER_receive_done(client, GNUNET_SYSERR);
1067 return;
1068 }
1069 t = t->next;
1070 }
1071
1072 /* Does client own tunnel? */
1073 if(t->client->handle != client) {
1074 GNUNET_break(0);
1075 GNUNET_SERVER_receive_done(client, GNUNET_SYSERR);
1076 return;
1077 }
1078
1079 /* Ok, lets find a peer offering the service */
1080 application = ntohl(connect_msg->type);
1081 application++; // FIXME silence warnings
1082
971 GNUNET_SERVER_receive_done(client, GNUNET_OK); 1083 GNUNET_SERVER_receive_done(client, GNUNET_OK);
972 return; 1084 return;
973} 1085}
@@ -985,12 +1097,53 @@ handle_local_network_traffic (void *cls,
985 struct GNUNET_SERVER_Client *client, 1097 struct GNUNET_SERVER_Client *client,
986 const struct GNUNET_MessageHeader *message) 1098 const struct GNUNET_MessageHeader *message)
987{ 1099{
1100 struct Client *c;
1101 struct MESH_tunnel *t;
1102 struct GNUNET_MESH_Data *data_msg;
1103 MESH_TunnelID tid;
1104
988 /* Sanity check for client registration */ 1105 /* Sanity check for client registration */
989 if(NULL == client_retrieve(client)) { 1106 if(NULL == (c = client_retrieve(client))) {
1107 GNUNET_break(0);
1108 GNUNET_SERVER_receive_done(client, GNUNET_SYSERR);
1109 return;
1110 }
1111 data_msg = (struct GNUNET_MESH_Data *)message;
1112 /* Sanity check for message size */
1113 if(sizeof(struct GNUNET_MESH_PeerControl) != ntohs(data_msg->header.size)) {
990 GNUNET_break(0); 1114 GNUNET_break(0);
991 GNUNET_SERVER_receive_done(client, GNUNET_SYSERR); 1115 GNUNET_SERVER_receive_done(client, GNUNET_SYSERR);
992 return; 1116 return;
993 } 1117 }
1118
1119 /* Tunnel exists? */
1120 tid = ntohl(data_msg->tunnel_id);
1121 if(NULL == (t = c->tunnels_head)) {
1122 GNUNET_break(0);
1123 GNUNET_SERVER_receive_done(client, GNUNET_SYSERR);
1124 return;
1125 }
1126 while(NULL != t) {
1127 if(t->tid == tid) {
1128 break;
1129 }
1130 if(t == c->tunnels_tail) {
1131 GNUNET_break(0);
1132 GNUNET_SERVER_receive_done(client, GNUNET_SYSERR);
1133 return;
1134 }
1135 t = t->next;
1136 }
1137
1138 /* Does client own tunnel? */
1139 if(t->client->handle != client) {
1140 GNUNET_break(0);
1141 GNUNET_SERVER_receive_done(client, GNUNET_SYSERR);
1142 return;
1143 }
1144
1145 /* TODO */
1146
994 GNUNET_SERVER_receive_done(client, GNUNET_OK); 1147 GNUNET_SERVER_receive_done(client, GNUNET_OK);
995 return; 1148 return;
996} 1149}
@@ -1007,12 +1160,53 @@ handle_local_network_traffic_bcast (void *cls,
1007 struct GNUNET_SERVER_Client *client, 1160 struct GNUNET_SERVER_Client *client,
1008 const struct GNUNET_MessageHeader *message) 1161 const struct GNUNET_MessageHeader *message)
1009{ 1162{
1163 struct Client *c;
1164 struct MESH_tunnel *t;
1165 struct GNUNET_MESH_DataBroadcast *data_msg;
1166 MESH_TunnelID tid;
1167
1010 /* Sanity check for client registration */ 1168 /* Sanity check for client registration */
1011 if(NULL == client_retrieve(client)) { 1169 if(NULL == (c = client_retrieve(client))) {
1170 GNUNET_break(0);
1171 GNUNET_SERVER_receive_done(client, GNUNET_SYSERR);
1172 return;
1173 }
1174 data_msg = (struct GNUNET_MESH_DataBroadcast *)message;
1175 /* Sanity check for message size */
1176 if(sizeof(struct GNUNET_MESH_PeerControl) != ntohs(data_msg->header.size)) {
1012 GNUNET_break(0); 1177 GNUNET_break(0);
1013 GNUNET_SERVER_receive_done(client, GNUNET_SYSERR); 1178 GNUNET_SERVER_receive_done(client, GNUNET_SYSERR);
1014 return; 1179 return;
1015 } 1180 }
1181
1182 /* Tunnel exists? */
1183 tid = ntohl(data_msg->tunnel_id);
1184 if(NULL == (t = c->tunnels_head)) {
1185 GNUNET_break(0);
1186 GNUNET_SERVER_receive_done(client, GNUNET_SYSERR);
1187 return;
1188 }
1189 while(NULL != t) {
1190 if(t->tid == tid) {
1191 break;
1192 }
1193 if(t == c->tunnels_tail) {
1194 GNUNET_break(0);
1195 GNUNET_SERVER_receive_done(client, GNUNET_SYSERR);
1196 return;
1197 }
1198 t = t->next;
1199 }
1200
1201 /* Does client own tunnel? */
1202 if(t->client->handle != client) {
1203 GNUNET_break(0);
1204 GNUNET_SERVER_receive_done(client, GNUNET_SYSERR);
1205 return;
1206 }
1207
1208 /* TODO */
1209
1016 GNUNET_SERVER_receive_done(client, GNUNET_OK); 1210 GNUNET_SERVER_receive_done(client, GNUNET_OK);
1017 return; 1211 return;
1018} 1212}
@@ -1106,9 +1300,9 @@ run (void *cls,
1106 const struct GNUNET_CONFIGURATION_Handle *c) 1300 const struct GNUNET_CONFIGURATION_Handle *c)
1107{ 1301{
1108 1302
1109 GNUNET_SERVER_add_handlers (server, plugin_handlers); 1303 GNUNET_SERVER_add_handlers (server, plugin_handlers);
1110 GNUNET_SERVER_disconnect_notify (server, &handle_client_disconnect, NULL); 1304 GNUNET_SERVER_disconnect_notify (server, &handle_client_disconnect, NULL);
1111 core_handle = GNUNET_CORE_connect (c, /* Main configuration */ 1305 core_handle = GNUNET_CORE_connect (c, /* Main configuration */
1112 32, /* queue size */ 1306 32, /* queue size */
1113 NULL, /* Closure passed to MESH functions */ 1307 NULL, /* Closure passed to MESH functions */
1114 &core_init, /* Call core_init once connected */ 1308 &core_init, /* Call core_init once connected */
@@ -1121,14 +1315,14 @@ run (void *cls,
1121 GNUNET_NO, /* For header-only out notification */ 1315 GNUNET_NO, /* For header-only out notification */
1122 core_handlers); /* Register these handlers */ 1316 core_handlers); /* Register these handlers */
1123 1317
1124 if (core_handle == NULL) { 1318 if (core_handle == NULL) {
1125 GNUNET_break(0); 1319 GNUNET_break(0);
1126 } 1320 }
1127 1321
1128 dht_handle = GNUNET_DHT_connect(c, 100); /* FIXME ht len correct size? */ 1322 dht_handle = GNUNET_DHT_connect(c, 100); /* FIXME ht len correct size? */
1129 if (dht_handle == NULL) { 1323 if (dht_handle == NULL) {
1130 GNUNET_break(0); 1324 GNUNET_break(0);
1131 } 1325 }
1132} 1326}
1133 1327
1134/** 1328/**