aboutsummaryrefslogtreecommitdiff
path: root/src/testbed/gnunet-service-testbed_oc.c
diff options
context:
space:
mode:
authorSree Harsha Totakura <totakura@in.tum.de>2013-05-05 18:48:18 +0000
committerSree Harsha Totakura <totakura@in.tum.de>2013-05-05 18:48:18 +0000
commitdaa1608a8c4cfe8b8510656cd233c4642db20d04 (patch)
tree728d107f96ace50d17561c450822c1a2d129cb63 /src/testbed/gnunet-service-testbed_oc.c
parent843f898e3d1391aba7003e6e7c9ec0d7b3530fac (diff)
downloadgnunet-daa1608a8c4cfe8b8510656cd233c4642db20d04.tar.gz
gnunet-daa1608a8c4cfe8b8510656cd233c4642db20d04.zip
- simplify on-demand linking in overlay connects
Diffstat (limited to 'src/testbed/gnunet-service-testbed_oc.c')
-rw-r--r--src/testbed/gnunet-service-testbed_oc.c231
1 files changed, 109 insertions, 122 deletions
diff --git a/src/testbed/gnunet-service-testbed_oc.c b/src/testbed/gnunet-service-testbed_oc.c
index c53bec007..744ae3d34 100644
--- a/src/testbed/gnunet-service-testbed_oc.c
+++ b/src/testbed/gnunet-service-testbed_oc.c
@@ -364,6 +364,7 @@ static struct RemoteOverlayConnectCtx *roccq_tail;
364void 364void
365GST_cleanup_focc (struct ForwardedOverlayConnectContext *focc) 365GST_cleanup_focc (struct ForwardedOverlayConnectContext *focc)
366{ 366{
367 GNUNET_SERVER_client_drop (focc->client);
367 GNUNET_free_non_null (focc->orig_msg); 368 GNUNET_free_non_null (focc->orig_msg);
368 GNUNET_free (focc); 369 GNUNET_free (focc);
369} 370}
@@ -387,10 +388,10 @@ forwarded_overlay_connect_timeout (void *cls,
387 rhc = fopc->cls; 388 rhc = fopc->cls;
388 focc = rhc->focc_dll_head; 389 focc = rhc->focc_dll_head;
389 GNUNET_CONTAINER_DLL_remove (rhc->focc_dll_head, rhc->focc_dll_tail, focc); 390 GNUNET_CONTAINER_DLL_remove (rhc->focc_dll_head, rhc->focc_dll_tail, focc);
390 GST_cleanup_focc (focc);
391 LOG_DEBUG ("Overlay linking between peers %u and %u failed\n", focc->peer1, 391 LOG_DEBUG ("Overlay linking between peers %u and %u failed\n", focc->peer1,
392 focc->peer2); 392 focc->peer2);
393 GST_forwarded_operation_timeout (cls, tc); 393 GST_cleanup_focc (focc);
394 GST_forwarded_operation_timeout (fopc, tc);
394 if (NULL != rhc->focc_dll_head) 395 if (NULL != rhc->focc_dll_head)
395 GST_process_next_focc (rhc); 396 GST_process_next_focc (rhc);
396} 397}
@@ -432,18 +433,24 @@ GST_process_next_focc (struct RegisteredHostContext *rhc)
432{ 433{
433 struct ForwardedOperationContext *fopc; 434 struct ForwardedOperationContext *fopc;
434 struct ForwardedOverlayConnectContext *focc; 435 struct ForwardedOverlayConnectContext *focc;
436 struct Peer *peer;
437 struct Slave *slave;
435 438
436 focc = rhc->focc_dll_head; 439 focc = rhc->focc_dll_head;
437 GNUNET_assert (NULL != focc); 440 GNUNET_assert (NULL != focc);
438 GNUNET_assert (RHC_OL_CONNECT == rhc->state); 441 GNUNET_assert (RHC_DONE == rhc->state);
442 GNUNET_assert (!INVALID_PEER_ID (focc->peer1));
443 peer = GST_peer_list[focc->peer1];
444 GNUNET_assert (GNUNET_YES == peer->is_remote);
445 GNUNET_assert (NULL != (slave = peer->details.remote.slave));
439 fopc = GNUNET_malloc (sizeof (struct ForwardedOperationContext)); 446 fopc = GNUNET_malloc (sizeof (struct ForwardedOperationContext));
440 GNUNET_SERVER_client_keep (rhc->client); 447 GNUNET_SERVER_client_keep (focc->client);
441 fopc->client = rhc->client; 448 fopc->client = focc->client;
442 fopc->operation_id = focc->operation_id; 449 fopc->operation_id = focc->operation_id;
443 fopc->cls = rhc; 450 fopc->cls = rhc;
444 fopc->type = OP_OVERLAY_CONNECT; 451 fopc->type = OP_OVERLAY_CONNECT;
445 fopc->opc = 452 fopc->opc =
446 GNUNET_TESTBED_forward_operation_msg_ (rhc->gateway->controller, 453 GNUNET_TESTBED_forward_operation_msg_ (slave->controller,
447 focc->operation_id, focc->orig_msg, 454 focc->operation_id, focc->orig_msg,
448 &forwarded_overlay_connect_listener, 455 &forwarded_overlay_connect_listener,
449 fopc); 456 fopc);
@@ -1135,28 +1142,12 @@ overlay_connect_get_config (void *cls, const struct GNUNET_MessageHeader *msg)
1135 * @param emsg the error message; NULL if host registration is successful 1142 * @param emsg the error message; NULL if host registration is successful
1136 */ 1143 */
1137static void 1144static void
1138registeredhost_registration_completion (void *cls, const char *emsg) 1145host_registration_comp (void *cls, const char *emsg)
1139{ 1146{
1140 struct RegisteredHostContext *rhc = cls; 1147 struct RegisteredHostContext *rhc = cls;
1141 uint32_t peer2_host_id; 1148
1142 1149 rhc->state = RHC_DONE;
1143 peer2_host_id = GNUNET_TESTBED_host_get_id_ (rhc->reg_host); 1150 GST_process_next_focc (rhc);
1144 GNUNET_assert (RHC_INIT == rhc->state);
1145 GNUNET_assert (NULL == rhc->sub_op);
1146 if ((NULL == rhc->gateway2) ||
1147 ( (peer2_host_id < GST_host_list_size) /* Check if we have the needed config */
1148 && (NULL != GST_host_list[peer2_host_id]) ) )
1149 {
1150 rhc->state = RHC_LINK;
1151 rhc->sub_op =
1152 GNUNET_TESTBED_controller_link (rhc, rhc->gateway->controller,
1153 rhc->reg_host, rhc->host, GNUNET_NO);
1154 return;
1155 }
1156 rhc->state = RHC_GET_CFG;
1157 rhc->sub_op =
1158 GNUNET_TESTBED_get_slave_config (rhc, rhc->gateway2->controller,
1159 rhc->reg_host);
1160} 1151}
1161 1152
1162 1153
@@ -1208,6 +1199,47 @@ hash_hosts (struct GNUNET_TESTBED_Host *reg_host,
1208} 1199}
1209 1200
1210 1201
1202static struct RegisteredHostContext *
1203register_p2_host (struct Slave *slave, uint32_t peer2_host_id)
1204{
1205 struct GNUNET_HashCode hash;
1206 struct RegisteredHostContext *rhc;
1207
1208 rhc = GNUNET_malloc (sizeof (struct RegisteredHostContext));
1209 rhc->reg_host = GST_host_list[peer2_host_id];
1210 rhc->host = GST_host_list[slave->host_id];
1211 GNUNET_assert (NULL != rhc->reg_host);
1212 GNUNET_assert (NULL != rhc->host);
1213 rhc->state = RHC_INIT;
1214 hash = hash_hosts (rhc->reg_host, rhc->host);
1215 if ((GNUNET_NO ==
1216 GNUNET_CONTAINER_multihashmap_contains (slave->reghost_map, &hash)) ||
1217 (GNUNET_SYSERR !=
1218 GNUNET_CONTAINER_multihashmap_get_multiple (slave->reghost_map,
1219 &hash,
1220 reghost_match_iterator,
1221 &rhc)))
1222 {
1223 /* create and add a new registerd host context */
1224 /* add the focc to its queue */
1225 GNUNET_CONTAINER_multihashmap_put (slave->reghost_map, &hash, rhc,
1226 GNUNET_CONTAINER_MULTIHASHMAPOPTION_MULTIPLE);
1227 GST_queue_host_registration (slave, host_registration_comp,
1228 rhc, rhc->reg_host);
1229 }
1230 else
1231 {
1232 /* rhc is now set to the existing one from the hash map by
1233 * reghost_match_iterator() */
1234 /* if queue is empty then ignore creating focc and proceed with normal
1235 * forwarding */
1236 if (RHC_DONE == rhc->state)
1237 return NULL;
1238 }
1239 return rhc;
1240}
1241
1242
1211/** 1243/**
1212 * Forwards the overlay connect request to a slave controller. Before 1244 * Forwards the overlay connect request to a slave controller. Before
1213 * forwarding, any hosts which are needed to be known by the slave controller to 1245 * forwarding, any hosts which are needed to be known by the slave controller to
@@ -1225,6 +1257,8 @@ forward_overlay_connect (const struct GNUNET_TESTBED_OverlayConnectMessage *msg,
1225 struct Route *route_to_peer2_host; 1257 struct Route *route_to_peer2_host;
1226 struct Route *route_to_peer1_host; 1258 struct Route *route_to_peer1_host;
1227 struct Peer *peer; 1259 struct Peer *peer;
1260 struct RegisteredHostContext *rhc;
1261 struct ForwardedOverlayConnectContext *focc;
1228 uint64_t op_id; 1262 uint64_t op_id;
1229 uint32_t peer2_host_id; 1263 uint32_t peer2_host_id;
1230 uint32_t p1; 1264 uint32_t p1;
@@ -1234,96 +1268,39 @@ forward_overlay_connect (const struct GNUNET_TESTBED_OverlayConnectMessage *msg,
1234 p2 = ntohl (msg->peer2); 1268 p2 = ntohl (msg->peer2);
1235 op_id = GNUNET_ntohll (msg->operation_id); 1269 op_id = GNUNET_ntohll (msg->operation_id);
1236 peer2_host_id = ntohl (msg->peer2_host_id); 1270 peer2_host_id = ntohl (msg->peer2_host_id);
1237 GNUNET_assert (p1 < GST_peer_list_size); 1271 GNUNET_assert (! INVALID_PEER_ID (p1));
1238 GNUNET_assert (NULL != (peer = GST_peer_list[p1])); 1272 GNUNET_assert (! INVALID_HOST_ID (peer2_host_id));
1273 peer = GST_peer_list[p1];
1239 GNUNET_assert (GNUNET_YES == peer->is_remote); 1274 GNUNET_assert (GNUNET_YES == peer->is_remote);
1240 LOG_DEBUG ("0x%llx: Forwarding overlay connect\n", op_id); 1275 LOG_DEBUG ("0x%llx: Forwarding overlay connect\n", op_id);
1241 route_to_peer2_host = NULL;
1242 route_to_peer1_host = NULL;
1243 route_to_peer2_host = GST_find_dest_route (peer2_host_id); 1276 route_to_peer2_host = GST_find_dest_route (peer2_host_id);
1244 if ((NULL != route_to_peer2_host) || 1277 route_to_peer1_host = GST_find_dest_route
1245 (peer2_host_id == GST_context->host_id)) 1278 (peer->details.remote.remote_host_id);
1279 GNUNET_assert (NULL != route_to_peer1_host);
1280 if ((NULL != route_to_peer2_host) &&
1281 (route_to_peer1_host->dest == route_to_peer2_host->dest))
1282 goto forward;
1283 /* Peer2 is either with us OR peer1 and peer2 can be reached through
1284 different subtrees OR peer2 is on a subtree unknown to us */
1285 if (NULL != (rhc = register_p2_host (peer->details.remote.slave,
1286 peer2_host_id)))
1246 { 1287 {
1247 /* Peer 2 either below us OR with us */ 1288 LOG_DEBUG ("Forwarding with FOCC for connecting peers %u and %u\n", p1, p2);
1248 route_to_peer1_host = 1289 focc = GNUNET_malloc (sizeof (struct ForwardedOverlayConnectContext));
1249 GST_find_dest_route (GST_peer_list[p1]->details. 1290 focc->peer1 = p1;
1250 remote.remote_host_id); 1291 focc->peer2 = p2;
1251 /* Because we get this message only if we know where peer 1 is */ 1292 focc->peer2_host_id = peer2_host_id;
1252 GNUNET_assert (NULL != route_to_peer1_host); 1293 focc->orig_msg = GNUNET_copy_message (&msg->header);
1253 if ((peer2_host_id == GST_context->host_id) || 1294 focc->operation_id = op_id;
1254 (route_to_peer2_host->dest != route_to_peer1_host->dest)) 1295 focc->client = client;
1255 { 1296 GNUNET_SERVER_client_keep (client);
1256 /* Peer2 is either with us OR peer1 and peer2 can be reached through 1297 GNUNET_CONTAINER_DLL_insert_tail (rhc->focc_dll_head, rhc->focc_dll_tail,
1257 * different gateways */ 1298 focc);
1258 struct GNUNET_HashCode hash; 1299 return;
1259 struct RegisteredHostContext *rhc;
1260 int skip_focc;
1261
1262 rhc = GNUNET_malloc (sizeof (struct RegisteredHostContext));
1263 rhc->type = CLOSURE_TYPE_RHC;
1264 if (NULL != route_to_peer2_host)
1265 rhc->reg_host = GST_host_list[route_to_peer2_host->dest];
1266 else
1267 rhc->reg_host = GST_host_list[GST_context->host_id];
1268 rhc->host = GST_host_list[route_to_peer1_host->dest];
1269 GNUNET_assert (NULL != rhc->reg_host);
1270 GNUNET_assert (NULL != rhc->host);
1271 rhc->gateway = peer->details.remote.slave;
1272 rhc->gateway2 =
1273 (NULL ==
1274 route_to_peer2_host) ? NULL :
1275 GST_slave_list[route_to_peer2_host->dest];
1276 rhc->state = RHC_INIT;
1277 GNUNET_SERVER_client_keep (client);
1278 rhc->client = client;
1279 hash = hash_hosts (rhc->reg_host, rhc->host);
1280 skip_focc = GNUNET_NO;
1281 if ((GNUNET_NO ==
1282 GNUNET_CONTAINER_multihashmap_contains (peer->details.
1283 remote.slave->reghost_map,
1284 &hash)) ||
1285 (GNUNET_SYSERR !=
1286 GNUNET_CONTAINER_multihashmap_get_multiple (peer->details.remote.
1287 slave->reghost_map,
1288 &hash,
1289 reghost_match_iterator,
1290 &rhc)))
1291 {
1292 /* create and add a new registerd host context */
1293 /* add the focc to its queue */
1294 GNUNET_CONTAINER_multihashmap_put (peer->details.remote.
1295 slave->reghost_map, &hash, rhc,
1296 GNUNET_CONTAINER_MULTIHASHMAPOPTION_MULTIPLE);
1297 GNUNET_assert (NULL != GST_host_list[peer2_host_id]);
1298 GST_queue_host_registration (peer->details.remote.slave,
1299 registeredhost_registration_completion,
1300 rhc, GST_host_list[peer2_host_id]);
1301 }
1302 else
1303 {
1304 /* rhc is now set to the existing one from the hash map by
1305 * reghost_match_iterator() */
1306 /* if queue is empty then ignore creating focc and proceed with
1307 * normal forwarding */
1308 if (RHC_OL_CONNECT == rhc->state)
1309 skip_focc = GNUNET_YES;
1310 }
1311 if (GNUNET_NO == skip_focc)
1312 {
1313 struct ForwardedOverlayConnectContext *focc;
1314
1315 focc = GNUNET_malloc (sizeof (struct ForwardedOverlayConnectContext));
1316 focc->peer1 = p1;
1317 focc->peer2 = p2;
1318 focc->peer2_host_id = peer2_host_id;
1319 focc->orig_msg = GNUNET_copy_message (&msg->header);
1320 focc->operation_id = op_id;
1321 GNUNET_CONTAINER_DLL_insert_tail (rhc->focc_dll_head,
1322 rhc->focc_dll_tail, focc);
1323 return;
1324 }
1325 }
1326 } 1300 }
1301
1302 forward:
1303 LOG_DEBUG ("Forwarding without FOCC for connecting peers %u and %u\n", p1, p2);
1327 fopc = GNUNET_malloc (sizeof (struct ForwardedOperationContext)); 1304 fopc = GNUNET_malloc (sizeof (struct ForwardedOperationContext));
1328 GNUNET_SERVER_client_keep (client); 1305 GNUNET_SERVER_client_keep (client);
1329 fopc->client = client; 1306 fopc->client = client;
@@ -1409,7 +1386,7 @@ GST_handle_overlay_connect (void *cls, struct GNUNET_SERVER_Client *client,
1409 msg = (const struct GNUNET_TESTBED_OverlayConnectMessage *) message; 1386 msg = (const struct GNUNET_TESTBED_OverlayConnectMessage *) message;
1410 p1 = ntohl (msg->peer1); 1387 p1 = ntohl (msg->peer1);
1411 p2 = ntohl (msg->peer2); 1388 p2 = ntohl (msg->peer2);
1412 if ((p1 >= GST_peer_list_size) || (NULL == GST_peer_list[p1])) 1389 if INVALID_PEER_ID (p1)
1413 { 1390 {
1414 GNUNET_break (0); 1391 GNUNET_break (0);
1415 GNUNET_SERVER_receive_done (client, GNUNET_SYSERR); 1392 GNUNET_SERVER_receive_done (client, GNUNET_SYSERR);
@@ -1420,8 +1397,15 @@ GST_handle_overlay_connect (void *cls, struct GNUNET_SERVER_Client *client,
1420 LOG_DEBUG 1397 LOG_DEBUG
1421 ("Received overlay connect for peers %u and %u with op id: 0x%llx\n", p1, 1398 ("Received overlay connect for peers %u and %u with op id: 0x%llx\n", p1,
1422 p2, operation_id); 1399 p2, operation_id);
1400 peer2_host_id = ntohl (msg->peer2_host_id);
1423 if (GNUNET_YES == peer->is_remote) 1401 if (GNUNET_YES == peer->is_remote)
1424 { 1402 {
1403 if INVALID_HOST_ID (peer2_host_id)
1404 {
1405 GNUNET_break (0);
1406 GNUNET_SERVER_receive_done (client, GNUNET_SYSERR);
1407 return;
1408 }
1425 forward_overlay_connect (msg, client); 1409 forward_overlay_connect (msg, client);
1426 GNUNET_SERVER_receive_done (client, GNUNET_OK); 1410 GNUNET_SERVER_receive_done (client, GNUNET_OK);
1427 return; 1411 return;
@@ -1429,18 +1413,21 @@ GST_handle_overlay_connect (void *cls, struct GNUNET_SERVER_Client *client,
1429 p2n = NULL; 1413 p2n = NULL;
1430 occ = GNUNET_malloc (sizeof (struct OverlayConnectContext)); 1414 occ = GNUNET_malloc (sizeof (struct OverlayConnectContext));
1431 occ->type = OCC_TYPE_LOCAL; 1415 occ->type = OCC_TYPE_LOCAL;
1432 peer2_host_id = ntohl (msg->peer2_host_id); 1416 if INVALID_PEER_ID (p2) /* May be peer2 is on a another controller */
1433 if ((p2 >= GST_peer_list_size) || (NULL == GST_peer_list[p2])) 1417 {
1434 {
1435 if (NULL == (p2n = GST_get_neighbour (peer2_host_id))) 1418 if (NULL == (p2n = GST_get_neighbour (peer2_host_id)))
1436 { 1419 {
1437 GNUNET_break (0); 1420 if (INVALID_HOST_ID (peer2_host_id))
1438 LOG (GNUNET_ERROR_TYPE_WARNING, 1421 {
1439 "0x%llx: Peer %u's host not in our neighbours list\n", 1422 GNUNET_break (0);
1440 operation_id, p2); 1423 LOG (GNUNET_ERROR_TYPE_WARNING,
1441 GNUNET_SERVER_receive_done (client, GNUNET_SYSERR); 1424 "0x%llx: Peer %u's host not in our neighbours list\n",
1442 GNUNET_free (occ); 1425 operation_id, p2);
1443 return; 1426 GNUNET_SERVER_receive_done (client, GNUNET_SYSERR);
1427 GNUNET_free (occ);
1428 return;
1429 }
1430 p2n = GST_create_neighbour (GST_host_list[peer2_host_id]);
1444 } 1431 }
1445 occ->type = OCC_TYPE_REMOTE_LATERAL; 1432 occ->type = OCC_TYPE_REMOTE_LATERAL;
1446 occ->p2ctx.remote.p2n = p2n; 1433 occ->p2ctx.remote.p2n = p2n;