aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorSree Harsha Totakura <totakura@in.tum.de>2013-05-06 16:06:08 +0000
committerSree Harsha Totakura <totakura@in.tum.de>2013-05-06 16:06:08 +0000
commitad25eef39dc8c15b85bd70c6585af95d7e687fd5 (patch)
tree152df39da268b913fd5a93467556ca9249e20416 /src
parente2bb863887e78b5847fd86ef5a399a5d13d856d3 (diff)
downloadgnunet-ad25eef39dc8c15b85bd70c6585af95d7e687fd5.tar.gz
gnunet-ad25eef39dc8c15b85bd70c6585af95d7e687fd5.zip
- doc
Diffstat (limited to 'src')
-rw-r--r--src/testbed/gnunet-service-testbed.h29
-rw-r--r--src/testbed/gnunet-service-testbed_links.c300
-rw-r--r--src/testbed/gnunet-service-testbed_links.h65
-rw-r--r--src/testbed/gnunet-service-testbed_oc.c37
4 files changed, 339 insertions, 92 deletions
diff --git a/src/testbed/gnunet-service-testbed.h b/src/testbed/gnunet-service-testbed.h
index 149a1ad77..bdf0f4cce 100644
--- a/src/testbed/gnunet-service-testbed.h
+++ b/src/testbed/gnunet-service-testbed.h
@@ -345,23 +345,6 @@ struct ForwardedOverlayConnectContext
345 345
346 346
347/** 347/**
348 * The type for data structures which commonly arrive at the slave_event_callback
349 */
350enum ClosureType
351{
352 /**
353 * Type for RegisteredHostContext closures
354 */
355 CLOSURE_TYPE_RHC = 1,
356
357 /**
358 * Type for LinkControllersForwardingContext closures
359 */
360 CLOSURE_TYPE_LCF
361};
362
363
364/**
365 * This context information will be created for each host that is registered at 348 * This context information will be created for each host that is registered at
366 * slave controllers during overlay connects. 349 * slave controllers during overlay connects.
367 */ 350 */
@@ -482,16 +465,16 @@ extern unsigned int GST_host_list_size;
482extern char *GST_stats_dir; 465extern char *GST_stats_dir;
483 466
484/** 467/**
485 * Condition to check if host id is invalid 468 * Condition to check if host id is valid
486 */ 469 */
487#define INVALID_HOST_ID(id) \ 470#define VALID_HOST_ID(id) \
488 ( ((id) >= GST_host_list_size) || (NULL == GST_host_list[id]) ) 471 ( ((id) < GST_host_list_size) && (NULL != GST_host_list[id]) )
489 472
490/** 473/**
491 * Condition to check if peer id is invalid 474 * Condition to check if peer id is valid
492 */ 475 */
493#define INVALID_PEER_ID(id) \ 476#define VALID_PEER_ID(id) \
494 ( ((id) >= GST_peer_list_size) || (NULL == GST_peer_list[id]) ) 477 ( ((id) < GST_peer_list_size) && (NULL != GST_peer_list[id]) )
495 478
496 479
497/** 480/**
diff --git a/src/testbed/gnunet-service-testbed_links.c b/src/testbed/gnunet-service-testbed_links.c
index 1da071660..bcf8d91c8 100644
--- a/src/testbed/gnunet-service-testbed_links.c
+++ b/src/testbed/gnunet-service-testbed_links.c
@@ -75,11 +75,6 @@ enum LCFContextState
75struct LCFContext 75struct LCFContext
76{ 76{
77 /** 77 /**
78 * The type of this data structure. Set this to CLOSURE_TYPE_LCF
79 */
80 enum ClosureType type;
81
82 /**
83 * The gateway which will pass the link message to delegated host 78 * The gateway which will pass the link message to delegated host
84 */ 79 */
85 struct Slave *gateway; 80 struct Slave *gateway;
@@ -148,15 +143,40 @@ struct LCFContextQueue
148 struct LCFContextQueue *prev; 143 struct LCFContextQueue *prev;
149}; 144};
150 145
146
147/**
148 * Notification context to be used to notify when connection to the neighbour's
149 * controller is opened
150 */
151struct NeighbourConnectNotification 151struct NeighbourConnectNotification
152{ 152{
153 /**
154 * DLL next for inclusion in neighbour's list of notification requests
155 */
153 struct NeighbourConnectNotification *next; 156 struct NeighbourConnectNotification *next;
157
158 /**
159 * DLL prev
160 */
154 struct NeighbourConnectNotification *prev; 161 struct NeighbourConnectNotification *prev;
162
163 /**
164 * The neighbour
165 */
155 struct Neighbour *n; 166 struct Neighbour *n;
167
168 /**
169 * The notification callback to call when we are connect to neighbour
170 */
156 GST_NeigbourConnectNotifyCallback cb; 171 GST_NeigbourConnectNotifyCallback cb;
172
173 /**
174 * The closure for the above callback
175 */
157 void *cb_cls; 176 void *cb_cls;
158}; 177};
159 178
179
160/** 180/**
161 * A connected controller which is not our child 181 * A connected controller which is not our child
162 */ 182 */
@@ -173,39 +193,100 @@ struct Neighbour
173 */ 193 */
174 struct GNUNET_TESTBED_Operation *conn_op; 194 struct GNUNET_TESTBED_Operation *conn_op;
175 195
196 /**
197 * DLL head for the list of notification requests
198 */
176 struct NeighbourConnectNotification *nl_head; 199 struct NeighbourConnectNotification *nl_head;
177 200
201 /**
202 * DLL tail for the list of notification requests
203 */
178 struct NeighbourConnectNotification *nl_tail; 204 struct NeighbourConnectNotification *nl_tail;
179 205
206 /**
207 * Task id for the task to call notifications from the notification list
208 */
180 GNUNET_SCHEDULER_TaskIdentifier notify_task; 209 GNUNET_SCHEDULER_TaskIdentifier notify_task;
181 210
211 /**
212 * How many references are present currently to this neighbour's connection
213 */
182 unsigned int reference_cnt; 214 unsigned int reference_cnt;
183 215
216 /**
217 * Is the conn_op inactivated?
218 */
184 unsigned int inactive; 219 unsigned int inactive;
185
186 220
187 /** 221 /**
188 * The id of the host this controller is running on 222 * The id of the host this controller is running on
189 */ 223 */
190 uint32_t host_id; 224 uint32_t host_id;
191
192}; 225};
193 226
227
228/**
229 * The neighbour list
230 */
194static struct Neighbour **neighbour_list; 231static struct Neighbour **neighbour_list;
232
233/**
234 * The size of the neighbour list
235 */
195static unsigned int neighbour_list_size; 236static unsigned int neighbour_list_size;
196 237
238
239/**
240 * Context information for establishing a link to neighbour (Used is
241 * GST_handle_link_controllers()
242 */
197struct NeighbourConnectCtxt 243struct NeighbourConnectCtxt
198{ 244{
245 /**
246 * DLL next for inclusion in the corresponding context list
247 */
199 struct NeighbourConnectCtxt *next; 248 struct NeighbourConnectCtxt *next;
249
250 /**
251 * DLL tail
252 */
200 struct NeighbourConnectCtxt *prev; 253 struct NeighbourConnectCtxt *prev;
254
255 /**
256 * The neighbour to whom connection should be made
257 */
201 struct Neighbour *n; 258 struct Neighbour *n;
259
260 /**
261 * The client requesting the connection
262 */
202 struct GNUNET_SERVER_Client *client; 263 struct GNUNET_SERVER_Client *client;
264
265 /**
266 * Task to be run upon timeout
267 */
203 GNUNET_SCHEDULER_TaskIdentifier timeout_task; 268 GNUNET_SCHEDULER_TaskIdentifier timeout_task;
269
270 /**
271 * The notification handle associated with the neighbour's connection request
272 */
204 struct NeighbourConnectNotification *nh; 273 struct NeighbourConnectNotification *nh;
274
275 /**
276 * The id of the link-controllers operation responsible for creating this
277 * context
278 */
205 uint64_t op_id; 279 uint64_t op_id;
206}; 280};
207 281
282/**
283 * DLL head for the list of neighbour connect contexts
284 */
208struct NeighbourConnectCtxt *ncc_head; 285struct NeighbourConnectCtxt *ncc_head;
286
287/**
288 * DLL tail for the list of neighbour connect contexts
289 */
209struct NeighbourConnectCtxt *ncc_tail; 290struct NeighbourConnectCtxt *ncc_tail;
210 291
211/** 292/**
@@ -274,6 +355,13 @@ route_list_add (struct Route *route)
274 route_list[route->dest] = route; 355 route_list[route->dest] = route;
275} 356}
276 357
358
359/**
360 * Add a neighbour to the neighbour list. Grows the neighbour list
361 * automatically.
362 *
363 * @param n the neighbour to add
364 */
277static void 365static void
278neighbour_list_add (struct Neighbour *n) 366neighbour_list_add (struct Neighbour *n)
279{ 367{
@@ -611,8 +699,7 @@ lcf_proc_task (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc)
611 * @param event information about the event 699 * @param event information about the event
612 */ 700 */
613static void 701static void
614slave_event_callback (void *cls, 702slave_event_cb (void *cls, const struct GNUNET_TESTBED_EventInformation *event)
615 const struct GNUNET_TESTBED_EventInformation *event)
616{ 703{
617 struct LCFContext *lcf; 704 struct LCFContext *lcf;
618 705
@@ -620,31 +707,24 @@ slave_event_callback (void *cls,
620 LCFContexts */ 707 LCFContexts */
621 GNUNET_assert (GNUNET_TESTBED_ET_OPERATION_FINISHED == event->type); 708 GNUNET_assert (GNUNET_TESTBED_ET_OPERATION_FINISHED == event->type);
622 lcf = event->op_cls; 709 lcf = event->op_cls;
623 if (CLOSURE_TYPE_LCF == lcf->type) 710 GNUNET_assert (lcf->op == event->op);
624 { 711 GNUNET_assert (FINISHED == lcf->state);
625 GNUNET_assert (lcf->op == event->op); 712 GNUNET_assert (GNUNET_SCHEDULER_NO_TASK != lcf->timeout_task);
626 GNUNET_assert (FINISHED == lcf->state); 713 GNUNET_SCHEDULER_cancel (lcf->timeout_task);
627 GNUNET_assert (GNUNET_SCHEDULER_NO_TASK != lcf->timeout_task); 714 if (NULL == event->details.operation_finished.emsg)
628 GNUNET_SCHEDULER_cancel (lcf->timeout_task); 715 send_controller_link_response (lcf->client, lcf->operation_id,
629 if (NULL == event->details.operation_finished.emsg) 716 GNUNET_TESTBED_host_get_cfg_
630 send_controller_link_response (lcf->client, lcf->operation_id, 717 (GST_host_list[lcf->delegated_host_id]),
631 GNUNET_TESTBED_host_get_cfg_ 718 NULL);
632 (GST_host_list[lcf->delegated_host_id]), 719 else
633 NULL); 720 send_controller_link_response (lcf->client, lcf->operation_id,
634 else 721 NULL,
635 send_controller_link_response (lcf->client, lcf->operation_id, 722 event->details.operation_finished.emsg);
636 NULL, 723 GNUNET_assert (GNUNET_SCHEDULER_NO_TASK == lcf_proc_task_id);
637 event->details.operation_finished.emsg); 724 lcf_proc_task_id = GNUNET_SCHEDULER_add_now (&lcf_proc_task, lcf);
638 GNUNET_assert (GNUNET_SCHEDULER_NO_TASK == lcf_proc_task_id); 725 return;
639 lcf_proc_task_id = GNUNET_SCHEDULER_add_now (&lcf_proc_task, lcf);
640 return;
641 }
642 GNUNET_assert (0);
643} 726}
644 727
645static void
646slave_status_callback (void *cls, const struct GNUNET_CONFIGURATION_Handle *cfg,
647 int status);
648 728
649/** 729/**
650 * Callback to signal successfull startup of the controller process 730 * Callback to signal successfull startup of the controller process
@@ -656,8 +736,8 @@ slave_status_callback (void *cls, const struct GNUNET_CONFIGURATION_Handle *cfg,
656 * GNUNET_TESTBED_controller_stop() shouldn't be called in this case 736 * GNUNET_TESTBED_controller_stop() shouldn't be called in this case
657 */ 737 */
658static void 738static void
659slave_status_callback (void *cls, const struct GNUNET_CONFIGURATION_Handle *cfg, 739slave_status_cb (void *cls, const struct GNUNET_CONFIGURATION_Handle *cfg,
660 int status) 740 int status)
661{ 741{
662 struct Slave *slave = cls; 742 struct Slave *slave = cls;
663 struct LinkControllersContext *lcc; 743 struct LinkControllersContext *lcc;
@@ -675,7 +755,7 @@ slave_status_callback (void *cls, const struct GNUNET_CONFIGURATION_Handle *cfg,
675 } 755 }
676 slave->controller = 756 slave->controller =
677 GNUNET_TESTBED_controller_connect (GST_host_list[slave->host_id], 757 GNUNET_TESTBED_controller_connect (GST_host_list[slave->host_id],
678 EVENT_MASK, &slave_event_callback, 758 EVENT_MASK, &slave_event_cb,
679 slave); 759 slave);
680 if (NULL != slave->controller) 760 if (NULL != slave->controller)
681 { 761 {
@@ -706,10 +786,52 @@ clean_lcc:
706 slave->lcc = NULL; 786 slave->lcc = NULL;
707} 787}
708 788
789
790/**
791 * Trigger notification task if there are notification requests currently
792 * waiting in the given neighbour. Also activates the neighbour connect operation
793 * if it was previously inactivated so that the connection to the neighbour can
794 * be re-used
795 *
796 * @param n the neighbour
797 */
798static void
799trigger_notifications (struct Neighbour *n);
800
801
802/**
803 * Task to call the notification queued in the notifications list of the given
804 * neighbour
805 *
806 * @param cls the neighbour
807 * @param tc scheduler task context
808 */
709static void 809static void
710neighbour_connect_notify_task (void *cls, 810neighbour_connect_notify_task (void *cls,
711 const struct GNUNET_SCHEDULER_TaskContext *tc); 811 const struct GNUNET_SCHEDULER_TaskContext *tc)
812{
813 struct Neighbour *n = cls;
814 struct NeighbourConnectNotification *h;
815
816 GNUNET_assert (NULL != (h = n->nl_head));
817 GNUNET_assert (GNUNET_SCHEDULER_NO_TASK != n->notify_task);
818 n->notify_task = GNUNET_SCHEDULER_NO_TASK;
819 GNUNET_assert (NULL != n->controller);
820 GNUNET_CONTAINER_DLL_remove (n->nl_head, n->nl_tail, h);
821 trigger_notifications (n);
822 h->cb (h->cb_cls, n->controller);
823 GNUNET_free (h);
824}
825
712 826
827/**
828 * Trigger notification task if there are notification requests currently
829 * waiting in the given neighbour. Also activates the neighbour connect operation
830 * if it was previously inactivated so that the connection to the neighbour can
831 * be re-used
832 *
833 * @param n the neighbour
834 */
713static void 835static void
714trigger_notifications (struct Neighbour *n) 836trigger_notifications (struct Neighbour *n)
715{ 837{
@@ -731,23 +853,14 @@ trigger_notifications (struct Neighbour *n)
731 GNUNET_SCHEDULER_add_now (&neighbour_connect_notify_task, n); 853 GNUNET_SCHEDULER_add_now (&neighbour_connect_notify_task, n);
732} 854}
733 855
734static void
735neighbour_connect_notify_task (void *cls,
736 const struct GNUNET_SCHEDULER_TaskContext *tc)
737{
738 struct Neighbour *n = cls;
739 struct NeighbourConnectNotification *h;
740
741 GNUNET_assert (NULL != (h = n->nl_head));
742 GNUNET_assert (GNUNET_SCHEDULER_NO_TASK != n->notify_task);
743 n->notify_task = GNUNET_SCHEDULER_NO_TASK;
744 GNUNET_assert (NULL != n->controller);
745 GNUNET_CONTAINER_DLL_remove (n->nl_head, n->nl_tail, h);
746 trigger_notifications (n);
747 h->cb (h->cb_cls, n->controller);
748 GNUNET_free (h);
749}
750 856
857/**
858 * Callback to be called when the neighbour connect operation is started. The
859 * connection to the neigbour is opened here and any pending notifications are
860 * trigger.
861 *
862 * @param cls the neighbour
863 */
751static void 864static void
752opstart_neighbour_conn (void *cls) 865opstart_neighbour_conn (void *cls)
753{ 866{
@@ -758,11 +871,17 @@ opstart_neighbour_conn (void *cls)
758 LOG_DEBUG ("Opening connection to controller on host %u\n", n->host_id); 871 LOG_DEBUG ("Opening connection to controller on host %u\n", n->host_id);
759 n->controller = GNUNET_TESTBED_controller_connect (GST_host_list[n->host_id], 872 n->controller = GNUNET_TESTBED_controller_connect (GST_host_list[n->host_id],
760 EVENT_MASK, 873 EVENT_MASK,
761 &slave_event_callback, 874 &slave_event_cb,
762 NULL); 875 NULL);
763 trigger_notifications (n); 876 trigger_notifications (n);
764} 877}
765 878
879
880/**
881 * Callback to be called when the neighbour connect operation is released
882 *
883 * @param cls the neighbour
884 */
766static void 885static void
767oprelease_neighbour_conn (void *cls) 886oprelease_neighbour_conn (void *cls)
768{ 887{
@@ -781,6 +900,18 @@ oprelease_neighbour_conn (void *cls)
781 n->inactive = 0; 900 n->inactive = 0;
782} 901}
783 902
903
904/**
905 * Try to open a connection to the given neigbour. If the connection is open
906 * already, then it is re-used. If not, the request is queued in the operation
907 * queues responsible for bounding the total number of file descriptors. The
908 * actual connection will happen when the operation queue marks the
909 * corresponding operation as active.
910 *
911 * @param n the neighbour to open a connection to
912 * @param cb the notification callback to call when the connection is opened
913 * @param cb_cls the closure for the above callback
914 */
784struct NeighbourConnectNotification * 915struct NeighbourConnectNotification *
785GST_neighbour_get_connection (struct Neighbour *n, 916GST_neighbour_get_connection (struct Neighbour *n,
786 GST_NeigbourConnectNotifyCallback cb, 917 GST_NeigbourConnectNotifyCallback cb,
@@ -809,6 +940,12 @@ GST_neighbour_get_connection (struct Neighbour *n,
809 return h; 940 return h;
810} 941}
811 942
943
944/**
945 * Cancel the request for opening a connection to the neighbour
946 *
947 * @param h the notification handle
948 */
812void 949void
813GST_neighbour_get_connection_cancel (struct NeighbourConnectNotification *h) 950GST_neighbour_get_connection_cancel (struct NeighbourConnectNotification *h)
814{ 951{
@@ -839,6 +976,14 @@ GST_neighbour_get_connection_cancel (struct NeighbourConnectNotification *h)
839 trigger_notifications (n); 976 trigger_notifications (n);
840} 977}
841 978
979
980/**
981 * Release the connection to the neighbour. The actual connection will be
982 * closed if connections to other neighbour are waiting (to maintain a bound on
983 * the total number of connections that are open).
984 *
985 * @param n the neighbour whose connection can be closed
986 */
842void 987void
843GST_neighbour_release_connection (struct Neighbour *n) 988GST_neighbour_release_connection (struct Neighbour *n)
844{ 989{
@@ -852,6 +997,12 @@ GST_neighbour_release_connection (struct Neighbour *n)
852 } 997 }
853} 998}
854 999
1000
1001/**
1002 * Cleanup neighbour connect contexts
1003 *
1004 * @param ncc the neighbour connect context to cleanup
1005 */
855static void 1006static void
856cleanup_ncc (struct NeighbourConnectCtxt *ncc) 1007cleanup_ncc (struct NeighbourConnectCtxt *ncc)
857{ 1008{
@@ -864,6 +1015,10 @@ cleanup_ncc (struct NeighbourConnectCtxt *ncc)
864 GNUNET_free (ncc); 1015 GNUNET_free (ncc);
865} 1016}
866 1017
1018
1019/**
1020 * Cleans up the neighbour list
1021 */
867void 1022void
868GST_neighbour_list_clean() 1023GST_neighbour_list_clean()
869{ 1024{
@@ -882,6 +1037,14 @@ GST_neighbour_list_clean()
882 GNUNET_free_non_null (neighbour_list); 1037 GNUNET_free_non_null (neighbour_list);
883} 1038}
884 1039
1040
1041/**
1042 * Get a neighbour from the neighbour list
1043 *
1044 * @param id the index of the neighbour in the neighbour list
1045 * @return the Neighbour; NULL if the given index in invalid (index greater than
1046 * the list size or neighbour at that index is NULL)
1047 */
885struct Neighbour * 1048struct Neighbour *
886GST_get_neighbour (uint32_t id) 1049GST_get_neighbour (uint32_t id)
887{ 1050{
@@ -891,6 +1054,10 @@ GST_get_neighbour (uint32_t id)
891 return neighbour_list[id]; 1054 return neighbour_list[id];
892} 1055}
893 1056
1057
1058/**
1059 * Function to cleanup the neighbour connect contexts
1060 */
894void 1061void
895GST_free_nccq () 1062GST_free_nccq ()
896{ 1063{
@@ -898,6 +1065,13 @@ GST_free_nccq ()
898 cleanup_ncc (ncc_head); 1065 cleanup_ncc (ncc_head);
899} 1066}
900 1067
1068
1069/**
1070 * Task to be run upon timeout while attempting to connect to the neighbour
1071 *
1072 * @param cls the NeighbourConnectCtxt created in GST_handle_link_controllers()
1073 * @param tc the scheduler task context
1074 */
901static void 1075static void
902timeout_neighbour_connect (void *cls, 1076timeout_neighbour_connect (void *cls,
903 const struct GNUNET_SCHEDULER_TaskContext *tc) 1077 const struct GNUNET_SCHEDULER_TaskContext *tc)
@@ -910,6 +1084,13 @@ timeout_neighbour_connect (void *cls,
910 cleanup_ncc (ncc); 1084 cleanup_ncc (ncc);
911} 1085}
912 1086
1087
1088/**
1089 * Callback called when a connection to the neighbour is made
1090 *
1091 * @param cls the NeighbourConnectCtxt created in GST_handle_link_controllers()
1092 * @param c the handle the neighbour's controller
1093 */
913static void 1094static void
914neighbour_connect_cb (void *cls, struct GNUNET_TESTBED_Controller *c) 1095neighbour_connect_cb (void *cls, struct GNUNET_TESTBED_Controller *c)
915{ 1096{
@@ -923,6 +1104,12 @@ neighbour_connect_cb (void *cls, struct GNUNET_TESTBED_Controller *c)
923 cleanup_ncc (ncc); 1104 cleanup_ncc (ncc);
924} 1105}
925 1106
1107
1108/**
1109 * Function to create a neigbour and add it into the neighbour list
1110 *
1111 * @param host the host of the neighbour
1112 */
926struct Neighbour * 1113struct Neighbour *
927GST_create_neighbour (struct GNUNET_TESTBED_Host *host) 1114GST_create_neighbour (struct GNUNET_TESTBED_Host *host)
928{ 1115{
@@ -1048,7 +1235,7 @@ GST_handle_link_controllers (void *cls, struct GNUNET_SERVER_Client *client,
1048 slave->controller_proc = 1235 slave->controller_proc =
1049 GNUNET_TESTBED_controller_start (GST_context->master_ip, 1236 GNUNET_TESTBED_controller_start (GST_context->master_ip,
1050 GST_host_list[slave->host_id], 1237 GST_host_list[slave->host_id],
1051 &slave_status_callback, slave); 1238 &slave_status_cb, slave);
1052 new_route = GNUNET_malloc (sizeof (struct Route)); 1239 new_route = GNUNET_malloc (sizeof (struct Route));
1053 new_route->dest = delegated_host_id; 1240 new_route->dest = delegated_host_id;
1054 new_route->thru = GST_context->host_id; 1241 new_route->thru = GST_context->host_id;
@@ -1065,7 +1252,6 @@ GST_handle_link_controllers (void *cls, struct GNUNET_SERVER_Client *client,
1065 } 1252 }
1066 lcfq = GNUNET_malloc (sizeof (struct LCFContextQueue)); 1253 lcfq = GNUNET_malloc (sizeof (struct LCFContextQueue));
1067 lcfq->lcf = GNUNET_malloc (sizeof (struct LCFContext)); 1254 lcfq->lcf = GNUNET_malloc (sizeof (struct LCFContext));
1068 lcfq->lcf->type = CLOSURE_TYPE_LCF;
1069 lcfq->lcf->delegated_host_id = delegated_host_id; 1255 lcfq->lcf->delegated_host_id = delegated_host_id;
1070 lcfq->lcf->slave_host_id = slave_host_id; 1256 lcfq->lcf->slave_host_id = slave_host_id;
1071 route = GST_find_dest_route (slave_host_id); 1257 route = GST_find_dest_route (slave_host_id);
diff --git a/src/testbed/gnunet-service-testbed_links.h b/src/testbed/gnunet-service-testbed_links.h
index 65741c21c..9134ab545 100644
--- a/src/testbed/gnunet-service-testbed_links.h
+++ b/src/testbed/gnunet-service-testbed_links.h
@@ -25,6 +25,10 @@
25 * @author Sree Harsha Totakura 25 * @author Sree Harsha Totakura
26 */ 26 */
27 27
28
29/**
30 * A connected controller which is not our child
31 */
28struct Neighbour; 32struct Neighbour;
29 33
30 34
@@ -92,36 +96,97 @@ extern struct Slave **GST_slave_list;
92 */ 96 */
93extern unsigned int GST_slave_list_size; 97extern unsigned int GST_slave_list_size;
94 98
99
100/**
101 * Cleans up the neighbour list
102 */
95void 103void
96GST_neighbour_list_clean(); 104GST_neighbour_list_clean();
97 105
106
107/**
108 * Get a neighbour from the neighbour list
109 *
110 * @param id the index of the neighbour in the neighbour list
111 * @return the Neighbour; NULL if the given index in invalid (index greater than
112 * the list size or neighbour at that index is NULL)
113 */
98struct Neighbour * 114struct Neighbour *
99GST_get_neighbour (uint32_t id); 115GST_get_neighbour (uint32_t id);
100 116
117
118/**
119 * Function to cleanup the neighbour connect contexts
120 */
101void 121void
102GST_free_nccq (); 122GST_free_nccq ();
103 123
124
125/**
126 * Notification context to be used to notify when connection to the neighbour's
127 * controller is opened
128 */
104struct NeighbourConnectNotification; 129struct NeighbourConnectNotification;
105 130
131
132/**
133 * The notification callback to call when we are connect to neighbour
134 *
135 * @param cls the closure given to GST_neighbour_get_connection()
136 * @param controller the controller handle to the neighbour
137 */
106typedef void (*GST_NeigbourConnectNotifyCallback) (void *cls, 138typedef void (*GST_NeigbourConnectNotifyCallback) (void *cls,
107 struct 139 struct
108 GNUNET_TESTBED_Controller 140 GNUNET_TESTBED_Controller
109 *controller); 141 *controller);
110 142
143
144/**
145 * Try to open a connection to the given neigbour. If the connection is open
146 * already, then it is re-used. If not, the request is queued in the operation
147 * queues responsible for bounding the total number of file descriptors. The
148 * actual connection will happen when the operation queue marks the
149 * corresponding operation as active.
150 *
151 * @param n the neighbour to open a connection to
152 * @param cb the notification callback to call when the connection is opened
153 * @param cb_cls the closure for the above callback
154 */
111struct NeighbourConnectNotification * 155struct NeighbourConnectNotification *
112GST_neighbour_get_connection (struct Neighbour *n, 156GST_neighbour_get_connection (struct Neighbour *n,
113 GST_NeigbourConnectNotifyCallback cb, 157 GST_NeigbourConnectNotifyCallback cb,
114 void *cb_cls); 158 void *cb_cls);
115 159
160
161/**
162 * Cancel the request for opening a connection to the neighbour
163 *
164 * @param h the notification handle
165 */
116void 166void
117GST_neighbour_get_connection_cancel (struct NeighbourConnectNotification *h); 167GST_neighbour_get_connection_cancel (struct NeighbourConnectNotification *h);
118 168
169
170/**
171 * Release the connection to the neighbour. The actual connection will be
172 * closed if connections to other neighbour are waiting (to maintain a bound on
173 * the total number of connections that are open).
174 *
175 * @param n the neighbour whose connection can be closed
176 */
119void 177void
120GST_neighbour_release_connection (struct Neighbour *n); 178GST_neighbour_release_connection (struct Neighbour *n);
121 179
180
181/**
182 * Function to create a neigbour and add it into the neighbour list
183 *
184 * @param host the host of the neighbour
185 */
122struct Neighbour * 186struct Neighbour *
123GST_create_neighbour (struct GNUNET_TESTBED_Host *host); 187GST_create_neighbour (struct GNUNET_TESTBED_Host *host);
124 188
189
125/** 190/**
126 * Message handler for GNUNET_MESSAGE_TYPE_TESTBED_LCONTROLLERS message 191 * Message handler for GNUNET_MESSAGE_TYPE_TESTBED_LCONTROLLERS message
127 * 192 *
diff --git a/src/testbed/gnunet-service-testbed_oc.c b/src/testbed/gnunet-service-testbed_oc.c
index 744ae3d34..418defb25 100644
--- a/src/testbed/gnunet-service-testbed_oc.c
+++ b/src/testbed/gnunet-service-testbed_oc.c
@@ -439,7 +439,7 @@ GST_process_next_focc (struct RegisteredHostContext *rhc)
439 focc = rhc->focc_dll_head; 439 focc = rhc->focc_dll_head;
440 GNUNET_assert (NULL != focc); 440 GNUNET_assert (NULL != focc);
441 GNUNET_assert (RHC_DONE == rhc->state); 441 GNUNET_assert (RHC_DONE == rhc->state);
442 GNUNET_assert (!INVALID_PEER_ID (focc->peer1)); 442 GNUNET_assert (VALID_PEER_ID (focc->peer1));
443 peer = GST_peer_list[focc->peer1]; 443 peer = GST_peer_list[focc->peer1];
444 GNUNET_assert (GNUNET_YES == peer->is_remote); 444 GNUNET_assert (GNUNET_YES == peer->is_remote);
445 GNUNET_assert (NULL != (slave = peer->details.remote.slave)); 445 GNUNET_assert (NULL != (slave = peer->details.remote.slave));
@@ -1199,14 +1199,27 @@ hash_hosts (struct GNUNET_TESTBED_Host *reg_host,
1199} 1199}
1200 1200
1201 1201
1202/**
1203 * Checks if the given host is registered at the given slave.
1204 *
1205 * @param slave the slave where registration has to be checked. The check is
1206 * actually done through a locally maintained hashmap. No
1207 * communication with the slave is involved.
1208 * @param host the host to register
1209 * @return If the given host is not registered already or the registration is
1210 * pending, it returns the registration context. Any overlay connects
1211 * to be forwarded should be queued in the context so that they can be
1212 * executed when the registration is completed. If the given host is
1213 * already registered, NULL is returned.
1214 */
1202static struct RegisteredHostContext * 1215static struct RegisteredHostContext *
1203register_p2_host (struct Slave *slave, uint32_t peer2_host_id) 1216register_host (struct Slave *slave, struct GNUNET_TESTBED_Host *host)
1204{ 1217{
1205 struct GNUNET_HashCode hash; 1218 struct GNUNET_HashCode hash;
1206 struct RegisteredHostContext *rhc; 1219 struct RegisteredHostContext *rhc;
1207 1220
1208 rhc = GNUNET_malloc (sizeof (struct RegisteredHostContext)); 1221 rhc = GNUNET_malloc (sizeof (struct RegisteredHostContext));
1209 rhc->reg_host = GST_host_list[peer2_host_id]; 1222 rhc->reg_host = host;
1210 rhc->host = GST_host_list[slave->host_id]; 1223 rhc->host = GST_host_list[slave->host_id];
1211 GNUNET_assert (NULL != rhc->reg_host); 1224 GNUNET_assert (NULL != rhc->reg_host);
1212 GNUNET_assert (NULL != rhc->host); 1225 GNUNET_assert (NULL != rhc->host);
@@ -1268,8 +1281,8 @@ forward_overlay_connect (const struct GNUNET_TESTBED_OverlayConnectMessage *msg,
1268 p2 = ntohl (msg->peer2); 1281 p2 = ntohl (msg->peer2);
1269 op_id = GNUNET_ntohll (msg->operation_id); 1282 op_id = GNUNET_ntohll (msg->operation_id);
1270 peer2_host_id = ntohl (msg->peer2_host_id); 1283 peer2_host_id = ntohl (msg->peer2_host_id);
1271 GNUNET_assert (! INVALID_PEER_ID (p1)); 1284 GNUNET_assert (VALID_PEER_ID (p1));
1272 GNUNET_assert (! INVALID_HOST_ID (peer2_host_id)); 1285 GNUNET_assert (VALID_HOST_ID (peer2_host_id));
1273 peer = GST_peer_list[p1]; 1286 peer = GST_peer_list[p1];
1274 GNUNET_assert (GNUNET_YES == peer->is_remote); 1287 GNUNET_assert (GNUNET_YES == peer->is_remote);
1275 LOG_DEBUG ("0x%llx: Forwarding overlay connect\n", op_id); 1288 LOG_DEBUG ("0x%llx: Forwarding overlay connect\n", op_id);
@@ -1282,10 +1295,10 @@ forward_overlay_connect (const struct GNUNET_TESTBED_OverlayConnectMessage *msg,
1282 goto forward; 1295 goto forward;
1283 /* Peer2 is either with us OR peer1 and peer2 can be reached through 1296 /* 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 */ 1297 different subtrees OR peer2 is on a subtree unknown to us */
1285 if (NULL != (rhc = register_p2_host (peer->details.remote.slave, 1298 if (NULL != (rhc = register_host (peer->details.remote.slave,
1286 peer2_host_id))) 1299 GST_host_list[peer2_host_id])))
1287 { 1300 {
1288 LOG_DEBUG ("Forwarding with FOCC for connecting peers %u and %u\n", p1, p2); 1301 LOG_DEBUG ("Queueing forwarding FOCC for connecting peers %u and %u\n", p1, p2);
1289 focc = GNUNET_malloc (sizeof (struct ForwardedOverlayConnectContext)); 1302 focc = GNUNET_malloc (sizeof (struct ForwardedOverlayConnectContext));
1290 focc->peer1 = p1; 1303 focc->peer1 = p1;
1291 focc->peer2 = p2; 1304 focc->peer2 = p2;
@@ -1386,7 +1399,7 @@ GST_handle_overlay_connect (void *cls, struct GNUNET_SERVER_Client *client,
1386 msg = (const struct GNUNET_TESTBED_OverlayConnectMessage *) message; 1399 msg = (const struct GNUNET_TESTBED_OverlayConnectMessage *) message;
1387 p1 = ntohl (msg->peer1); 1400 p1 = ntohl (msg->peer1);
1388 p2 = ntohl (msg->peer2); 1401 p2 = ntohl (msg->peer2);
1389 if INVALID_PEER_ID (p1) 1402 if (!VALID_PEER_ID (p1))
1390 { 1403 {
1391 GNUNET_break (0); 1404 GNUNET_break (0);
1392 GNUNET_SERVER_receive_done (client, GNUNET_SYSERR); 1405 GNUNET_SERVER_receive_done (client, GNUNET_SYSERR);
@@ -1400,7 +1413,7 @@ GST_handle_overlay_connect (void *cls, struct GNUNET_SERVER_Client *client,
1400 peer2_host_id = ntohl (msg->peer2_host_id); 1413 peer2_host_id = ntohl (msg->peer2_host_id);
1401 if (GNUNET_YES == peer->is_remote) 1414 if (GNUNET_YES == peer->is_remote)
1402 { 1415 {
1403 if INVALID_HOST_ID (peer2_host_id) 1416 if (!VALID_HOST_ID (peer2_host_id))
1404 { 1417 {
1405 GNUNET_break (0); 1418 GNUNET_break (0);
1406 GNUNET_SERVER_receive_done (client, GNUNET_SYSERR); 1419 GNUNET_SERVER_receive_done (client, GNUNET_SYSERR);
@@ -1413,11 +1426,11 @@ GST_handle_overlay_connect (void *cls, struct GNUNET_SERVER_Client *client,
1413 p2n = NULL; 1426 p2n = NULL;
1414 occ = GNUNET_malloc (sizeof (struct OverlayConnectContext)); 1427 occ = GNUNET_malloc (sizeof (struct OverlayConnectContext));
1415 occ->type = OCC_TYPE_LOCAL; 1428 occ->type = OCC_TYPE_LOCAL;
1416 if INVALID_PEER_ID (p2) /* May be peer2 is on a another controller */ 1429 if (!VALID_PEER_ID (p2)) /* May be peer2 is on a another controller */
1417 { 1430 {
1418 if (NULL == (p2n = GST_get_neighbour (peer2_host_id))) 1431 if (NULL == (p2n = GST_get_neighbour (peer2_host_id)))
1419 { 1432 {
1420 if (INVALID_HOST_ID (peer2_host_id)) 1433 if (!VALID_HOST_ID (peer2_host_id))
1421 { 1434 {
1422 GNUNET_break (0); 1435 GNUNET_break (0);
1423 LOG (GNUNET_ERROR_TYPE_WARNING, 1436 LOG (GNUNET_ERROR_TYPE_WARNING,