diff options
author | Sree Harsha Totakura <totakura@in.tum.de> | 2013-05-05 18:48:18 +0000 |
---|---|---|
committer | Sree Harsha Totakura <totakura@in.tum.de> | 2013-05-05 18:48:18 +0000 |
commit | daa1608a8c4cfe8b8510656cd233c4642db20d04 (patch) | |
tree | 728d107f96ace50d17561c450822c1a2d129cb63 /src/testbed/gnunet-service-testbed_oc.c | |
parent | 843f898e3d1391aba7003e6e7c9ec0d7b3530fac (diff) | |
download | gnunet-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.c | 231 |
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; | |||
364 | void | 364 | void |
365 | GST_cleanup_focc (struct ForwardedOverlayConnectContext *focc) | 365 | GST_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 | */ |
1137 | static void | 1144 | static void |
1138 | registeredhost_registration_completion (void *cls, const char *emsg) | 1145 | host_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 | ||
1202 | static struct RegisteredHostContext * | ||
1203 | register_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; |