aboutsummaryrefslogtreecommitdiff
path: root/src
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
parent843f898e3d1391aba7003e6e7c9ec0d7b3530fac (diff)
downloadgnunet-daa1608a8c4cfe8b8510656cd233c4642db20d04.tar.gz
gnunet-daa1608a8c4cfe8b8510656cd233c4642db20d04.zip
- simplify on-demand linking in overlay connects
Diffstat (limited to 'src')
-rw-r--r--src/testbed/gnunet-service-testbed.h55
-rw-r--r--src/testbed/gnunet-service-testbed_links.c48
-rw-r--r--src/testbed/gnunet-service-testbed_links.h3
-rw-r--r--src/testbed/gnunet-service-testbed_oc.c231
-rw-r--r--src/testbed/test_testbed_api_controllerlink.c2
5 files changed, 145 insertions, 194 deletions
diff --git a/src/testbed/gnunet-service-testbed.h b/src/testbed/gnunet-service-testbed.h
index b17c3d781..149a1ad77 100644
--- a/src/testbed/gnunet-service-testbed.h
+++ b/src/testbed/gnunet-service-testbed.h
@@ -318,6 +318,11 @@ struct ForwardedOverlayConnectContext
318 struct GNUNET_MessageHeader *orig_msg; 318 struct GNUNET_MessageHeader *orig_msg;
319 319
320 /** 320 /**
321 * The client handle
322 */
323 struct GNUNET_SERVER_Client *client;
324
325 /**
321 * The id of the operation which created this context information 326 * The id of the operation which created this context information
322 */ 327 */
323 uint64_t operation_id; 328 uint64_t operation_id;
@@ -363,11 +368,6 @@ enum ClosureType
363struct RegisteredHostContext 368struct RegisteredHostContext
364{ 369{
365 /** 370 /**
366 * The type of this data structure. Set this to CLOSURE_TYPE_RHC
367 */
368 enum ClosureType type;
369
370 /**
371 * The host which is being registered 371 * The host which is being registered
372 */ 372 */
373 struct GNUNET_TESTBED_Host *reg_host; 373 struct GNUNET_TESTBED_Host *reg_host;
@@ -378,26 +378,6 @@ struct RegisteredHostContext
378 struct GNUNET_TESTBED_Host *host; 378 struct GNUNET_TESTBED_Host *host;
379 379
380 /** 380 /**
381 * The gateway to which this operation is forwarded to
382 */
383 struct Slave *gateway;
384
385 /**
386 * The gateway through which peer2's controller can be reached
387 */
388 struct Slave *gateway2;
389
390 /**
391 * Handle for sub-operations
392 */
393 struct GNUNET_TESTBED_Operation *sub_op;
394
395 /**
396 * The client which initiated the link controller operation
397 */
398 struct GNUNET_SERVER_Client *client;
399
400 /**
401 * Head of the ForwardedOverlayConnectContext DLL 381 * Head of the ForwardedOverlayConnectContext DLL
402 */ 382 */
403 struct ForwardedOverlayConnectContext *focc_dll_head; 383 struct ForwardedOverlayConnectContext *focc_dll_head;
@@ -419,20 +399,9 @@ struct RegisteredHostContext
419 RHC_INIT = 0, 399 RHC_INIT = 0,
420 400
421 /** 401 /**
422 * State where we attempt to get peer2's controller configuration
423 */
424 RHC_GET_CFG,
425
426 /**
427 * State where we attempt to link the controller of peer 1 to the controller
428 * of peer2
429 */
430 RHC_LINK,
431
432 /**
433 * State where we attempt to do the overlay connection again 402 * State where we attempt to do the overlay connection again
434 */ 403 */
435 RHC_OL_CONNECT 404 RHC_DONE
436 } state; 405 } state;
437 406
438}; 407};
@@ -512,6 +481,18 @@ extern unsigned int GST_host_list_size;
512 */ 481 */
513extern char *GST_stats_dir; 482extern char *GST_stats_dir;
514 483
484/**
485 * Condition to check if host id is invalid
486 */
487#define INVALID_HOST_ID(id) \
488 ( ((id) >= GST_host_list_size) || (NULL == GST_host_list[id]) )
489
490/**
491 * Condition to check if peer id is invalid
492 */
493#define INVALID_PEER_ID(id) \
494 ( ((id) >= GST_peer_list_size) || (NULL == GST_peer_list[id]) )
495
515 496
516/** 497/**
517 * Similar to GNUNET_array_grow(); however instead of calling GNUNET_array_grow() 498 * Similar to GNUNET_array_grow(); however instead of calling GNUNET_array_grow()
diff --git a/src/testbed/gnunet-service-testbed_links.c b/src/testbed/gnunet-service-testbed_links.c
index 6209bf248..1da071660 100644
--- a/src/testbed/gnunet-service-testbed_links.c
+++ b/src/testbed/gnunet-service-testbed_links.c
@@ -326,10 +326,6 @@ reghost_free_iterator (void *cls, const struct GNUNET_HashCode *key,
326 GNUNET_CONTAINER_DLL_remove (rhc->focc_dll_head, rhc->focc_dll_tail, focc); 326 GNUNET_CONTAINER_DLL_remove (rhc->focc_dll_head, rhc->focc_dll_tail, focc);
327 GST_cleanup_focc (focc); 327 GST_cleanup_focc (focc);
328 } 328 }
329 if (NULL != rhc->sub_op)
330 GNUNET_TESTBED_operation_done (rhc->sub_op);
331 if (NULL != rhc->client)
332 GNUNET_SERVER_client_drop (rhc->client);
333 GNUNET_free (value); 329 GNUNET_free (value);
334 return GNUNET_YES; 330 return GNUNET_YES;
335} 331}
@@ -618,39 +614,11 @@ static void
618slave_event_callback (void *cls, 614slave_event_callback (void *cls,
619 const struct GNUNET_TESTBED_EventInformation *event) 615 const struct GNUNET_TESTBED_EventInformation *event)
620{ 616{
621 struct RegisteredHostContext *rhc;
622 struct LCFContext *lcf; 617 struct LCFContext *lcf;
623 struct GNUNET_TESTBED_Operation *old_op;
624 618
625 /* We currently only get here when working on RegisteredHostContexts and 619 /* We currently only get here when working on RegisteredHostContexts and
626 LCFContexts */ 620 LCFContexts */
627 GNUNET_assert (GNUNET_TESTBED_ET_OPERATION_FINISHED == event->type); 621 GNUNET_assert (GNUNET_TESTBED_ET_OPERATION_FINISHED == event->type);
628 rhc = event->op_cls;
629 if (CLOSURE_TYPE_RHC == rhc->type)
630 {
631 GNUNET_assert (rhc->sub_op == event->op);
632 switch (rhc->state)
633 {
634 case RHC_GET_CFG:
635 old_op = rhc->sub_op;
636 rhc->state = RHC_LINK;
637 rhc->sub_op =
638 GNUNET_TESTBED_controller_link (rhc, rhc->gateway->controller,
639 rhc->reg_host, rhc->host, GNUNET_NO);
640 GNUNET_TESTBED_operation_done (old_op);
641 break;
642 case RHC_LINK:
643 LOG_DEBUG ("OL: Linking controllers successfull\n");
644 GNUNET_TESTBED_operation_done (rhc->sub_op);
645 rhc->sub_op = NULL;
646 rhc->state = RHC_OL_CONNECT;
647 GST_process_next_focc (rhc);
648 break;
649 default:
650 GNUNET_assert (0);
651 }
652 return;
653 }
654 lcf = event->op_cls; 622 lcf = event->op_cls;
655 if (CLOSURE_TYPE_LCF == lcf->type) 623 if (CLOSURE_TYPE_LCF == lcf->type)
656 { 624 {
@@ -955,6 +923,18 @@ neighbour_connect_cb (void *cls, struct GNUNET_TESTBED_Controller *c)
955 cleanup_ncc (ncc); 923 cleanup_ncc (ncc);
956} 924}
957 925
926struct Neighbour *
927GST_create_neighbour (struct GNUNET_TESTBED_Host *host)
928{
929 struct Neighbour *n;
930
931 n = GNUNET_malloc (sizeof (struct Neighbour));
932 n->host_id = GNUNET_TESTBED_host_get_id_ (host);
933 neighbour_list_add (n); /* just add; connect on-demand */
934 return n;
935}
936
937
958/** 938/**
959 * Message handler for GNUNET_MESSAGE_TYPE_TESTBED_LCONTROLLERS message 939 * Message handler for GNUNET_MESSAGE_TYPE_TESTBED_LCONTROLLERS message
960 * 940 *
@@ -1033,9 +1013,7 @@ GST_handle_link_controllers (void *cls, struct GNUNET_SERVER_Client *client,
1033 } 1013 }
1034 LOG_DEBUG ("Received request to establish a link to host %u\n", 1014 LOG_DEBUG ("Received request to establish a link to host %u\n",
1035 delegated_host_id); 1015 delegated_host_id);
1036 n = GNUNET_malloc (sizeof (struct Neighbour)); 1016 n = GST_create_neighbour (GST_host_list[delegated_host_id]);
1037 n->host_id = delegated_host_id;
1038 neighbour_list_add (n); /* just add; connect on-demand */
1039 ncc = GNUNET_malloc (sizeof (struct NeighbourConnectCtxt)); 1017 ncc = GNUNET_malloc (sizeof (struct NeighbourConnectCtxt));
1040 ncc->n = n; 1018 ncc->n = n;
1041 ncc->op_id = op_id; 1019 ncc->op_id = op_id;
diff --git a/src/testbed/gnunet-service-testbed_links.h b/src/testbed/gnunet-service-testbed_links.h
index b6a38c09e..65741c21c 100644
--- a/src/testbed/gnunet-service-testbed_links.h
+++ b/src/testbed/gnunet-service-testbed_links.h
@@ -119,6 +119,9 @@ GST_neighbour_get_connection_cancel (struct NeighbourConnectNotification *h);
119void 119void
120GST_neighbour_release_connection (struct Neighbour *n); 120GST_neighbour_release_connection (struct Neighbour *n);
121 121
122struct Neighbour *
123GST_create_neighbour (struct GNUNET_TESTBED_Host *host);
124
122/** 125/**
123 * Message handler for GNUNET_MESSAGE_TYPE_TESTBED_LCONTROLLERS message 126 * Message handler for GNUNET_MESSAGE_TYPE_TESTBED_LCONTROLLERS message
124 * 127 *
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;
diff --git a/src/testbed/test_testbed_api_controllerlink.c b/src/testbed/test_testbed_api_controllerlink.c
index c5fae9257..c60b8227e 100644
--- a/src/testbed/test_testbed_api_controllerlink.c
+++ b/src/testbed/test_testbed_api_controllerlink.c
@@ -541,6 +541,8 @@ controller_cb (void *cls, const struct GNUNET_TESTBED_EventInformation *event)
541 FAIL_TEST (event->details.peer_start.peer == slave3_peer); 541 FAIL_TEST (event->details.peer_start.peer == slave3_peer);
542 GNUNET_TESTBED_operation_done (op); 542 GNUNET_TESTBED_operation_done (op);
543 result = SLAVE3_PEER_START_SUCCESS; 543 result = SLAVE3_PEER_START_SUCCESS;
544 sleep (1);
545 LOG_DEBUG ("**************************************\n");
544 op = GNUNET_TESTBED_overlay_connect (mc, NULL, NULL, slave2_peer, 546 op = GNUNET_TESTBED_overlay_connect (mc, NULL, NULL, slave2_peer,
545 slave3_peer); 547 slave3_peer);
546 FAIL_TEST (NULL != op); 548 FAIL_TEST (NULL != op);