diff options
author | Sree Harsha Totakura <totakura@in.tum.de> | 2012-06-13 10:56:34 +0000 |
---|---|---|
committer | Sree Harsha Totakura <totakura@in.tum.de> | 2012-06-13 10:56:34 +0000 |
commit | ec56f91ac361b2a95d78e7529ed60549b7e9ddf3 (patch) | |
tree | b0855ec7e121253457c980d2d91b4a56c6e5b34e /src/testbed/testbed_api.c | |
parent | bd6e734d7d2a5472c959611d8aa452613f4f696b (diff) | |
download | gnunet-ec56f91ac361b2a95d78e7529ed60549b7e9ddf3.tar.gz gnunet-ec56f91ac361b2a95d78e7529ed60549b7e9ddf3.zip |
-testbed controller startup
Diffstat (limited to 'src/testbed/testbed_api.c')
-rw-r--r-- | src/testbed/testbed_api.c | 236 |
1 files changed, 234 insertions, 2 deletions
diff --git a/src/testbed/testbed_api.c b/src/testbed/testbed_api.c index 51680812b..f12ed64fc 100644 --- a/src/testbed/testbed_api.c +++ b/src/testbed/testbed_api.c | |||
@@ -32,8 +32,224 @@ | |||
32 | #include "gnunet_transport_service.h" | 32 | #include "gnunet_transport_service.h" |
33 | #include "gnunet_hello_lib.h" | 33 | #include "gnunet_hello_lib.h" |
34 | 34 | ||
35 | #include "testbed.h" | ||
36 | #include "testbed_api_hosts.h" | ||
35 | 37 | ||
36 | 38 | ||
39 | #define LOG(kind, ...) \ | ||
40 | GNUNET_log_from (kind, "testbed-api", __VA_ARGS__); | ||
41 | |||
42 | |||
43 | /** | ||
44 | * The message queue for sending messages to the controller service | ||
45 | */ | ||
46 | struct MessageQueue | ||
47 | { | ||
48 | /** | ||
49 | * The message to be sent | ||
50 | */ | ||
51 | struct GNUNET_MessageHeader *msg; | ||
52 | |||
53 | /** | ||
54 | * next pointer for DLL | ||
55 | */ | ||
56 | struct MessageQueue *next; | ||
57 | |||
58 | /** | ||
59 | * prev pointer for DLL | ||
60 | */ | ||
61 | struct MessageQueue *prev; | ||
62 | }; | ||
63 | |||
64 | |||
65 | /** | ||
66 | * Handle to interact with a GNUnet testbed controller. Each | ||
67 | * controller has at least one master handle which is created when the | ||
68 | * controller is created; this master handle interacts with the | ||
69 | * controller process, destroying it destroys the controller (by | ||
70 | * closing stdin of the controller process). Additionally, | ||
71 | * controllers can interact with each other (in a P2P fashion); those | ||
72 | * links are established via TCP/IP on the controller's service port. | ||
73 | */ | ||
74 | struct GNUNET_TESTBED_Controller | ||
75 | { | ||
76 | |||
77 | /** | ||
78 | * The host where the controller is running | ||
79 | */ | ||
80 | const struct GNUNET_TESTBED_Host *host; | ||
81 | |||
82 | /** | ||
83 | * The helper handle | ||
84 | */ | ||
85 | struct GNUNET_HELPER_Handle *h; | ||
86 | |||
87 | /** | ||
88 | * The controller callback | ||
89 | */ | ||
90 | GNUNET_TESTBED_ControllerCallback cc; | ||
91 | |||
92 | /** | ||
93 | * The closure for controller callback | ||
94 | */ | ||
95 | void *cc_cls; | ||
96 | |||
97 | /** | ||
98 | * The configuration to use while connecting to controller | ||
99 | */ | ||
100 | struct GNUNET_CONFIGURATION_Handle *cfg; | ||
101 | |||
102 | /** | ||
103 | * The client connection handle to the controller service | ||
104 | */ | ||
105 | struct GNUNET_CLIENT_Connection *client; | ||
106 | |||
107 | /** | ||
108 | * The head of the message queue | ||
109 | */ | ||
110 | struct MessageQueue *mq_head; | ||
111 | |||
112 | /** | ||
113 | * The tail of the message queue | ||
114 | */ | ||
115 | struct MessageQueue *mq_tail; | ||
116 | |||
117 | /** | ||
118 | * The client transmit handle | ||
119 | */ | ||
120 | struct GNUNET_CLIENT_TransmitHandle *th; | ||
121 | |||
122 | /** | ||
123 | * The controller event mask | ||
124 | */ | ||
125 | uint64_t event_mask; | ||
126 | }; | ||
127 | |||
128 | |||
129 | /** | ||
130 | * Function called to notify a client about the connection begin ready to queue | ||
131 | * more data. "buf" will be NULL and "size" zero if the connection was closed | ||
132 | * for writing in the meantime. | ||
133 | * | ||
134 | * @param cls closure | ||
135 | * @param size number of bytes available in buf | ||
136 | * @param buf where the callee should write the message | ||
137 | * @return number of bytes written to buf | ||
138 | */ | ||
139 | static size_t | ||
140 | transmit_ready_notify (void *cls, size_t size, void *buf) | ||
141 | { | ||
142 | struct GNUNET_TESTBED_Controller *c = cls; | ||
143 | struct MessageQueue *mq_entry; | ||
144 | |||
145 | mq_entry = c->mq_head; | ||
146 | GNUNET_assert (NULL != mq_entry); | ||
147 | GNUNET_assert (ntohs (mq_entry->msg->size) <= size); | ||
148 | size = ntohs (mq_entry->msg->size); | ||
149 | memcpy (buf, mq_entry->msg, size); | ||
150 | GNUNET_free (mq_entry->msg); | ||
151 | GNUNET_CONTAINER_DLL_remove (c->mq_head, c->mq_tail, mq_entry); | ||
152 | GNUNET_free (mq_entry); | ||
153 | mq_entry = c->mq_head; | ||
154 | if (NULL != mq_entry) | ||
155 | c->th = | ||
156 | GNUNET_CLIENT_notify_transmit_ready (c->client, | ||
157 | ntohs (mq_entry->msg->size), | ||
158 | GNUNET_TIME_UNIT_FOREVER_REL, | ||
159 | GNUNET_NO, &transmit_ready_notify, | ||
160 | c); | ||
161 | return size; | ||
162 | } | ||
163 | |||
164 | |||
165 | /** | ||
166 | * Queues a message in send queue for sending to the service | ||
167 | * | ||
168 | * @param controller the handle to the controller | ||
169 | * @param msg the message to queue | ||
170 | */ | ||
171 | static void | ||
172 | queue_message (struct GNUNET_TESTBED_Controller *controller, | ||
173 | struct GNUNET_MessageHeader *msg) | ||
174 | { | ||
175 | struct MessageQueue *mq_entry; | ||
176 | uint16_t type; | ||
177 | uint16_t size; | ||
178 | |||
179 | type = ntohs (msg->type); | ||
180 | size = ntohs (msg->size); | ||
181 | GNUNET_assert ((GNUNET_MESSAGE_TYPE_TESTBED_INIT <= type) && | ||
182 | (GNUNET_MESSAGE_TYPE_TESTBED_MAX > type)); | ||
183 | mq_entry = GNUNET_malloc (sizeof (struct MessageQueue)); | ||
184 | mq_entry->msg = msg; | ||
185 | LOG (GNUNET_ERROR_TYPE_DEBUG, | ||
186 | "Queueing message of type %u, size %u for sending\n", type, | ||
187 | ntohs (msg->size)); | ||
188 | GNUNET_CONTAINER_DLL_insert_tail (controller->mq_head, controller->mq_tail, | ||
189 | mq_entry); | ||
190 | if (NULL == controller->th) | ||
191 | controller->th = | ||
192 | GNUNET_CLIENT_notify_transmit_ready (controller->client, size, | ||
193 | GNUNET_TIME_UNIT_FOREVER_REL, | ||
194 | GNUNET_NO, &transmit_ready_notify, | ||
195 | controller); | ||
196 | } | ||
197 | |||
198 | |||
199 | /** | ||
200 | * Handler for messages from controller (testbed service) | ||
201 | * | ||
202 | * @param cls the controller handler | ||
203 | * @param msg message received, NULL on timeout or fatal error | ||
204 | */ | ||
205 | static void | ||
206 | message_handler (void *cls, const struct GNUNET_MessageHeader *msg) | ||
207 | { | ||
208 | struct GNUNET_TESTBED_Controller *c = cls; | ||
209 | |||
210 | /* FIXME: Add checks for message integrity */ | ||
211 | switch (ntohs (msg->type)) | ||
212 | { | ||
213 | default: | ||
214 | GNUNET_break (0); | ||
215 | } | ||
216 | GNUNET_CLIENT_receive (c->client, &message_handler, c, | ||
217 | GNUNET_TIME_UNIT_FOREVER_REL); | ||
218 | } | ||
219 | |||
220 | |||
221 | /** | ||
222 | * ?Callback for messages recevied from server? | ||
223 | * | ||
224 | * Do not call GNUNET_SERVER_mst_destroy in callback | ||
225 | * | ||
226 | * @param cls closure | ||
227 | * @param client identification of the client | ||
228 | * @param message the actual message | ||
229 | * | ||
230 | * @return GNUNET_OK on success, GNUNET_SYSERR to stop further processing | ||
231 | */ | ||
232 | static int | ||
233 | server_mst_cb (void *cls, void *client, | ||
234 | const struct GNUNET_MessageHeader *message) | ||
235 | { | ||
236 | struct GNUNET_TESTBED_Controller *c = cls; | ||
237 | struct GNUNET_TESTBED_Message *msg; | ||
238 | |||
239 | c->client = GNUNET_CLIENT_connect ("testbed", c->cfg); | ||
240 | if (NULL == c->client) | ||
241 | return GNUNET_SYSERR; /* FIXME: Call controller startup_cb ? */ | ||
242 | GNUNET_CLIENT_receive (c->client, &message_handler, c, | ||
243 | GNUNET_TIME_UNIT_FOREVER_REL); | ||
244 | msg = GNUNET_malloc (sizeof (struct GNUNET_TESTBED_Message)); | ||
245 | msg->header.type = htons (GNUNET_MESSAGE_TYPE_TESTBED_INIT); | ||
246 | msg->header.size = htons (sizeof (struct GNUNET_TESTBED_Message)); | ||
247 | msg->host_id = htonl (GNUNET_TESTBED_host_get_id_ (c->host)); | ||
248 | msg->event_mask = GNUNET_htonll (c->event_mask); | ||
249 | queue_message (c, (struct GNUNET_MessageHeader *) msg); | ||
250 | return GNUNET_OK; | ||
251 | } | ||
252 | |||
37 | 253 | ||
38 | /** | 254 | /** |
39 | * Start a controller process using the given configuration at the | 255 | * Start a controller process using the given configuration at the |
@@ -56,8 +272,24 @@ GNUNET_TESTBED_controller_start (const struct GNUNET_CONFIGURATION_Handle *cfg, | |||
56 | GNUNET_TESTBED_ControllerCallback cc, | 272 | GNUNET_TESTBED_ControllerCallback cc, |
57 | void *cc_cls) | 273 | void *cc_cls) |
58 | { | 274 | { |
59 | GNUNET_break (0); | 275 | struct GNUNET_TESTBED_Controller *controller; |
60 | return NULL; | 276 | char * binary_argv[] = {"gnunet-service-testbed", |
277 | "gnunet-service-testbed", | ||
278 | NULL}; | ||
279 | controller = GNUNET_malloc (sizeof (struct GNUNET_TESTBED_Controller)); | ||
280 | controller->h = GNUNET_TESTBED_host_run_ (host, binary_argv, | ||
281 | &server_mst_cb, controller); | ||
282 | if (NULL == controller->h) | ||
283 | { | ||
284 | GNUNET_free (controller); | ||
285 | return NULL; | ||
286 | } | ||
287 | controller->host = host; | ||
288 | controller->cc = cc; | ||
289 | controller->cc_cls = cc_cls; | ||
290 | controller->event_mask = event_mask; | ||
291 | controller->cfg = GNUNET_CONFIGURATION_dup (cfg); | ||
292 | return controller; | ||
61 | } | 293 | } |
62 | 294 | ||
63 | 295 | ||