aboutsummaryrefslogtreecommitdiff
path: root/src/testbed/gnunet-service-testbed_links.c
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/testbed/gnunet-service-testbed_links.c
parente2bb863887e78b5847fd86ef5a399a5d13d856d3 (diff)
downloadgnunet-ad25eef39dc8c15b85bd70c6585af95d7e687fd5.tar.gz
gnunet-ad25eef39dc8c15b85bd70c6585af95d7e687fd5.zip
- doc
Diffstat (limited to 'src/testbed/gnunet-service-testbed_links.c')
-rw-r--r--src/testbed/gnunet-service-testbed_links.c300
1 files changed, 243 insertions, 57 deletions
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);