aboutsummaryrefslogtreecommitdiff
path: root/src/testbed
diff options
context:
space:
mode:
authorChristian Grothoff <christian@grothoff.org>2016-10-10 15:47:00 +0000
committerChristian Grothoff <christian@grothoff.org>2016-10-10 15:47:00 +0000
commit93085e8a2991fde229400b588a5930e9fcca0d75 (patch)
tree0384246adbd96fa0138a46ad5fecb777aa40e789 /src/testbed
parent2bf962c76bb82c1f38acea42c7bdfb241e2582e7 (diff)
downloadgnunet-93085e8a2991fde229400b588a5930e9fcca0d75.tar.gz
gnunet-93085e8a2991fde229400b588a5930e9fcca0d75.zip
migrating testbed to new service API
Diffstat (limited to 'src/testbed')
-rw-r--r--src/testbed/gnunet-service-test-barriers.c20
-rw-r--r--src/testbed/gnunet-service-testbed.c730
-rw-r--r--src/testbed/gnunet-service-testbed.h234
-rw-r--r--src/testbed/gnunet-service-testbed_barriers.c603
-rw-r--r--src/testbed/gnunet-service-testbed_barriers.h71
-rw-r--r--src/testbed/gnunet-service-testbed_links.c380
-rw-r--r--src/testbed/gnunet-service-testbed_links.h34
-rw-r--r--src/testbed/gnunet-service-testbed_oc.c225
-rw-r--r--src/testbed/gnunet-service-testbed_peers.c596
-rw-r--r--src/testbed/test_testbed_api_barriers.c27
-rw-r--r--src/testbed/testbed_api.c9
-rw-r--r--src/testbed/testbed_api_barriers.c10
12 files changed, 1621 insertions, 1318 deletions
diff --git a/src/testbed/gnunet-service-test-barriers.c b/src/testbed/gnunet-service-test-barriers.c
index ce5249696..874c7a363 100644
--- a/src/testbed/gnunet-service-test-barriers.c
+++ b/src/testbed/gnunet-service-test-barriers.c
@@ -76,7 +76,9 @@ do_shutdown (void *cls)
76 * #GNUNET_OK if the barrier is crossed 76 * #GNUNET_OK if the barrier is crossed
77 */ 77 */
78static void 78static void
79barrier_wait_cb (void *cls, const char *name, int status) 79barrier_wait_cb (void *cls,
80 const char *name,
81 int status)
80{ 82{
81 GNUNET_break (NULL == cls); 83 GNUNET_break (NULL == cls);
82 wh = NULL; 84 wh = NULL;
@@ -117,10 +119,12 @@ run (void *cls,
117{ 119{
118 unsigned int rsec; 120 unsigned int rsec;
119 121
120 rsec = GNUNET_CRYPTO_random_u32 (GNUNET_CRYPTO_QUALITY_NONCE, 10); 122 rsec = GNUNET_CRYPTO_random_u32 (GNUNET_CRYPTO_QUALITY_NONCE,
121 tt = GNUNET_SCHEDULER_add_delayed (GNUNET_TIME_relative_multiply 123 10);
122 (GNUNET_TIME_UNIT_SECONDS, rsec), 124 tt = GNUNET_SCHEDULER_add_delayed (GNUNET_TIME_relative_multiply (GNUNET_TIME_UNIT_SECONDS,
123 &do_wait, NULL); 125 rsec),
126 &do_wait,
127 NULL);
124 GNUNET_SCHEDULER_add_shutdown (&do_shutdown, NULL); 128 GNUNET_SCHEDULER_add_shutdown (&do_shutdown, NULL);
125} 129}
126 130
@@ -139,6 +143,10 @@ main (int argc, char **argv)
139 143
140 ret = 144 ret =
141 GNUNET_PROGRAM_run (argc, argv, 145 GNUNET_PROGRAM_run (argc, argv,
142 "test-barriers", "nohelp", options, &run, NULL); 146 "test-barriers",
147 "nohelp",
148 options,
149 &run,
150 NULL);
143 return ret; 151 return ret;
144} 152}
diff --git a/src/testbed/gnunet-service-testbed.c b/src/testbed/gnunet-service-testbed.c
index 9e181f85a..39697cb56 100644
--- a/src/testbed/gnunet-service-testbed.c
+++ b/src/testbed/gnunet-service-testbed.c
@@ -1,6 +1,6 @@
1/* 1/*
2 This file is part of GNUnet. 2 This file is part of GNUnet.
3 Copyright (C) 2008--2013 GNUnet e.V. 3 Copyright (C) 2008--2013, 2016 GNUnet e.V.
4 4
5 GNUnet is free software; you can redistribute it and/or modify 5 GNUnet is free software; you can redistribute it and/or modify
6 it under the terms of the GNU General Public License as published 6 it under the terms of the GNU General Public License as published
@@ -83,128 +83,16 @@ unsigned int GST_peer_list_size;
83/***********************************/ 83/***********************************/
84 84
85/** 85/**
86 * The message queue for sending messages to clients
87 */
88struct MessageQueue
89{
90 /**
91 * The message to be sent
92 */
93 struct GNUNET_MessageHeader *msg;
94
95 /**
96 * The client to send the message to
97 */
98 struct GNUNET_SERVER_Client *client;
99
100 /**
101 * next pointer for DLL
102 */
103 struct MessageQueue *next;
104
105 /**
106 * prev pointer for DLL
107 */
108 struct MessageQueue *prev;
109};
110
111/**
112 * Our hostname; we give this to all the peers we start 86 * Our hostname; we give this to all the peers we start
113 */ 87 */
114static char *hostname; 88static char *hostname;
115 89
116/**
117 * Current Transmit Handle; NULL if no notify transmit exists currently
118 */
119static struct GNUNET_SERVER_TransmitHandle *transmit_handle;
120
121/**
122 * The message queue head
123 */
124static struct MessageQueue *mq_head;
125
126/**
127 * The message queue tail
128 */
129static struct MessageQueue *mq_tail;
130
131
132/**
133 * Function called to notify a client about the connection begin ready to queue
134 * more data. "buf" will be NULL and "size" zero if the connection was closed
135 * for writing in the meantime.
136 *
137 * @param cls NULL
138 * @param size number of bytes available in buf
139 * @param buf where the callee should write the message
140 * @return number of bytes written to buf
141 */
142static size_t
143transmit_ready_notify (void *cls, size_t size, void *buf)
144{
145 struct MessageQueue *mq_entry;
146
147 transmit_handle = NULL;
148 mq_entry = mq_head;
149 GNUNET_assert (NULL != mq_entry);
150 if (0 == size)
151 return 0;
152 GNUNET_assert (ntohs (mq_entry->msg->size) <= size);
153 size = ntohs (mq_entry->msg->size);
154 GNUNET_memcpy (buf, mq_entry->msg, size);
155 GNUNET_free (mq_entry->msg);
156 GNUNET_SERVER_client_drop (mq_entry->client);
157 GNUNET_CONTAINER_DLL_remove (mq_head, mq_tail, mq_entry);
158 GNUNET_free (mq_entry);
159 mq_entry = mq_head;
160 if (NULL != mq_entry)
161 transmit_handle =
162 GNUNET_SERVER_notify_transmit_ready (mq_entry->client,
163 ntohs (mq_entry->msg->size),
164 GNUNET_TIME_UNIT_FOREVER_REL,
165 &transmit_ready_notify, NULL);
166 return size;
167}
168
169
170/**
171 * Queues a message in send queue for sending to the service
172 *
173 * @param client the client to whom the queued message has to be sent
174 * @param msg the message to queue
175 */
176void
177GST_queue_message (struct GNUNET_SERVER_Client *client,
178 struct GNUNET_MessageHeader *msg)
179{
180 struct MessageQueue *mq_entry;
181 uint16_t type;
182 uint16_t size;
183
184 type = ntohs (msg->type);
185 size = ntohs (msg->size);
186 GNUNET_assert ((GNUNET_MESSAGE_TYPE_TESTBED_INIT <= type) &&
187 (GNUNET_MESSAGE_TYPE_TESTBED_MAX > type));
188 mq_entry = GNUNET_new (struct MessageQueue);
189 mq_entry->msg = msg;
190 mq_entry->client = client;
191 GNUNET_SERVER_client_keep (client);
192 LOG_DEBUG ("Queueing message of type %u, size %u for sending\n", type,
193 ntohs (msg->size));
194 GNUNET_CONTAINER_DLL_insert_tail (mq_head, mq_tail, mq_entry);
195 if (NULL == transmit_handle)
196 transmit_handle =
197 GNUNET_SERVER_notify_transmit_ready (client, size,
198 GNUNET_TIME_UNIT_FOREVER_REL,
199 &transmit_ready_notify, NULL);
200}
201
202 90
203/** 91/**
204 * Function to add a host to the current list of known hosts 92 * Function to add a host to the current list of known hosts
205 * 93 *
206 * @param host the host to add 94 * @param host the host to add
207 * @return GNUNET_OK on success; GNUNET_SYSERR on failure due to host-id 95 * @return #GNUNET_OK on success; #GNUNET_SYSERR on failure due to host-id
208 * already in use 96 * already in use
209 */ 97 */
210static int 98static int
@@ -233,24 +121,25 @@ host_list_add (struct GNUNET_TESTBED_Host *host)
233 * @param emsg the error message; can be NULL 121 * @param emsg the error message; can be NULL
234 */ 122 */
235void 123void
236GST_send_operation_fail_msg (struct GNUNET_SERVER_Client *client, 124GST_send_operation_fail_msg (struct GNUNET_SERVICE_Client *client,
237 uint64_t operation_id, const char *emsg) 125 uint64_t operation_id,
126 const char *emsg)
238{ 127{
128 struct GNUNET_MQ_Envelope *env;
239 struct GNUNET_TESTBED_OperationFailureEventMessage *msg; 129 struct GNUNET_TESTBED_OperationFailureEventMessage *msg;
240 uint16_t msize;
241 uint16_t emsg_len; 130 uint16_t emsg_len;
242 131
243 msize = sizeof (struct GNUNET_TESTBED_OperationFailureEventMessage);
244 emsg_len = (NULL == emsg) ? 0 : strlen (emsg) + 1; 132 emsg_len = (NULL == emsg) ? 0 : strlen (emsg) + 1;
245 msize += emsg_len; 133 env = GNUNET_MQ_msg_extra (msg,
246 msg = GNUNET_malloc (msize); 134 emsg_len,
247 msg->header.size = htons (msize); 135 GNUNET_MESSAGE_TYPE_TESTBED_OPERATION_FAIL_EVENT);
248 msg->header.type = htons (GNUNET_MESSAGE_TYPE_TESTBED_OPERATION_FAIL_EVENT);
249 msg->event_type = htonl (GNUNET_TESTBED_ET_OPERATION_FINISHED); 136 msg->event_type = htonl (GNUNET_TESTBED_ET_OPERATION_FINISHED);
250 msg->operation_id = GNUNET_htonll (operation_id); 137 msg->operation_id = GNUNET_htonll (operation_id);
251 if (0 != emsg_len) 138 GNUNET_memcpy (&msg[1],
252 GNUNET_memcpy (&msg[1], emsg, emsg_len); 139 emsg,
253 GST_queue_message (client, &msg->header); 140 emsg_len);
141 GNUNET_MQ_send (GNUNET_SERVICE_client_get_mq (client),
142 env);
254} 143}
255 144
256 145
@@ -261,22 +150,21 @@ GST_send_operation_fail_msg (struct GNUNET_SERVER_Client *client,
261 * @param operation_id the id of the operation which was successful 150 * @param operation_id the id of the operation which was successful
262 */ 151 */
263void 152void
264GST_send_operation_success_msg (struct GNUNET_SERVER_Client *client, 153GST_send_operation_success_msg (struct GNUNET_SERVICE_Client *client,
265 uint64_t operation_id) 154 uint64_t operation_id)
266{ 155{
156 struct GNUNET_MQ_Envelope *env;
267 struct GNUNET_TESTBED_GenericOperationSuccessEventMessage *msg; 157 struct GNUNET_TESTBED_GenericOperationSuccessEventMessage *msg;
268 uint16_t msize;
269 158
270 msize = sizeof (struct GNUNET_TESTBED_GenericOperationSuccessEventMessage); 159 env = GNUNET_MQ_msg (msg,
271 msg = GNUNET_malloc (msize); 160 GNUNET_MESSAGE_TYPE_TESTBED_GENERIC_OPERATION_SUCCESS);
272 msg->header.size = htons (msize);
273 msg->header.type =
274 htons (GNUNET_MESSAGE_TYPE_TESTBED_GENERIC_OPERATION_SUCCESS);
275 msg->operation_id = GNUNET_htonll (operation_id); 161 msg->operation_id = GNUNET_htonll (operation_id);
276 msg->event_type = htonl (GNUNET_TESTBED_ET_OPERATION_FINISHED); 162 msg->event_type = htonl (GNUNET_TESTBED_ET_OPERATION_FINISHED);
277 GST_queue_message (client, &msg->header); 163 GNUNET_MQ_send (GNUNET_SERVICE_client_get_mq (client),
164 env);
278} 165}
279 166
167
280/** 168/**
281 * Callback which will be called after a host registration succeeded or failed 169 * Callback which will be called after a host registration succeeded or failed
282 * 170 *
@@ -284,7 +172,8 @@ GST_send_operation_success_msg (struct GNUNET_SERVER_Client *client,
284 * @param emsg the error message; NULL if host registration is successful 172 * @param emsg the error message; NULL if host registration is successful
285 */ 173 */
286static void 174static void
287hr_completion (void *cls, const char *emsg); 175hr_completion (void *cls,
176 const char *emsg);
288 177
289 178
290/** 179/**
@@ -304,8 +193,10 @@ register_next_host (struct Slave *slave)
304 LOG (GNUNET_ERROR_TYPE_DEBUG, "Registering host %u at %u\n", 193 LOG (GNUNET_ERROR_TYPE_DEBUG, "Registering host %u at %u\n",
305 GNUNET_TESTBED_host_get_id_ (hr->host), 194 GNUNET_TESTBED_host_get_id_ (hr->host),
306 GNUNET_TESTBED_host_get_id_ (GST_host_list[slave->host_id])); 195 GNUNET_TESTBED_host_get_id_ (GST_host_list[slave->host_id]));
307 slave->rhandle = 196 slave->rhandle
308 GNUNET_TESTBED_register_host (slave->controller, hr->host, hr_completion, 197 = GNUNET_TESTBED_register_host (slave->controller,
198 hr->host,
199 hr_completion,
309 slave); 200 slave);
310} 201}
311 202
@@ -317,7 +208,8 @@ register_next_host (struct Slave *slave)
317 * @param emsg the error message; NULL if host registration is successful 208 * @param emsg the error message; NULL if host registration is successful
318 */ 209 */
319static void 210static void
320hr_completion (void *cls, const char *emsg) 211hr_completion (void *cls,
212 const char *emsg)
321{ 213{
322 struct Slave *slave = cls; 214 struct Slave *slave = cls;
323 struct HostRegistration *hr; 215 struct HostRegistration *hr;
@@ -325,12 +217,16 @@ hr_completion (void *cls, const char *emsg)
325 slave->rhandle = NULL; 217 slave->rhandle = NULL;
326 hr = slave->hr_dll_head; 218 hr = slave->hr_dll_head;
327 GNUNET_assert (NULL != hr); 219 GNUNET_assert (NULL != hr);
328 LOG (GNUNET_ERROR_TYPE_DEBUG, "Registering host %u at %u successful\n", 220 LOG (GNUNET_ERROR_TYPE_DEBUG,
221 "Registering host %u at %u successful\n",
329 GNUNET_TESTBED_host_get_id_ (hr->host), 222 GNUNET_TESTBED_host_get_id_ (hr->host),
330 GNUNET_TESTBED_host_get_id_ (GST_host_list[slave->host_id])); 223 GNUNET_TESTBED_host_get_id_ (GST_host_list[slave->host_id]));
331 GNUNET_CONTAINER_DLL_remove (slave->hr_dll_head, slave->hr_dll_tail, hr); 224 GNUNET_CONTAINER_DLL_remove (slave->hr_dll_head,
225 slave->hr_dll_tail,
226 hr);
332 if (NULL != hr->cb) 227 if (NULL != hr->cb)
333 hr->cb (hr->cb_cls, emsg); 228 hr->cb (hr->cb_cls,
229 emsg);
334 GNUNET_free (hr); 230 GNUNET_free (hr);
335 if (NULL != slave->hr_dll_head) 231 if (NULL != slave->hr_dll_head)
336 register_next_host (slave); 232 register_next_host (slave);
@@ -349,7 +245,8 @@ hr_completion (void *cls, const char *emsg)
349void 245void
350GST_queue_host_registration (struct Slave *slave, 246GST_queue_host_registration (struct Slave *slave,
351 GNUNET_TESTBED_HostRegistrationCompletion cb, 247 GNUNET_TESTBED_HostRegistrationCompletion cb,
352 void *cb_cls, struct GNUNET_TESTBED_Host *host) 248 void *cb_cls,
249 struct GNUNET_TESTBED_Host *host)
353{ 250{
354 struct HostRegistration *hr; 251 struct HostRegistration *hr;
355 int call_register; 252 int call_register;
@@ -363,7 +260,9 @@ GST_queue_host_registration (struct Slave *slave,
363 hr->cb_cls = cb_cls; 260 hr->cb_cls = cb_cls;
364 hr->host = host; 261 hr->host = host;
365 call_register = (NULL == slave->hr_dll_head) ? GNUNET_YES : GNUNET_NO; 262 call_register = (NULL == slave->hr_dll_head) ? GNUNET_YES : GNUNET_NO;
366 GNUNET_CONTAINER_DLL_insert_tail (slave->hr_dll_head, slave->hr_dll_tail, hr); 263 GNUNET_CONTAINER_DLL_insert_tail (slave->hr_dll_head,
264 slave->hr_dll_tail,
265 hr);
367 if (GNUNET_YES == call_register) 266 if (GNUNET_YES == call_register)
368 register_next_host (slave); 267 register_next_host (slave);
369} 268}
@@ -380,23 +279,24 @@ GST_forwarded_operation_reply_relay (void *cls,
380 const struct GNUNET_MessageHeader *msg) 279 const struct GNUNET_MessageHeader *msg)
381{ 280{
382 struct ForwardedOperationContext *fopc = cls; 281 struct ForwardedOperationContext *fopc = cls;
383 struct GNUNET_MessageHeader *dup_msg; 282 struct GNUNET_MQ_Envelope *env;
384 uint16_t msize;
385 283
386 msize = ntohs (msg->size); 284 LOG_DEBUG ("Relaying message with type: %u, size: %u\n",
387 LOG_DEBUG ("Relaying message with type: %u, size: %u\n", ntohs (msg->type), 285 ntohs (msg->type),
388 msize); 286 ntohs (msg->size));
389 dup_msg = GNUNET_copy_message (msg); 287 env = GNUNET_MQ_msg_copy (msg);
390 GST_queue_message (fopc->client, dup_msg); 288 GNUNET_MQ_send (GNUNET_SERVICE_client_get_mq (fopc->client),
391 GNUNET_SERVER_client_drop (fopc->client); 289 env);
392 GNUNET_SCHEDULER_cancel (fopc->timeout_task); 290 GNUNET_SCHEDULER_cancel (fopc->timeout_task);
393 GNUNET_CONTAINER_DLL_remove (fopcq_head, fopcq_tail, fopc); 291 GNUNET_CONTAINER_DLL_remove (fopcq_head,
292 fopcq_tail,
293 fopc);
394 GNUNET_free (fopc); 294 GNUNET_free (fopc);
395} 295}
396 296
397 297
398/** 298/**
399 * Task to free resources when forwarded operation has been timedout 299 * Task to free resources when forwarded operation has been timed out
400 * 300 *
401 * @param cls the ForwardedOperationContext 301 * @param cls the ForwardedOperationContext
402 */ 302 */
@@ -405,12 +305,16 @@ GST_forwarded_operation_timeout (void *cls)
405{ 305{
406 struct ForwardedOperationContext *fopc = cls; 306 struct ForwardedOperationContext *fopc = cls;
407 307
308 fopc->timeout_task = NULL;
408 GNUNET_TESTBED_forward_operation_msg_cancel_ (fopc->opc); 309 GNUNET_TESTBED_forward_operation_msg_cancel_ (fopc->opc);
409 LOG (GNUNET_ERROR_TYPE_DEBUG, "A forwarded operation has timed out\n"); 310 LOG (GNUNET_ERROR_TYPE_DEBUG,
410 GST_send_operation_fail_msg (fopc->client, fopc->operation_id, 311 "A forwarded operation has timed out\n");
312 GST_send_operation_fail_msg (fopc->client,
313 fopc->operation_id,
411 "A forwarded operation has timed out"); 314 "A forwarded operation has timed out");
412 GNUNET_SERVER_client_drop (fopc->client); 315 GNUNET_CONTAINER_DLL_remove (fopcq_head,
413 GNUNET_CONTAINER_DLL_remove (fopcq_head, fopcq_tail, fopc); 316 fopcq_tail,
317 fopc);
414 GNUNET_free (fopc); 318 GNUNET_free (fopc);
415} 319}
416 320
@@ -425,7 +329,8 @@ GST_forwarded_operation_timeout (void *cls)
425 * upon empty service sharing specification. 329 * upon empty service sharing specification.
426 */ 330 */
427static struct GNUNET_TESTING_SharedService * 331static struct GNUNET_TESTING_SharedService *
428parse_shared_services (char *ss_str, struct GNUNET_CONFIGURATION_Handle *cfg) 332parse_shared_services (char *ss_str,
333 struct GNUNET_CONFIGURATION_Handle *cfg)
429{ 334{
430 struct GNUNET_TESTING_SharedService ss; 335 struct GNUNET_TESTING_SharedService ss;
431 struct GNUNET_TESTING_SharedService *slist; 336 struct GNUNET_TESTING_SharedService *slist;
@@ -446,19 +351,27 @@ parse_shared_services (char *ss_str, struct GNUNET_CONFIGURATION_Handle *cfg)
446 { 351 {
447 ss.service = NULL; 352 ss.service = NULL;
448 ss.share = 0; 353 ss.share = 0;
449 if (2 != sscanf (arg, "%255[^:]:%u", service, &ss.share)) 354 if (2 != sscanf (arg, "%255[^:]:%u",
355 service,
356 &ss.share))
450 { 357 {
451 LOG (GNUNET_ERROR_TYPE_WARNING, "Ignoring shared service spec: %s", arg); 358 LOG (GNUNET_ERROR_TYPE_WARNING,
359 "Ignoring shared service spec: %s",
360 arg);
452 continue; 361 continue;
453 } 362 }
454 LOG_DEBUG ("Will be sharing %s service among %u peers\n", service, ss.share); 363 LOG_DEBUG ("Will be sharing %s service among %u peers\n",
364 service,
365 ss.share);
455 ss.service = GNUNET_strdup (service); 366 ss.service = GNUNET_strdup (service);
456 GROW_SS; 367 GROW_SS;
457 } 368 }
458 if (NULL != slist) 369 if (NULL != slist)
459 { 370 {
460 /* Add trailing NULL block */ 371 /* Add trailing NULL block */
461 (void) memset (&ss, 0, sizeof (struct GNUNET_TESTING_SharedService)); 372 (void) memset (&ss,
373 0,
374 sizeof (struct GNUNET_TESTING_SharedService));
462 GROW_SS; 375 GROW_SS;
463 } 376 }
464 return slist; 377 return slist;
@@ -467,66 +380,78 @@ parse_shared_services (char *ss_str, struct GNUNET_CONFIGURATION_Handle *cfg)
467 380
468 381
469/** 382/**
470 * Message handler for GNUNET_MESSAGE_TYPE_TESTBED_INIT messages 383 * Check #GNUNET_MESSAGE_TYPE_TESTBED_INIT messages
471 * 384 *
472 * @param cls NULL 385 * @param cls identification of the client
473 * @param client identification of the client 386 * @param message the actual message
387 * @return #GNUNET_OK if @a message is well-formed
388 */
389static int
390check_init (void *cls,
391 const struct GNUNET_TESTBED_InitMessage *msg)
392{
393 const char *controller_hostname;
394 uint16_t msize;
395
396 msize = ntohs (msg->header.size) - sizeof (struct GNUNET_TESTBED_InitMessage);
397 controller_hostname = (const char *) &msg[1];
398 if ('\0' != controller_hostname[msize - 1])
399 {
400 GNUNET_break (0);
401 return GNUNET_SYSERR;
402 }
403 return GNUNET_OK;
404}
405
406
407/**
408 * Message handler for #GNUNET_MESSAGE_TYPE_TESTBED_INIT messages
409 *
410 * @param cls identification of the client
474 * @param message the actual message 411 * @param message the actual message
475 */ 412 */
476static void 413static void
477handle_init (void *cls, 414handle_init (void *cls,
478 struct GNUNET_SERVER_Client *client, 415 const struct GNUNET_TESTBED_InitMessage *msg)
479 const struct GNUNET_MessageHeader *message)
480{ 416{
481 const struct GNUNET_TESTBED_InitMessage *msg; 417 struct GNUNET_SERVICE_Client *client = cls;
482 struct GNUNET_TESTBED_Host *host; 418 struct GNUNET_TESTBED_Host *host;
483 const char *controller_hostname; 419 const char *controller_hostname;
484 char *ss_str; 420 char *ss_str;
485 struct GNUNET_TESTING_SharedService *ss; 421 struct GNUNET_TESTING_SharedService *ss;
486 unsigned int cnt; 422 unsigned int cnt;
487 uint16_t msize;
488 423
489 if (NULL != GST_context) 424 if (NULL != GST_context)
490 { 425 {
491 LOG_DEBUG ("We are being connected to laterally\n"); 426 LOG_DEBUG ("We are being connected to laterally\n");
492 GNUNET_SERVER_receive_done (client, GNUNET_OK); 427 GNUNET_SERVICE_client_continue (client);
493 return; 428 return;
494 } 429 }
495 msg = (const struct GNUNET_TESTBED_InitMessage *) message;
496 msize = ntohs (message->size);
497 if (msize <= sizeof (struct GNUNET_TESTBED_InitMessage))
498 {
499 GNUNET_break (0);
500 GNUNET_SERVER_receive_done (client, GNUNET_SYSERR);
501 return;
502 }
503 msize -= sizeof (struct GNUNET_TESTBED_InitMessage);
504 controller_hostname = (const char *) &msg[1]; 430 controller_hostname = (const char *) &msg[1];
505 if ('\0' != controller_hostname[msize - 1])
506 {
507 GNUNET_break (0);
508 GNUNET_SERVER_receive_done (client, GNUNET_SYSERR);
509 return;
510 }
511 ss_str = NULL; 431 ss_str = NULL;
512 ss = NULL; 432 ss = NULL;
513 if (GNUNET_OK == GNUNET_CONFIGURATION_get_value_string (GST_config, "TESTBED", 433 if (GNUNET_OK ==
514 "SHARED_SERVICES", 434 GNUNET_CONFIGURATION_get_value_string (GST_config,
515 &ss_str)) 435 "TESTBED",
436 "SHARED_SERVICES",
437 &ss_str))
516 { 438 {
517 ss = parse_shared_services (ss_str, GST_config); 439 ss = parse_shared_services (ss_str,
440 GST_config);
518 GNUNET_free (ss_str); 441 GNUNET_free (ss_str);
519 ss_str = NULL; 442 ss_str = NULL;
520 } 443 }
521 GST_context = GNUNET_new (struct Context); 444 GST_context = GNUNET_new (struct Context);
522 GNUNET_SERVER_client_keep (client);
523 GST_context->client = client; 445 GST_context->client = client;
524 GST_context->host_id = ntohl (msg->host_id); 446 GST_context->host_id = ntohl (msg->host_id);
525 GST_context->master_ip = GNUNET_strdup (controller_hostname); 447 GST_context->master_ip = GNUNET_strdup (controller_hostname);
526 LOG_DEBUG ("Our IP: %s\n", GST_context->master_ip); 448 LOG_DEBUG ("Our IP: %s\n",
527 GST_context->system = 449 GST_context->master_ip);
528 GNUNET_TESTING_system_create ("testbed", GST_context->master_ip, 450 GST_context->system
529 hostname, ss); 451 = GNUNET_TESTING_system_create ("testbed",
452 GST_context->master_ip,
453 hostname,
454 ss);
530 if (NULL != ss) 455 if (NULL != ss)
531 { 456 {
532 for (cnt = 0; NULL != ss[cnt].service; cnt++) 457 for (cnt = 0; NULL != ss[cnt].service; cnt++)
@@ -539,28 +464,64 @@ handle_init (void *cls,
539 } 464 }
540 host = 465 host =
541 GNUNET_TESTBED_host_create_with_id (GST_context->host_id, 466 GNUNET_TESTBED_host_create_with_id (GST_context->host_id,
542 GST_context->master_ip, NULL, 467 GST_context->master_ip,
543 GST_config, 0); 468 NULL,
469 GST_config,
470 0);
544 host_list_add (host); 471 host_list_add (host);
545 LOG_DEBUG ("Created master context with host ID: %u\n", GST_context->host_id); 472 LOG_DEBUG ("Created master context with host ID: %u\n",
546 GNUNET_SERVER_receive_done (client, GNUNET_OK); 473 GST_context->host_id);
474 GNUNET_SERVICE_client_continue (client);
475}
476
477
478/**
479 * Check #GNUNET_MESSAGE_TYPE_TESTBED_ADDHOST messages
480 *
481 * @param cls identification of the client
482 * @param msg the actual message
483 * @return #GNUNET_OK if @a message is well-formed
484 */
485static int
486check_add_host (void *cls,
487 const struct GNUNET_TESTBED_AddHostMessage *msg)
488{
489 uint16_t username_length;
490 uint16_t hostname_length;
491 uint16_t msize;
492
493 msize = ntohs (msg->header.size) - sizeof (struct GNUNET_TESTBED_AddHostMessage);
494 username_length = ntohs (msg->username_length);
495 hostname_length = ntohs (msg->hostname_length);
496 /* msg must contain hostname */
497 if ( (msize <= username_length) ||
498 (0 == hostname_length) )
499 {
500 GNUNET_break (0);
501 return GNUNET_SYSERR;
502 }
503 /* msg must contain configuration */
504 if (msize <= username_length + hostname_length)
505 {
506 GNUNET_break (0);
507 return GNUNET_SYSERR;
508 }
509 return GNUNET_OK;
547} 510}
548 511
549 512
550/** 513/**
551 * Message handler for #GNUNET_MESSAGE_TYPE_TESTBED_ADDHOST messages 514 * Message handler for #GNUNET_MESSAGE_TYPE_TESTBED_ADDHOST messages
552 * 515 *
553 * @param cls NULL 516 * @param cls identification of the client
554 * @param client identification of the client 517 * @param msg the actual message
555 * @param message the actual message
556 */ 518 */
557static void 519static void
558handle_add_host (void *cls, 520handle_add_host (void *cls,
559 struct GNUNET_SERVER_Client *client, 521 const struct GNUNET_TESTBED_AddHostMessage *msg)
560 const struct GNUNET_MessageHeader *message)
561{ 522{
523 struct GNUNET_SERVICE_Client *client = cls;
562 struct GNUNET_TESTBED_Host *host; 524 struct GNUNET_TESTBED_Host *host;
563 const struct GNUNET_TESTBED_AddHostMessage *msg;
564 struct GNUNET_TESTBED_HostConfirmedMessage *reply; 525 struct GNUNET_TESTBED_HostConfirmedMessage *reply;
565 struct GNUNET_CONFIGURATION_Handle *host_cfg; 526 struct GNUNET_CONFIGURATION_Handle *host_cfg;
566 char *username; 527 char *username;
@@ -570,36 +531,10 @@ handle_add_host (void *cls,
570 uint32_t host_id; 531 uint32_t host_id;
571 uint16_t username_length; 532 uint16_t username_length;
572 uint16_t hostname_length; 533 uint16_t hostname_length;
573 uint16_t reply_size; 534 struct GNUNET_MQ_Envelope *env;
574 uint16_t msize;
575 535
576 msg = (const struct GNUNET_TESTBED_AddHostMessage *) message;
577 msize = ntohs (msg->header.size);
578 if (msize <= sizeof (struct GNUNET_TESTBED_AddHostMessage))
579 {
580 GNUNET_break_op (0);
581 GNUNET_SERVER_receive_done (client, GNUNET_SYSERR);
582 return;
583 }
584 username_length = ntohs (msg->username_length); 536 username_length = ntohs (msg->username_length);
585 hostname_length = ntohs (msg->hostname_length); 537 hostname_length = ntohs (msg->hostname_length);
586 /* msg must contain hostname */
587 if ((msize <= (sizeof (struct GNUNET_TESTBED_AddHostMessage) +
588 username_length))
589 || (0 == hostname_length))
590 {
591 GNUNET_break_op (0);
592 GNUNET_SERVER_receive_done (client, GNUNET_SYSERR);
593 return;
594 }
595 /* msg must contain configuration */
596 if (msize <= (sizeof (struct GNUNET_TESTBED_AddHostMessage) +
597 username_length + hostname_length))
598 {
599 GNUNET_break_op (0);
600 GNUNET_SERVER_receive_done (client, GNUNET_SYSERR);
601 return;
602 }
603 username = NULL; 538 username = NULL;
604 hostname = NULL; 539 hostname = NULL;
605 ptr = &msg[1]; 540 ptr = &msg[1];
@@ -610,13 +545,15 @@ handle_add_host (void *cls,
610 ptr += username_length; 545 ptr += username_length;
611 } 546 }
612 hostname = GNUNET_malloc (hostname_length + 1); 547 hostname = GNUNET_malloc (hostname_length + 1);
613 strncpy (hostname, ptr, hostname_length); 548 strncpy (hostname,
614 if (NULL == (host_cfg = GNUNET_TESTBED_extract_config_ (message))) 549 ptr,
550 hostname_length);
551 if (NULL == (host_cfg = GNUNET_TESTBED_extract_config_ (&msg->header)))
615 { 552 {
616 GNUNET_free_non_null (username); 553 GNUNET_free_non_null (username);
617 GNUNET_free_non_null (hostname); 554 GNUNET_free_non_null (hostname);
618 GNUNET_break_op (0); 555 GNUNET_break_op (0);
619 GNUNET_SERVER_receive_done (client, GNUNET_SYSERR); 556 GNUNET_SERVICE_client_drop (client);
620 return; 557 return;
621 } 558 }
622 host_id = ntohl (msg->host_id); 559 host_id = ntohl (msg->host_id);
@@ -628,94 +565,108 @@ handle_add_host (void *cls,
628 else 565 else
629 LOG_DEBUG ("-------username: <not given>\n"); 566 LOG_DEBUG ("-------username: <not given>\n");
630 LOG_DEBUG ("-------ssh port: %u\n", ntohs (msg->ssh_port)); 567 LOG_DEBUG ("-------ssh port: %u\n", ntohs (msg->ssh_port));
631 host = 568 host = GNUNET_TESTBED_host_create_with_id (host_id,
632 GNUNET_TESTBED_host_create_with_id (host_id, hostname, username, 569 hostname,
633 host_cfg, ntohs (msg->ssh_port)); 570 username,
571 host_cfg,
572 ntohs (msg->ssh_port));
634 GNUNET_free_non_null (username); 573 GNUNET_free_non_null (username);
635 GNUNET_free (hostname); 574 GNUNET_free (hostname);
636 GNUNET_CONFIGURATION_destroy (host_cfg); 575 GNUNET_CONFIGURATION_destroy (host_cfg);
637 if (NULL == host) 576 if (NULL == host)
638 { 577 {
639 GNUNET_break_op (0); 578 GNUNET_break_op (0);
640 GNUNET_SERVER_receive_done (client, GNUNET_SYSERR); 579 GNUNET_SERVICE_client_drop (client);
641 return; 580 return;
642 } 581 }
643 reply_size = sizeof (struct GNUNET_TESTBED_HostConfirmedMessage);
644 if (GNUNET_OK != host_list_add (host)) 582 if (GNUNET_OK != host_list_add (host))
645 { 583 {
646 /* We are unable to add a host */ 584 /* We are unable to add a host */
647 emsg = "A host exists with given host-id"; 585 emsg = "A host exists with given host-id";
648 LOG_DEBUG ("%s: %u", emsg, host_id); 586 LOG_DEBUG ("%s: %u",
587 emsg,
588 host_id);
649 GNUNET_TESTBED_host_destroy (host); 589 GNUNET_TESTBED_host_destroy (host);
650 reply_size += strlen (emsg) + 1; 590 env = GNUNET_MQ_msg_extra (reply,
651 reply = GNUNET_malloc (reply_size); 591 strlen (emsg) + 1,
652 GNUNET_memcpy (&reply[1], emsg, strlen (emsg) + 1); 592 GNUNET_MESSAGE_TYPE_TESTBED_ADD_HOST_SUCCESS);
593 GNUNET_memcpy (&reply[1],
594 emsg,
595 strlen (emsg) + 1);
653 } 596 }
654 else 597 else
655 { 598 {
656 LOG_DEBUG ("Added host %u at %u\n", host_id, GST_context->host_id); 599 LOG_DEBUG ("Added host %u at %u\n",
657 reply = GNUNET_malloc (reply_size); 600 host_id,
601 GST_context->host_id);
602 env = GNUNET_MQ_msg (reply,
603 GNUNET_MESSAGE_TYPE_TESTBED_ADD_HOST_SUCCESS);
658 } 604 }
659 reply->header.type = htons (GNUNET_MESSAGE_TYPE_TESTBED_ADD_HOST_SUCCESS);
660 reply->header.size = htons (reply_size);
661 reply->host_id = htonl (host_id); 605 reply->host_id = htonl (host_id);
662 GST_queue_message (client, &reply->header); 606 GNUNET_MQ_send (GNUNET_SERVICE_client_get_mq (client),
663 GNUNET_SERVER_receive_done (client, GNUNET_OK); 607 env);
608 GNUNET_SERVICE_client_continue (client);
664} 609}
665 610
666 611
667/** 612/**
668 * Handler for #GNUNET_MESSAGE_TYPE_TESTBED_GETSLAVECONFIG messages 613 * Handler for #GNUNET_MESSAGE_TYPE_TESTBED_GETSLAVECONFIG messages
669 * 614 *
670 * @param cls NULL 615 * @param cls identification of the client
671 * @param client identification of the client 616 * @param msg the actual message
672 * @param message the actual message
673 */ 617 */
674static void 618static void
675handle_slave_get_config (void *cls, 619handle_slave_get_config (void *cls,
676 struct GNUNET_SERVER_Client *client, 620 const struct GNUNET_TESTBED_SlaveGetConfigurationMessage *msg)
677 const struct GNUNET_MessageHeader *message)
678{ 621{
679 struct GNUNET_TESTBED_SlaveGetConfigurationMessage *msg; 622 struct GNUNET_SERVICE_Client *client = cls;
680 struct Slave *slave; 623 struct Slave *slave;
681 struct GNUNET_TESTBED_SlaveConfiguration *reply; 624 struct GNUNET_TESTBED_SlaveConfiguration *reply;
682 const struct GNUNET_CONFIGURATION_Handle *cfg; 625 const struct GNUNET_CONFIGURATION_Handle *cfg;
626 struct GNUNET_MQ_Envelope *env;
683 char *config; 627 char *config;
684 char *xconfig; 628 char *xconfig;
685 size_t config_size; 629 size_t config_size;
686 size_t xconfig_size; 630 size_t xconfig_size;
687 size_t reply_size;
688 uint64_t op_id; 631 uint64_t op_id;
689 uint32_t slave_id; 632 uint32_t slave_id;
690 633
691 msg = (struct GNUNET_TESTBED_SlaveGetConfigurationMessage *) message;
692 slave_id = ntohl (msg->slave_id); 634 slave_id = ntohl (msg->slave_id);
693 op_id = GNUNET_ntohll (msg->operation_id); 635 op_id = GNUNET_ntohll (msg->operation_id);
694 if ((GST_slave_list_size <= slave_id) || (NULL == GST_slave_list[slave_id])) 636 if ( (GST_slave_list_size <= slave_id) ||
637 (NULL == GST_slave_list[slave_id]) )
695 { 638 {
696 /* FIXME: Add forwardings for this type of message here.. */ 639 /* FIXME: Add forwardings for this type of message here.. */
697 GST_send_operation_fail_msg (client, op_id, "Slave not found"); 640 GST_send_operation_fail_msg (client,
698 GNUNET_SERVER_receive_done (client, GNUNET_OK); 641 op_id,
642 "Slave not found");
643 GNUNET_SERVICE_client_continue (client);
699 return; 644 return;
700 } 645 }
701 slave = GST_slave_list[slave_id]; 646 slave = GST_slave_list[slave_id];
702 GNUNET_assert (NULL != (cfg = GNUNET_TESTBED_host_get_cfg_ (GST_host_list[slave->host_id]))); 647 GNUNET_assert (NULL != (cfg = GNUNET_TESTBED_host_get_cfg_ (GST_host_list[slave->host_id])));
703 config = GNUNET_CONFIGURATION_serialize (cfg, &config_size); 648 config = GNUNET_CONFIGURATION_serialize (cfg,
704 xconfig_size = 649 &config_size);
705 GNUNET_TESTBED_compress_config_ (config, config_size, &xconfig); 650 /* FIXME: maybe we want to transmit the delta to the default here? */
651 xconfig_size = GNUNET_TESTBED_compress_config_ (config,
652 config_size,
653 &xconfig);
706 GNUNET_free (config); 654 GNUNET_free (config);
707 reply_size = xconfig_size + sizeof (struct GNUNET_TESTBED_SlaveConfiguration); 655 GNUNET_assert (xconfig_size + sizeof (struct GNUNET_TESTBED_SlaveConfiguration) <= UINT16_MAX);
708 GNUNET_break (reply_size <= UINT16_MAX); 656 GNUNET_assert (xconfig_size <= UINT16_MAX);
709 GNUNET_break (config_size <= UINT16_MAX); 657 env = GNUNET_MQ_msg_extra (reply,
710 reply = GNUNET_realloc (xconfig, reply_size); 658 xconfig_size,
711 (void) memmove (&reply[1], reply, xconfig_size); 659 GNUNET_MESSAGE_TYPE_TESTBED_SLAVE_CONFIGURATION);
712 reply->header.type = htons (GNUNET_MESSAGE_TYPE_TESTBED_SLAVE_CONFIGURATION);
713 reply->header.size = htons ((uint16_t) reply_size);
714 reply->slave_id = msg->slave_id; 660 reply->slave_id = msg->slave_id;
715 reply->operation_id = msg->operation_id; 661 reply->operation_id = msg->operation_id;
716 reply->config_size = htons ((uint16_t) config_size); 662 reply->config_size = htons ((uint16_t) config_size);
717 GST_queue_message (client, &reply->header); 663 GNUNET_memcpy (&reply[1],
718 GNUNET_SERVER_receive_done (client, GNUNET_OK); 664 xconfig,
665 xconfig_size);
666 GNUNET_free (xconfig);
667 GNUNET_MQ_send (GNUNET_SERVICE_client_get_mq (client),
668 env);
669 GNUNET_SERVICE_client_continue (client);
719} 670}
720 671
721 672
@@ -729,11 +680,12 @@ GST_clear_fopcq ()
729 680
730 while (NULL != (fopc = fopcq_head)) 681 while (NULL != (fopc = fopcq_head))
731 { 682 {
732 GNUNET_CONTAINER_DLL_remove (fopcq_head, fopcq_tail, fopc); 683 GNUNET_CONTAINER_DLL_remove (fopcq_head,
684 fopcq_tail,
685 fopc);
733 GNUNET_TESTBED_forward_operation_msg_cancel_ (fopc->opc); 686 GNUNET_TESTBED_forward_operation_msg_cancel_ (fopc->opc);
734 if (NULL != fopc->timeout_task) 687 if (NULL != fopc->timeout_task)
735 GNUNET_SCHEDULER_cancel (fopc->timeout_task); 688 GNUNET_SCHEDULER_cancel (fopc->timeout_task);
736 GNUNET_SERVER_client_drop (fopc->client);
737 switch (fopc->type) 689 switch (fopc->type)
738 { 690 {
739 case OP_PEER_CREATE: 691 case OP_PEER_CREATE:
@@ -775,13 +727,12 @@ GST_clear_fopcq ()
775static void 727static void
776shutdown_task (void *cls) 728shutdown_task (void *cls)
777{ 729{
778 struct MessageQueue *mq_entry;
779 uint32_t id; 730 uint32_t id;
780 731
781 LOG_DEBUG ("Shutting down testbed service\n"); 732 LOG_DEBUG ("Shutting down testbed service\n");
782 /* cleanup any remaining forwarded operations */ 733 /* cleanup any remaining forwarded operations */
783 GST_clear_fopcq (); 734 GST_clear_fopcq ();
784 GST_free_lcfq (); 735 GST_free_lcf ();
785 GST_free_mctxq (); 736 GST_free_mctxq ();
786 GST_free_occq (); 737 GST_free_occq ();
787 GST_free_roccq (); 738 GST_free_roccq ();
@@ -803,20 +754,11 @@ shutdown_task (void *cls)
803 { 754 {
804 GNUNET_free_non_null (GST_context->master_ip); 755 GNUNET_free_non_null (GST_context->master_ip);
805 if (NULL != GST_context->system) 756 if (NULL != GST_context->system)
806 GNUNET_TESTING_system_destroy (GST_context->system, GNUNET_YES); 757 GNUNET_TESTING_system_destroy (GST_context->system,
807 GNUNET_SERVER_client_drop (GST_context->client); 758 GNUNET_YES);
808 GNUNET_free (GST_context); 759 GNUNET_free (GST_context);
809 GST_context = NULL; 760 GST_context = NULL;
810 } 761 }
811 if (NULL != transmit_handle)
812 GNUNET_SERVER_notify_transmit_ready_cancel (transmit_handle);
813 while (NULL != (mq_entry = mq_head))
814 {
815 GNUNET_free (mq_entry->msg);
816 GNUNET_SERVER_client_drop (mq_entry->client);
817 GNUNET_CONTAINER_DLL_remove (mq_head, mq_tail, mq_entry);
818 GNUNET_free (mq_entry);
819 }
820 GNUNET_free_non_null (hostname); 762 GNUNET_free_non_null (hostname);
821 /* Free hello cache */ 763 /* Free hello cache */
822 GST_cache_clear (); 764 GST_cache_clear ();
@@ -830,19 +772,58 @@ shutdown_task (void *cls)
830 772
831 773
832/** 774/**
775 * Callback for client connect
776 *
777 * @param cls NULL
778 * @param client the client which has disconnected
779 * @param mq queue for sending messages to @a client
780 * @return @a client
781 */
782static void *
783client_connect_cb (void *cls,
784 struct GNUNET_SERVICE_Client *client,
785 struct GNUNET_MQ_Handle *mq)
786{
787 return client;
788}
789
790
791/**
833 * Callback for client disconnect 792 * Callback for client disconnect
834 * 793 *
835 * @param cls NULL 794 * @param cls NULL
836 * @param client the client which has disconnected 795 * @param client the client which has disconnected
796 * @param app_ctx should match @a client
837 */ 797 */
838static void 798static void
839client_disconnect_cb (void *cls, struct GNUNET_SERVER_Client *client) 799client_disconnect_cb (void *cls,
800 struct GNUNET_SERVICE_Client *client,
801 void *app_ctx)
840{ 802{
803 struct ForwardedOperationContext *fopc;
804 struct ForwardedOperationContext *fopcn;
805
806 GNUNET_assert (client == app_ctx);
807 GST_notify_client_disconnect_oc (client);
808 GST_link_notify_disconnect (client);
809 GST_notify_client_disconnect_peers (client);
810 for (fopc = fopcq_head; NULL != fopc; fopc = fopcn)
811 {
812 fopcn = fopc->next;
813 if (fopc->client == client)
814 {
815 /* handle as if it were a timeout */
816 GNUNET_SCHEDULER_cancel (fopc->timeout_task);
817 GST_forwarded_operation_timeout (fopc);
818 }
819 }
841 if (NULL == GST_context) 820 if (NULL == GST_context)
842 return; 821 return;
843 if (client == GST_context->client) 822 if (client == GST_context->client)
844 { 823 {
845 LOG (GNUNET_ERROR_TYPE_DEBUG, "Master client disconnected\n"); 824 LOG (GNUNET_ERROR_TYPE_DEBUG,
825 "Master client disconnected\n");
826 GST_context->client = NULL;
846 /* should not be needed as we're terminated by failure to read 827 /* should not be needed as we're terminated by failure to read
847 * from stdin, but if stdin fails for some reason, this shouldn't 828 * from stdin, but if stdin fails for some reason, this shouldn't
848 * hurt for now --- might need to revise this later if we ever 829 * hurt for now --- might need to revise this later if we ever
@@ -857,51 +838,14 @@ client_disconnect_cb (void *cls, struct GNUNET_SERVER_Client *client)
857 * Testbed setup 838 * Testbed setup
858 * 839 *
859 * @param cls closure 840 * @param cls closure
860 * @param server the initialized server
861 * @param cfg configuration to use 841 * @param cfg configuration to use
842 * @param service the initialized server
862 */ 843 */
863static void 844static void
864testbed_run (void *cls, struct GNUNET_SERVER_Handle *server, 845testbed_run (void *cls,
865 const struct GNUNET_CONFIGURATION_Handle *cfg) 846 const struct GNUNET_CONFIGURATION_Handle *cfg,
847 struct GNUNET_SERVICE_Handle *service)
866{ 848{
867 static const struct GNUNET_SERVER_MessageHandler message_handlers[] = {
868 {&handle_init, NULL, GNUNET_MESSAGE_TYPE_TESTBED_INIT, 0},
869 {&handle_add_host, NULL, GNUNET_MESSAGE_TYPE_TESTBED_ADD_HOST, 0},
870 {&GST_handle_link_controllers, NULL,
871 GNUNET_MESSAGE_TYPE_TESTBED_LINK_CONTROLLERS,
872 sizeof (struct GNUNET_TESTBED_ControllerLinkRequest)},
873 {&GST_handle_peer_create, NULL, GNUNET_MESSAGE_TYPE_TESTBED_CREATE_PEER, 0},
874 {&GST_handle_peer_destroy, NULL, GNUNET_MESSAGE_TYPE_TESTBED_DESTROY_PEER,
875 sizeof (struct GNUNET_TESTBED_PeerDestroyMessage)},
876 {&GST_handle_peer_start, NULL, GNUNET_MESSAGE_TYPE_TESTBED_START_PEER,
877 sizeof (struct GNUNET_TESTBED_PeerStartMessage)},
878 {&GST_handle_peer_stop, NULL, GNUNET_MESSAGE_TYPE_TESTBED_STOP_PEER,
879 sizeof (struct GNUNET_TESTBED_PeerStopMessage)},
880 {&GST_handle_peer_get_config, NULL,
881 GNUNET_MESSAGE_TYPE_TESTBED_GET_PEER_INFORMATION,
882 sizeof (struct GNUNET_TESTBED_PeerGetConfigurationMessage)},
883 {&GST_handle_overlay_connect, NULL,
884 GNUNET_MESSAGE_TYPE_TESTBED_OVERLAY_CONNECT,
885 sizeof (struct GNUNET_TESTBED_OverlayConnectMessage)},
886 {&GST_handle_remote_overlay_connect, NULL,
887 GNUNET_MESSAGE_TYPE_TESTBED_REMOTE_OVERLAY_CONNECT, 0},
888 {&GST_handle_manage_peer_service, NULL,
889 GNUNET_MESSAGE_TYPE_TESTBED_MANAGE_PEER_SERVICE, 0},
890 {&handle_slave_get_config, NULL,
891 GNUNET_MESSAGE_TYPE_TESTBED_GET_SLAVE_CONFIGURATION,
892 sizeof (struct GNUNET_TESTBED_SlaveGetConfigurationMessage)},
893 {&GST_handle_shutdown_peers, NULL, GNUNET_MESSAGE_TYPE_TESTBED_SHUTDOWN_PEERS,
894 sizeof (struct GNUNET_TESTBED_ShutdownPeersMessage)},
895 {&GST_handle_peer_reconfigure, NULL,
896 GNUNET_MESSAGE_TYPE_TESTBED_RECONFIGURE_PEER, 0},
897 {&GST_handle_barrier_init, NULL,
898 GNUNET_MESSAGE_TYPE_TESTBED_BARRIER_INIT, 0},
899 {&GST_handle_barrier_cancel, NULL,
900 GNUNET_MESSAGE_TYPE_TESTBED_BARRIER_CANCEL, 0},
901 {&GST_handle_barrier_status, NULL,
902 GNUNET_MESSAGE_TYPE_TESTBED_BARRIER_STATUS, 0},
903 {NULL, NULL, 0, 0}
904 };
905 char *logfile; 849 char *logfile;
906 unsigned long long num; 850 unsigned long long num;
907 851
@@ -910,32 +854,40 @@ testbed_run (void *cls, struct GNUNET_SERVER_Handle *server,
910 GNUNET_CONFIGURATION_get_value_filename (cfg, "TESTBED", "LOG_FILE", 854 GNUNET_CONFIGURATION_get_value_filename (cfg, "TESTBED", "LOG_FILE",
911 &logfile)) 855 &logfile))
912 { 856 {
913 GNUNET_break (GNUNET_OK == GNUNET_log_setup ("testbed", "DEBUG", logfile)); 857 GNUNET_break (GNUNET_OK ==
858 GNUNET_log_setup ("testbed",
859 "DEBUG",
860 logfile));
914 GNUNET_free (logfile); 861 GNUNET_free (logfile);
915 } 862 }
916 GNUNET_assert (GNUNET_OK == 863 GNUNET_assert (GNUNET_OK ==
917 GNUNET_CONFIGURATION_get_value_number (cfg, "TESTBED", 864 GNUNET_CONFIGURATION_get_value_number (cfg,
918 "CACHE_SIZE", &num)); 865 "TESTBED",
866 "CACHE_SIZE",
867 &num));
919 GST_cache_init ((unsigned int) num); 868 GST_cache_init ((unsigned int) num);
920 GST_connection_pool_init ((unsigned int) num); 869 GST_connection_pool_init ((unsigned int) num);
921 GNUNET_assert (GNUNET_OK == 870 GNUNET_assert (GNUNET_OK ==
922 GNUNET_CONFIGURATION_get_value_number (cfg, "TESTBED", 871 GNUNET_CONFIGURATION_get_value_number (cfg,
923 "MAX_OPEN_FDS", &num)); 872 "TESTBED",
924 GST_opq_openfds = GNUNET_TESTBED_operation_queue_create_ 873 "MAX_OPEN_FDS",
925 (OPERATION_QUEUE_TYPE_FIXED, (unsigned int) num); 874 &num));
875 GST_opq_openfds = GNUNET_TESTBED_operation_queue_create_ (OPERATION_QUEUE_TYPE_FIXED,
876 (unsigned int) num);
926 GNUNET_assert (GNUNET_OK == 877 GNUNET_assert (GNUNET_OK ==
927 GNUNET_CONFIGURATION_get_value_time (cfg, "TESTBED", 878 GNUNET_CONFIGURATION_get_value_time (cfg,
879 "TESTBED",
928 "OPERATION_TIMEOUT", 880 "OPERATION_TIMEOUT",
929 (struct 881 (struct GNUNET_TIME_Relative *)
930 GNUNET_TIME_Relative *)
931 &GST_timeout)); 882 &GST_timeout));
932 GNUNET_assert (GNUNET_OK == 883 GNUNET_assert (GNUNET_OK ==
933 GNUNET_CONFIGURATION_get_value_string (cfg, "testbed", 884 GNUNET_CONFIGURATION_get_value_string (cfg,
934 "HOSTNAME", &hostname)); 885 "testbed",
886 "HOSTNAME",
887 &hostname));
935 GST_config = GNUNET_CONFIGURATION_dup (cfg); 888 GST_config = GNUNET_CONFIGURATION_dup (cfg);
936 GNUNET_SERVER_add_handlers (server, message_handlers); 889 GNUNET_SCHEDULER_add_shutdown (&shutdown_task,
937 GNUNET_SERVER_disconnect_notify (server, &client_disconnect_cb, NULL); 890 NULL);
938 GNUNET_SCHEDULER_add_shutdown (&shutdown_task, NULL);
939 LOG_DEBUG ("Testbed startup complete\n"); 891 LOG_DEBUG ("Testbed startup complete\n");
940 GST_stats_init (GST_config); 892 GST_stats_init (GST_config);
941 GST_barriers_init (GST_config); 893 GST_barriers_init (GST_config);
@@ -943,16 +895,84 @@ testbed_run (void *cls, struct GNUNET_SERVER_Handle *server,
943 895
944 896
945/** 897/**
946 * The starting point of execution 898 * Define "main" method using service macro.
947 */ 899 */
948int 900GNUNET_SERVICE_MAIN
949main (int argc, char *const *argv) 901("testbed",
950{ 902 GNUNET_SERVICE_OPTION_NONE,
951 return (GNUNET_OK == 903 &testbed_run,
952 GNUNET_SERVICE_run (argc, argv, 904 &client_connect_cb,
953 "testbed", 905 &client_disconnect_cb,
954 GNUNET_SERVICE_OPTION_NONE, 906 NULL,
955 &testbed_run, NULL)) ? 0 : 1; 907 GNUNET_MQ_hd_var_size (init,
956} 908 GNUNET_MESSAGE_TYPE_TESTBED_INIT,
909 struct GNUNET_TESTBED_InitMessage,
910 NULL),
911 GNUNET_MQ_hd_var_size (add_host,
912 GNUNET_MESSAGE_TYPE_TESTBED_ADD_HOST,
913 struct GNUNET_TESTBED_AddHostMessage,
914 NULL),
915 GNUNET_MQ_hd_fixed_size (slave_get_config,
916 GNUNET_MESSAGE_TYPE_TESTBED_GET_SLAVE_CONFIGURATION,
917 struct GNUNET_TESTBED_SlaveGetConfigurationMessage,
918 NULL),
919 GNUNET_MQ_hd_fixed_size (link_controllers,
920 GNUNET_MESSAGE_TYPE_TESTBED_LINK_CONTROLLERS,
921 struct GNUNET_TESTBED_ControllerLinkRequest,
922 NULL),
923 GNUNET_MQ_hd_var_size (remote_overlay_connect,
924 GNUNET_MESSAGE_TYPE_TESTBED_REMOTE_OVERLAY_CONNECT,
925 struct GNUNET_TESTBED_RemoteOverlayConnectMessage,
926 NULL),
927 GNUNET_MQ_hd_fixed_size (overlay_connect,
928 GNUNET_MESSAGE_TYPE_TESTBED_OVERLAY_CONNECT,
929 struct GNUNET_TESTBED_OverlayConnectMessage,
930 NULL),
931 GNUNET_MQ_hd_var_size (peer_create,
932 GNUNET_MESSAGE_TYPE_TESTBED_CREATE_PEER,
933 struct GNUNET_TESTBED_PeerCreateMessage,
934 NULL),
935 GNUNET_MQ_hd_fixed_size (peer_destroy,
936 GNUNET_MESSAGE_TYPE_TESTBED_DESTROY_PEER,
937 struct GNUNET_TESTBED_PeerDestroyMessage,
938 NULL),
939 GNUNET_MQ_hd_fixed_size (peer_start,
940 GNUNET_MESSAGE_TYPE_TESTBED_START_PEER,
941 struct GNUNET_TESTBED_PeerStartMessage,
942 NULL),
943 GNUNET_MQ_hd_fixed_size (peer_stop,
944 GNUNET_MESSAGE_TYPE_TESTBED_STOP_PEER,
945 struct GNUNET_TESTBED_PeerStopMessage,
946 NULL),
947 GNUNET_MQ_hd_fixed_size (peer_get_config,
948 GNUNET_MESSAGE_TYPE_TESTBED_GET_PEER_INFORMATION,
949 struct GNUNET_TESTBED_PeerGetConfigurationMessage,
950 NULL),
951 GNUNET_MQ_hd_var_size (manage_peer_service,
952 GNUNET_MESSAGE_TYPE_TESTBED_MANAGE_PEER_SERVICE,
953 struct GNUNET_TESTBED_ManagePeerServiceMessage,
954 NULL),
955 GNUNET_MQ_hd_fixed_size (shutdown_peers,
956 GNUNET_MESSAGE_TYPE_TESTBED_SHUTDOWN_PEERS,
957 struct GNUNET_TESTBED_ShutdownPeersMessage,
958 NULL),
959 GNUNET_MQ_hd_var_size (peer_reconfigure,
960 GNUNET_MESSAGE_TYPE_TESTBED_RECONFIGURE_PEER,
961 struct GNUNET_TESTBED_PeerReconfigureMessage,
962 NULL),
963 GNUNET_MQ_hd_var_size (barrier_init,
964 GNUNET_MESSAGE_TYPE_TESTBED_BARRIER_INIT,
965 struct GNUNET_TESTBED_BarrierInit,
966 NULL),
967 GNUNET_MQ_hd_var_size (barrier_cancel,
968 GNUNET_MESSAGE_TYPE_TESTBED_BARRIER_CANCEL,
969 struct GNUNET_TESTBED_BarrierCancel,
970 NULL),
971 GNUNET_MQ_hd_var_size (barrier_status,
972 GNUNET_MESSAGE_TYPE_TESTBED_BARRIER_STATUS,
973 struct GNUNET_TESTBED_BarrierStatusMsg,
974 NULL),
975 GNUNET_MQ_handler_end ());
976
957 977
958/* end of gnunet-service-testbed.c */ 978/* end of gnunet-service-testbed.c */
diff --git a/src/testbed/gnunet-service-testbed.h b/src/testbed/gnunet-service-testbed.h
index b19d3c516..6f797a066 100644
--- a/src/testbed/gnunet-service-testbed.h
+++ b/src/testbed/gnunet-service-testbed.h
@@ -96,7 +96,7 @@ struct ForwardedOperationContext
96 /** 96 /**
97 * The client to which we have to reply 97 * The client to which we have to reply
98 */ 98 */
99 struct GNUNET_SERVER_Client *client; 99 struct GNUNET_SERVICE_Client *client;
100 100
101 /** 101 /**
102 * Closure pointer 102 * Closure pointer
@@ -161,7 +161,7 @@ struct LinkControllersContext
161 /** 161 /**
162 * The client which initiated the link controller operation 162 * The client which initiated the link controller operation
163 */ 163 */
164 struct GNUNET_SERVER_Client *client; 164 struct GNUNET_SERVICE_Client *client;
165 165
166 /** 166 /**
167 * The ID of the operation 167 * The ID of the operation
@@ -174,7 +174,6 @@ struct LinkControllersContext
174/** 174/**
175 * A peer 175 * A peer
176 */ 176 */
177
178struct Peer 177struct Peer
179{ 178{
180 179
@@ -255,7 +254,7 @@ struct Context
255 /** 254 /**
256 * The client handle associated with this context 255 * The client handle associated with this context
257 */ 256 */
258 struct GNUNET_SERVER_Client *client; 257 struct GNUNET_SERVICE_Client *client;
259 258
260 /** 259 /**
261 * The network address of the master controller 260 * The network address of the master controller
@@ -296,6 +295,9 @@ struct SharedService
296}; 295};
297 296
298 297
298struct RegisteredHostContext;
299
300
299/** 301/**
300 * Context information to used during operations which forward the overlay 302 * Context information to used during operations which forward the overlay
301 * connect message 303 * connect message
@@ -313,6 +315,11 @@ struct ForwardedOverlayConnectContext
313 struct ForwardedOverlayConnectContext *prev; 315 struct ForwardedOverlayConnectContext *prev;
314 316
315 /** 317 /**
318 * Which host does this FOCC belong to?
319 */
320 struct RegisteredHostContext *rhc;
321
322 /**
316 * A copy of the original overlay connect message 323 * A copy of the original overlay connect message
317 */ 324 */
318 struct GNUNET_MessageHeader *orig_msg; 325 struct GNUNET_MessageHeader *orig_msg;
@@ -320,7 +327,7 @@ struct ForwardedOverlayConnectContext
320 /** 327 /**
321 * The client handle 328 * The client handle
322 */ 329 */
323 struct GNUNET_SERVER_Client *client; 330 struct GNUNET_SERVICE_Client *client;
324 331
325 /** 332 /**
326 * The id of the operation which created this context information 333 * The id of the operation which created this context information
@@ -391,13 +398,13 @@ struct RegisteredHostContext
391 398
392 399
393/** 400/**
394 * Context data for GNUNET_MESSAGE_TYPE_TESTBED_SHUTDOWN_PEERS handler 401 * Context data for #GNUNET_MESSAGE_TYPE_TESTBED_SHUTDOWN_PEERS handler
395 */ 402 */
396struct HandlerContext_ShutdownPeers 403struct HandlerContext_ShutdownPeers
397{ 404{
398 /** 405 /**
399 * The number of slave we expect to hear from since we forwarded the 406 * The number of slave we expect to hear from since we forwarded the
400 * GNUNET_MESSAGE_TYPE_TESTBED_SHUTDOWN_PEERS message to them 407 * #GNUNET_MESSAGE_TYPE_TESTBED_SHUTDOWN_PEERS message to them
401 */ 408 */
402 unsigned int nslaves; 409 unsigned int nslaves;
403 410
@@ -507,17 +514,6 @@ extern char *GST_stats_dir;
507 514
508 515
509/** 516/**
510 * Queues a message in send queue for sending to the service
511 *
512 * @param client the client to whom the queued message has to be sent
513 * @param msg the message to queue
514 */
515void
516GST_queue_message (struct GNUNET_SERVER_Client *client,
517 struct GNUNET_MessageHeader *msg);
518
519
520/**
521 * Function to destroy a peer 517 * Function to destroy a peer
522 * 518 *
523 * @param peer the peer structure to destroy 519 * @param peer the peer structure to destroy
@@ -530,7 +526,7 @@ GST_destroy_peer (struct Peer *peer);
530 * Stops and destroys all peers 526 * Stops and destroys all peers
531 */ 527 */
532void 528void
533GST_destroy_peers (); 529GST_destroy_peers (void);
534 530
535 531
536/** 532/**
@@ -546,15 +542,14 @@ GST_find_dest_route (uint32_t host_id);
546 542
547 543
548/** 544/**
549 * Handler for GNUNET_MESSAGE_TYPE_TESTBED_OLCONNECT messages 545 * Handler for #GNUNET_MESSAGE_TYPE_TESTBED_OVERLAY_CONNECT messages
550 * 546 *
551 * @param cls NULL 547 * @param cls identification of the client
552 * @param client identification of the client 548 * @param msg the actual message
553 * @param message the actual message
554 */ 549 */
555void 550void
556GST_handle_overlay_connect (void *cls, struct GNUNET_SERVER_Client *client, 551handle_overlay_connect (void *cls,
557 const struct GNUNET_MessageHeader *message); 552 const struct GNUNET_TESTBED_OverlayConnectMessage *msg);
558 553
559 554
560/** 555/**
@@ -597,7 +592,7 @@ GST_forwarded_operation_timeout (void *cls);
597 * Clears the forwarded operations queue 592 * Clears the forwarded operations queue
598 */ 593 */
599void 594void
600GST_clear_fopcq (); 595GST_clear_fopcq (void);
601 596
602 597
603/** 598/**
@@ -608,8 +603,27 @@ GST_clear_fopcq ();
608 * @param emsg the error message; can be NULL 603 * @param emsg the error message; can be NULL
609 */ 604 */
610void 605void
611GST_send_operation_fail_msg (struct GNUNET_SERVER_Client *client, 606GST_send_operation_fail_msg (struct GNUNET_SERVICE_Client *client,
612 uint64_t operation_id, const char *emsg); 607 uint64_t operation_id,
608 const char *emsg);
609
610
611/**
612 * Notify OC subsystem that @a client disconnected.
613 *
614 * @param client the client that disconnected
615 */
616void
617GST_notify_client_disconnect_oc (struct GNUNET_SERVICE_Client *client);
618
619
620/**
621 * Notify peers subsystem that @a client disconnected.
622 *
623 * @param client the client that disconnected
624 */
625void
626GST_notify_client_disconnect_peers (struct GNUNET_SERVICE_Client *client);
613 627
614 628
615/** 629/**
@@ -619,140 +633,180 @@ GST_send_operation_fail_msg (struct GNUNET_SERVER_Client *client,
619 * @param operation_id the id of the operation which was successful 633 * @param operation_id the id of the operation which was successful
620 */ 634 */
621void 635void
622GST_send_operation_success_msg (struct GNUNET_SERVER_Client *client, 636GST_send_operation_success_msg (struct GNUNET_SERVICE_Client *client,
623 uint64_t operation_id); 637 uint64_t operation_id);
624 638
625 639
626/** 640/**
627 * Handler for GNUNET_MESSAGE_TYPE_TESTBED_REQUESTCONNECT messages 641 * Check #GNUNET_MESSAGE_TYPE_TESTBED_REMOTE_OVERLAY_CONNECT messages
628 * 642 *
629 * @param cls NULL 643 * @param cls identification of the client
630 * @param client identification of the client 644 * @param msg the actual message
631 * @param message the actual message 645 * @return #GNUNET_OK if @a msg is well-formed
646 */
647int
648check_remote_overlay_connect (void *cls,
649 const struct GNUNET_TESTBED_RemoteOverlayConnectMessage *msg);
650
651
652/**
653 * Handler for #GNUNET_MESSAGE_TYPE_TESTBED_REMOTE_OVERLAY_CONNECT messages
654 *
655 * @param cls identification of the client
656 * @param msg the actual message
632 */ 657 */
633void 658void
634GST_handle_remote_overlay_connect (void *cls, 659handle_remote_overlay_connect (void *cls,
635 struct GNUNET_SERVER_Client *client, 660 const struct GNUNET_TESTBED_RemoteOverlayConnectMessage *msg);
636 const struct GNUNET_MessageHeader *message); 661
662
663/**
664 * Check #GNUNET_MESSAGE_TYPE_TESTBED_CREATEPEER messages
665 *
666 * @param cls identification of the client
667 * @param msg the actual message
668 * @return #GNUNET_OK if @a msg is well-formed
669 */
670int
671check_peer_create (void *cls,
672 const struct GNUNET_TESTBED_PeerCreateMessage *msg);
637 673
638 674
639/** 675/**
640 * Handler for GNUNET_MESSAGE_TYPE_TESTBED_CREATEPEER messages 676 * Handler for #GNUNET_MESSAGE_TYPE_TESTBED_CREATEPEER messages
641 * 677 *
642 * @param cls NULL 678 * @param cls identification of the client
643 * @param client identification of the client
644 * @param message the actual message 679 * @param message the actual message
645 */ 680 */
646void 681void
647GST_handle_peer_create (void *cls, struct GNUNET_SERVER_Client *client, 682handle_peer_create (void *cls,
648 const struct GNUNET_MessageHeader *message); 683 const struct GNUNET_TESTBED_PeerCreateMessage *msg);
649 684
650 685
651/** 686/**
652 * Message handler for GNUNET_MESSAGE_TYPE_TESTBED_DESTROYPEER messages 687 * Message handler for #GNUNET_MESSAGE_TYPE_TESTBED_DESTROYPEER messages
653 * 688 *
654 * @param cls NULL 689 * @param cls identification of the client
655 * @param client identification of the client 690 * @param msg the actual message
656 * @param message the actual message
657 */ 691 */
658void 692void
659GST_handle_peer_destroy (void *cls, struct GNUNET_SERVER_Client *client, 693handle_peer_destroy (void *cls,
660 const struct GNUNET_MessageHeader *message); 694 const struct GNUNET_TESTBED_PeerDestroyMessage *msg);
661 695
662 696
663/** 697/**
664 * Message handler for GNUNET_MESSAGE_TYPE_TESTBED_DESTROYPEER messages 698 * Message handler for #GNUNET_MESSAGE_TYPE_TESTBED_DESTROYPEER messages
665 * 699 *
666 * @param cls NULL 700 * @param cls identification of the client
667 * @param client identification of the client 701 * @param msg the actual message
668 * @param message the actual message
669 */ 702 */
670void 703void
671GST_handle_peer_start (void *cls, struct GNUNET_SERVER_Client *client, 704handle_peer_start (void *cls,
672 const struct GNUNET_MessageHeader *message); 705 const struct GNUNET_TESTBED_PeerStartMessage *msg);
673 706
674 707
675/** 708/**
676 * Message handler for GNUNET_MESSAGE_TYPE_TESTBED_DESTROYPEER messages 709 * Message handler for #GNUNET_MESSAGE_TYPE_TESTBED_DESTROYPEER messages
677 * 710 *
678 * @param cls NULL 711 * @param cls identification of the client
679 * @param client identification of the client
680 * @param message the actual message 712 * @param message the actual message
681 */ 713 */
682void 714void
683GST_handle_peer_stop (void *cls, struct GNUNET_SERVER_Client *client, 715handle_peer_stop (void *cls,
684 const struct GNUNET_MessageHeader *message); 716 const struct GNUNET_TESTBED_PeerStopMessage *msg);
685 717
686 718
687/** 719/**
688 * Handler for GNUNET_MESSAGE_TYPE_TESTBED_GETPEERCONFIG messages 720 * Handler for #GNUNET_MESSAGE_TYPE_TESTBED_GETPEERCONFIG messages
689 * 721 *
690 * @param cls NULL 722 * @param cls identification of the client
691 * @param client identification of the client 723 * @param msg the actual message
692 * @param message the actual message
693 */ 724 */
694void 725void
695GST_handle_peer_get_config (void *cls, struct GNUNET_SERVER_Client *client, 726handle_peer_get_config (void *cls,
696 const struct GNUNET_MessageHeader *message); 727 const struct GNUNET_TESTBED_PeerGetConfigurationMessage *msg);
697 728
698 729
699/** 730/**
700 * Handler for GNUNET_MESSAGE_TYPE_TESTBED_SHUTDOWN_PEERS messages 731 * Handler for #GNUNET_MESSAGE_TYPE_TESTBED_SHUTDOWN_PEERS messages
701 * 732 *
702 * @param cls NULL 733 * @param cls identification of the client
703 * @param client identification of the client 734 * @param msg the actual message
704 * @param message the actual message
705 */ 735 */
706void 736void
707GST_handle_shutdown_peers (void *cls, struct GNUNET_SERVER_Client *client, 737handle_shutdown_peers (void *cls,
708 const struct GNUNET_MessageHeader *message); 738 const struct GNUNET_TESTBED_ShutdownPeersMessage *msg);
709 739
710 740
711/** 741/**
712 * Handler for GNUNET_TESTBED_ManagePeerServiceMessage message 742 * Check #GNUNET_MESSAGE_TYPE_TESTBED_MANAGE_PEER_SERVICE message
713 * 743 *
714 * @param cls NULL 744 * @param cls identification of client
715 * @param client identification of client 745 * @param msg the actual message
716 * @param message the actual message 746 * @return #GNUNET_OK if @a msg is well-formed
747 */
748int
749check_manage_peer_service (void *cls,
750 const struct GNUNET_TESTBED_ManagePeerServiceMessage *msg);
751
752
753/**
754 * Handler for #GNUNET_MESSAGE_TYPE_TESTBED_MANAGE_PEER_SERVICE message
755 *
756 * @param cls identification of client
757 * @param msg the actual message
717 */ 758 */
718void 759void
719GST_handle_manage_peer_service (void *cls, struct GNUNET_SERVER_Client *client, 760handle_manage_peer_service (void *cls,
720 const struct GNUNET_MessageHeader *message); 761 const struct GNUNET_TESTBED_ManagePeerServiceMessage *msg);
762
763
721 764
722 765
723/** 766/**
724 * Handler for GNUNET_MESSAGE_TYPDE_TESTBED_RECONFIGURE_PEER type messages. 767 * Check #GNUNET_MESSAGE_TYPDE_TESTBED_RECONFIGURE_PEER type messages.
768 *
769 * @param cls identification of the client
770 * @param msg the actual message
771 * @return #GNUNET_OK if @a msg is well-formed
772 */
773int
774check_peer_reconfigure (void *cls,
775 const struct GNUNET_TESTBED_PeerReconfigureMessage *msg);
776
777
778/**
779 * Handler for #GNUNET_MESSAGE_TYPDE_TESTBED_RECONFIGURE_PEER type messages.
725 * Should stop the peer asyncronously, destroy it and create it again with the 780 * Should stop the peer asyncronously, destroy it and create it again with the
726 * new configuration. 781 * new configuration.
727 * 782 *
728 * @param cls NULL 783 * @param cls identification of the client
729 * @param client identification of the client 784 * @param msg the actual message
730 * @param message the actual message
731 */ 785 */
732void 786void
733GST_handle_peer_reconfigure (void *cls, struct GNUNET_SERVER_Client *client, 787handle_peer_reconfigure (void *cls,
734 const struct GNUNET_MessageHeader *message); 788 const struct GNUNET_TESTBED_PeerReconfigureMessage *msg);
735 789
736 790
737/** 791/**
738 * Frees the ManageServiceContext queue 792 * Frees the ManageServiceContext queue
739 */ 793 */
740void 794void
741GST_free_mctxq (); 795GST_free_mctxq (void);
742 796
743 797
744/** 798/**
745 * Cleans up the queue used for forwarding link controllers requests 799 * Cleans up the queue used for forwarding link controllers requests
746 */ 800 */
747void 801void
748GST_free_lcfq (); 802GST_free_lcf (void);
749 803
750 804
751/** 805/**
752 * Cleans up the route list 806 * Cleans up the route list
753 */ 807 */
754void 808void
755GST_route_list_clear (); 809GST_route_list_clear (void);
756 810
757 811
758/** 812/**
@@ -777,21 +831,21 @@ GST_cleanup_focc (struct ForwardedOverlayConnectContext *focc);
777 * Clears all pending overlay connect contexts in queue 831 * Clears all pending overlay connect contexts in queue
778 */ 832 */
779void 833void
780GST_free_occq (); 834GST_free_occq (void);
781 835
782 836
783/** 837/**
784 * Clears all pending remote overlay connect contexts in queue 838 * Clears all pending remote overlay connect contexts in queue
785 */ 839 */
786void 840void
787GST_free_roccq (); 841GST_free_roccq (void);
788 842
789 843
790/** 844/**
791 * Cleans up the Peer reconfigure context list 845 * Cleans up the Peer reconfigure context list
792 */ 846 */
793void 847void
794GST_free_prcq (); 848GST_free_prcq (void);
795 849
796 850
797/** 851/**
@@ -807,7 +861,7 @@ GST_cache_init (unsigned int size);
807 * Clear cache 861 * Clear cache
808 */ 862 */
809void 863void
810GST_cache_clear (); 864GST_cache_clear (void);
811 865
812 866
813/** 867/**
@@ -845,6 +899,6 @@ GST_stats_init (const struct GNUNET_CONFIGURATION_Handle *cfg);
845 * Shutdown the status calls module. 899 * Shutdown the status calls module.
846 */ 900 */
847void 901void
848GST_stats_destroy (); 902GST_stats_destroy (void);
849 903
850/* End of gnunet-service-testbed.h */ 904/* End of gnunet-service-testbed.h */
diff --git a/src/testbed/gnunet-service-testbed_barriers.c b/src/testbed/gnunet-service-testbed_barriers.c
index c3ae82ed8..831bc3c6d 100644
--- a/src/testbed/gnunet-service-testbed_barriers.c
+++ b/src/testbed/gnunet-service-testbed_barriers.c
@@ -61,28 +61,6 @@ struct Barrier;
61 61
62 62
63/** 63/**
64 * Message queue for transmitting messages
65 */
66struct MessageQueue
67{
68 /**
69 * next pointer for DLL
70 */
71 struct MessageQueue *next;
72
73 /**
74 * prev pointer for DLL
75 */
76 struct MessageQueue *prev;
77
78 /**
79 * The message to be sent
80 */
81 struct GNUNET_MessageHeader *msg;
82};
83
84
85/**
86 * Context to be associated with each client 64 * Context to be associated with each client
87 */ 65 */
88struct ClientCtx 66struct ClientCtx
@@ -105,22 +83,8 @@ struct ClientCtx
105 /** 83 /**
106 * The client handle 84 * The client handle
107 */ 85 */
108 struct GNUNET_SERVER_Client *client; 86 struct GNUNET_SERVICE_Client *client;
109
110 /**
111 * the transmission handle
112 */
113 struct GNUNET_SERVER_TransmitHandle *tx;
114 87
115 /**
116 * message queue head
117 */
118 struct MessageQueue *mq_head;
119
120 /**
121 * message queue tail
122 */
123 struct MessageQueue *mq_tail;
124}; 88};
125 89
126 90
@@ -169,7 +133,7 @@ struct Barrier
169 /** 133 /**
170 * The client handle to the master controller 134 * The client handle to the master controller
171 */ 135 */
172 struct GNUNET_SERVER_Client *mc; 136 struct GNUNET_SERVICE_Client *mc;
173 137
174 /** 138 /**
175 * The name of the barrier 139 * The name of the barrier
@@ -199,7 +163,7 @@ struct Barrier
199 /** 163 /**
200 * Identifier for the timeout task 164 * Identifier for the timeout task
201 */ 165 */
202 struct GNUNET_SCHEDULER_Task * tout_task; 166 struct GNUNET_SCHEDULER_Task *tout_task;
203 167
204 /** 168 /**
205 * The status of this barrier 169 * The status of this barrier
@@ -247,102 +211,7 @@ static struct GNUNET_CONTAINER_MultiHashMap *barrier_map;
247/** 211/**
248 * Service context 212 * Service context
249 */ 213 */
250static struct GNUNET_SERVICE_Context *ctx; 214static struct GNUNET_SERVICE_Handle *ctx;
251
252
253/**
254 * Function called to notify a client about the connection
255 * begin ready to queue more data. "buf" will be
256 * NULL and "size" zero if the connection was closed for
257 * writing in the meantime.
258 *
259 * @param cls client context
260 * @param size number of bytes available in buf
261 * @param buf where the callee should write the message
262 * @return number of bytes written to buf
263 */
264static size_t
265transmit_ready_cb (void *cls, size_t size, void *buf)
266{
267 struct ClientCtx *ctx = cls;
268 struct GNUNET_SERVER_Client *client = ctx->client;
269 struct MessageQueue *mq;
270 struct GNUNET_MessageHeader *msg;
271 size_t wrote;
272
273 ctx->tx = NULL;
274 if ((0 == size) || (NULL == buf))
275 {
276 GNUNET_assert (NULL != ctx->client);
277 GNUNET_SERVER_client_drop (ctx->client);
278 ctx->client = NULL;
279 return 0;
280 }
281 mq = ctx->mq_head;
282 msg = mq->msg;
283 wrote = ntohs (msg->size);
284 GNUNET_assert (size >= wrote);
285 GNUNET_memcpy (buf, msg, wrote);
286 GNUNET_CONTAINER_DLL_remove (ctx->mq_head, ctx->mq_tail, mq);
287 GNUNET_free (mq->msg);
288 GNUNET_free (mq);
289 if (NULL != (mq = ctx->mq_head))
290 ctx->tx = GNUNET_SERVER_notify_transmit_ready (client, ntohs (msg->size),
291 MESSAGE_SEND_TIMEOUT (30),
292 &transmit_ready_cb, ctx);
293 return wrote;
294}
295
296
297/**
298 * Queue a message into a clients message queue
299 *
300 * @param ctx the context associated with the client
301 * @param msg the message to queue. Will be consumed
302 */
303static void
304queue_message (struct ClientCtx *ctx, struct GNUNET_MessageHeader *msg)
305{
306 struct MessageQueue *mq;
307 struct GNUNET_SERVER_Client *client = ctx->client;
308
309 mq = GNUNET_new (struct MessageQueue);
310 mq->msg = msg;
311 LOG_DEBUG ("Queueing message of type %u, size %u for sending\n",
312 ntohs (msg->type), ntohs (msg->size));
313 GNUNET_CONTAINER_DLL_insert_tail (ctx->mq_head, ctx->mq_tail, mq);
314 if (NULL == ctx->tx)
315 ctx->tx = GNUNET_SERVER_notify_transmit_ready (client, ntohs (msg->size),
316 MESSAGE_SEND_TIMEOUT (30),
317 &transmit_ready_cb, ctx);
318}
319
320
321/**
322 * Function to cleanup client context data structure
323 *
324 * @param ctx the client context data structure
325 */
326static void
327cleanup_clientctx (struct ClientCtx *ctx)
328{
329 struct MessageQueue *mq;
330
331 if (NULL != ctx->client)
332 {
333 GNUNET_SERVER_client_set_user_context_ (ctx->client, NULL, 0);
334 GNUNET_SERVER_client_drop (ctx->client);
335 }
336 if (NULL != ctx->tx)
337 GNUNET_SERVER_notify_transmit_ready_cancel (ctx->tx);
338 if (NULL != (mq = ctx->mq_head))
339 {
340 GNUNET_CONTAINER_DLL_remove (ctx->mq_head, ctx->mq_tail, mq);
341 GNUNET_free (mq->msg);
342 GNUNET_free (mq);
343 }
344 GNUNET_free (ctx);
345}
346 215
347 216
348/** 217/**
@@ -356,16 +225,18 @@ remove_barrier (struct Barrier *barrier)
356{ 225{
357 struct ClientCtx *ctx; 226 struct ClientCtx *ctx;
358 227
359 GNUNET_assert (GNUNET_YES == GNUNET_CONTAINER_multihashmap_remove (barrier_map, 228 GNUNET_assert (GNUNET_YES ==
360 &barrier->hash, 229 GNUNET_CONTAINER_multihashmap_remove (barrier_map,
361 barrier)); 230 &barrier->hash,
231 barrier));
362 while (NULL != (ctx = barrier->head)) 232 while (NULL != (ctx = barrier->head))
363 { 233 {
364 GNUNET_CONTAINER_DLL_remove (barrier->head, barrier->tail, ctx); 234 GNUNET_CONTAINER_DLL_remove (barrier->head,
365 cleanup_clientctx (ctx); 235 barrier->tail,
236 ctx);
237 GNUNET_free (ctx);
366 } 238 }
367 GNUNET_free (barrier->name); 239 GNUNET_free (barrier->name);
368 GNUNET_SERVER_client_drop (barrier->mc);
369 GNUNET_free (barrier); 240 GNUNET_free (barrier);
370} 241}
371 242
@@ -383,7 +254,9 @@ cancel_wrappers (struct Barrier *barrier)
383 while (NULL != (wrapper = barrier->whead)) 254 while (NULL != (wrapper = barrier->whead))
384 { 255 {
385 GNUNET_TESTBED_barrier_cancel (wrapper->hbarrier); 256 GNUNET_TESTBED_barrier_cancel (wrapper->hbarrier);
386 GNUNET_CONTAINER_DLL_remove (barrier->whead, barrier->wtail, wrapper); 257 GNUNET_CONTAINER_DLL_remove (barrier->whead,
258 barrier->wtail,
259 wrapper);
387 GNUNET_free (wrapper); 260 GNUNET_free (wrapper);
388 } 261 }
389} 262}
@@ -399,29 +272,33 @@ cancel_wrappers (struct Barrier *barrier)
399 * status=GNUNET_TESTBED_BARRIERSTATUS_ERROR 272 * status=GNUNET_TESTBED_BARRIERSTATUS_ERROR
400 */ 273 */
401static void 274static void
402send_client_status_msg (struct GNUNET_SERVER_Client *client, 275send_client_status_msg (struct GNUNET_SERVICE_Client *client,
403 const char *name, 276 const char *name,
404 enum GNUNET_TESTBED_BarrierStatus status, 277 enum GNUNET_TESTBED_BarrierStatus status,
405 const char *emsg) 278 const char *emsg)
406{ 279{
280 struct GNUNET_MQ_Envelope *env;
407 struct GNUNET_TESTBED_BarrierStatusMsg *msg; 281 struct GNUNET_TESTBED_BarrierStatusMsg *msg;
408 size_t name_len; 282 size_t name_len;
409 uint16_t msize; 283 size_t err_len;
410 284
411 GNUNET_assert ((NULL == emsg) || (GNUNET_TESTBED_BARRIERSTATUS_ERROR == status)); 285 GNUNET_assert ( (NULL == emsg) ||
412 name_len = strlen (name); 286 (GNUNET_TESTBED_BARRIERSTATUS_ERROR == status) );
413 msize = sizeof (struct GNUNET_TESTBED_BarrierStatusMsg) 287 name_len = strlen (name) + 1;
414 + (name_len + 1) 288 err_len = ((NULL == emsg) ? 0 : (strlen (emsg) + 1));
415 + ((NULL == emsg) ? 0 : (strlen (emsg) + 1)); 289 env = GNUNET_MQ_msg_extra (msg,
416 msg = GNUNET_malloc (msize); 290 name_len + err_len,
417 msg->header.size = htons (msize); 291 GNUNET_MESSAGE_TYPE_TESTBED_BARRIER_STATUS);
418 msg->header.type = htons (GNUNET_MESSAGE_TYPE_TESTBED_BARRIER_STATUS);
419 msg->status = htons (status); 292 msg->status = htons (status);
420 msg->name_len = htons ((uint16_t) name_len); 293 msg->name_len = htons ((uint16_t) name_len - 1);
421 GNUNET_memcpy (msg->data, name, name_len); 294 GNUNET_memcpy (msg->data,
422 if (NULL != emsg) 295 name,
423 GNUNET_memcpy (msg->data + name_len + 1, emsg, strlen (emsg)); 296 name_len);
424 GST_queue_message (client, &msg->header); 297 GNUNET_memcpy (msg->data + name_len,
298 emsg,
299 err_len);
300 GNUNET_MQ_send (GNUNET_SERVICE_client_get_mq (client),
301 env);
425} 302}
426 303
427 304
@@ -433,82 +310,119 @@ send_client_status_msg (struct GNUNET_SERVER_Client *client,
433 * status=GNUNET_TESTBED_BARRIERSTATUS_ERROR 310 * status=GNUNET_TESTBED_BARRIERSTATUS_ERROR
434 */ 311 */
435static void 312static void
436send_barrier_status_msg (struct Barrier *barrier, const char *emsg) 313send_barrier_status_msg (struct Barrier *barrier,
314 const char *emsg)
437{ 315{
438 GNUNET_assert (0 != barrier->status); 316 GNUNET_assert (0 != barrier->status);
439 send_client_status_msg (barrier->mc, barrier->name, barrier->status, emsg); 317 send_client_status_msg (barrier->mc,
318 barrier->name,
319 barrier->status,
320 emsg);
440} 321}
441 322
442 323
443/** 324/**
444 * Message handler for GNUNET_MESSAGE_TYPE_TESTBED_BARRIER_WAIT messages. This 325 * Check #GNUNET_MESSAGE_TYPE_TESTBED_BARRIER_WAIT messages.
326 *
327 * @param cls identification of the client
328 * @param message the actual message
329 */
330static int
331check_barrier_wait (void *cls,
332 const struct GNUNET_TESTBED_BarrierWait *msg)
333{
334 return GNUNET_OK; /* always well-formed */
335}
336
337
338/**
339 * Message handler for #GNUNET_MESSAGE_TYPE_TESTBED_BARRIER_WAIT messages. This
445 * message should come from peers or a shared helper service using the 340 * message should come from peers or a shared helper service using the
446 * testbed-barrier client API (@see gnunet_testbed_barrier_service.h) 341 * testbed-barrier client API (@see gnunet_testbed_barrier_service.h)
447 * 342 *
448 * This handler is queued in the main service and will handle the messages sent 343 * This handler is queued in the main service and will handle the messages sent
449 * either from the testbed driver or from a high level controller 344 * either from the testbed driver or from a high level controller
450 * 345 *
451 * @param cls NULL 346 * @param cls identification of the client
452 * @param client identification of the client
453 * @param message the actual message 347 * @param message the actual message
454 */ 348 */
455static void 349static void
456handle_barrier_wait (void *cls, struct GNUNET_SERVER_Client *client, 350handle_barrier_wait (void *cls,
457 const struct GNUNET_MessageHeader *message) 351 const struct GNUNET_TESTBED_BarrierWait *msg)
458{ 352{
459 const struct GNUNET_TESTBED_BarrierWait *msg; 353 struct ClientCtx *client_ctx = cls;
460 struct Barrier *barrier; 354 struct Barrier *barrier;
461 char *name; 355 char *name;
462 struct ClientCtx *client_ctx;
463 struct GNUNET_HashCode key; 356 struct GNUNET_HashCode key;
464 size_t name_len; 357 size_t name_len;
465 uint16_t msize; 358 uint16_t msize;
466 359
467 msize = ntohs (message->size); 360 msize = ntohs (msg->header.size);
468 if (msize <= sizeof (struct GNUNET_TESTBED_BarrierWait))
469 {
470 GNUNET_break_op (0);
471 GNUNET_SERVER_receive_done (client, GNUNET_SYSERR);
472 return;
473 }
474 if (NULL == barrier_map) 361 if (NULL == barrier_map)
475 { 362 {
476 GNUNET_break (0); 363 GNUNET_break (0);
477 GNUNET_SERVER_receive_done (client, GNUNET_SYSERR); 364 GNUNET_SERVICE_client_drop (client_ctx->client);
478 return; 365 return;
479 } 366 }
480 msg = (const struct GNUNET_TESTBED_BarrierWait *) message;
481 name_len = msize - sizeof (struct GNUNET_TESTBED_BarrierWait); 367 name_len = msize - sizeof (struct GNUNET_TESTBED_BarrierWait);
482 name = GNUNET_malloc (name_len + 1); 368 name = GNUNET_malloc (name_len + 1);
483 name[name_len] = '\0'; 369 name[name_len] = '\0';
484 GNUNET_memcpy (name, msg->name, name_len); 370 GNUNET_memcpy (name,
485 LOG_DEBUG ("Received BARRIER_WAIT for barrier `%s'\n", name); 371 msg->name,
486 GNUNET_CRYPTO_hash (name, name_len, &key); 372 name_len);
373 LOG_DEBUG ("Received BARRIER_WAIT for barrier `%s'\n",
374 name);
375 GNUNET_CRYPTO_hash (name,
376 name_len,
377 &key);
487 GNUNET_free (name); 378 GNUNET_free (name);
488 if (NULL == (barrier = GNUNET_CONTAINER_multihashmap_get (barrier_map, &key))) 379 if (NULL == (barrier = GNUNET_CONTAINER_multihashmap_get (barrier_map, &key)))
489 { 380 {
490 GNUNET_break (0); 381 GNUNET_break (0);
491 GNUNET_SERVER_receive_done (client, GNUNET_SYSERR); 382 GNUNET_SERVICE_client_drop (client_ctx->client);
492 return; 383 return;
493 } 384 }
494 client_ctx = GNUNET_SERVER_client_get_user_context (client, struct ClientCtx); 385 if (NULL != client_ctx->barrier)
495 if (NULL == client_ctx)
496 { 386 {
497 client_ctx = GNUNET_new (struct ClientCtx); 387 GNUNET_break (0);
498 client_ctx->client = client; 388 GNUNET_SERVICE_client_drop (client_ctx->client);
499 GNUNET_SERVER_client_keep (client); 389 return;
500 client_ctx->barrier = barrier;
501 GNUNET_CONTAINER_DLL_insert_tail (barrier->head, barrier->tail, client_ctx);
502 GNUNET_SERVER_client_set_user_context (client, client_ctx);
503 } 390 }
391 client_ctx->barrier = barrier;
392 GNUNET_CONTAINER_DLL_insert_tail (barrier->head,
393 barrier->tail,
394 client_ctx);
504 barrier->nreached++; 395 barrier->nreached++;
505 if ((barrier->num_wbarriers_reached == barrier->num_wbarriers) 396 if ( (barrier->num_wbarriers_reached == barrier->num_wbarriers) &&
506 && (LOCAL_QUORUM_REACHED (barrier))) 397 (LOCAL_QUORUM_REACHED (barrier)) )
507 { 398 {
508 barrier->status = GNUNET_TESTBED_BARRIERSTATUS_CROSSED; 399 barrier->status = GNUNET_TESTBED_BARRIERSTATUS_CROSSED;
509 send_barrier_status_msg (barrier, NULL); 400 send_barrier_status_msg (barrier,
401 NULL);
510 } 402 }
511 GNUNET_SERVER_receive_done (client, GNUNET_OK); 403 GNUNET_SERVICE_client_continue (client_ctx->client);
404}
405
406
407/**
408 * Function called when a client connects to the testbed-barrier service.
409 *
410 * @param cls NULL
411 * @param client the connecting client
412 * @param mq queue to talk to @a client
413 * @return our `struct ClientCtx`
414 */
415static void *
416connect_cb (void *cls,
417 struct GNUNET_SERVICE_Client *client,
418 struct GNUNET_MQ_Handle *mq)
419{
420 struct ClientCtx *client_ctx;
421
422 LOG_DEBUG ("Client connected to testbed-barrier service\n");
423 client_ctx = GNUNET_new (struct ClientCtx);
424 client_ctx->client = client;
425 return client_ctx;
512} 426}
513 427
514 428
@@ -521,16 +435,22 @@ handle_barrier_wait (void *cls, struct GNUNET_SERVER_Client *client,
521 * for the last call when the server is destroyed 435 * for the last call when the server is destroyed
522 */ 436 */
523static void 437static void
524disconnect_cb (void *cls, struct GNUNET_SERVER_Client *client) 438disconnect_cb (void *cls,
439 struct GNUNET_SERVICE_Client *client,
440 void *app_ctx)
525{ 441{
526 struct ClientCtx *client_ctx; 442 struct ClientCtx *client_ctx = app_ctx;
443 struct Barrier *barrier = client_ctx->barrier;
527 444
528 if (NULL == client) 445 if (NULL != barrier)
529 return; 446 {
530 client_ctx = GNUNET_SERVER_client_get_user_context (client, struct ClientCtx); 447 GNUNET_CONTAINER_DLL_remove (barrier->head,
531 if (NULL == client_ctx) 448 barrier->tail,
532 return; 449 client_ctx);
533 cleanup_clientctx (client_ctx); 450 client_ctx->barrier = NULL;
451 }
452 GNUNET_free (client_ctx);
453 LOG_DEBUG ("Client disconnected from testbed-barrier service\n");
534} 454}
535 455
536 456
@@ -542,18 +462,23 @@ disconnect_cb (void *cls, struct GNUNET_SERVER_Client *client)
542void 462void
543GST_barriers_init (struct GNUNET_CONFIGURATION_Handle *cfg) 463GST_barriers_init (struct GNUNET_CONFIGURATION_Handle *cfg)
544{ 464{
545 static const struct GNUNET_SERVER_MessageHandler message_handlers[] = { 465 struct GNUNET_MQ_MessageHandler message_handlers[] = {
546 {&handle_barrier_wait, NULL, GNUNET_MESSAGE_TYPE_TESTBED_BARRIER_WAIT, 0}, 466 GNUNET_MQ_hd_var_size (barrier_wait,
547 {NULL, NULL, 0, 0} 467 GNUNET_MESSAGE_TYPE_TESTBED_BARRIER_WAIT,
468 struct GNUNET_TESTBED_BarrierWait,
469 NULL),
470 GNUNET_MQ_handler_end ()
548 }; 471 };
549 struct GNUNET_SERVER_Handle *srv; 472
550 473 LOG_DEBUG ("Launching testbed-barrier service\n");
551 barrier_map = GNUNET_CONTAINER_multihashmap_create (3, GNUNET_YES); 474 barrier_map = GNUNET_CONTAINER_multihashmap_create (3,
552 ctx = GNUNET_SERVICE_start ("testbed-barrier", cfg, 475 GNUNET_YES);
553 GNUNET_SERVICE_OPTION_MANUAL_SHUTDOWN); 476 ctx = GNUNET_SERVICE_starT ("testbed-barrier",
554 srv = GNUNET_SERVICE_get_server (ctx); 477 cfg,
555 GNUNET_SERVER_add_handlers (srv, message_handlers); 478 &connect_cb,
556 GNUNET_SERVER_disconnect_notify (srv, &disconnect_cb, NULL); 479 &disconnect_cb,
480 NULL,
481 message_handlers);
557} 482}
558 483
559 484
@@ -594,7 +519,7 @@ GST_barriers_destroy ()
594 NULL)); 519 NULL));
595 GNUNET_CONTAINER_multihashmap_destroy (barrier_map); 520 GNUNET_CONTAINER_multihashmap_destroy (barrier_map);
596 GNUNET_assert (NULL != ctx); 521 GNUNET_assert (NULL != ctx);
597 GNUNET_SERVICE_stop (ctx); 522 GNUNET_SERVICE_stoP (ctx);
598} 523}
599 524
600 525
@@ -606,13 +531,14 @@ GST_barriers_destroy ()
606 * @param cls the closure given to GNUNET_TESTBED_barrier_init() 531 * @param cls the closure given to GNUNET_TESTBED_barrier_init()
607 * @param name the name of the barrier 532 * @param name the name of the barrier
608 * @param b_ the barrier handle 533 * @param b_ the barrier handle
609 * @param status status of the barrier; GNUNET_OK if the barrier is crossed; 534 * @param status status of the barrier; #GNUNET_OK if the barrier is crossed;
610 * GNUNET_SYSERR upon error 535 * #GNUNET_SYSERR upon error
611 * @param emsg if the status were to be GNUNET_SYSERR, this parameter has the 536 * @param emsg if the status were to be #GNUNET_SYSERR, this parameter has the
612 * error messsage 537 * error messsage
613 */ 538 */
614static void 539static void
615wbarrier_status_cb (void *cls, const char *name, 540wbarrier_status_cb (void *cls,
541 const char *name,
616 struct GNUNET_TESTBED_Barrier *b_, 542 struct GNUNET_TESTBED_Barrier *b_,
617 enum GNUNET_TESTBED_BarrierStatus status, 543 enum GNUNET_TESTBED_BarrierStatus status,
618 const char *emsg) 544 const char *emsg)
@@ -622,14 +548,17 @@ wbarrier_status_cb (void *cls, const char *name,
622 548
623 GNUNET_assert (b_ == wrapper->hbarrier); 549 GNUNET_assert (b_ == wrapper->hbarrier);
624 wrapper->hbarrier = NULL; 550 wrapper->hbarrier = NULL;
625 GNUNET_CONTAINER_DLL_remove (barrier->whead, barrier->wtail, wrapper); 551 GNUNET_CONTAINER_DLL_remove (barrier->whead,
552 barrier->wtail,
553 wrapper);
626 GNUNET_free (wrapper); 554 GNUNET_free (wrapper);
627 switch (status) 555 switch (status)
628 { 556 {
629 case GNUNET_TESTBED_BARRIERSTATUS_ERROR: 557 case GNUNET_TESTBED_BARRIERSTATUS_ERROR:
630 LOG (GNUNET_ERROR_TYPE_ERROR, 558 LOG (GNUNET_ERROR_TYPE_ERROR,
631 "Initialising barrier `%s' failed at a sub-controller: %s\n", 559 "Initialising barrier `%s' failed at a sub-controller: %s\n",
632 barrier->name, (NULL != emsg) ? emsg : "NULL"); 560 barrier->name,
561 (NULL != emsg) ? emsg : "NULL");
633 cancel_wrappers (barrier); 562 cancel_wrappers (barrier);
634 if (NULL == emsg) 563 if (NULL == emsg)
635 emsg = "Initialisation failed at a sub-controller"; 564 emsg = "Initialisation failed at a sub-controller";
@@ -686,23 +615,38 @@ fwd_tout_barrier_init (void *cls)
686} 615}
687 616
688 617
618
619/**
620 * Check #GNUNET_MESSAGE_TYPE_TESTBED_BARRIER_INIT messages.
621 *
622 * @param cls identification of the client
623 * @param msg the actual message
624 * @return #GNUNET_OK if @a msg is well-formed
625 */
626int
627check_barrier_init (void *cls,
628 const struct GNUNET_TESTBED_BarrierInit *msg)
629{
630 return GNUNET_OK; /* always well-formed */
631}
632
633
689/** 634/**
690 * Message handler for GNUNET_MESSAGE_TYPE_TESTBED_BARRIER_INIT messages. This 635 * Message handler for #GNUNET_MESSAGE_TYPE_TESTBED_BARRIER_INIT messages. This
691 * message should always come from a parent controller or the testbed API if we 636 * message should always come from a parent controller or the testbed API if we
692 * are the root controller. 637 * are the root controller.
693 * 638 *
694 * This handler is queued in the main service and will handle the messages sent 639 * This handler is queued in the main service and will handle the messages sent
695 * either from the testbed driver or from a high level controller 640 * either from the testbed driver or from a high level controller
696 * 641 *
697 * @param cls NULL 642 * @param cls identification of the client
698 * @param client identification of the client 643 * @param msg the actual message
699 * @param message the actual message
700 */ 644 */
701void 645void
702GST_handle_barrier_init (void *cls, struct GNUNET_SERVER_Client *client, 646handle_barrier_init (void *cls,
703 const struct GNUNET_MessageHeader *message) 647 const struct GNUNET_TESTBED_BarrierInit *msg)
704{ 648{
705 const struct GNUNET_TESTBED_BarrierInit *msg; 649 struct GNUNET_SERVICE_Client *client = cls;
706 char *name; 650 char *name;
707 struct Barrier *barrier; 651 struct Barrier *barrier;
708 struct Slave *slave; 652 struct Slave *slave;
@@ -715,49 +659,45 @@ GST_handle_barrier_init (void *cls, struct GNUNET_SERVER_Client *client,
715 if (NULL == GST_context) 659 if (NULL == GST_context)
716 { 660 {
717 GNUNET_break_op (0); 661 GNUNET_break_op (0);
718 GNUNET_SERVER_receive_done (client, GNUNET_SYSERR); 662 GNUNET_SERVICE_client_drop (client);
719 return; 663 return;
720 } 664 }
721 if (client != GST_context->client) 665 if (client != GST_context->client)
722 { 666 {
723 GNUNET_break_op (0); 667 GNUNET_break_op (0);
724 GNUNET_SERVER_receive_done (client, GNUNET_SYSERR); 668 GNUNET_SERVICE_client_drop (client);
725 return; 669 return;
726 } 670 }
727 msize = ntohs (message->size); 671 msize = ntohs (msg->header.size);
728 if (msize <= sizeof (struct GNUNET_TESTBED_BarrierInit))
729 {
730 GNUNET_break_op (0);
731 GNUNET_SERVER_receive_done (client, GNUNET_SYSERR);
732 return;
733 }
734 msg = (const struct GNUNET_TESTBED_BarrierInit *) message;
735 name_len = (size_t) msize - sizeof (struct GNUNET_TESTBED_BarrierInit); 672 name_len = (size_t) msize - sizeof (struct GNUNET_TESTBED_BarrierInit);
736 name = GNUNET_malloc (name_len + 1); 673 name = GNUNET_malloc (name_len + 1);
737 GNUNET_memcpy (name, msg->name, name_len); 674 GNUNET_memcpy (name, msg->name, name_len);
738 GNUNET_CRYPTO_hash (name, name_len, &hash); 675 GNUNET_CRYPTO_hash (name, name_len, &hash);
739 LOG_DEBUG ("Received BARRIER_INIT for barrier `%s'\n", name); 676 LOG_DEBUG ("Received BARRIER_INIT for barrier `%s'\n",
740 if (GNUNET_YES == GNUNET_CONTAINER_multihashmap_contains (barrier_map, &hash)) 677 name);
678 if (GNUNET_YES ==
679 GNUNET_CONTAINER_multihashmap_contains (barrier_map,
680 &hash))
741 { 681 {
742 682 send_client_status_msg (client,
743 send_client_status_msg (client, name, GNUNET_TESTBED_BARRIERSTATUS_ERROR, 683 name,
684 GNUNET_TESTBED_BARRIERSTATUS_ERROR,
744 "A barrier with the same name already exists"); 685 "A barrier with the same name already exists");
745 GNUNET_free (name); 686 GNUNET_free (name);
746 GNUNET_SERVER_receive_done (client, GNUNET_OK); 687 GNUNET_SERVICE_client_continue (client);
747 return; 688 return;
748 } 689 }
749 barrier = GNUNET_new (struct Barrier); 690 barrier = GNUNET_new (struct Barrier);
750 GNUNET_memcpy (&barrier->hash, &hash, sizeof (struct GNUNET_HashCode)); 691 barrier->hash = hash;
751 barrier->quorum = msg->quorum; 692 barrier->quorum = msg->quorum;
752 barrier->name = name; 693 barrier->name = name;
753 barrier->mc = client; 694 barrier->mc = client;
754 GNUNET_SERVER_client_keep (client);
755 GNUNET_assert (GNUNET_OK == 695 GNUNET_assert (GNUNET_OK ==
756 GNUNET_CONTAINER_multihashmap_put (barrier_map, 696 GNUNET_CONTAINER_multihashmap_put (barrier_map,
757 &barrier->hash, 697 &barrier->hash,
758 barrier, 698 barrier,
759 GNUNET_CONTAINER_MULTIHASHMAPOPTION_UNIQUE_FAST)); 699 GNUNET_CONTAINER_MULTIHASHMAPOPTION_UNIQUE_FAST));
760 GNUNET_SERVER_receive_done (client, GNUNET_OK); 700 GNUNET_SERVICE_client_continue (client);
761 /* Propagate barrier init to subcontrollers */ 701 /* Propagate barrier init to subcontrollers */
762 for (cnt = 0; cnt < GST_slave_list_size; cnt++) 702 for (cnt = 0; cnt < GST_slave_list_size; cnt++)
763 { 703 {
@@ -770,7 +710,9 @@ GST_handle_barrier_init (void *cls, struct GNUNET_SERVER_Client *client,
770 } 710 }
771 wrapper = GNUNET_new (struct WBarrier); 711 wrapper = GNUNET_new (struct WBarrier);
772 wrapper->barrier = barrier; 712 wrapper->barrier = barrier;
773 GNUNET_CONTAINER_DLL_insert_tail (barrier->whead, barrier->wtail, wrapper); 713 GNUNET_CONTAINER_DLL_insert_tail (barrier->whead,
714 barrier->wtail,
715 wrapper);
774 wrapper->hbarrier = GNUNET_TESTBED_barrier_init_ (slave->controller, 716 wrapper->hbarrier = GNUNET_TESTBED_barrier_init_ (slave->controller,
775 barrier->name, 717 barrier->name,
776 barrier->quorum, 718 barrier->quorum,
@@ -792,22 +734,36 @@ GST_handle_barrier_init (void *cls, struct GNUNET_SERVER_Client *client,
792 734
793 735
794/** 736/**
795 * Message handler for GNUNET_MESSAGE_TYPE_TESTBED_BARRIER_CANCEL messages. This 737 * Check #GNUNET_MESSAGE_TYPE_TESTBED_BARRIER_CANCEL messages.
738 *
739 * @param cls identification of the client
740 * @param msg the actual message
741 * @return #GNUNET_OK if @a msg is well-formed
742 */
743int
744check_barrier_cancel (void *cls,
745 const struct GNUNET_TESTBED_BarrierCancel *msg)
746{
747 return GNUNET_OK; /* all are well-formed */
748}
749
750
751/**
752 * Message handler for #GNUNET_MESSAGE_TYPE_TESTBED_BARRIER_CANCEL messages. This
796 * message should always come from a parent controller or the testbed API if we 753 * message should always come from a parent controller or the testbed API if we
797 * are the root controller. 754 * are the root controller.
798 * 755 *
799 * This handler is queued in the main service and will handle the messages sent 756 * This handler is queued in the main service and will handle the messages sent
800 * either from the testbed driver or from a high level controller 757 * either from the testbed driver or from a high level controller
801 * 758 *
802 * @param cls NULL 759 * @param cls identification of the client
803 * @param client identification of the client 760 * @param msg the actual message
804 * @param message the actual message
805 */ 761 */
806void 762void
807GST_handle_barrier_cancel (void *cls, struct GNUNET_SERVER_Client *client, 763handle_barrier_cancel (void *cls,
808 const struct GNUNET_MessageHeader *message) 764 const struct GNUNET_TESTBED_BarrierCancel *msg)
809{ 765{
810 const struct GNUNET_TESTBED_BarrierCancel *msg; 766 struct GNUNET_SERVICE_Client *client = cls;
811 char *name; 767 char *name;
812 struct Barrier *barrier; 768 struct Barrier *barrier;
813 struct GNUNET_HashCode hash; 769 struct GNUNET_HashCode hash;
@@ -817,119 +773,140 @@ GST_handle_barrier_cancel (void *cls, struct GNUNET_SERVER_Client *client,
817 if (NULL == GST_context) 773 if (NULL == GST_context)
818 { 774 {
819 GNUNET_break_op (0); 775 GNUNET_break_op (0);
820 GNUNET_SERVER_receive_done (client, GNUNET_SYSERR); 776 GNUNET_SERVICE_client_drop (client);
821 return; 777 return;
822 } 778 }
823 if (client != GST_context->client) 779 if (client != GST_context->client)
824 { 780 {
825 GNUNET_break_op (0); 781 GNUNET_break_op (0);
826 GNUNET_SERVER_receive_done (client, GNUNET_SYSERR); 782 GNUNET_SERVICE_client_drop (client);
827 return; 783 return;
828 } 784 }
829 msize = ntohs (message->size); 785 msize = ntohs (msg->header.size);
830 if (msize <= sizeof (struct GNUNET_TESTBED_BarrierCancel))
831 {
832 GNUNET_break_op (0);
833 GNUNET_SERVER_receive_done (client, GNUNET_SYSERR);
834 return;
835 }
836 msg = (const struct GNUNET_TESTBED_BarrierCancel *) message;
837 name_len = msize - sizeof (struct GNUNET_TESTBED_BarrierCancel); 786 name_len = msize - sizeof (struct GNUNET_TESTBED_BarrierCancel);
838 name = GNUNET_malloc (name_len + 1); 787 name = GNUNET_malloc (name_len + 1);
839 GNUNET_memcpy (name, msg->name, name_len); 788 GNUNET_memcpy (name,
840 GNUNET_CRYPTO_hash (name, name_len, &hash); 789 msg->name,
841 if (GNUNET_NO == GNUNET_CONTAINER_multihashmap_contains (barrier_map, &hash)) 790 name_len);
791 LOG_DEBUG ("Received BARRIER_CANCEL for barrier `%s'\n",
792 name);
793 GNUNET_CRYPTO_hash (name,
794 name_len,
795 &hash);
796 if (GNUNET_NO ==
797 GNUNET_CONTAINER_multihashmap_contains (barrier_map,
798 &hash))
842 { 799 {
843 GNUNET_break_op (0); 800 GNUNET_break_op (0);
844 GNUNET_SERVER_receive_done (client, GNUNET_SYSERR); 801 GNUNET_SERVICE_client_drop (client);
845 return; 802 return;
846 } 803 }
847 barrier = GNUNET_CONTAINER_multihashmap_get (barrier_map, &hash); 804 barrier = GNUNET_CONTAINER_multihashmap_get (barrier_map,
805 &hash);
848 GNUNET_assert (NULL != barrier); 806 GNUNET_assert (NULL != barrier);
849 cancel_wrappers (barrier); 807 cancel_wrappers (barrier);
850 remove_barrier (barrier); 808 remove_barrier (barrier);
851 GNUNET_SERVER_receive_done (client, GNUNET_OK); 809 GNUNET_SERVICE_client_continue (client);
852} 810}
853 811
854 812
855/** 813/**
856 * Message handler for GNUNET_MESSAGE_TYPE_TESTBED_BARRIER_STATUS messages. 814 * Check #GNUNET_MESSAGE_TYPE_TESTBED_BARRIER_STATUS messages.
815 *
816 * @param cls identification of the client
817 * @param msg the actual message
818 * @return #GNUNET_OK if @a msg is well-formed
819 */
820int
821check_barrier_status (void *cls,
822 const struct GNUNET_TESTBED_BarrierStatusMsg *msg)
823{
824 uint16_t msize;
825 uint16_t name_len;
826 const char *name;
827 enum GNUNET_TESTBED_BarrierStatus status;
828
829 msize = ntohs (msg->header.size) - sizeof (*msg);
830 status = ntohs (msg->status);
831 if (GNUNET_TESTBED_BARRIERSTATUS_CROSSED != status)
832 {
833 GNUNET_break_op (0); /* current we only expect BARRIER_CROSSED
834 status message this way */
835 return GNUNET_SYSERR;
836 }
837 name = msg->data;
838 name_len = ntohs (msg->name_len);
839 if ((name_len + 1) != msize)
840 {
841 GNUNET_break_op (0);
842 return GNUNET_SYSERR;
843 }
844 if ('\0' != name[name_len])
845 {
846 GNUNET_break_op (0);
847 return GNUNET_SYSERR;
848 }
849 return GNUNET_OK;
850}
851
852
853/**
854 * Message handler for #GNUNET_MESSAGE_TYPE_TESTBED_BARRIER_STATUS messages.
857 * This handler is queued in the main service and will handle the messages sent 855 * This handler is queued in the main service and will handle the messages sent
858 * either from the testbed driver or from a high level controller 856 * either from the testbed driver or from a high level controller
859 * 857 *
860 * @param cls NULL 858 * @param cls identification of the client
861 * @param client identification of the client 859 * @param msg the actual message
862 * @param message the actual message
863 */ 860 */
864void 861void
865GST_handle_barrier_status (void *cls, 862handle_barrier_status (void *cls,
866 struct GNUNET_SERVER_Client *client, 863 const struct GNUNET_TESTBED_BarrierStatusMsg *msg)
867 const struct GNUNET_MessageHeader *message)
868{ 864{
869 const struct GNUNET_TESTBED_BarrierStatusMsg *msg; 865 struct GNUNET_SERVICE_Client *client = cls;
870 struct Barrier *barrier; 866 struct Barrier *barrier;
871 struct ClientCtx *client_ctx; 867 struct ClientCtx *client_ctx;
872 const char *name; 868 const char *name;
873 struct GNUNET_HashCode key; 869 struct GNUNET_HashCode key;
874 enum GNUNET_TESTBED_BarrierStatus status;
875 uint16_t msize;
876 uint16_t name_len; 870 uint16_t name_len;
871 struct GNUNET_MQ_Envelope *env;
877 872
878 if (NULL == GST_context) 873 if (NULL == GST_context)
879 { 874 {
880 GNUNET_break_op (0); 875 GNUNET_break_op (0);
881 GNUNET_SERVER_receive_done (client, GNUNET_SYSERR); 876 GNUNET_SERVICE_client_drop (client);
882 return; 877 return;
883 } 878 }
884 if (client != GST_context->client) 879 if (client != GST_context->client)
885 { 880 {
886 GNUNET_break_op (0); 881 GNUNET_break_op (0);
887 GNUNET_SERVER_receive_done (client, GNUNET_SYSERR); 882 GNUNET_SERVICE_client_drop (client);
888 return;
889 }
890 msize = ntohs (message->size);
891 if (msize <= sizeof (struct GNUNET_TESTBED_BarrierStatusMsg))
892 {
893 GNUNET_break_op (0);
894 GNUNET_SERVER_receive_done (client, GNUNET_SYSERR);
895 return;
896 }
897 msg = (const struct GNUNET_TESTBED_BarrierStatusMsg *) message;
898 status = ntohs (msg->status);
899 if (GNUNET_TESTBED_BARRIERSTATUS_CROSSED != status)
900 {
901 GNUNET_break_op (0); /* current we only expect BARRIER_CROSSED
902 status message this way */
903 GNUNET_SERVER_receive_done (client, GNUNET_SYSERR);
904 return; 883 return;
905 } 884 }
906 name = msg->data; 885 name = msg->data;
907 name_len = ntohs (msg->name_len); 886 name_len = ntohs (msg->name_len);
908 if ((sizeof (struct GNUNET_TESTBED_BarrierStatusMsg) + name_len + 1) != msize) 887 LOG_DEBUG ("Received BARRIER_STATUS for barrier `%s'\n",
909 { 888 name);
910 GNUNET_break_op (0); 889 GNUNET_CRYPTO_hash (name,
911 GNUNET_SERVER_receive_done (client, GNUNET_SYSERR); 890 name_len,
912 return; 891 &key);
913 } 892 barrier = GNUNET_CONTAINER_multihashmap_get (barrier_map,
914 if ('\0' != name[name_len]) 893 &key);
915 {
916 GNUNET_break_op (0);
917 GNUNET_SERVER_receive_done (client, GNUNET_SYSERR);
918 return;
919 }
920 GNUNET_CRYPTO_hash (name, name_len, &key);
921 barrier = GNUNET_CONTAINER_multihashmap_get (barrier_map, &key);
922 if (NULL == barrier) 894 if (NULL == barrier)
923 { 895 {
924 GNUNET_break_op (0); 896 GNUNET_break_op (0);
925 GNUNET_SERVER_receive_done (client, GNUNET_SYSERR); 897 GNUNET_SERVICE_client_drop (client);
926 return; 898 return;
927 } 899 }
928 GNUNET_SERVER_receive_done (client, GNUNET_OK); 900 GNUNET_SERVICE_client_continue (client);
929 while (NULL != (client_ctx = barrier->head)) /* Notify peers */ 901 while (NULL != (client_ctx = barrier->head)) /* Notify peers */
930 { 902 {
931 queue_message (client_ctx, GNUNET_copy_message (message)); 903 env = GNUNET_MQ_msg_copy (&msg->header);
932 GNUNET_CONTAINER_DLL_remove (barrier->head, barrier->tail, client_ctx); 904 GNUNET_MQ_send (GNUNET_SERVICE_client_get_mq (client),
905 env);
906 GNUNET_CONTAINER_DLL_remove (barrier->head,
907 barrier->tail,
908 client_ctx);
909 client_ctx->barrier = NULL;
933 } 910 }
934} 911}
935 912
diff --git a/src/testbed/gnunet-service-testbed_barriers.h b/src/testbed/gnunet-service-testbed_barriers.h
index ed5ba309b..2fc3222f8 100644
--- a/src/testbed/gnunet-service-testbed_barriers.h
+++ b/src/testbed/gnunet-service-testbed_barriers.h
@@ -40,55 +40,88 @@ GST_barriers_init (struct GNUNET_CONFIGURATION_Handle *cfg);
40 * Function to stop the barrier service 40 * Function to stop the barrier service
41 */ 41 */
42void 42void
43GST_barriers_destroy (); 43GST_barriers_destroy (void);
44 44
45 45
46/** 46/**
47 * Message handler for GNUNET_MESSAGE_TYPE_TESTBED_BARRIER_INIT messages. This 47 * Check #GNUNET_MESSAGE_TYPE_TESTBED_BARRIER_INIT messages.
48 *
49 * @param cls identification of the client
50 * @param msg the actual message
51 * @return #GNUNET_OK if @a msg is well-formed
52 */
53int
54check_barrier_init (void *cls,
55 const struct GNUNET_TESTBED_BarrierInit *msg);
56
57
58/**
59 * Message handler for #GNUNET_MESSAGE_TYPE_TESTBED_BARRIER_INIT messages. This
48 * message should always come from a parent controller or the testbed API if we 60 * message should always come from a parent controller or the testbed API if we
49 * are the root controller. 61 * are the root controller.
50 * 62 *
51 * This handler is queued in the main service and will handle the messages sent 63 * This handler is queued in the main service and will handle the messages sent
52 * either from the testbed driver or from a high level controller 64 * either from the testbed driver or from a high level controller
53 * 65 *
54 * @param cls NULL 66 * @param cls identification of the client
55 * @param client identification of the client 67 * @param msg the actual message
56 * @param message the actual message
57 */ 68 */
58void 69void
59GST_handle_barrier_init (void *cls, struct GNUNET_SERVER_Client *client, 70handle_barrier_init (void *cls,
60 const struct GNUNET_MessageHeader *message); 71 const struct GNUNET_TESTBED_BarrierInit *msg);
61 72
62 73
63/** 74/**
64 * Message handler for GNUNET_MESSAGE_TYPE_TESTBED_BARRIER_CANCEL messages. This 75 * Check #GNUNET_MESSAGE_TYPE_TESTBED_BARRIER_CANCEL messages.
76 *
77 * @param cls identification of the client
78 * @param msg the actual message
79 * @return #GNUNET_OK if @a msg is well-formed
80 */
81int
82check_barrier_cancel (void *cls,
83 const struct GNUNET_TESTBED_BarrierCancel *msg);
84
85
86/**
87 * Message handler for #GNUNET_MESSAGE_TYPE_TESTBED_BARRIER_CANCEL messages. This
65 * message should always come from a parent controller or the testbed API if we 88 * message should always come from a parent controller or the testbed API if we
66 * are the root controller. 89 * are the root controller.
67 * 90 *
68 * This handler is queued in the main service and will handle the messages sent 91 * This handler is queued in the main service and will handle the messages sent
69 * either from the testbed driver or from a high level controller 92 * either from the testbed driver or from a high level controller
70 * 93 *
71 * @param cls NULL 94 * @param cls identification of the client
72 * @param client identification of the client 95 * @param msg the actual message
73 * @param message the actual message
74 */ 96 */
75void 97void
76GST_handle_barrier_cancel (void *cls, struct GNUNET_SERVER_Client *client, 98handle_barrier_cancel (void *cls,
77 const struct GNUNET_MessageHeader *message); 99 const struct GNUNET_TESTBED_BarrierCancel *msg);
100
101
102/**
103 * Check #GNUNET_MESSAGE_TYPE_TESTBED_BARRIER_STATUS messages.
104 *
105 * @param cls identification of the client
106 * @param msg the actual message
107 * @return #GNUNET_OK if @a msg is well-formed
108 */
109int
110check_barrier_status (void *cls,
111 const struct GNUNET_TESTBED_BarrierStatusMsg *msg);
78 112
79 113
80/** 114/**
81 * Message handler for GNUNET_MESSAGE_TYPE_TESTBED_BARRIER_STATUS messages. 115 * Message handler for #GNUNET_MESSAGE_TYPE_TESTBED_BARRIER_STATUS messages.
82 * This handler is queued in the main service and will handle the messages sent 116 * This handler is queued in the main service and will handle the messages sent
83 * either from the testbed driver or from a high level controller 117 * either from the testbed driver or from a high level controller
84 * 118 *
85 * @param cls NULL 119 * @param cls identification of the client
86 * @param client identification of the client 120 * @param msg the actual message
87 * @param message the actual message
88 */ 121 */
89void 122void
90GST_handle_barrier_status (void *cls, struct GNUNET_SERVER_Client *client, 123handle_barrier_status (void *cls,
91 const struct GNUNET_MessageHeader *message); 124 const struct GNUNET_TESTBED_BarrierStatusMsg *msg);
92 125
93#endif /* GNUNET_SERVER_TESTBED_BARRIERS_H_ */ 126#endif /* GNUNET_SERVER_TESTBED_BARRIERS_H_ */
94 127
diff --git a/src/testbed/gnunet-service-testbed_links.c b/src/testbed/gnunet-service-testbed_links.c
index b922a8da8..3447a3f34 100644
--- a/src/testbed/gnunet-service-testbed_links.c
+++ b/src/testbed/gnunet-service-testbed_links.c
@@ -75,6 +75,16 @@ enum LCFContextState
75struct LCFContext 75struct LCFContext
76{ 76{
77 /** 77 /**
78 * The LCFContext
79 */
80 struct LCFContext *next;
81
82 /**
83 * The LCFContext
84 */
85 struct LCFContext *prev;
86
87 /**
78 * The gateway which will pass the link message to delegated host 88 * The gateway which will pass the link message to delegated host
79 */ 89 */
80 struct Slave *gateway; 90 struct Slave *gateway;
@@ -82,7 +92,7 @@ struct LCFContext
82 /** 92 /**
83 * The client which has asked to perform this operation 93 * The client which has asked to perform this operation
84 */ 94 */
85 struct GNUNET_SERVER_Client *client; 95 struct GNUNET_SERVICE_Client *client;
86 96
87 /** 97 /**
88 * Handle for operations which are forwarded while linking controllers 98 * Handle for operations which are forwarded while linking controllers
@@ -92,7 +102,7 @@ struct LCFContext
92 /** 102 /**
93 * The timeout task 103 * The timeout task
94 */ 104 */
95 struct GNUNET_SCHEDULER_Task * timeout_task; 105 struct GNUNET_SCHEDULER_Task *timeout_task;
96 106
97 /** 107 /**
98 * The id of the operation which created this context 108 * The id of the operation which created this context
@@ -123,28 +133,6 @@ struct LCFContext
123 133
124 134
125/** 135/**
126 * Structure of a queue entry in LCFContext request queue
127 */
128struct LCFContextQueue
129{
130 /**
131 * The LCFContext
132 */
133 struct LCFContext *lcf;
134
135 /**
136 * Head prt for DLL
137 */
138 struct LCFContextQueue *next;
139
140 /**
141 * Tail ptr for DLL
142 */
143 struct LCFContextQueue *prev;
144};
145
146
147/**
148 * Notification context to be used to notify when connection to the neighbour's 136 * Notification context to be used to notify when connection to the neighbour's
149 * controller is opened 137 * controller is opened
150 */ 138 */
@@ -260,12 +248,12 @@ struct NeighbourConnectCtxt
260 /** 248 /**
261 * The client requesting the connection 249 * The client requesting the connection
262 */ 250 */
263 struct GNUNET_SERVER_Client *client; 251 struct GNUNET_SERVICE_Client *client;
264 252
265 /** 253 /**
266 * Task to be run upon timeout 254 * Task to be run upon timeout
267 */ 255 */
268 struct GNUNET_SCHEDULER_Task * timeout_task; 256 struct GNUNET_SCHEDULER_Task *timeout_task;
269 257
270 /** 258 /**
271 * The notification handle associated with the neighbour's connection request 259 * The notification handle associated with the neighbour's connection request
@@ -305,14 +293,14 @@ unsigned int GST_slave_list_size;
305static struct Route **route_list; 293static struct Route **route_list;
306 294
307/** 295/**
308 * The head for the LCF queue 296 * The LCF queue
309 */ 297 */
310static struct LCFContextQueue *lcfq_head; 298static struct LCFContext *lcf_head;
311 299
312/** 300/**
313 * The tail for the LCF queue 301 * The tail for the LCF queue
314 */ 302 */
315static struct LCFContextQueue *lcfq_tail; 303static struct LCFContext *lcf_tail;
316 304
317/** 305/**
318 * The lcf_task handle 306 * The lcf_task handle
@@ -334,7 +322,8 @@ static void
334slave_list_add (struct Slave *slave) 322slave_list_add (struct Slave *slave)
335{ 323{
336 if (slave->host_id >= GST_slave_list_size) 324 if (slave->host_id >= GST_slave_list_size)
337 GST_array_grow_large_enough (GST_slave_list, GST_slave_list_size, 325 GST_array_grow_large_enough (GST_slave_list,
326 GST_slave_list_size,
338 slave->host_id); 327 slave->host_id);
339 GNUNET_assert (NULL == GST_slave_list[slave->host_id]); 328 GNUNET_assert (NULL == GST_slave_list[slave->host_id]);
340 GST_slave_list[slave->host_id] = slave; 329 GST_slave_list[slave->host_id] = slave;
@@ -342,6 +331,35 @@ slave_list_add (struct Slave *slave)
342 331
343 332
344/** 333/**
334 * Clean up all forwarded operation overlay context matching the
335 * client given in @a cls.
336 *
337 * @param cls a `struct GNUNET_SERVICE_Client *` to match
338 * @param key unused
339 * @param value the `struct RegisteredHostContext` to search for @a cls
340 * @return #GNUNET_OK (continue iterating)
341 */
342static int
343drop_client_entries (void *cls,
344 const struct GNUNET_HashCode *key,
345 void *value)
346{
347 struct GNUNET_SERVICE_Client *client = cls;
348 struct RegisteredHostContext *rhc = value;
349 struct ForwardedOverlayConnectContext *focc;
350 struct ForwardedOverlayConnectContext *foccn;
351
352 for (focc = rhc->focc_dll_head; NULL != focc; focc = foccn)
353 {
354 foccn = focc->next;
355 if (focc->client == client)
356 GST_cleanup_focc (focc);
357 }
358 return GNUNET_OK;
359}
360
361
362/**
345 * Adds a route to the route list 363 * Adds a route to the route list
346 * 364 *
347 * @param route the route to add 365 * @param route the route to add
@@ -394,12 +412,12 @@ GST_route_list_clear ()
394 * @param cls handle to the slave 412 * @param cls handle to the slave
395 * @param key current key code 413 * @param key current key code
396 * @param value value in the hash map 414 * @param value value in the hash map
397 * @return GNUNET_YES if we should continue to 415 * @return #GNUNET_YES if we should continue to iterate,
398 * iterate, 416 * #GNUNET_NO if not.
399 * GNUNET_NO if not.
400 */ 417 */
401static int 418static int
402reghost_free_iterator (void *cls, const struct GNUNET_HashCode *key, 419reghost_free_iterator (void *cls,
420 const struct GNUNET_HashCode *key,
403 void *value) 421 void *value)
404{ 422{
405 struct Slave *slave = cls; 423 struct Slave *slave = cls;
@@ -410,10 +428,7 @@ reghost_free_iterator (void *cls, const struct GNUNET_HashCode *key,
410 GNUNET_CONTAINER_multihashmap_remove (slave->reghost_map, key, 428 GNUNET_CONTAINER_multihashmap_remove (slave->reghost_map, key,
411 value)); 429 value));
412 while (NULL != (focc = rhc->focc_dll_head)) 430 while (NULL != (focc = rhc->focc_dll_head))
413 {
414 GNUNET_CONTAINER_DLL_remove (rhc->focc_dll_head, rhc->focc_dll_tail, focc);
415 GST_cleanup_focc (focc); 431 GST_cleanup_focc (focc);
416 }
417 GNUNET_free (value); 432 GNUNET_free (value);
418 return GNUNET_YES; 433 return GNUNET_YES;
419} 434}
@@ -536,12 +551,12 @@ GST_find_dest_route (uint32_t host_id)
536 * NULL if cfg is set! 551 * NULL if cfg is set!
537 */ 552 */
538static void 553static void
539send_controller_link_response (struct GNUNET_SERVER_Client *client, 554send_controller_link_response (struct GNUNET_SERVICE_Client *client,
540 uint64_t operation_id, 555 uint64_t operation_id,
541 const struct GNUNET_CONFIGURATION_Handle 556 const struct GNUNET_CONFIGURATION_Handle *cfg,
542 *cfg,
543 const char *emsg) 557 const char *emsg)
544{ 558{
559 struct GNUNET_MQ_Envelope *env;
545 struct GNUNET_TESTBED_ControllerLinkResponse *msg; 560 struct GNUNET_TESTBED_ControllerLinkResponse *msg;
546 char *xconfig; 561 char *xconfig;
547 size_t config_size; 562 size_t config_size;
@@ -552,7 +567,7 @@ send_controller_link_response (struct GNUNET_SERVER_Client *client,
552 xconfig = NULL; 567 xconfig = NULL;
553 xconfig_size = 0; 568 xconfig_size = 0;
554 config_size = 0; 569 config_size = 0;
555 msize = sizeof (struct GNUNET_TESTBED_ControllerLinkResponse); 570 msize = 0;
556 if (NULL != cfg) 571 if (NULL != cfg)
557 { 572 {
558 xconfig = GNUNET_TESTBED_compress_cfg_ (cfg, 573 xconfig = GNUNET_TESTBED_compress_cfg_ (cfg,
@@ -562,22 +577,26 @@ send_controller_link_response (struct GNUNET_SERVER_Client *client,
562 } 577 }
563 if (NULL != emsg) 578 if (NULL != emsg)
564 msize += strlen (emsg); 579 msize += strlen (emsg);
565 msg = GNUNET_malloc (msize); 580 env = GNUNET_MQ_msg_extra (msg,
566 msg->header.type = htons 581 msize,
567 (GNUNET_MESSAGE_TYPE_TESTBED_LINK_CONTROLLERS_RESULT); 582 GNUNET_MESSAGE_TYPE_TESTBED_LINK_CONTROLLERS_RESULT);
568 msg->header.size = htons (msize);
569 if (NULL == emsg) 583 if (NULL == emsg)
570 msg->success = htons (GNUNET_YES); 584 msg->success = htons (GNUNET_YES);
571 msg->operation_id = GNUNET_htonll (operation_id); 585 msg->operation_id = GNUNET_htonll (operation_id);
572 msg->config_size = htons ((uint16_t) config_size); 586 msg->config_size = htons ((uint16_t) config_size);
573 if (NULL != xconfig) 587 if (NULL != xconfig)
574 { 588 {
575 GNUNET_memcpy (&msg[1], xconfig, xconfig_size); 589 GNUNET_memcpy (&msg[1],
590 xconfig,
591 xconfig_size);
576 GNUNET_free (xconfig); 592 GNUNET_free (xconfig);
577 } 593 }
578 if (NULL != emsg) 594 if (NULL != emsg)
579 GNUNET_memcpy (&msg[1], emsg, strlen (emsg)); 595 GNUNET_memcpy (&msg[1],
580 GST_queue_message (client, &msg->header); 596 emsg,
597 strlen (emsg));
598 GNUNET_MQ_send (GNUNET_SERVICE_client_get_mq (client),
599 env);
581} 600}
582 601
583 602
@@ -597,7 +616,8 @@ lcf_proc_task (void *cls);
597 * @param emsg the error message; NULL if host registration is successful 616 * @param emsg the error message; NULL if host registration is successful
598 */ 617 */
599static void 618static void
600lcf_proc_cc (void *cls, const char *emsg) 619lcf_proc_cc (void *cls,
620 const char *emsg)
601{ 621{
602 struct LCFContext *lcf = cls; 622 struct LCFContext *lcf = cls;
603 623
@@ -622,10 +642,12 @@ lcf_proc_cc (void *cls, const char *emsg)
622 return; 642 return;
623 643
624registration_error: 644registration_error:
625 LOG (GNUNET_ERROR_TYPE_WARNING, "Host registration failed with message: %s\n", 645 LOG (GNUNET_ERROR_TYPE_WARNING,
646 "Host registration failed with message: %s\n",
626 emsg); 647 emsg);
627 lcf->state = FINISHED; 648 lcf->state = FINISHED;
628 lcf_proc_task_id = GNUNET_SCHEDULER_add_now (&lcf_proc_task, lcf); 649 lcf_proc_task_id = GNUNET_SCHEDULER_add_now (&lcf_proc_task,
650 lcf);
629} 651}
630 652
631 653
@@ -652,11 +674,13 @@ lcf_forwarded_operation_timeout (void *cls)
652 // GST_forwarded_operation_timeout (lcf->fopc, tc); 674 // GST_forwarded_operation_timeout (lcf->fopc, tc);
653 LOG (GNUNET_ERROR_TYPE_WARNING, 675 LOG (GNUNET_ERROR_TYPE_WARNING,
654 "A forwarded controller link operation has timed out\n"); 676 "A forwarded controller link operation has timed out\n");
655 send_controller_link_response (lcf->client, lcf->operation_id, NULL, 677 send_controller_link_response (lcf->client,
656 "A forwarded controller link operation has " 678 lcf->operation_id,
657 "timed out\n"); 679 NULL,
680 "A forwarded controller link operation has timed out\n");
658 GNUNET_assert (NULL == lcf_proc_task_id); 681 GNUNET_assert (NULL == lcf_proc_task_id);
659 lcf_proc_task_id = GNUNET_SCHEDULER_add_now (&lcf_proc_task, lcf); 682 lcf_proc_task_id = GNUNET_SCHEDULER_add_now (&lcf_proc_task,
683 lcf);
660} 684}
661 685
662 686
@@ -669,7 +693,6 @@ static void
669lcf_proc_task (void *cls) 693lcf_proc_task (void *cls)
670{ 694{
671 struct LCFContext *lcf = cls; 695 struct LCFContext *lcf = cls;
672 struct LCFContextQueue *lcfq;
673 696
674 lcf_proc_task_id = NULL; 697 lcf_proc_task_id = NULL;
675 switch (lcf->state) 698 switch (lcf->state)
@@ -710,22 +733,21 @@ lcf_proc_task (void *cls)
710 GST_host_list[lcf->slave_host_id], 733 GST_host_list[lcf->slave_host_id],
711 lcf->is_subordinate); 734 lcf->is_subordinate);
712 lcf->timeout_task = 735 lcf->timeout_task =
713 GNUNET_SCHEDULER_add_delayed (GST_timeout, &lcf_forwarded_operation_timeout, 736 GNUNET_SCHEDULER_add_delayed (GST_timeout,
737 &lcf_forwarded_operation_timeout,
714 lcf); 738 lcf);
715 lcf->state = FINISHED; 739 lcf->state = FINISHED;
716 break; 740 break;
717 case FINISHED: 741 case FINISHED:
718 lcfq = lcfq_head;
719 GNUNET_assert (lcfq->lcf == lcf);
720 GNUNET_SERVER_client_drop (lcf->client);
721 if (NULL != lcf->op) 742 if (NULL != lcf->op)
722 GNUNET_TESTBED_operation_done (lcf->op); 743 GNUNET_TESTBED_operation_done (lcf->op);
744 GNUNET_CONTAINER_DLL_remove (lcf_head,
745 lcf_tail,
746 lcf);
723 GNUNET_free (lcf); 747 GNUNET_free (lcf);
724 GNUNET_CONTAINER_DLL_remove (lcfq_head, lcfq_tail, lcfq); 748 if (NULL != lcf_head)
725 GNUNET_free (lcfq); 749 lcf_proc_task_id = GNUNET_SCHEDULER_add_now (&lcf_proc_task,
726 if (NULL != lcfq_head) 750 lcf_head);
727 lcf_proc_task_id =
728 GNUNET_SCHEDULER_add_now (&lcf_proc_task, lcfq_head->lcf);
729 } 751 }
730} 752}
731 753
@@ -770,12 +792,13 @@ slave_event_cb (void *cls, const struct GNUNET_TESTBED_EventInformation *event)
770 * 792 *
771 * @param cls the handle to the slave whose status is to be found here 793 * @param cls the handle to the slave whose status is to be found here
772 * @param cfg the configuration with which the controller has been started; 794 * @param cfg the configuration with which the controller has been started;
773 * NULL if status is not GNUNET_OK 795 * NULL if status is not #GNUNET_OK
774 * @param status GNUNET_OK if the startup is successfull; GNUNET_SYSERR if not, 796 * @param status #GNUNET_OK if the startup is successfull; #GNUNET_SYSERR if not,
775 * GNUNET_TESTBED_controller_stop() shouldn't be called in this case 797 * GNUNET_TESTBED_controller_stop() shouldn't be called in this case
776 */ 798 */
777static void 799static void
778slave_status_cb (void *cls, const struct GNUNET_CONFIGURATION_Handle *cfg, 800slave_status_cb (void *cls,
801 const struct GNUNET_CONFIGURATION_Handle *cfg,
779 int status) 802 int status)
780{ 803{
781 struct Slave *slave = cls; 804 struct Slave *slave = cls;
@@ -789,7 +812,7 @@ slave_status_cb (void *cls, const struct GNUNET_CONFIGURATION_Handle *cfg,
789 and as these tasks they depend on the operation queues which are created 812 and as these tasks they depend on the operation queues which are created
790 through GNUNET_TESTBED_controller_connect() and in kill_slave() we call 813 through GNUNET_TESTBED_controller_connect() and in kill_slave() we call
791 the destructor function GNUNET_TESTBED_controller_disconnect() */ 814 the destructor function GNUNET_TESTBED_controller_disconnect() */
792 GST_free_lcfq (); 815 GST_free_lcf ();
793 kill_slave (slave); 816 kill_slave (slave);
794 destroy_slave (slave); 817 destroy_slave (slave);
795 slave = NULL; 818 slave = NULL;
@@ -819,8 +842,7 @@ slave_status_cb (void *cls, const struct GNUNET_CONFIGURATION_Handle *cfg,
819 { 842 {
820 if (NULL != lcc->client) 843 if (NULL != lcc->client)
821 { 844 {
822 GNUNET_SERVER_receive_done (lcc->client, GNUNET_OK); 845 GNUNET_SERVICE_client_continue (lcc->client);
823 GNUNET_SERVER_client_drop (lcc->client);
824 lcc->client = NULL; 846 lcc->client = NULL;
825 } 847 }
826 GNUNET_free (lcc); 848 GNUNET_free (lcc);
@@ -1051,8 +1073,9 @@ cleanup_ncc (struct NeighbourConnectCtxt *ncc)
1051 GST_neighbour_get_connection_cancel (ncc->nh); 1073 GST_neighbour_get_connection_cancel (ncc->nh);
1052 if (NULL != ncc->timeout_task) 1074 if (NULL != ncc->timeout_task)
1053 GNUNET_SCHEDULER_cancel (ncc->timeout_task); 1075 GNUNET_SCHEDULER_cancel (ncc->timeout_task);
1054 GNUNET_SERVER_client_drop (ncc->client); 1076 GNUNET_CONTAINER_DLL_remove (ncc_head,
1055 GNUNET_CONTAINER_DLL_remove (ncc_head, ncc_tail, ncc); 1077 ncc_tail,
1078 ncc);
1056 GNUNET_free (ncc); 1079 GNUNET_free (ncc);
1057} 1080}
1058 1081
@@ -1061,7 +1084,7 @@ cleanup_ncc (struct NeighbourConnectCtxt *ncc)
1061 * Cleans up the neighbour list 1084 * Cleans up the neighbour list
1062 */ 1085 */
1063void 1086void
1064GST_neighbour_list_clean() 1087GST_neighbour_list_clean ()
1065{ 1088{
1066 struct Neighbour *n; 1089 struct Neighbour *n;
1067 unsigned int id; 1090 unsigned int id;
@@ -1091,8 +1114,7 @@ GST_get_neighbour (uint32_t id)
1091{ 1114{
1092 if (neighbour_list_size <= id) 1115 if (neighbour_list_size <= id)
1093 return NULL; 1116 return NULL;
1094 else 1117 return neighbour_list[id];
1095 return neighbour_list[id];
1096} 1118}
1097 1119
1098 1120
@@ -1118,7 +1140,9 @@ timeout_neighbour_connect (void *cls)
1118 struct NeighbourConnectCtxt *ncc = cls; 1140 struct NeighbourConnectCtxt *ncc = cls;
1119 1141
1120 ncc->timeout_task = NULL; 1142 ncc->timeout_task = NULL;
1121 send_controller_link_response (ncc->client, ncc->op_id, NULL, 1143 send_controller_link_response (ncc->client,
1144 ncc->op_id,
1145 NULL,
1122 "Could not connect to delegated controller"); 1146 "Could not connect to delegated controller");
1123 cleanup_ncc (ncc); 1147 cleanup_ncc (ncc);
1124} 1148}
@@ -1131,7 +1155,8 @@ timeout_neighbour_connect (void *cls)
1131 * @param c the handle the neighbour's controller 1155 * @param c the handle the neighbour's controller
1132 */ 1156 */
1133static void 1157static void
1134neighbour_connect_cb (void *cls, struct GNUNET_TESTBED_Controller *c) 1158neighbour_connect_cb (void *cls,
1159 struct GNUNET_TESTBED_Controller *c)
1135{ 1160{
1136 struct NeighbourConnectCtxt *ncc = cls; 1161 struct NeighbourConnectCtxt *ncc = cls;
1137 1162
@@ -1139,7 +1164,10 @@ neighbour_connect_cb (void *cls, struct GNUNET_TESTBED_Controller *c)
1139 ncc->timeout_task = NULL; 1164 ncc->timeout_task = NULL;
1140 ncc->nh = NULL; 1165 ncc->nh = NULL;
1141 GST_neighbour_release_connection (ncc->n); 1166 GST_neighbour_release_connection (ncc->n);
1142 send_controller_link_response (ncc->client, ncc->op_id, NULL, NULL); 1167 send_controller_link_response (ncc->client,
1168 ncc->op_id,
1169 NULL,
1170 NULL);
1143 cleanup_ncc (ncc); 1171 cleanup_ncc (ncc);
1144} 1172}
1145 1173
@@ -1162,18 +1190,17 @@ GST_create_neighbour (struct GNUNET_TESTBED_Host *host)
1162 1190
1163 1191
1164/** 1192/**
1165 * Message handler for GNUNET_MESSAGE_TYPE_TESTBED_LCONTROLLERS message 1193 * Message handler for #GNUNET_MESSAGE_TYPE_TESTBED_LCONTROLLERS message
1166 * 1194 *
1167 * @param cls NULL 1195 * @param cls identification of the client
1168 * @param client identification of the client 1196 * @param msg the actual message
1169 * @param message the actual message
1170 */ 1197 */
1171void 1198void
1172GST_handle_link_controllers (void *cls, struct GNUNET_SERVER_Client *client, 1199handle_link_controllers (void *cls,
1173 const struct GNUNET_MessageHeader *message) 1200 const struct GNUNET_TESTBED_ControllerLinkRequest *msg)
1174{ 1201{
1175 const struct GNUNET_TESTBED_ControllerLinkRequest *msg; 1202 struct GNUNET_SERVICE_Client *client = cls;
1176 struct LCFContextQueue *lcfq; 1203 struct LCFContext *lcf;
1177 struct Route *route; 1204 struct Route *route;
1178 struct Route *new_route; 1205 struct Route *new_route;
1179 uint64_t op_id; 1206 uint64_t op_id;
@@ -1183,39 +1210,42 @@ GST_handle_link_controllers (void *cls, struct GNUNET_SERVER_Client *client,
1183 if (NULL == GST_context) 1210 if (NULL == GST_context)
1184 { 1211 {
1185 GNUNET_break (0); 1212 GNUNET_break (0);
1186 GNUNET_SERVER_receive_done (client, GNUNET_SYSERR); 1213 GNUNET_SERVICE_client_drop (client);
1187 return; 1214 return;
1188 } 1215 }
1189 msg = (const struct GNUNET_TESTBED_ControllerLinkRequest *) message;
1190 delegated_host_id = ntohl (msg->delegated_host_id); 1216 delegated_host_id = ntohl (msg->delegated_host_id);
1191 if (delegated_host_id == GST_context->host_id) 1217 if (delegated_host_id == GST_context->host_id)
1192 { 1218 {
1193 GNUNET_break (0); 1219 GNUNET_break (0);
1194 LOG (GNUNET_ERROR_TYPE_WARNING, "Trying to link ourselves\n"); 1220 LOG (GNUNET_ERROR_TYPE_WARNING,
1195 GNUNET_SERVER_receive_done (client, GNUNET_SYSERR); 1221 "Trying to link ourselves\n");
1222 GNUNET_SERVICE_client_drop (client);
1196 return; 1223 return;
1197 } 1224 }
1198 if ((delegated_host_id >= GST_host_list_size) || 1225 if ((delegated_host_id >= GST_host_list_size) ||
1199 (NULL == GST_host_list[delegated_host_id])) 1226 (NULL == GST_host_list[delegated_host_id]))
1200 { 1227 {
1201 LOG (GNUNET_ERROR_TYPE_WARNING, 1228 LOG (GNUNET_ERROR_TYPE_WARNING,
1202 "Delegated host %u not registered with us\n", delegated_host_id); 1229 "Delegated host %u not registered with us\n",
1203 GNUNET_SERVER_receive_done (client, GNUNET_SYSERR); 1230 delegated_host_id);
1231 GNUNET_SERVICE_client_drop (client);
1204 return; 1232 return;
1205 } 1233 }
1206 slave_host_id = ntohl (msg->slave_host_id); 1234 slave_host_id = ntohl (msg->slave_host_id);
1207 if ((slave_host_id >= GST_host_list_size) || 1235 if ((slave_host_id >= GST_host_list_size) ||
1208 (NULL == GST_host_list[slave_host_id])) 1236 (NULL == GST_host_list[slave_host_id]))
1209 { 1237 {
1210 LOG (GNUNET_ERROR_TYPE_WARNING, "Slave host %u not registered with us\n", 1238 LOG (GNUNET_ERROR_TYPE_WARNING,
1239 "Slave host %u not registered with us\n",
1211 slave_host_id); 1240 slave_host_id);
1212 GNUNET_SERVER_receive_done (client, GNUNET_SYSERR); 1241 GNUNET_SERVICE_client_drop (client);
1213 return; 1242 return;
1214 } 1243 }
1215 if (slave_host_id == delegated_host_id) 1244 if (slave_host_id == delegated_host_id)
1216 { 1245 {
1217 LOG (GNUNET_ERROR_TYPE_WARNING, "Slave and delegated host are same\n"); 1246 LOG (GNUNET_ERROR_TYPE_WARNING,
1218 GNUNET_SERVER_receive_done (client, GNUNET_SYSERR); 1247 "Slave and delegated host are same\n");
1248 GNUNET_SERVICE_client_drop (client);
1219 return; 1249 return;
1220 } 1250 }
1221 op_id = GNUNET_ntohll (msg->operation_id); 1251 op_id = GNUNET_ntohll (msg->operation_id);
@@ -1224,7 +1254,6 @@ GST_handle_link_controllers (void *cls, struct GNUNET_SERVER_Client *client,
1224 struct Slave *slave; 1254 struct Slave *slave;
1225 struct LinkControllersContext *lcc; 1255 struct LinkControllersContext *lcc;
1226 1256
1227
1228 if (1 != msg->is_subordinate) 1257 if (1 != msg->is_subordinate)
1229 { 1258 {
1230 struct Neighbour *n; 1259 struct Neighbour *n;
@@ -1234,7 +1263,7 @@ GST_handle_link_controllers (void *cls, struct GNUNET_SERVER_Client *client,
1234 (NULL != neighbour_list[delegated_host_id])) 1263 (NULL != neighbour_list[delegated_host_id]))
1235 { 1264 {
1236 GNUNET_break (0); 1265 GNUNET_break (0);
1237 GNUNET_SERVER_receive_done (client, GNUNET_SYSERR); 1266 GNUNET_SERVICE_client_drop (client);
1238 return; 1267 return;
1239 } 1268 }
1240 LOG_DEBUG ("Received request to establish a link to host %u\n", 1269 LOG_DEBUG ("Received request to establish a link to host %u\n",
@@ -1244,37 +1273,42 @@ GST_handle_link_controllers (void *cls, struct GNUNET_SERVER_Client *client,
1244 ncc->n = n; 1273 ncc->n = n;
1245 ncc->op_id = op_id; 1274 ncc->op_id = op_id;
1246 ncc->client = client; 1275 ncc->client = client;
1247 GNUNET_SERVER_client_keep (client); 1276 ncc->nh = GST_neighbour_get_connection (n,
1248 ncc->nh = GST_neighbour_get_connection (n, neighbour_connect_cb, ncc); 1277 &neighbour_connect_cb,
1249 ncc->timeout_task = GNUNET_SCHEDULER_add_delayed (GST_timeout, 1278 ncc);
1250 &timeout_neighbour_connect, 1279 ncc->timeout_task
1251 ncc); 1280 = GNUNET_SCHEDULER_add_delayed (GST_timeout,
1252 GNUNET_CONTAINER_DLL_insert_tail (ncc_head, ncc_tail, ncc); 1281 &timeout_neighbour_connect,
1253 GNUNET_SERVER_receive_done (client, GNUNET_OK); 1282 ncc);
1283 GNUNET_CONTAINER_DLL_insert_tail (ncc_head,
1284 ncc_tail,
1285 ncc);
1286 GNUNET_SERVICE_client_continue (client);
1254 return; 1287 return;
1255 } 1288 }
1256 if ((delegated_host_id < GST_slave_list_size) && 1289 if ( (delegated_host_id < GST_slave_list_size) &&
1257 (NULL != GST_slave_list[delegated_host_id])) 1290 (NULL != GST_slave_list[delegated_host_id]) )
1258 { 1291 {
1259 GNUNET_break (0); 1292 GNUNET_break (0);
1260 GNUNET_SERVER_receive_done (client, GNUNET_SYSERR); 1293 GNUNET_SERVICE_client_drop (client);
1261 return; 1294 return;
1262 } 1295 }
1263 LOG_DEBUG ("Received request to start and establish a link to host %u\n", 1296 LOG_DEBUG ("Received request to start and establish a link to host %u\n",
1264 delegated_host_id); 1297 delegated_host_id);
1265 slave = GNUNET_new (struct Slave); 1298 slave = GNUNET_new (struct Slave);
1266 slave->host_id = delegated_host_id; 1299 slave->host_id = delegated_host_id;
1267 slave->reghost_map = GNUNET_CONTAINER_multihashmap_create (100, GNUNET_NO); 1300 slave->reghost_map = GNUNET_CONTAINER_multihashmap_create (100,
1301 GNUNET_NO);
1268 slave_list_add (slave); 1302 slave_list_add (slave);
1269 lcc = GNUNET_new (struct LinkControllersContext); 1303 lcc = GNUNET_new (struct LinkControllersContext);
1270 lcc->operation_id = op_id; 1304 lcc->operation_id = op_id;
1271 GNUNET_SERVER_client_keep (client);
1272 lcc->client = client; 1305 lcc->client = client;
1273 slave->lcc = lcc; 1306 slave->lcc = lcc;
1274 slave->controller_proc = 1307 slave->controller_proc
1275 GNUNET_TESTBED_controller_start (GST_context->master_ip, 1308 = GNUNET_TESTBED_controller_start (GST_context->master_ip,
1276 GST_host_list[slave->host_id], 1309 GST_host_list[slave->host_id],
1277 &slave_status_cb, slave); 1310 &slave_status_cb,
1311 slave);
1278 new_route = GNUNET_new (struct Route); 1312 new_route = GNUNET_new (struct Route);
1279 new_route->dest = delegated_host_id; 1313 new_route->dest = delegated_host_id;
1280 new_route->thru = GST_context->host_id; 1314 new_route->thru = GST_context->host_id;
@@ -1285,52 +1319,114 @@ GST_handle_link_controllers (void *cls, struct GNUNET_SERVER_Client *client,
1285 /* Route the request */ 1319 /* Route the request */
1286 if (slave_host_id >= route_list_size) 1320 if (slave_host_id >= route_list_size)
1287 { 1321 {
1288 LOG (GNUNET_ERROR_TYPE_WARNING, "No route towards slave host"); 1322 LOG (GNUNET_ERROR_TYPE_WARNING,
1289 GNUNET_SERVER_receive_done (client, GNUNET_SYSERR); 1323 "No route towards slave host");
1324 GNUNET_SERVICE_client_drop (client);
1290 return; 1325 return;
1291 } 1326 }
1292 lcfq = GNUNET_new (struct LCFContextQueue); 1327 lcf = GNUNET_new (struct LCFContext);
1293 lcfq->lcf = GNUNET_new (struct LCFContext); 1328 lcf->delegated_host_id = delegated_host_id;
1294 lcfq->lcf->delegated_host_id = delegated_host_id; 1329 lcf->slave_host_id = slave_host_id;
1295 lcfq->lcf->slave_host_id = slave_host_id;
1296 route = GST_find_dest_route (slave_host_id); 1330 route = GST_find_dest_route (slave_host_id);
1297 GNUNET_assert (NULL != route); /* because we add routes carefully */ 1331 GNUNET_assert (NULL != route); /* because we add routes carefully */
1298 GNUNET_assert (route->dest < GST_slave_list_size); 1332 GNUNET_assert (route->dest < GST_slave_list_size);
1299 GNUNET_assert (NULL != GST_slave_list[route->dest]); 1333 GNUNET_assert (NULL != GST_slave_list[route->dest]);
1300 lcfq->lcf->is_subordinate = msg->is_subordinate; 1334 lcf->is_subordinate = msg->is_subordinate;
1301 lcfq->lcf->state = INIT; 1335 lcf->state = INIT;
1302 lcfq->lcf->operation_id = op_id; 1336 lcf->operation_id = op_id;
1303 lcfq->lcf->gateway = GST_slave_list[route->dest]; 1337 lcf->gateway = GST_slave_list[route->dest];
1304 GNUNET_SERVER_client_keep (client); 1338 lcf->client = client;
1305 lcfq->lcf->client = client; 1339 if (NULL == lcf_head)
1306 if (NULL == lcfq_head)
1307 { 1340 {
1308 GNUNET_assert (NULL == lcf_proc_task_id); 1341 GNUNET_assert (NULL == lcf_proc_task_id);
1309 GNUNET_CONTAINER_DLL_insert_tail (lcfq_head, lcfq_tail, lcfq); 1342 GNUNET_CONTAINER_DLL_insert_tail (lcf_head,
1310 lcf_proc_task_id = GNUNET_SCHEDULER_add_now (&lcf_proc_task, lcfq->lcf); 1343 lcf_tail,
1344 lcf);
1345 lcf_proc_task_id = GNUNET_SCHEDULER_add_now (&lcf_proc_task,
1346 lcf);
1311 } 1347 }
1312 else 1348 else
1313 GNUNET_CONTAINER_DLL_insert_tail (lcfq_head, lcfq_tail, lcfq); 1349 {
1350 GNUNET_CONTAINER_DLL_insert_tail (lcf_head,
1351 lcf_tail,
1352 lcf);
1353 }
1314 /* FIXME: Adding a new route should happen after the controllers are linked 1354 /* FIXME: Adding a new route should happen after the controllers are linked
1315 * successfully */ 1355 * successfully */
1316 if (1 != msg->is_subordinate) 1356 if (1 != msg->is_subordinate)
1317 { 1357 {
1318 GNUNET_SERVER_receive_done (client, GNUNET_OK); 1358 GNUNET_SERVICE_client_continue (client);
1319 return; 1359 return;
1320 } 1360 }
1321 if ((delegated_host_id < route_list_size) && 1361 if ( (delegated_host_id < route_list_size) &&
1322 (NULL != route_list[delegated_host_id])) 1362 (NULL != route_list[delegated_host_id]) )
1323 { 1363 {
1324 GNUNET_break_op (0); /* Are you trying to link delegated host twice 1364 GNUNET_break_op (0); /* Are you trying to link delegated host twice
1325 * with is subordinate flag set to GNUNET_YES? */ 1365 * with is subordinate flag set to GNUNET_YES? */
1326 GNUNET_SERVER_receive_done (client, GNUNET_SYSERR); 1366 GNUNET_SERVICE_client_drop (client);
1327 return; 1367 return;
1328 } 1368 }
1329 new_route = GNUNET_new (struct Route); 1369 new_route = GNUNET_new (struct Route);
1330 new_route->dest = delegated_host_id; 1370 new_route->dest = delegated_host_id;
1331 new_route->thru = route->dest; 1371 new_route->thru = route->dest;
1332 route_list_add (new_route); 1372 route_list_add (new_route);
1333 GNUNET_SERVER_receive_done (client, GNUNET_OK); 1373 GNUNET_SERVICE_client_continue (client);
1374}
1375
1376
1377/**
1378 * Clean up @a client handle if we stored any via #handle_link_controllers(),
1379 * the given client disconnected.
1380 *
1381 * @param client the client that is history
1382 */
1383void
1384GST_link_notify_disconnect (struct GNUNET_SERVICE_Client *client)
1385{
1386 struct NeighbourConnectCtxt *ncc;
1387 struct NeighbourConnectCtxt *nccn;
1388 struct LCFContext *lcf;
1389 struct LCFContext *lcfn;
1390
1391 for (ncc = ncc_head; NULL != ncc; ncc = nccn)
1392 {
1393 nccn = ncc->next;
1394 if (ncc->client == client)
1395 cleanup_ncc (ncc);
1396 }
1397 for (unsigned int i=0;i<GST_slave_list_size;i++)
1398 {
1399 struct Slave *slave = GST_slave_list[i];
1400 struct LinkControllersContext *lcc;
1401
1402 if (NULL == slave)
1403 continue;
1404 GNUNET_CONTAINER_multihashmap_iterate (slave->reghost_map,
1405 &drop_client_entries,
1406 client);
1407 lcc = slave->lcc;
1408 if (NULL == lcc)
1409 continue;
1410 if (lcc->client == client)
1411 {
1412 slave->lcc = NULL;
1413 GNUNET_free (lcc);
1414 }
1415 }
1416 for (lcf = lcf_head; NULL != lcf; lcf = lcfn)
1417 {
1418 lcfn = lcf->next;
1419 if ( (NULL != lcf) &&
1420 (client == lcf->client) )
1421 {
1422 if (NULL != lcf->op)
1423 GNUNET_TESTBED_operation_done (lcf->op);
1424 GNUNET_CONTAINER_DLL_remove (lcf_head,
1425 lcf_tail,
1426 lcf);
1427 GNUNET_free (lcf);
1428 }
1429 }
1334} 1430}
1335 1431
1336 1432
@@ -1338,12 +1434,11 @@ GST_handle_link_controllers (void *cls, struct GNUNET_SERVER_Client *client,
1338 * Cleans up the queue used for forwarding link controllers requests 1434 * Cleans up the queue used for forwarding link controllers requests
1339 */ 1435 */
1340void 1436void
1341GST_free_lcfq () 1437GST_free_lcf ()
1342{ 1438{
1343 struct LCFContextQueue *lcfq;
1344 struct LCFContext *lcf; 1439 struct LCFContext *lcf;
1345 1440
1346 if (NULL != lcfq_head) 1441 if (NULL != lcf_head)
1347 { 1442 {
1348 if (NULL != lcf_proc_task_id) 1443 if (NULL != lcf_proc_task_id)
1349 { 1444 {
@@ -1352,16 +1447,15 @@ GST_free_lcfq ()
1352 } 1447 }
1353 } 1448 }
1354 GNUNET_assert (NULL == lcf_proc_task_id); 1449 GNUNET_assert (NULL == lcf_proc_task_id);
1355 for (lcfq = lcfq_head; NULL != lcfq; lcfq = lcfq_head) 1450 for (lcf = lcf_head; NULL != lcf; lcf = lcf_head)
1356 { 1451 {
1357 lcf = lcfq->lcf;
1358 GNUNET_SERVER_client_drop (lcf->client);
1359 if (NULL != lcf->op) 1452 if (NULL != lcf->op)
1360 GNUNET_TESTBED_operation_done (lcf->op); 1453 GNUNET_TESTBED_operation_done (lcf->op);
1361 if (NULL != lcf->timeout_task) 1454 if (NULL != lcf->timeout_task)
1362 GNUNET_SCHEDULER_cancel (lcf->timeout_task); 1455 GNUNET_SCHEDULER_cancel (lcf->timeout_task);
1456 GNUNET_CONTAINER_DLL_remove (lcf_head,
1457 lcf_tail,
1458 lcf);
1363 GNUNET_free (lcf); 1459 GNUNET_free (lcf);
1364 GNUNET_CONTAINER_DLL_remove (lcfq_head, lcfq_tail, lcfq);
1365 GNUNET_free (lcfq);
1366 } 1460 }
1367} 1461}
diff --git a/src/testbed/gnunet-service-testbed_links.h b/src/testbed/gnunet-service-testbed_links.h
index b39851ed7..09764b99a 100644
--- a/src/testbed/gnunet-service-testbed_links.h
+++ b/src/testbed/gnunet-service-testbed_links.h
@@ -94,7 +94,7 @@ extern unsigned int GST_slave_list_size;
94 * Cleans up the neighbour list 94 * Cleans up the neighbour list
95 */ 95 */
96void 96void
97GST_neighbour_list_clean(); 97GST_neighbour_list_clean (void);
98 98
99 99
100/** 100/**
@@ -112,7 +112,7 @@ GST_get_neighbour (uint32_t id);
112 * Function to cleanup the neighbour connect contexts 112 * Function to cleanup the neighbour connect contexts
113 */ 113 */
114void 114void
115GST_free_nccq (); 115GST_free_nccq (void);
116 116
117 117
118/** 118/**
@@ -128,10 +128,9 @@ struct NeighbourConnectNotification;
128 * @param cls the closure given to GST_neighbour_get_connection() 128 * @param cls the closure given to GST_neighbour_get_connection()
129 * @param controller the controller handle to the neighbour 129 * @param controller the controller handle to the neighbour
130 */ 130 */
131typedef void (*GST_NeigbourConnectNotifyCallback) (void *cls, 131typedef void
132 struct 132(*GST_NeigbourConnectNotifyCallback) (void *cls,
133 GNUNET_TESTBED_Controller 133 struct GNUNET_TESTBED_Controller *controller);
134 *controller);
135 134
136 135
137/** 136/**
@@ -181,19 +180,28 @@ GST_create_neighbour (struct GNUNET_TESTBED_Host *host);
181 180
182 181
183/** 182/**
184 * Message handler for GNUNET_MESSAGE_TYPE_TESTBED_LCONTROLLERS message 183 * Message handler for #GNUNET_MESSAGE_TYPE_TESTBED_LCONTROLLERS message
185 * 184 *
186 * @param cls NULL 185 * @param cls identification of the client
187 * @param client identification of the client 186 * @param msg the actual message
188 * @param message the actual message
189 */ 187 */
190void 188void
191GST_handle_link_controllers (void *cls, struct GNUNET_SERVER_Client *client, 189handle_link_controllers (void *cls,
192 const struct GNUNET_MessageHeader *message); 190 const struct GNUNET_TESTBED_ControllerLinkRequest *msg);
191
192
193/**
194 * Clean up @a client handle if we stored any via #handle_link_controllers(),
195 * the given client disconnected.
196 *
197 * @param client the client that is history
198 */
199void
200GST_link_notify_disconnect (struct GNUNET_SERVICE_Client *client);
193 201
194 202
195/** 203/**
196 * Cleans up the slave list 204 * Cleans up the slave list
197 */ 205 */
198void 206void
199GST_slave_list_clear (); 207GST_slave_list_clear (void);
diff --git a/src/testbed/gnunet-service-testbed_oc.c b/src/testbed/gnunet-service-testbed_oc.c
index c681c3810..b775f31bd 100644
--- a/src/testbed/gnunet-service-testbed_oc.c
+++ b/src/testbed/gnunet-service-testbed_oc.c
@@ -168,7 +168,7 @@ struct OverlayConnectContext
168 * The client which has requested for overlay connection. This is used to send 168 * The client which has requested for overlay connection. This is used to send
169 * either a success of failure message 169 * either a success of failure message
170 */ 170 */
171 struct GNUNET_SERVER_Client *client; 171 struct GNUNET_SERVICE_Client *client;
172 172
173 /** 173 /**
174 * the first peer which is to expect an overlay connection from the second peer. 174 * the first peer which is to expect an overlay connection from the second peer.
@@ -358,7 +358,11 @@ static struct RemoteOverlayConnectCtx *roccq_tail;
358void 358void
359GST_cleanup_focc (struct ForwardedOverlayConnectContext *focc) 359GST_cleanup_focc (struct ForwardedOverlayConnectContext *focc)
360{ 360{
361 GNUNET_SERVER_client_drop (focc->client); 361 struct RegisteredHostContext *rhc = focc->rhc;
362
363 GNUNET_CONTAINER_DLL_remove (rhc->focc_dll_head,
364 rhc->focc_dll_tail,
365 focc);
362 GNUNET_free_non_null (focc->orig_msg); 366 GNUNET_free_non_null (focc->orig_msg);
363 GNUNET_free (focc); 367 GNUNET_free (focc);
364} 368}
@@ -376,10 +380,11 @@ forwarded_overlay_connect_timeout (void *cls)
376 struct RegisteredHostContext *rhc; 380 struct RegisteredHostContext *rhc;
377 struct ForwardedOverlayConnectContext *focc; 381 struct ForwardedOverlayConnectContext *focc;
378 382
383 fopc->timeout_task = NULL;
379 rhc = fopc->cls; 384 rhc = fopc->cls;
380 focc = rhc->focc_dll_head; 385 focc = rhc->focc_dll_head;
381 GNUNET_CONTAINER_DLL_remove (rhc->focc_dll_head, rhc->focc_dll_tail, focc); 386 LOG_DEBUG ("Overlay linking between peers %u and %u failed\n",
382 LOG_DEBUG ("Overlay linking between peers %u and %u failed\n", focc->peer1, 387 focc->peer1,
383 focc->peer2); 388 focc->peer2);
384 GST_cleanup_focc (focc); 389 GST_cleanup_focc (focc);
385 GST_forwarded_operation_timeout (fopc); 390 GST_forwarded_operation_timeout (fopc);
@@ -407,7 +412,6 @@ forwarded_overlay_connect_listener (void *cls,
407 rhc = fopc->cls; 412 rhc = fopc->cls;
408 GST_forwarded_operation_reply_relay (cls, msg); 413 GST_forwarded_operation_reply_relay (cls, msg);
409 focc = rhc->focc_dll_head; 414 focc = rhc->focc_dll_head;
410 GNUNET_CONTAINER_DLL_remove (rhc->focc_dll_head, rhc->focc_dll_tail, focc);
411 GST_cleanup_focc (focc); 415 GST_cleanup_focc (focc);
412 if (NULL != rhc->focc_dll_head) 416 if (NULL != rhc->focc_dll_head)
413 GST_process_next_focc (rhc); 417 GST_process_next_focc (rhc);
@@ -435,22 +439,24 @@ GST_process_next_focc (struct RegisteredHostContext *rhc)
435 GNUNET_assert (GNUNET_YES == peer->is_remote); 439 GNUNET_assert (GNUNET_YES == peer->is_remote);
436 GNUNET_assert (NULL != (slave = peer->details.remote.slave)); 440 GNUNET_assert (NULL != (slave = peer->details.remote.slave));
437 fopc = GNUNET_new (struct ForwardedOperationContext); 441 fopc = GNUNET_new (struct ForwardedOperationContext);
438 GNUNET_SERVER_client_keep (focc->client);
439 fopc->client = focc->client; 442 fopc->client = focc->client;
440 fopc->operation_id = focc->operation_id; 443 fopc->operation_id = focc->operation_id;
441 fopc->cls = rhc; 444 fopc->cls = rhc;
442 fopc->type = OP_OVERLAY_CONNECT; 445 fopc->type = OP_OVERLAY_CONNECT;
443 fopc->opc = 446 fopc->opc =
444 GNUNET_TESTBED_forward_operation_msg_ (slave->controller, 447 GNUNET_TESTBED_forward_operation_msg_ (slave->controller,
445 focc->operation_id, focc->orig_msg, 448 focc->operation_id,
449 focc->orig_msg,
446 &forwarded_overlay_connect_listener, 450 &forwarded_overlay_connect_listener,
447 fopc); 451 fopc);
448 GNUNET_free (focc->orig_msg); 452 GNUNET_free (focc->orig_msg);
449 focc->orig_msg = NULL; 453 focc->orig_msg = NULL;
450 fopc->timeout_task = 454 fopc->timeout_task = GNUNET_SCHEDULER_add_delayed (GST_timeout,
451 GNUNET_SCHEDULER_add_delayed (GST_timeout, &forwarded_overlay_connect_timeout, 455 &forwarded_overlay_connect_timeout,
456 fopc);
457 GNUNET_CONTAINER_DLL_insert_tail (fopcq_head,
458 fopcq_tail,
452 fopc); 459 fopc);
453 GNUNET_CONTAINER_DLL_insert_tail (fopcq_head, fopcq_tail, fopc);
454} 460}
455 461
456 462
@@ -533,7 +539,6 @@ cleanup_occ (struct OverlayConnectContext *occ)
533 occ->op_id); 539 occ->op_id);
534 GNUNET_free_non_null (occ->emsg); 540 GNUNET_free_non_null (occ->emsg);
535 GNUNET_free_non_null (occ->hello); 541 GNUNET_free_non_null (occ->hello);
536 GNUNET_SERVER_client_drop (occ->client);
537 if (NULL != occ->send_hello_task) 542 if (NULL != occ->send_hello_task)
538 GNUNET_SCHEDULER_cancel (occ->send_hello_task); 543 GNUNET_SCHEDULER_cancel (occ->send_hello_task);
539 if (NULL != occ->cleanup_task) 544 if (NULL != occ->cleanup_task)
@@ -610,24 +615,58 @@ timeout_overlay_connect (void *cls)
610 615
611 616
612/** 617/**
618 * Notify OC subsystem that @a client disconnected.
619 *
620 * @param client the client that disconnected
621 */
622void
623GST_notify_client_disconnect_oc (struct GNUNET_SERVICE_Client *client)
624{
625 struct ForwardedOperationContext *fopc;
626 struct ForwardedOperationContext *fopcn;
627 struct OverlayConnectContext *occ;
628 struct OverlayConnectContext *occn;
629
630 for (fopc = fopcq_head; NULL != fopc; fopc = fopcn)
631 {
632 fopcn = fopc->next;
633 if (fopc->client == client)
634 {
635 GNUNET_SCHEDULER_cancel (fopc->timeout_task);
636 GST_forwarded_operation_timeout (fopc);
637 }
638 }
639 for (occ = occq_head; NULL != occ; occ = occn)
640 {
641 occn = occ->next;
642 if (occ->client == client)
643 cleanup_occ (occ);
644 }
645 // FIXME: implement clean up for client_keep replacements!
646}
647
648
649
650
651/**
613 * FIXME. 652 * FIXME.
614 */ 653 */
615static void 654static void
616send_overlay_connect_success_msg (struct OverlayConnectContext *occ) 655send_overlay_connect_success_msg (struct OverlayConnectContext *occ)
617{ 656{
657 struct GNUNET_MQ_Envelope *env;
618 struct GNUNET_TESTBED_ConnectionEventMessage *msg; 658 struct GNUNET_TESTBED_ConnectionEventMessage *msg;
619 659
620 LOG_DEBUG ("0x%llx: Peers connected - Sending overlay connect success\n", 660 LOG_DEBUG ("0x%llx: Peers connected - Sending overlay connect success\n",
621 occ->op_id); 661 occ->op_id);
622 msg = GNUNET_new (struct GNUNET_TESTBED_ConnectionEventMessage); 662 env = GNUNET_MQ_msg (msg,
623 msg->header.size = 663 GNUNET_MESSAGE_TYPE_TESTBED_PEER_CONNECT_EVENT);
624 htons (sizeof (struct GNUNET_TESTBED_ConnectionEventMessage));
625 msg->header.type = htons (GNUNET_MESSAGE_TYPE_TESTBED_PEER_CONNECT_EVENT);
626 msg->event_type = htonl (GNUNET_TESTBED_ET_CONNECT); 664 msg->event_type = htonl (GNUNET_TESTBED_ET_CONNECT);
627 msg->peer1 = htonl (occ->peer->id); 665 msg->peer1 = htonl (occ->peer->id);
628 msg->peer2 = htonl (occ->other_peer_id); 666 msg->peer2 = htonl (occ->other_peer_id);
629 msg->operation_id = GNUNET_htonll (occ->op_id); 667 msg->operation_id = GNUNET_htonll (occ->op_id);
630 GST_queue_message (occ->client, &msg->header); 668 GNUNET_MQ_send (GNUNET_SERVICE_client_get_mq (occ->client),
669 env);
631} 670}
632 671
633 672
@@ -1314,7 +1353,8 @@ register_host (struct Slave *slave,
1314 rhc->state = RHC_INIT; 1353 rhc->state = RHC_INIT;
1315 hash = hash_hosts (rhc->reg_host, rhc->host); 1354 hash = hash_hosts (rhc->reg_host, rhc->host);
1316 if ((GNUNET_NO == 1355 if ((GNUNET_NO ==
1317 GNUNET_CONTAINER_multihashmap_contains (slave->reghost_map, &hash)) || 1356 GNUNET_CONTAINER_multihashmap_contains (slave->reghost_map,
1357 &hash)) ||
1318 (GNUNET_SYSERR != 1358 (GNUNET_SYSERR !=
1319 GNUNET_CONTAINER_multihashmap_get_multiple (slave->reghost_map, 1359 GNUNET_CONTAINER_multihashmap_get_multiple (slave->reghost_map,
1320 &hash, 1360 &hash,
@@ -1323,10 +1363,14 @@ register_host (struct Slave *slave,
1323 { 1363 {
1324 /* create and add a new registerd host context */ 1364 /* create and add a new registerd host context */
1325 /* add the focc to its queue */ 1365 /* add the focc to its queue */
1326 GNUNET_CONTAINER_multihashmap_put (slave->reghost_map, &hash, rhc, 1366 GNUNET_CONTAINER_multihashmap_put (slave->reghost_map,
1367 &hash,
1368 rhc,
1327 GNUNET_CONTAINER_MULTIHASHMAPOPTION_MULTIPLE); 1369 GNUNET_CONTAINER_MULTIHASHMAPOPTION_MULTIPLE);
1328 GST_queue_host_registration (slave, host_registration_comp, 1370 GST_queue_host_registration (slave,
1329 rhc, rhc->reg_host); 1371 host_registration_comp,
1372 rhc,
1373 rhc->reg_host);
1330 } 1374 }
1331 else 1375 else
1332 { 1376 {
@@ -1352,7 +1396,7 @@ register_host (struct Slave *slave,
1352 */ 1396 */
1353static void 1397static void
1354forward_overlay_connect (const struct GNUNET_TESTBED_OverlayConnectMessage *msg, 1398forward_overlay_connect (const struct GNUNET_TESTBED_OverlayConnectMessage *msg,
1355 struct GNUNET_SERVER_Client *client) 1399 struct GNUNET_SERVICE_Client *client)
1356{ 1400{
1357 struct ForwardedOperationContext *fopc; 1401 struct ForwardedOperationContext *fopc;
1358 struct Route *route_to_peer2_host; 1402 struct Route *route_to_peer2_host;
@@ -1388,14 +1432,15 @@ forward_overlay_connect (const struct GNUNET_TESTBED_OverlayConnectMessage *msg,
1388 { 1432 {
1389 LOG_DEBUG ("Queueing forwarding FOCC for connecting peers %u and %u\n", p1, p2); 1433 LOG_DEBUG ("Queueing forwarding FOCC for connecting peers %u and %u\n", p1, p2);
1390 focc = GNUNET_new (struct ForwardedOverlayConnectContext); 1434 focc = GNUNET_new (struct ForwardedOverlayConnectContext);
1435 focc->rhc = rhc;
1391 focc->peer1 = p1; 1436 focc->peer1 = p1;
1392 focc->peer2 = p2; 1437 focc->peer2 = p2;
1393 focc->peer2_host_id = peer2_host_id; 1438 focc->peer2_host_id = peer2_host_id;
1394 focc->orig_msg = GNUNET_copy_message (&msg->header); 1439 focc->orig_msg = GNUNET_copy_message (&msg->header);
1395 focc->operation_id = op_id; 1440 focc->operation_id = op_id;
1396 focc->client = client; 1441 focc->client = client;
1397 GNUNET_SERVER_client_keep (client); 1442 GNUNET_CONTAINER_DLL_insert_tail (rhc->focc_dll_head,
1398 GNUNET_CONTAINER_DLL_insert_tail (rhc->focc_dll_head, rhc->focc_dll_tail, 1443 rhc->focc_dll_tail,
1399 focc); 1444 focc);
1400 return; 1445 return;
1401 } 1446 }
@@ -1403,7 +1448,6 @@ forward_overlay_connect (const struct GNUNET_TESTBED_OverlayConnectMessage *msg,
1403 forward: 1448 forward:
1404 LOG_DEBUG ("Forwarding without FOCC for connecting peers %u and %u\n", p1, p2); 1449 LOG_DEBUG ("Forwarding without FOCC for connecting peers %u and %u\n", p1, p2);
1405 fopc = GNUNET_new (struct ForwardedOperationContext); 1450 fopc = GNUNET_new (struct ForwardedOperationContext);
1406 GNUNET_SERVER_client_keep (client);
1407 fopc->client = client; 1451 fopc->client = client;
1408 fopc->operation_id = op_id; 1452 fopc->operation_id = op_id;
1409 fopc->type = OP_OVERLAY_CONNECT; 1453 fopc->type = OP_OVERLAY_CONNECT;
@@ -1450,7 +1494,8 @@ p2_controller_connect_cb (void *cls,
1450 cmsg.operation_id = GNUNET_htonll (occ->op_id); 1494 cmsg.operation_id = GNUNET_htonll (occ->op_id);
1451 rp2c->opc = 1495 rp2c->opc =
1452 GNUNET_TESTBED_forward_operation_msg_ (rp2c->p2c, 1496 GNUNET_TESTBED_forward_operation_msg_ (rp2c->p2c,
1453 occ->op_id, &cmsg.header, 1497 occ->op_id,
1498 &cmsg.header,
1454 &overlay_connect_get_config, 1499 &overlay_connect_get_config,
1455 occ); 1500 occ);
1456 GNUNET_free_non_null (occ->emsg); 1501 GNUNET_free_non_null (occ->emsg);
@@ -1463,18 +1508,16 @@ p2_controller_connect_cb (void *cls,
1463 1508
1464 1509
1465/** 1510/**
1466 * Handler for #GNUNET_MESSAGE_TYPE_TESTBED_OLCONNECT messages 1511 * Handler for #GNUNET_MESSAGE_TYPE_TESTBED_OVERLAY_CONNECT messages
1467 * 1512 *
1468 * @param cls NULL 1513 * @param cls identification of the client
1469 * @param client identification of the client 1514 * @param msg the actual message
1470 * @param message the actual message
1471 */ 1515 */
1472void 1516void
1473GST_handle_overlay_connect (void *cls, 1517handle_overlay_connect (void *cls,
1474 struct GNUNET_SERVER_Client *client, 1518 const struct GNUNET_TESTBED_OverlayConnectMessage *msg)
1475 const struct GNUNET_MessageHeader *message)
1476{ 1519{
1477 const struct GNUNET_TESTBED_OverlayConnectMessage *msg; 1520 struct GNUNET_SERVICE_Client *client = cls;
1478 struct Peer *peer; 1521 struct Peer *peer;
1479 struct Peer *peer2; 1522 struct Peer *peer2;
1480 struct OverlayConnectContext *occ; 1523 struct OverlayConnectContext *occ;
@@ -1484,20 +1527,12 @@ GST_handle_overlay_connect (void *cls,
1484 uint32_t p2; 1527 uint32_t p2;
1485 uint32_t peer2_host_id; 1528 uint32_t peer2_host_id;
1486 1529
1487 if (sizeof (struct GNUNET_TESTBED_OverlayConnectMessage) !=
1488 ntohs (message->size))
1489 {
1490 GNUNET_break (0);
1491 GNUNET_SERVER_receive_done (client, GNUNET_SYSERR);
1492 return;
1493 }
1494 msg = (const struct GNUNET_TESTBED_OverlayConnectMessage *) message;
1495 p1 = ntohl (msg->peer1); 1530 p1 = ntohl (msg->peer1);
1496 p2 = ntohl (msg->peer2); 1531 p2 = ntohl (msg->peer2);
1497 if (!VALID_PEER_ID (p1)) 1532 if (! VALID_PEER_ID (p1))
1498 { 1533 {
1499 GNUNET_break (0); 1534 GNUNET_break (0);
1500 GNUNET_SERVER_receive_done (client, GNUNET_SYSERR); 1535 GNUNET_SERVICE_client_drop (client);
1501 return; 1536 return;
1502 } 1537 }
1503 peer = GST_peer_list[p1]; 1538 peer = GST_peer_list[p1];
@@ -1513,30 +1548,27 @@ GST_handle_overlay_connect (void *cls,
1513 if (! VALID_HOST_ID (peer2_host_id)) 1548 if (! VALID_HOST_ID (peer2_host_id))
1514 { 1549 {
1515 GNUNET_break (0); 1550 GNUNET_break (0);
1516 GNUNET_SERVER_receive_done (client, 1551 GNUNET_SERVICE_client_drop (client);
1517 GNUNET_SYSERR);
1518 return; 1552 return;
1519 } 1553 }
1520 forward_overlay_connect (msg, client); 1554 forward_overlay_connect (msg, client);
1521 GNUNET_SERVER_receive_done (client, 1555 GNUNET_SERVICE_client_continue (client);
1522 GNUNET_OK);
1523 return; 1556 return;
1524 } 1557 }
1525 p2n = NULL; 1558 p2n = NULL;
1526 occ = GNUNET_new (struct OverlayConnectContext); 1559 occ = GNUNET_new (struct OverlayConnectContext);
1527 occ->type = OCC_TYPE_LOCAL; 1560 occ->type = OCC_TYPE_LOCAL;
1528 if (!VALID_PEER_ID (p2)) /* May be peer2 is on a another controller */ 1561 if (! VALID_PEER_ID (p2)) /* May be peer2 is on a another controller */
1529 { 1562 {
1530 if (NULL == (p2n = GST_get_neighbour (peer2_host_id))) 1563 if (NULL == (p2n = GST_get_neighbour (peer2_host_id)))
1531 { 1564 {
1532 if (!VALID_HOST_ID (peer2_host_id)) 1565 if (! VALID_HOST_ID (peer2_host_id))
1533 { 1566 {
1534 GNUNET_break (0); 1567 GNUNET_break (0);
1535 LOG (GNUNET_ERROR_TYPE_WARNING, 1568 LOG (GNUNET_ERROR_TYPE_WARNING,
1536 "0x%llx: Peer %u's host not in our neighbours list\n", 1569 "0x%llx: Peer %u's host not in our neighbours list\n",
1537 operation_id, p2); 1570 operation_id, p2);
1538 GNUNET_SERVER_receive_done (client, 1571 GNUNET_SERVICE_client_drop (client);
1539 GNUNET_SYSERR);
1540 GNUNET_free (occ); 1572 GNUNET_free (occ);
1541 return; 1573 return;
1542 } 1574 }
@@ -1553,7 +1585,6 @@ GST_handle_overlay_connect (void *cls,
1553 GNUNET_CONTAINER_DLL_insert_tail (occq_head, 1585 GNUNET_CONTAINER_DLL_insert_tail (occq_head,
1554 occq_tail, 1586 occq_tail,
1555 occ); 1587 occ);
1556 GNUNET_SERVER_client_keep (client);
1557 occ->client = client; 1588 occ->client = client;
1558 occ->other_peer_id = p2; 1589 occ->other_peer_id = p2;
1559 GST_peer_list[p1]->reference_cnt++; 1590 GST_peer_list[p1]->reference_cnt++;
@@ -1573,11 +1604,14 @@ GST_handle_overlay_connect (void *cls,
1573 occ->op_id, 1604 occ->op_id,
1574 occ->other_peer_id, 1605 occ->other_peer_id,
1575 peer2_host_id); 1606 peer2_host_id);
1576 occ->p2ctx.remote.ncn = 1607 occ->p2ctx.remote.ncn
1577 GST_neighbour_get_connection (p2n, &p2_controller_connect_cb, occ); 1608 = GST_neighbour_get_connection (p2n,
1609 &p2_controller_connect_cb,
1610 occ);
1578 break; 1611 break;
1579 case OCC_TYPE_REMOTE_SLAVE: 1612 case OCC_TYPE_REMOTE_SLAVE:
1580 p2_controller_connect_cb (occ, occ->p2ctx.remote.p2c); 1613 p2_controller_connect_cb (occ,
1614 occ->p2ctx.remote.p2c);
1581 break; 1615 break;
1582 case OCC_TYPE_LOCAL: 1616 case OCC_TYPE_LOCAL:
1583 peer2 = GST_peer_list[occ->other_peer_id]; 1617 peer2 = GST_peer_list[occ->other_peer_id];
@@ -1598,7 +1632,7 @@ GST_handle_overlay_connect (void *cls,
1598 &overlay_connect_notify, occ); 1632 &overlay_connect_notify, occ);
1599 break; 1633 break;
1600 } 1634 }
1601 GNUNET_SERVER_receive_done (client, GNUNET_OK); 1635 GNUNET_SERVICE_client_continue (client);
1602} 1636}
1603 1637
1604 1638
@@ -1793,64 +1827,72 @@ rocc_cache_get_handle_transport_cb (void *cls,
1793 1827
1794 1828
1795/** 1829/**
1796 * Handler for #GNUNET_MESSAGE_TYPE_TESTBED_REQUEST_CONNECT messages 1830 * Check #GNUNET_MESSAGE_TYPE_TESTBED_REMOTE_OVERLAY_CONNECT messages
1797 * 1831 *
1798 * @param cls NULL 1832 * @param cls identification of the client
1799 * @param client identification of the client 1833 * @param msg the actual message
1800 * @param message the actual message 1834 * @return #GNUNET_OK if @a msg is well-formed
1801 */ 1835 */
1802void 1836int
1803GST_handle_remote_overlay_connect (void *cls, 1837check_remote_overlay_connect (void *cls,
1804 struct GNUNET_SERVER_Client *client, 1838 const struct GNUNET_TESTBED_RemoteOverlayConnectMessage *msg)
1805 const struct GNUNET_MessageHeader *message)
1806{ 1839{
1807 const struct GNUNET_TESTBED_RemoteOverlayConnectMessage *msg;
1808 struct RemoteOverlayConnectCtx *rocc;
1809 struct Peer *peer;
1810 struct GNUNET_PeerIdentity pid;
1811 static char pid_str[16];
1812 uint32_t peer_id; 1840 uint32_t peer_id;
1813 uint16_t msize; 1841 uint16_t msize;
1814 uint16_t hsize; 1842 uint16_t hsize;
1815 1843
1816 msize = ntohs (message->size); 1844 msize = ntohs (msg->header.size);
1817 if (sizeof (struct GNUNET_TESTBED_RemoteOverlayConnectMessage) >= msize)
1818 {
1819 GNUNET_break (0);
1820 GNUNET_SERVER_receive_done (client, GNUNET_SYSERR);
1821 return;
1822 }
1823 msg = (const struct GNUNET_TESTBED_RemoteOverlayConnectMessage *) message;
1824 if (GNUNET_MESSAGE_TYPE_HELLO != ntohs (msg->hello->type)) 1845 if (GNUNET_MESSAGE_TYPE_HELLO != ntohs (msg->hello->type))
1825 { 1846 {
1826 GNUNET_break (0); 1847 GNUNET_break (0);
1827 GNUNET_SERVER_receive_done (client, GNUNET_SYSERR); 1848 return GNUNET_SYSERR;
1828 return;
1829 } 1849 }
1830 hsize = ntohs (msg->hello->size); 1850 hsize = ntohs (msg->hello->size);
1831 if ((sizeof (struct GNUNET_TESTBED_RemoteOverlayConnectMessage) + hsize) != 1851 if ((sizeof (struct GNUNET_TESTBED_RemoteOverlayConnectMessage) + hsize) != msize)
1832 msize)
1833 { 1852 {
1834 GNUNET_break (0); 1853 GNUNET_break (0);
1835 GNUNET_SERVER_receive_done (client, GNUNET_SYSERR); 1854 return GNUNET_SYSERR;
1836 return;
1837 } 1855 }
1838 peer_id = ntohl (msg->peer); 1856 peer_id = ntohl (msg->peer);
1839 if ((peer_id >= GST_peer_list_size) || 1857 if ((peer_id >= GST_peer_list_size) ||
1840 (NULL == (peer = GST_peer_list[peer_id]))) 1858 (NULL == GST_peer_list[peer_id]))
1841 { 1859 {
1842 GNUNET_break_op (0); 1860 GNUNET_break_op (0);
1843 GNUNET_SERVER_receive_done (client, GNUNET_SYSERR); 1861 return GNUNET_SYSERR;
1844 return;
1845 } 1862 }
1863 return GNUNET_OK;
1864}
1865
1866
1867/**
1868 * Handler for #GNUNET_MESSAGE_TYPE_TESTBED_REMOTE_OVERLAY_CONNECT messages
1869 *
1870 * @param cls identification of the client
1871 * @param msg the actual message
1872 */
1873void
1874handle_remote_overlay_connect (void *cls,
1875 const struct GNUNET_TESTBED_RemoteOverlayConnectMessage *msg)
1876{
1877 struct GNUNET_SERVICE_Client *client = cls;
1878 struct RemoteOverlayConnectCtx *rocc;
1879 struct Peer *peer;
1880 struct GNUNET_PeerIdentity pid;
1881 static char pid_str[16];
1882 uint32_t peer_id;
1883 uint16_t hsize;
1884
1885 hsize = ntohs (msg->hello->size);
1886 peer_id = ntohl (msg->peer);
1887 peer = GST_peer_list[peer_id];
1846 if (GNUNET_YES == peer->is_remote) 1888 if (GNUNET_YES == peer->is_remote)
1847 { 1889 {
1848 struct GNUNET_MessageHeader *msg2; 1890 struct GNUNET_MessageHeader *msg2;
1849 1891
1850 msg2 = GNUNET_copy_message (message); 1892 msg2 = GNUNET_copy_message (&msg->header);
1851 GNUNET_TESTBED_queue_message_ (peer->details.remote.slave->controller, 1893 GNUNET_TESTBED_queue_message_ (peer->details.remote.slave->controller,
1852 msg2); 1894 msg2);
1853 GNUNET_SERVER_receive_done (client, GNUNET_OK); 1895 GNUNET_SERVICE_client_continue (client);
1854 return; 1896 return;
1855 } 1897 }
1856 rocc = GNUNET_new (struct RemoteOverlayConnectCtx); 1898 rocc = GNUNET_new (struct RemoteOverlayConnectCtx);
@@ -1872,7 +1914,9 @@ GST_handle_remote_overlay_connect (void *cls,
1872 rocc->peer = peer; 1914 rocc->peer = peer;
1873 rocc->peer->reference_cnt++; 1915 rocc->peer->reference_cnt++;
1874 rocc->hello = GNUNET_malloc (hsize); 1916 rocc->hello = GNUNET_malloc (hsize);
1875 GNUNET_memcpy (rocc->hello, msg->hello, hsize); 1917 GNUNET_memcpy (rocc->hello,
1918 msg->hello,
1919 hsize);
1876 rocc->tcc.cgh_p2_th = 1920 rocc->tcc.cgh_p2_th =
1877 GST_connection_pool_get_handle (peer_id, 1921 GST_connection_pool_get_handle (peer_id,
1878 rocc->peer->details.local.cfg, 1922 rocc->peer->details.local.cfg,
@@ -1886,8 +1930,7 @@ GST_handle_remote_overlay_connect (void *cls,
1886 GNUNET_SCHEDULER_add_delayed (GST_timeout, 1930 GNUNET_SCHEDULER_add_delayed (GST_timeout,
1887 &timeout_rocc_task, 1931 &timeout_rocc_task,
1888 rocc); 1932 rocc);
1889 GNUNET_SERVER_receive_done (client, 1933 GNUNET_SERVICE_client_continue (client);
1890 GNUNET_OK);
1891} 1934}
1892 1935
1893 1936
diff --git a/src/testbed/gnunet-service-testbed_peers.c b/src/testbed/gnunet-service-testbed_peers.c
index b55f5a8c8..a977b2b9b 100644
--- a/src/testbed/gnunet-service-testbed_peers.c
+++ b/src/testbed/gnunet-service-testbed_peers.c
@@ -69,7 +69,7 @@ struct ManageServiceContext
69 /** 69 /**
70 * The client which requested to manage the peer's service 70 * The client which requested to manage the peer's service
71 */ 71 */
72 struct GNUNET_SERVER_Client *client; 72 struct GNUNET_SERVICE_Client *client;
73 73
74 /** 74 /**
75 * Name of the service. 75 * Name of the service.
@@ -112,7 +112,7 @@ struct PeerReconfigureContext
112 /** 112 /**
113 * The client which gave this operation to us 113 * The client which gave this operation to us
114 */ 114 */
115 struct GNUNET_SERVER_Client *client; 115 struct GNUNET_SERVICE_Client *client;
116 116
117 /** 117 /**
118 * The configuration handle to use as the new template 118 * The configuration handle to use as the new template
@@ -246,7 +246,8 @@ peer_create_success_cb (void *cls, const struct GNUNET_MessageHeader *msg)
246 remote_peer = fopc->cls; 246 remote_peer = fopc->cls;
247 peer_list_add (remote_peer); 247 peer_list_add (remote_peer);
248 } 248 }
249 GST_forwarded_operation_reply_relay (fopc, msg); 249 GST_forwarded_operation_reply_relay (fopc,
250 msg);
250} 251}
251 252
252 253
@@ -278,6 +279,115 @@ GST_destroy_peer (struct Peer *peer)
278 279
279 280
280/** 281/**
282 * Cleanup the context information created for managing a peer's service
283 *
284 * @param mctx the ManageServiceContext
285 */
286static void
287cleanup_mctx (struct ManageServiceContext *mctx)
288{
289 mctx->expired = GNUNET_YES;
290 GNUNET_CONTAINER_DLL_remove (mctx_head,
291 mctx_tail,
292 mctx);
293 GNUNET_ARM_disconnect (mctx->ah);
294 GNUNET_assert (0 < mctx->peer->reference_cnt);
295 mctx->peer->reference_cnt--;
296 if ( (GNUNET_YES == mctx->peer->destroy_flag) &&
297 (0 == mctx->peer->reference_cnt) )
298 GST_destroy_peer (mctx->peer);
299 GNUNET_free (mctx->service);
300 GNUNET_free (mctx);
301}
302
303
304/**
305 * Stops a peer
306 *
307 * @param peer the peer to stop
308 * @return #GNUNET_OK upon success; #GNUNET_SYSERR upon failure
309 */
310static int
311stop_peer (struct Peer *peer)
312{
313 GNUNET_assert (GNUNET_NO == peer->is_remote);
314 if (GNUNET_OK != GNUNET_TESTING_peer_kill (peer->details.local.peer))
315 return GNUNET_SYSERR;
316 peer->details.local.is_running = GNUNET_NO;
317 return GNUNET_OK;
318}
319
320
321/**
322 * Cleans up the given PeerReconfigureContext
323 *
324 * @param prc the PeerReconfigureContext
325 */
326static void
327cleanup_prc (struct PeerReconfigureContext *prc)
328{
329 struct Peer *peer;
330
331 if (VALID_PEER_ID (prc->peer_id))
332 {
333 peer = GST_peer_list [prc->peer_id];
334 if (1 != prc->stopped)
335 {
336 GNUNET_TESTING_peer_stop_async_cancel (peer->details.local.peer);
337 stop_peer (peer); /* Stop the peer synchronously */
338 }
339 }
340 if (NULL != prc->cfg)
341 GNUNET_CONFIGURATION_destroy (prc->cfg);
342 GNUNET_CONTAINER_DLL_remove (prc_head,
343 prc_tail,
344 prc);
345 GNUNET_free (prc);
346}
347
348
349/**
350 * Notify peers subsystem that @a client disconnected.
351 *
352 * @param client the client that disconnected
353 */
354void
355GST_notify_client_disconnect_peers (struct GNUNET_SERVICE_Client *client)
356{
357 struct ForwardedOperationContext *fopc;
358 struct ForwardedOperationContext *fopcn;
359 struct ManageServiceContext *mctx;
360 struct ManageServiceContext *mctxn;
361 struct PeerReconfigureContext *prc;
362 struct PeerReconfigureContext *prcn;
363
364 for (fopc = fopcq_head; NULL != fopc; fopc = fopcn)
365 {
366 fopcn = fopc->next;
367 if (client == fopc->client)
368 {
369 if (OP_PEER_CREATE == fopc->type)
370 GNUNET_free (fopc->cls);
371 GNUNET_SCHEDULER_cancel (fopc->timeout_task);
372 GST_forwarded_operation_timeout (fopc);
373 }
374 }
375 for (mctx = mctx_head; NULL != mctx; mctx = mctxn)
376 {
377 mctxn = mctx->next;
378 if (client == mctx->client)
379 cleanup_mctx (mctx);
380 }
381 for (prc = prc_head; NULL != prc; prc = prcn)
382 {
383 prcn = prc->next;
384 if (client == prc->client)
385 cleanup_prc (prc);
386 }
387}
388
389
390/**
281 * Callback to be called when forwarded peer destroy operation is successfull. We 391 * Callback to be called when forwarded peer destroy operation is successfull. We
282 * have to relay the reply msg back to the client 392 * have to relay the reply msg back to the client
283 * 393 *
@@ -299,22 +409,38 @@ peer_destroy_success_cb (void *cls, const struct GNUNET_MessageHeader *msg)
299 if (0 == remote_peer->reference_cnt) 409 if (0 == remote_peer->reference_cnt)
300 GST_destroy_peer (remote_peer); 410 GST_destroy_peer (remote_peer);
301 } 411 }
302 GST_forwarded_operation_reply_relay (fopc, msg); 412 GST_forwarded_operation_reply_relay (fopc,
413 msg);
414}
415
416
417/**
418 * Check #GNUNET_MESSAGE_TYPE_TESTBED_CREATEPEER messages
419 *
420 * @param cls identification of the client
421 * @param msg the actual message
422 * @return #GNUNET_OK if @a msg is well-formed
423 */
424int
425check_peer_create (void *cls,
426 const struct GNUNET_TESTBED_PeerCreateMessage *msg)
427{
428 return GNUNET_OK; /* checked later */
303} 429}
304 430
305 431
306/** 432/**
307 * Handler for GNUNET_MESSAGE_TYPE_TESTBED_CREATEPEER messages 433 * Handler for #GNUNET_MESSAGE_TYPE_TESTBED_CREATEPEER messages
308 * 434 *
309 * @param cls NULL 435 * @param cls identification of the client
310 * @param client identification of the client 436 * @param msg the actual message
311 * @param message the actual message
312 */ 437 */
313void 438void
314GST_handle_peer_create (void *cls, struct GNUNET_SERVER_Client *client, 439handle_peer_create (void *cls,
315 const struct GNUNET_MessageHeader *message) 440 const struct GNUNET_TESTBED_PeerCreateMessage *msg)
316{ 441{
317 const struct GNUNET_TESTBED_PeerCreateMessage *msg; 442 struct GNUNET_SERVICE_Client *client = cls;
443 struct GNUNET_MQ_Envelope *env;
318 struct GNUNET_TESTBED_PeerCreateSuccessEventMessage *reply; 444 struct GNUNET_TESTBED_PeerCreateSuccessEventMessage *reply;
319 struct GNUNET_CONFIGURATION_Handle *cfg; 445 struct GNUNET_CONFIGURATION_Handle *cfg;
320 struct ForwardedOperationContext *fo_ctxt; 446 struct ForwardedOperationContext *fo_ctxt;
@@ -323,55 +449,54 @@ GST_handle_peer_create (void *cls, struct GNUNET_SERVER_Client *client,
323 char *emsg; 449 char *emsg;
324 uint32_t host_id; 450 uint32_t host_id;
325 uint32_t peer_id; 451 uint32_t peer_id;
326 uint16_t msize;
327
328 452
329 msize = ntohs (message->size);
330 if (msize <= sizeof (struct GNUNET_TESTBED_PeerCreateMessage))
331 {
332 GNUNET_break (0); /* We need configuration */
333 GNUNET_SERVER_receive_done (client, GNUNET_OK);
334 return;
335 }
336 msg = (const struct GNUNET_TESTBED_PeerCreateMessage *) message;
337 host_id = ntohl (msg->host_id); 453 host_id = ntohl (msg->host_id);
338 peer_id = ntohl (msg->peer_id); 454 peer_id = ntohl (msg->peer_id);
339 if (VALID_PEER_ID (peer_id)) 455 if (VALID_PEER_ID (peer_id))
340 { 456 {
341 (void) GNUNET_asprintf (&emsg, "Peer with ID %u already exists", peer_id); 457 (void) GNUNET_asprintf (&emsg,
342 GST_send_operation_fail_msg (client, GNUNET_ntohll (msg->operation_id), 458 "Peer with ID %u already exists",
459 peer_id);
460 GST_send_operation_fail_msg (client,
461 GNUNET_ntohll (msg->operation_id),
343 emsg); 462 emsg);
344 GNUNET_free (emsg); 463 GNUNET_free (emsg);
345 GNUNET_SERVER_receive_done (client, GNUNET_OK); 464 GNUNET_SERVICE_client_continue (client);
346 return; 465 return;
347 } 466 }
348 if (UINT32_MAX == peer_id) 467 if (UINT32_MAX == peer_id)
349 { 468 {
350 GST_send_operation_fail_msg (client, GNUNET_ntohll (msg->operation_id), 469 GST_send_operation_fail_msg (client,
470 GNUNET_ntohll (msg->operation_id),
351 "Cannot create peer with given ID"); 471 "Cannot create peer with given ID");
352 GNUNET_SERVER_receive_done (client, GNUNET_OK); 472 GNUNET_SERVICE_client_continue (client);
353 return; 473 return;
354 } 474 }
355 if (host_id == GST_context->host_id) 475 if (host_id == GST_context->host_id)
356 { 476 {
357 /* We are responsible for this peer */ 477 /* We are responsible for this peer */
358 cfg = GNUNET_TESTBED_extract_config_ (message); 478 cfg = GNUNET_TESTBED_extract_config_ (&msg->header);
359 if (NULL == cfg) 479 if (NULL == cfg)
360 { 480 {
361 GNUNET_break (0); 481 GNUNET_break (0);
362 GNUNET_SERVER_receive_done (client, GNUNET_SYSERR); 482 GNUNET_SERVICE_client_drop (client);
363 return; 483 return;
364 } 484 }
365 GNUNET_CONFIGURATION_set_value_number (cfg, "TESTBED", "PEERID", 485 GNUNET_CONFIGURATION_set_value_number (cfg,
486 "TESTBED",
487 "PEERID",
366 (unsigned long long) peer_id); 488 (unsigned long long) peer_id);
367 489
368 GNUNET_CONFIGURATION_set_value_number (cfg, "PATHS", "PEERID", 490 GNUNET_CONFIGURATION_set_value_number (cfg,
491 "PATHS",
492 "PEERID",
369 (unsigned long long) peer_id); 493 (unsigned long long) peer_id);
370 peer = GNUNET_new (struct Peer); 494 peer = GNUNET_new (struct Peer);
371 peer->is_remote = GNUNET_NO; 495 peer->is_remote = GNUNET_NO;
372 peer->details.local.cfg = cfg; 496 peer->details.local.cfg = cfg;
373 peer->id = peer_id; 497 peer->id = peer_id;
374 LOG_DEBUG ("Creating peer with id: %u\n", (unsigned int) peer->id); 498 LOG_DEBUG ("Creating peer with id: %u\n",
499 (unsigned int) peer->id);
375 peer->details.local.peer = 500 peer->details.local.peer =
376 GNUNET_TESTING_peer_configure (GST_context->system, 501 GNUNET_TESTING_peer_configure (GST_context->system,
377 peer->details.local.cfg, peer->id, 502 peer->details.local.cfg, peer->id,
@@ -379,24 +504,24 @@ GST_handle_peer_create (void *cls, struct GNUNET_SERVER_Client *client,
379 &emsg); 504 &emsg);
380 if (NULL == peer->details.local.peer) 505 if (NULL == peer->details.local.peer)
381 { 506 {
382 LOG (GNUNET_ERROR_TYPE_WARNING, "Configuring peer failed: %s\n", emsg); 507 LOG (GNUNET_ERROR_TYPE_WARNING,
508 "Configuring peer failed: %s\n",
509 emsg);
383 GNUNET_free (emsg); 510 GNUNET_free (emsg);
384 GNUNET_free (peer); 511 GNUNET_free (peer);
385 GNUNET_break (0); 512 GNUNET_break (0);
386 GNUNET_SERVER_receive_done (client, GNUNET_SYSERR); 513 GNUNET_SERVICE_client_drop (client);
387 return; 514 return;
388 } 515 }
389 peer->details.local.is_running = GNUNET_NO; 516 peer->details.local.is_running = GNUNET_NO;
390 peer_list_add (peer); 517 peer_list_add (peer);
391 reply = GNUNET_new (struct GNUNET_TESTBED_PeerCreateSuccessEventMessage); 518 env = GNUNET_MQ_msg (reply,
392 reply->header.size = 519 GNUNET_MESSAGE_TYPE_TESTBED_CREATE_PEER_SUCCESS);
393 htons (sizeof (struct GNUNET_TESTBED_PeerCreateSuccessEventMessage));
394 reply->header.type =
395 htons (GNUNET_MESSAGE_TYPE_TESTBED_CREATE_PEER_SUCCESS);
396 reply->peer_id = msg->peer_id; 520 reply->peer_id = msg->peer_id;
397 reply->operation_id = msg->operation_id; 521 reply->operation_id = msg->operation_id;
398 GST_queue_message (client, &reply->header); 522 GNUNET_MQ_send (GNUNET_SERVICE_client_get_mq (client),
399 GNUNET_SERVER_receive_done (client, GNUNET_OK); 523 env);
524 GNUNET_SERVICE_client_continue (client);
400 return; 525 return;
401 } 526 }
402 527
@@ -405,7 +530,7 @@ GST_handle_peer_create (void *cls, struct GNUNET_SERVER_Client *client,
405 if (NULL == route) 530 if (NULL == route)
406 { 531 {
407 GNUNET_break (0); 532 GNUNET_break (0);
408 GNUNET_SERVER_receive_done (client, GNUNET_OK); 533 GNUNET_SERVICE_client_continue (client); // ?
409 return; 534 return;
410 } 535 }
411 peer = GNUNET_new (struct Peer); 536 peer = GNUNET_new (struct Peer);
@@ -414,7 +539,6 @@ GST_handle_peer_create (void *cls, struct GNUNET_SERVER_Client *client,
414 peer->details.remote.slave = GST_slave_list[route->dest]; 539 peer->details.remote.slave = GST_slave_list[route->dest];
415 peer->details.remote.remote_host_id = host_id; 540 peer->details.remote.remote_host_id = host_id;
416 fo_ctxt = GNUNET_new (struct ForwardedOperationContext); 541 fo_ctxt = GNUNET_new (struct ForwardedOperationContext);
417 GNUNET_SERVER_client_keep (client);
418 fo_ctxt->client = client; 542 fo_ctxt->client = client;
419 fo_ctxt->operation_id = GNUNET_ntohll (msg->operation_id); 543 fo_ctxt->operation_id = GNUNET_ntohll (msg->operation_id);
420 fo_ctxt->cls = peer; 544 fo_ctxt->cls = peer;
@@ -424,34 +548,34 @@ GST_handle_peer_create (void *cls, struct GNUNET_SERVER_Client *client,
424 [route->dest]->controller, 548 [route->dest]->controller,
425 fo_ctxt->operation_id, 549 fo_ctxt->operation_id,
426 &msg->header, 550 &msg->header,
427 peer_create_success_cb, fo_ctxt); 551 &peer_create_success_cb,
552 fo_ctxt);
428 fo_ctxt->timeout_task = 553 fo_ctxt->timeout_task =
429 GNUNET_SCHEDULER_add_delayed (GST_timeout, 554 GNUNET_SCHEDULER_add_delayed (GST_timeout,
430 &peer_create_forward_timeout, 555 &peer_create_forward_timeout,
431 fo_ctxt); 556 fo_ctxt);
432 GNUNET_CONTAINER_DLL_insert_tail (fopcq_head, fopcq_tail, fo_ctxt); 557 GNUNET_CONTAINER_DLL_insert_tail (fopcq_head,
433 GNUNET_SERVER_receive_done (client, GNUNET_OK); 558 fopcq_tail,
559 fo_ctxt);
560 GNUNET_SERVICE_client_continue (client);
434} 561}
435 562
436 563
437/** 564/**
438 * Message handler for #GNUNET_MESSAGE_TYPE_TESTBED_DESTROYPEER messages 565 * Message handler for #GNUNET_MESSAGE_TYPE_TESTBED_DESTROYPEER messages
439 * 566 *
440 * @param cls NULL 567 * @param cls identification of the client
441 * @param client identification of the client 568 * @param msg the actual message
442 * @param message the actual message
443 */ 569 */
444void 570void
445GST_handle_peer_destroy (void *cls, 571handle_peer_destroy (void *cls,
446 struct GNUNET_SERVER_Client *client, 572 const struct GNUNET_TESTBED_PeerDestroyMessage *msg)
447 const struct GNUNET_MessageHeader *message)
448{ 573{
449 const struct GNUNET_TESTBED_PeerDestroyMessage *msg; 574 struct GNUNET_SERVICE_Client *client = cls;
450 struct ForwardedOperationContext *fopc; 575 struct ForwardedOperationContext *fopc;
451 struct Peer *peer; 576 struct Peer *peer;
452 uint32_t peer_id; 577 uint32_t peer_id;
453 578
454 msg = (const struct GNUNET_TESTBED_PeerDestroyMessage *) message;
455 peer_id = ntohl (msg->peer_id); 579 peer_id = ntohl (msg->peer_id);
456 LOG_DEBUG ("Received peer destory on peer: %u and operation id: %llu\n", 580 LOG_DEBUG ("Received peer destory on peer: %u and operation id: %llu\n",
457 (unsigned int) peer_id, 581 (unsigned int) peer_id,
@@ -460,9 +584,10 @@ GST_handle_peer_destroy (void *cls,
460 { 584 {
461 LOG (GNUNET_ERROR_TYPE_ERROR, 585 LOG (GNUNET_ERROR_TYPE_ERROR,
462 "Asked to destroy a non existent peer with id: %u\n", peer_id); 586 "Asked to destroy a non existent peer with id: %u\n", peer_id);
463 GST_send_operation_fail_msg (client, GNUNET_ntohll (msg->operation_id), 587 GST_send_operation_fail_msg (client,
588 GNUNET_ntohll (msg->operation_id),
464 "Peer doesn't exist"); 589 "Peer doesn't exist");
465 GNUNET_SERVER_receive_done (client, GNUNET_OK); 590 GNUNET_SERVICE_client_continue (client);
466 return; 591 return;
467 } 592 }
468 peer = GST_peer_list[peer_id]; 593 peer = GST_peer_list[peer_id];
@@ -470,7 +595,6 @@ GST_handle_peer_destroy (void *cls,
470 { 595 {
471 /* Forward the destory message to sub controller */ 596 /* Forward the destory message to sub controller */
472 fopc = GNUNET_new (struct ForwardedOperationContext); 597 fopc = GNUNET_new (struct ForwardedOperationContext);
473 GNUNET_SERVER_client_keep (client);
474 fopc->client = client; 598 fopc->client = client;
475 fopc->cls = peer; 599 fopc->cls = peer;
476 fopc->type = OP_PEER_DESTROY; 600 fopc->type = OP_PEER_DESTROY;
@@ -478,14 +602,18 @@ GST_handle_peer_destroy (void *cls,
478 fopc->opc = 602 fopc->opc =
479 GNUNET_TESTBED_forward_operation_msg_ (peer->details.remote. 603 GNUNET_TESTBED_forward_operation_msg_ (peer->details.remote.
480 slave->controller, 604 slave->controller,
481 fopc->operation_id, &msg->header, 605 fopc->operation_id,
482 &peer_destroy_success_cb, fopc); 606 &msg->header,
607 &peer_destroy_success_cb,
608 fopc);
483 fopc->timeout_task = 609 fopc->timeout_task =
484 GNUNET_SCHEDULER_add_delayed (GST_timeout, 610 GNUNET_SCHEDULER_add_delayed (GST_timeout,
485 &GST_forwarded_operation_timeout, 611 &GST_forwarded_operation_timeout,
486 fopc); 612 fopc);
487 GNUNET_CONTAINER_DLL_insert_tail (fopcq_head, fopcq_tail, fopc); 613 GNUNET_CONTAINER_DLL_insert_tail (fopcq_head,
488 GNUNET_SERVER_receive_done (client, GNUNET_OK); 614 fopcq_tail,
615 fopc);
616 GNUNET_SERVICE_client_continue (client);
489 return; 617 return;
490 } 618 }
491 peer->destroy_flag = GNUNET_YES; 619 peer->destroy_flag = GNUNET_YES;
@@ -494,8 +622,9 @@ GST_handle_peer_destroy (void *cls,
494 else 622 else
495 LOG (GNUNET_ERROR_TYPE_DEBUG, 623 LOG (GNUNET_ERROR_TYPE_DEBUG,
496 "Delaying peer destroy as peer is currently in use\n"); 624 "Delaying peer destroy as peer is currently in use\n");
497 GST_send_operation_success_msg (client, GNUNET_ntohll (msg->operation_id)); 625 GST_send_operation_success_msg (client,
498 GNUNET_SERVER_receive_done (client, GNUNET_OK); 626 GNUNET_ntohll (msg->operation_id));
627 GNUNET_SERVICE_client_continue (client);
499} 628}
500 629
501 630
@@ -517,54 +646,36 @@ start_peer (struct Peer *peer)
517 646
518 647
519/** 648/**
520 * Stops a peer 649 * Message handler for #GNUNET_MESSAGE_TYPE_TESTBED_START_PEER messages
521 * 650 *
522 * @param peer the peer to stop 651 * @param cls identification of the client
523 * @return #GNUNET_OK upon success; #GNUNET_SYSERR upon failure 652 * @param msg the actual message
524 */
525static int
526stop_peer (struct Peer *peer)
527{
528 GNUNET_assert (GNUNET_NO == peer->is_remote);
529 if (GNUNET_OK != GNUNET_TESTING_peer_kill (peer->details.local.peer))
530 return GNUNET_SYSERR;
531 peer->details.local.is_running = GNUNET_NO;
532 return GNUNET_OK;
533}
534
535
536/**
537 * Message handler for GNUNET_MESSAGE_TYPE_TESTBED_DESTROYPEER messages
538 *
539 * @param cls NULL
540 * @param client identification of the client
541 * @param message the actual message
542 */ 653 */
543void 654void
544GST_handle_peer_start (void *cls, struct GNUNET_SERVER_Client *client, 655handle_peer_start (void *cls,
545 const struct GNUNET_MessageHeader *message) 656 const struct GNUNET_TESTBED_PeerStartMessage *msg)
546{ 657{
547 const struct GNUNET_TESTBED_PeerStartMessage *msg; 658 struct GNUNET_SERVICE_Client *client = cls;
659 struct GNUNET_MQ_Envelope *env;
548 struct GNUNET_TESTBED_PeerEventMessage *reply; 660 struct GNUNET_TESTBED_PeerEventMessage *reply;
549 struct ForwardedOperationContext *fopc; 661 struct ForwardedOperationContext *fopc;
550 struct Peer *peer; 662 struct Peer *peer;
551 uint32_t peer_id; 663 uint32_t peer_id;
552 664
553 msg = (const struct GNUNET_TESTBED_PeerStartMessage *) message;
554 peer_id = ntohl (msg->peer_id); 665 peer_id = ntohl (msg->peer_id);
555 if (!VALID_PEER_ID (peer_id)) 666 if (! VALID_PEER_ID (peer_id))
556 { 667 {
557 GNUNET_break (0); 668 GNUNET_break (0);
558 LOG (GNUNET_ERROR_TYPE_ERROR, 669 LOG (GNUNET_ERROR_TYPE_ERROR,
559 "Asked to start a non existent peer with id: %u\n", peer_id); 670 "Asked to start a non existent peer with id: %u\n",
560 GNUNET_SERVER_receive_done (client, GNUNET_OK); 671 peer_id);
672 GNUNET_SERVICE_client_continue (client);
561 return; 673 return;
562 } 674 }
563 peer = GST_peer_list[peer_id]; 675 peer = GST_peer_list[peer_id];
564 if (GNUNET_YES == peer->is_remote) 676 if (GNUNET_YES == peer->is_remote)
565 { 677 {
566 fopc = GNUNET_new (struct ForwardedOperationContext); 678 fopc = GNUNET_new (struct ForwardedOperationContext);
567 GNUNET_SERVER_client_keep (client);
568 fopc->client = client; 679 fopc->client = client;
569 fopc->operation_id = GNUNET_ntohll (msg->operation_id); 680 fopc->operation_id = GNUNET_ntohll (msg->operation_id);
570 fopc->type = OP_PEER_START; 681 fopc->type = OP_PEER_START;
@@ -578,58 +689,58 @@ GST_handle_peer_start (void *cls, struct GNUNET_SERVER_Client *client,
578 GNUNET_SCHEDULER_add_delayed (GST_timeout, 689 GNUNET_SCHEDULER_add_delayed (GST_timeout,
579 &GST_forwarded_operation_timeout, 690 &GST_forwarded_operation_timeout,
580 fopc); 691 fopc);
581 GNUNET_CONTAINER_DLL_insert_tail (fopcq_head, fopcq_tail, fopc); 692 GNUNET_CONTAINER_DLL_insert_tail (fopcq_head,
582 GNUNET_SERVER_receive_done (client, GNUNET_OK); 693 fopcq_tail,
694 fopc);
695 GNUNET_SERVICE_client_continue (client);
583 return; 696 return;
584 } 697 }
585 if (GNUNET_OK != start_peer (peer)) 698 if (GNUNET_OK != start_peer (peer))
586 { 699 {
587 GST_send_operation_fail_msg (client, GNUNET_ntohll (msg->operation_id), 700 GST_send_operation_fail_msg (client, GNUNET_ntohll (msg->operation_id),
588 "Failed to start"); 701 "Failed to start");
589 GNUNET_SERVER_receive_done (client, GNUNET_OK); 702 GNUNET_SERVICE_client_continue (client);
590 return; 703 return;
591 } 704 }
592 reply = GNUNET_new (struct GNUNET_TESTBED_PeerEventMessage); 705 env = GNUNET_MQ_msg (reply,
593 reply->header.type = htons (GNUNET_MESSAGE_TYPE_TESTBED_PEER_EVENT); 706 GNUNET_MESSAGE_TYPE_TESTBED_PEER_EVENT);
594 reply->header.size = htons (sizeof (struct GNUNET_TESTBED_PeerEventMessage));
595 reply->event_type = htonl (GNUNET_TESTBED_ET_PEER_START); 707 reply->event_type = htonl (GNUNET_TESTBED_ET_PEER_START);
596 reply->host_id = htonl (GST_context->host_id); 708 reply->host_id = htonl (GST_context->host_id);
597 reply->peer_id = msg->peer_id; 709 reply->peer_id = msg->peer_id;
598 reply->operation_id = msg->operation_id; 710 reply->operation_id = msg->operation_id;
599 GST_queue_message (client, &reply->header); 711 GNUNET_MQ_send (GNUNET_SERVICE_client_get_mq (client),
600 GNUNET_SERVER_receive_done (client, GNUNET_OK); 712 env);
713 GNUNET_SERVICE_client_continue (client);
601} 714}
602 715
603 716
604/** 717/**
605 * Message handler for #GNUNET_MESSAGE_TYPE_TESTBED_DESTROYPEER messages 718 * Message handler for #GNUNET_MESSAGE_TYPE_TESTBED_STOP_PEER messages
606 * 719 *
607 * @param cls NULL 720 * @param cls identification of the client
608 * @param client identification of the client 721 * @param msg the actual message
609 * @param message the actual message
610 */ 722 */
611void 723void
612GST_handle_peer_stop (void *cls, 724handle_peer_stop (void *cls,
613 struct GNUNET_SERVER_Client *client, 725 const struct GNUNET_TESTBED_PeerStopMessage *msg)
614 const struct GNUNET_MessageHeader *message)
615{ 726{
616 const struct GNUNET_TESTBED_PeerStopMessage *msg; 727 struct GNUNET_SERVICE_Client *client = cls;
728 struct GNUNET_MQ_Envelope *env;
617 struct GNUNET_TESTBED_PeerEventMessage *reply; 729 struct GNUNET_TESTBED_PeerEventMessage *reply;
618 struct ForwardedOperationContext *fopc; 730 struct ForwardedOperationContext *fopc;
619 struct Peer *peer; 731 struct Peer *peer;
620 uint32_t peer_id; 732 uint32_t peer_id;
621 733
622 msg = (const struct GNUNET_TESTBED_PeerStopMessage *) message;
623 peer_id = ntohl (msg->peer_id); 734 peer_id = ntohl (msg->peer_id);
624 LOG (GNUNET_ERROR_TYPE_DEBUG, 735 LOG (GNUNET_ERROR_TYPE_DEBUG,
625 "Received PEER_STOP for peer %u\n", 736 "Received PEER_STOP for peer %u\n",
626 (unsigned int) peer_id); 737 (unsigned int) peer_id);
627 if (!VALID_PEER_ID (peer_id)) 738 if (! VALID_PEER_ID (peer_id))
628 { 739 {
629 GST_send_operation_fail_msg (client, 740 GST_send_operation_fail_msg (client,
630 GNUNET_ntohll (msg->operation_id), 741 GNUNET_ntohll (msg->operation_id),
631 "Peer not found"); 742 "Peer not found");
632 GNUNET_SERVER_receive_done (client, GNUNET_OK); 743 GNUNET_SERVICE_client_continue (client);
633 return; 744 return;
634 } 745 }
635 peer = GST_peer_list[peer_id]; 746 peer = GST_peer_list[peer_id];
@@ -639,7 +750,6 @@ GST_handle_peer_stop (void *cls,
639 "Forwarding PEER_STOP for peer %u\n", 750 "Forwarding PEER_STOP for peer %u\n",
640 (unsigned int) peer_id); 751 (unsigned int) peer_id);
641 fopc = GNUNET_new (struct ForwardedOperationContext); 752 fopc = GNUNET_new (struct ForwardedOperationContext);
642 GNUNET_SERVER_client_keep (client);
643 fopc->client = client; 753 fopc->client = client;
644 fopc->operation_id = GNUNET_ntohll (msg->operation_id); 754 fopc->operation_id = GNUNET_ntohll (msg->operation_id);
645 fopc->type = OP_PEER_STOP; 755 fopc->type = OP_PEER_STOP;
@@ -657,7 +767,7 @@ GST_handle_peer_stop (void *cls,
657 GNUNET_CONTAINER_DLL_insert_tail (fopcq_head, 767 GNUNET_CONTAINER_DLL_insert_tail (fopcq_head,
658 fopcq_tail, 768 fopcq_tail,
659 fopc); 769 fopc);
660 GNUNET_SERVER_receive_done (client, GNUNET_OK); 770 GNUNET_SERVICE_client_continue (client);
661 return; 771 return;
662 } 772 }
663 if (GNUNET_OK != stop_peer (peer)) 773 if (GNUNET_OK != stop_peer (peer))
@@ -668,38 +778,37 @@ GST_handle_peer_stop (void *cls,
668 GST_send_operation_fail_msg (client, 778 GST_send_operation_fail_msg (client,
669 GNUNET_ntohll (msg->operation_id), 779 GNUNET_ntohll (msg->operation_id),
670 "Peer not running"); 780 "Peer not running");
671 GNUNET_SERVER_receive_done (client, 781 GNUNET_SERVICE_client_continue (client);
672 GNUNET_OK);
673 return; 782 return;
674 } 783 }
675 LOG (GNUNET_ERROR_TYPE_DEBUG, 784 LOG (GNUNET_ERROR_TYPE_DEBUG,
676 "Peer %u successfully stopped\n", 785 "Peer %u successfully stopped\n",
677 (unsigned int) peer_id); 786 (unsigned int) peer_id);
678 reply = GNUNET_new (struct GNUNET_TESTBED_PeerEventMessage); 787 env = GNUNET_MQ_msg (reply,
679 reply->header.type = htons (GNUNET_MESSAGE_TYPE_TESTBED_PEER_EVENT); 788 GNUNET_MESSAGE_TYPE_TESTBED_PEER_EVENT);
680 reply->header.size = htons (sizeof (struct GNUNET_TESTBED_PeerEventMessage));
681 reply->event_type = htonl (GNUNET_TESTBED_ET_PEER_STOP); 789 reply->event_type = htonl (GNUNET_TESTBED_ET_PEER_STOP);
682 reply->host_id = htonl (GST_context->host_id); 790 reply->host_id = htonl (GST_context->host_id);
683 reply->peer_id = msg->peer_id; 791 reply->peer_id = msg->peer_id;
684 reply->operation_id = msg->operation_id; 792 reply->operation_id = msg->operation_id;
685 GST_queue_message (client, &reply->header); 793 GNUNET_MQ_send (GNUNET_SERVICE_client_get_mq (client),
686 GNUNET_SERVER_receive_done (client, GNUNET_OK); 794 env);
795 GNUNET_SERVICE_client_continue (client);
687 GNUNET_TESTING_peer_wait (peer->details.local.peer); 796 GNUNET_TESTING_peer_wait (peer->details.local.peer);
688} 797}
689 798
690 799
691/** 800/**
692 * Handler for GNUNET_MESSAGE_TYPE_TESTBED_GETPEERCONFIG messages 801 * Handler for #GNUNET_MESSAGE_TYPE_TESTBED_GET_PEER_INFORMATION messages
693 * 802 *
694 * @param cls NULL 803 * @param cls identification of the client
695 * @param client identification of the client 804 * @param msg the actual message
696 * @param message the actual message
697 */ 805 */
698void 806void
699GST_handle_peer_get_config (void *cls, struct GNUNET_SERVER_Client *client, 807handle_peer_get_config (void *cls,
700 const struct GNUNET_MessageHeader *message) 808 const struct GNUNET_TESTBED_PeerGetConfigurationMessage *msg)
701{ 809{
702 const struct GNUNET_TESTBED_PeerGetConfigurationMessage *msg; 810 struct GNUNET_SERVICE_Client *client = cls;
811 struct GNUNET_MQ_Envelope *env;
703 struct GNUNET_TESTBED_PeerConfigurationInformationMessage *reply; 812 struct GNUNET_TESTBED_PeerConfigurationInformationMessage *reply;
704 struct ForwardedOperationContext *fopc; 813 struct ForwardedOperationContext *fopc;
705 struct Peer *peer; 814 struct Peer *peer;
@@ -708,9 +817,7 @@ GST_handle_peer_get_config (void *cls, struct GNUNET_SERVER_Client *client,
708 size_t c_size; 817 size_t c_size;
709 size_t xc_size; 818 size_t xc_size;
710 uint32_t peer_id; 819 uint32_t peer_id;
711 uint16_t msize;
712 820
713 msg = (const struct GNUNET_TESTBED_PeerGetConfigurationMessage *) message;
714 peer_id = ntohl (msg->peer_id); 821 peer_id = ntohl (msg->peer_id);
715 LOG_DEBUG ("Received GET_CONFIG for peer %u\n", 822 LOG_DEBUG ("Received GET_CONFIG for peer %u\n",
716 (unsigned int) peer_id); 823 (unsigned int) peer_id);
@@ -719,7 +826,7 @@ GST_handle_peer_get_config (void *cls, struct GNUNET_SERVER_Client *client,
719 GST_send_operation_fail_msg (client, 826 GST_send_operation_fail_msg (client,
720 GNUNET_ntohll (msg->operation_id), 827 GNUNET_ntohll (msg->operation_id),
721 "Peer not found"); 828 "Peer not found");
722 GNUNET_SERVER_receive_done (client, GNUNET_OK); 829 GNUNET_SERVICE_client_continue (client);
723 return; 830 return;
724 } 831 }
725 peer = GST_peer_list[peer_id]; 832 peer = GST_peer_list[peer_id];
@@ -728,7 +835,6 @@ GST_handle_peer_get_config (void *cls, struct GNUNET_SERVER_Client *client,
728 LOG_DEBUG ("Forwarding PEER_GET_CONFIG for peer: %u\n", 835 LOG_DEBUG ("Forwarding PEER_GET_CONFIG for peer: %u\n",
729 (unsigned int) peer_id); 836 (unsigned int) peer_id);
730 fopc = GNUNET_new (struct ForwardedOperationContext); 837 fopc = GNUNET_new (struct ForwardedOperationContext);
731 GNUNET_SERVER_client_keep (client);
732 fopc->client = client; 838 fopc->client = client;
733 fopc->operation_id = GNUNET_ntohll (msg->operation_id); 839 fopc->operation_id = GNUNET_ntohll (msg->operation_id);
734 fopc->type = OP_PEER_INFO; 840 fopc->type = OP_PEER_INFO;
@@ -746,7 +852,7 @@ GST_handle_peer_get_config (void *cls, struct GNUNET_SERVER_Client *client,
746 GNUNET_CONTAINER_DLL_insert_tail (fopcq_head, 852 GNUNET_CONTAINER_DLL_insert_tail (fopcq_head,
747 fopcq_tail, 853 fopcq_tail,
748 fopc); 854 fopc);
749 GNUNET_SERVER_receive_done (client, GNUNET_OK); 855 GNUNET_SERVICE_client_continue (client);
750 return; 856 return;
751 } 857 }
752 LOG_DEBUG ("Received PEER_GET_CONFIG for peer: %u\n", 858 LOG_DEBUG ("Received PEER_GET_CONFIG for peer: %u\n",
@@ -758,47 +864,21 @@ GST_handle_peer_get_config (void *cls, struct GNUNET_SERVER_Client *client,
758 c_size, 864 c_size,
759 &xconfig); 865 &xconfig);
760 GNUNET_free (config); 866 GNUNET_free (config);
761 msize = 867 env = GNUNET_MQ_msg_extra (reply,
762 xc_size + 868 xc_size,
763 sizeof (struct GNUNET_TESTBED_PeerConfigurationInformationMessage); 869 GNUNET_MESSAGE_TYPE_TESTBED_PEER_INFORMATION);
764 reply = GNUNET_realloc (xconfig, msize);
765 (void) memmove (&reply[1], reply, xc_size);
766 reply->header.size = htons (msize);
767 reply->header.type = htons (GNUNET_MESSAGE_TYPE_TESTBED_PEER_INFORMATION);
768 reply->peer_id = msg->peer_id; 870 reply->peer_id = msg->peer_id;
769 reply->operation_id = msg->operation_id; 871 reply->operation_id = msg->operation_id;
770 GNUNET_TESTING_peer_get_identity (GST_peer_list[peer_id]->details.local.peer, 872 GNUNET_TESTING_peer_get_identity (GST_peer_list[peer_id]->details.local.peer,
771 &reply->peer_identity); 873 &reply->peer_identity);
772 reply->config_size = htons ((uint16_t) c_size); 874 reply->config_size = htons ((uint16_t) c_size);
773 GST_queue_message (client, &reply->header); 875 GNUNET_memcpy (&reply[1],
774 GNUNET_SERVER_receive_done (client, GNUNET_OK); 876 xconfig,
775} 877 xc_size);
776 878 GNUNET_free (xconfig);
777 879 GNUNET_MQ_send (GNUNET_SERVICE_client_get_mq (client),
778/** 880 env);
779 * Cleans up the given PeerReconfigureContext 881 GNUNET_SERVICE_client_continue (client);
780 *
781 * @param prc the PeerReconfigureContext
782 */
783static void
784cleanup_prc (struct PeerReconfigureContext *prc)
785{
786 struct Peer *peer;
787
788 if (VALID_PEER_ID (prc->peer_id))
789 {
790 peer = GST_peer_list [prc->peer_id];
791 if (1 != prc->stopped)
792 {
793 GNUNET_TESTING_peer_stop_async_cancel (peer->details.local.peer);
794 stop_peer (peer); /* Stop the peer synchronously */
795 }
796 }
797 if (NULL != prc->cfg)
798 GNUNET_CONFIGURATION_destroy (prc->cfg);
799 GNUNET_SERVER_client_drop (prc->client);
800 GNUNET_CONTAINER_DLL_remove (prc_head, prc_tail, prc);
801 GNUNET_free (prc);
802} 882}
803 883
804 884
@@ -887,20 +967,33 @@ prc_stop_cb (void *cls,
887 967
888 968
889/** 969/**
970 * Check #GNUNET_MESSAGE_TYPDE_TESTBED_RECONFIGURE_PEER type messages.
971 *
972 * @param cls identification of the client
973 * @param msg the actual message
974 * @return #GNUNET_OK if @a msg is well-formed
975 */
976int
977check_peer_reconfigure (void *cls,
978 const struct GNUNET_TESTBED_PeerReconfigureMessage *msg)
979{
980 return GNUNET_OK; /* checked later */
981}
982
983
984/**
890 * Handler for #GNUNET_MESSAGE_TYPDE_TESTBED_RECONFIGURE_PEER type messages. 985 * Handler for #GNUNET_MESSAGE_TYPDE_TESTBED_RECONFIGURE_PEER type messages.
891 * Should stop the peer asyncronously, destroy it and create it again with the 986 * Should stop the peer asyncronously, destroy it and create it again with the
892 * new configuration. 987 * new configuration.
893 * 988 *
894 * @param cls NULL 989 * @param cls identification of the client
895 * @param client identification of the client 990 * @param msg the actual message
896 * @param message the actual message
897 */ 991 */
898void 992void
899GST_handle_peer_reconfigure (void *cls, 993handle_peer_reconfigure (void *cls,
900 struct GNUNET_SERVER_Client *client, 994 const struct GNUNET_TESTBED_PeerReconfigureMessage *msg)
901 const struct GNUNET_MessageHeader *message)
902{ 995{
903 const struct GNUNET_TESTBED_PeerReconfigureMessage *msg; 996 struct GNUNET_SERVICE_Client *client = cls;
904 struct Peer *peer; 997 struct Peer *peer;
905 struct GNUNET_CONFIGURATION_Handle *cfg; 998 struct GNUNET_CONFIGURATION_Handle *cfg;
906 struct ForwardedOperationContext *fopc; 999 struct ForwardedOperationContext *fopc;
@@ -908,27 +1001,16 @@ GST_handle_peer_reconfigure (void *cls,
908 char *emsg; 1001 char *emsg;
909 uint64_t op_id; 1002 uint64_t op_id;
910 uint32_t peer_id; 1003 uint32_t peer_id;
911 uint16_t msize;
912 1004
913 msize = ntohs (message->size);
914 if (msize <= sizeof (struct GNUNET_TESTBED_PeerReconfigureMessage))
915 {
916 GNUNET_break_op (0);
917 GNUNET_SERVER_receive_done (client,
918 GNUNET_SYSERR);
919 return;
920 }
921 msg = (const struct GNUNET_TESTBED_PeerReconfigureMessage *) message;
922 peer_id = ntohl (msg->peer_id); 1005 peer_id = ntohl (msg->peer_id);
923 op_id = GNUNET_ntohll (msg->operation_id); 1006 op_id = GNUNET_ntohll (msg->operation_id);
924 if (!VALID_PEER_ID (peer_id)) 1007 if (! VALID_PEER_ID (peer_id))
925 { 1008 {
926 GNUNET_break (0); 1009 GNUNET_break (0);
927 GST_send_operation_fail_msg (client, 1010 GST_send_operation_fail_msg (client,
928 op_id, 1011 op_id,
929 "Peer not found"); 1012 "Peer not found");
930 GNUNET_SERVER_receive_done (client, 1013 GNUNET_SERVICE_client_continue (client);
931 GNUNET_OK);
932 return; 1014 return;
933 } 1015 }
934 peer = GST_peer_list[peer_id]; 1016 peer = GST_peer_list[peer_id];
@@ -936,7 +1018,6 @@ GST_handle_peer_reconfigure (void *cls,
936 { 1018 {
937 LOG_DEBUG ("Forwarding PEER_RECONFIGURE for peer: %u\n", peer_id); 1019 LOG_DEBUG ("Forwarding PEER_RECONFIGURE for peer: %u\n", peer_id);
938 fopc = GNUNET_new (struct ForwardedOperationContext); 1020 fopc = GNUNET_new (struct ForwardedOperationContext);
939 GNUNET_SERVER_client_keep (client);
940 fopc->client = client; 1021 fopc->client = client;
941 fopc->operation_id = op_id; 1022 fopc->operation_id = op_id;
942 fopc->type = OP_PEER_RECONFIGURE; 1023 fopc->type = OP_PEER_RECONFIGURE;
@@ -954,7 +1035,7 @@ GST_handle_peer_reconfigure (void *cls,
954 GNUNET_CONTAINER_DLL_insert_tail (fopcq_head, 1035 GNUNET_CONTAINER_DLL_insert_tail (fopcq_head,
955 fopcq_tail, 1036 fopcq_tail,
956 fopc); 1037 fopc);
957 GNUNET_SERVER_receive_done (client, GNUNET_OK); 1038 GNUNET_SERVICE_client_continue (client);
958 return; 1039 return;
959 } 1040 }
960 LOG_DEBUG ("Received PEER_RECONFIGURE for peer %u\n", 1041 LOG_DEBUG ("Received PEER_RECONFIGURE for peer %u\n",
@@ -965,8 +1046,7 @@ GST_handle_peer_reconfigure (void *cls,
965 GST_send_operation_fail_msg (client, 1046 GST_send_operation_fail_msg (client,
966 op_id, 1047 op_id,
967 "Peer in use"); 1048 "Peer in use");
968 GNUNET_SERVER_receive_done (client, 1049 GNUNET_SERVICE_client_continue (client);
969 GNUNET_OK);
970 return; 1050 return;
971 } 1051 }
972 if (GNUNET_YES == peer->destroy_flag) 1052 if (GNUNET_YES == peer->destroy_flag)
@@ -975,19 +1055,17 @@ GST_handle_peer_reconfigure (void *cls,
975 GST_send_operation_fail_msg (client, 1055 GST_send_operation_fail_msg (client,
976 op_id, 1056 op_id,
977 "Peer is being destroyed"); 1057 "Peer is being destroyed");
978 GNUNET_SERVER_receive_done (client, 1058 GNUNET_SERVICE_client_continue (client);
979 GNUNET_OK);
980 return; 1059 return;
981 } 1060 }
982 cfg = GNUNET_TESTBED_extract_config_ (message); 1061 cfg = GNUNET_TESTBED_extract_config_ (&msg->header);
983 if (NULL == cfg) 1062 if (NULL == cfg)
984 { 1063 {
985 GNUNET_break (0); 1064 GNUNET_break (0);
986 GST_send_operation_fail_msg (client, 1065 GST_send_operation_fail_msg (client,
987 op_id, 1066 op_id,
988 "Compression error"); 1067 "Compression error");
989 GNUNET_SERVER_receive_done (client, 1068 GNUNET_SERVICE_client_continue (client);
990 GNUNET_OK);
991 return; 1069 return;
992 } 1070 }
993 if (GNUNET_NO == peer->details.local.is_running) 1071 if (GNUNET_NO == peer->details.local.is_running)
@@ -1000,8 +1078,7 @@ GST_handle_peer_reconfigure (void *cls,
1000 emsg); 1078 emsg);
1001 GST_send_operation_success_msg (client, 1079 GST_send_operation_success_msg (client,
1002 op_id); 1080 op_id);
1003 GNUNET_SERVER_receive_done (client, 1081 GNUNET_SERVICE_client_continue (client);
1004 GNUNET_OK);
1005 GNUNET_free_non_null (emsg); 1082 GNUNET_free_non_null (emsg);
1006 return; 1083 return;
1007 } 1084 }
@@ -1020,8 +1097,7 @@ GST_handle_peer_reconfigure (void *cls,
1020 GST_send_operation_fail_msg (client, 1097 GST_send_operation_fail_msg (client,
1021 op_id, 1098 op_id,
1022 emsg); 1099 emsg);
1023 GNUNET_SERVER_receive_done (client, 1100 GNUNET_SERVICE_client_continue (client);
1024 GNUNET_OK);
1025 GNUNET_free (prc); 1101 GNUNET_free (prc);
1026 GNUNET_free (emsg); 1102 GNUNET_free (emsg);
1027 return; 1103 return;
@@ -1030,36 +1106,10 @@ GST_handle_peer_reconfigure (void *cls,
1030 prc->peer_id = peer_id; 1106 prc->peer_id = peer_id;
1031 prc->op_id = op_id; 1107 prc->op_id = op_id;
1032 prc->client = client; 1108 prc->client = client;
1033 GNUNET_SERVER_client_keep (client);
1034 GNUNET_CONTAINER_DLL_insert_tail (prc_head, 1109 GNUNET_CONTAINER_DLL_insert_tail (prc_head,
1035 prc_tail, 1110 prc_tail,
1036 prc); 1111 prc);
1037 GNUNET_SERVER_receive_done (client, 1112 GNUNET_SERVICE_client_continue (client);
1038 GNUNET_OK);
1039}
1040
1041
1042/**
1043 * Cleanup the context information created for managing a peer's service
1044 *
1045 * @param mctx the ManageServiceContext
1046 */
1047static void
1048cleanup_mctx (struct ManageServiceContext *mctx)
1049{
1050 mctx->expired = GNUNET_YES;
1051 GNUNET_CONTAINER_DLL_remove (mctx_head,
1052 mctx_tail,
1053 mctx);
1054 GNUNET_SERVER_client_drop (mctx->client);
1055 GNUNET_ARM_disconnect (mctx->ah);
1056 GNUNET_assert (0 < mctx->peer->reference_cnt);
1057 mctx->peer->reference_cnt--;
1058 if ( (GNUNET_YES == mctx->peer->destroy_flag)
1059 && (0 == mctx->peer->reference_cnt) )
1060 GST_destroy_peer (mctx->peer);
1061 GNUNET_free (mctx->service);
1062 GNUNET_free (mctx);
1063} 1113}
1064 1114
1065 1115
@@ -1211,51 +1261,57 @@ service_manage_result_cb (void *cls,
1211 1261
1212 1262
1213/** 1263/**
1214 * Handler for GNUNET_TESTBED_ManagePeerServiceMessage message 1264 * Check #GNUNET_MESSAGE_TYPE_TESTBED_MANAGE_PEER_SERVICE message
1215 * 1265 *
1216 * @param cls NULL 1266 * @param cls identification of client
1217 * @param client identification of client 1267 * @param msg the actual message
1218 * @param message the actual message 1268 * @return #GNUNET_OK if @a msg is well-formed
1219 */ 1269 */
1220void 1270int
1221GST_handle_manage_peer_service (void *cls, 1271check_manage_peer_service (void *cls,
1222 struct GNUNET_SERVER_Client *client, 1272 const struct GNUNET_TESTBED_ManagePeerServiceMessage *msg)
1223 const struct GNUNET_MessageHeader *message)
1224{ 1273{
1225 const struct GNUNET_TESTBED_ManagePeerServiceMessage *msg;
1226 const char* service;
1227 struct Peer *peer;
1228 char *emsg;
1229 struct GNUNET_ARM_Handle *ah;
1230 struct ManageServiceContext *mctx;
1231 struct ForwardedOperationContext *fopc;
1232 uint64_t op_id;
1233 uint32_t peer_id;
1234 uint16_t msize; 1274 uint16_t msize;
1275 const char* service;
1235 1276
1236 1277 msize = ntohs (msg->header.size);
1237 msize = ntohs (message->size);
1238 if (msize <= sizeof (struct GNUNET_TESTBED_ManagePeerServiceMessage))
1239 {
1240 GNUNET_break_op (0);
1241 GNUNET_SERVER_receive_done (client, GNUNET_SYSERR);
1242 return;
1243 }
1244 msg = (const struct GNUNET_TESTBED_ManagePeerServiceMessage *) message;
1245 service = (const char *) &msg[1]; 1278 service = (const char *) &msg[1];
1246 if ('\0' != service[msize - sizeof 1279 if ('\0' != service[msize - sizeof
1247 (struct GNUNET_TESTBED_ManagePeerServiceMessage) - 1]) 1280 (struct GNUNET_TESTBED_ManagePeerServiceMessage) - 1])
1248 { 1281 {
1249 GNUNET_break_op (0); 1282 GNUNET_break_op (0);
1250 GNUNET_SERVER_receive_done (client, GNUNET_SYSERR); 1283 return GNUNET_SYSERR;
1251 return;
1252 } 1284 }
1253 if (1 < msg->start) 1285 if (1 < msg->start)
1254 { 1286 {
1255 GNUNET_break_op (0); 1287 GNUNET_break_op (0);
1256 GNUNET_SERVER_receive_done (client, GNUNET_SYSERR); 1288 return GNUNET_SYSERR;
1257 return;
1258 } 1289 }
1290 return GNUNET_OK;
1291}
1292
1293
1294/**
1295 * Handler for #GNUNET_MESSAGE_TYPE_TESTBED_MANAGE_PEER_SERVICE messages
1296 *
1297 * @param cls identification of client
1298 * @param msg the actual message
1299 */
1300void
1301handle_manage_peer_service (void *cls,
1302 const struct GNUNET_TESTBED_ManagePeerServiceMessage *msg)
1303{
1304 struct GNUNET_SERVICE_Client *client = cls;
1305 const char* service;
1306 struct Peer *peer;
1307 char *emsg;
1308 struct GNUNET_ARM_Handle *ah;
1309 struct ManageServiceContext *mctx;
1310 struct ForwardedOperationContext *fopc;
1311 uint64_t op_id;
1312 uint32_t peer_id;
1313
1314 service = (const char *) &msg[1];
1259 peer_id = ntohl (msg->peer_id); 1315 peer_id = ntohl (msg->peer_id);
1260 op_id = GNUNET_ntohll (msg->operation_id); 1316 op_id = GNUNET_ntohll (msg->operation_id);
1261 LOG_DEBUG ("Received request to manage service %s on peer %u\n", 1317 LOG_DEBUG ("Received request to manage service %s on peer %u\n",
@@ -1277,7 +1333,6 @@ GST_handle_manage_peer_service (void *cls,
1277 { 1333 {
1278 /* Forward the destory message to sub controller */ 1334 /* Forward the destory message to sub controller */
1279 fopc = GNUNET_new (struct ForwardedOperationContext); 1335 fopc = GNUNET_new (struct ForwardedOperationContext);
1280 GNUNET_SERVER_client_keep (client);
1281 fopc->client = client; 1336 fopc->client = client;
1282 fopc->cls = peer; 1337 fopc->cls = peer;
1283 fopc->type = OP_MANAGE_SERVICE; 1338 fopc->type = OP_MANAGE_SERVICE;
@@ -1296,7 +1351,7 @@ GST_handle_manage_peer_service (void *cls,
1296 GNUNET_CONTAINER_DLL_insert_tail (fopcq_head, 1351 GNUNET_CONTAINER_DLL_insert_tail (fopcq_head,
1297 fopcq_tail, 1352 fopcq_tail,
1298 fopc); 1353 fopc);
1299 GNUNET_SERVER_receive_done (client, GNUNET_OK); 1354 GNUNET_SERVICE_client_continue (client);
1300 return; 1355 return;
1301 } 1356 }
1302 if (GNUNET_NO == peer->details.local.is_running) 1357 if (GNUNET_NO == peer->details.local.is_running)
@@ -1326,7 +1381,6 @@ GST_handle_manage_peer_service (void *cls,
1326 peer->reference_cnt++; 1381 peer->reference_cnt++;
1327 mctx->op_id = op_id; 1382 mctx->op_id = op_id;
1328 mctx->ah = ah; 1383 mctx->ah = ah;
1329 GNUNET_SERVER_client_keep (client);
1330 mctx->client = client; 1384 mctx->client = client;
1331 mctx->start = msg->start; 1385 mctx->start = msg->start;
1332 mctx->service = GNUNET_strdup (service); 1386 mctx->service = GNUNET_strdup (service);
@@ -1343,14 +1397,14 @@ GST_handle_manage_peer_service (void *cls,
1343 GNUNET_ARM_request_service_stop (mctx->ah, service, 1397 GNUNET_ARM_request_service_stop (mctx->ah, service,
1344 &service_manage_result_cb, 1398 &service_manage_result_cb,
1345 mctx); 1399 mctx);
1346 GNUNET_SERVER_receive_done (client, GNUNET_OK); 1400 GNUNET_SERVICE_client_continue (client);
1347 return; 1401 return;
1348 1402
1349 err_ret: 1403 err_ret:
1350 LOG (GNUNET_ERROR_TYPE_ERROR, "%s\n", emsg); 1404 LOG (GNUNET_ERROR_TYPE_ERROR, "%s\n", emsg);
1351 GST_send_operation_fail_msg (client, op_id, emsg); 1405 GST_send_operation_fail_msg (client, op_id, emsg);
1352 GNUNET_free (emsg); 1406 GNUNET_free (emsg);
1353 GNUNET_SERVER_receive_done (client, GNUNET_OK); 1407 GNUNET_SERVICE_client_continue (client);
1354} 1408}
1355 1409
1356 1410
@@ -1432,7 +1486,6 @@ shutdown_peers_reply_cb (void *cls,
1432 GNUNET_free (hc); 1486 GNUNET_free (hc);
1433 hc = NULL; 1487 hc = NULL;
1434 } 1488 }
1435 GNUNET_SERVER_client_drop (fo_ctxt->client);
1436 GNUNET_CONTAINER_DLL_remove (fopcq_head, 1489 GNUNET_CONTAINER_DLL_remove (fopcq_head,
1437 fopcq_tail, 1490 fopcq_tail,
1438 fo_ctxt); 1491 fo_ctxt);
@@ -1443,23 +1496,20 @@ shutdown_peers_reply_cb (void *cls,
1443/** 1496/**
1444 * Handler for #GNUNET_MESSAGE_TYPE_TESTBED_SHUTDOWN_PEERS messages 1497 * Handler for #GNUNET_MESSAGE_TYPE_TESTBED_SHUTDOWN_PEERS messages
1445 * 1498 *
1446 * @param cls NULL 1499 * @param cls identification of the client
1447 * @param client identification of the client 1500 * @param msg the actual message
1448 * @param message the actual message
1449 */ 1501 */
1450void 1502void
1451GST_handle_shutdown_peers (void *cls, 1503handle_shutdown_peers (void *cls,
1452 struct GNUNET_SERVER_Client *client, 1504 const struct GNUNET_TESTBED_ShutdownPeersMessage *msg)
1453 const struct GNUNET_MessageHeader *message)
1454{ 1505{
1455 const struct GNUNET_TESTBED_ShutdownPeersMessage *msg; 1506 struct GNUNET_SERVICE_Client *client = cls;
1456 struct HandlerContext_ShutdownPeers *hc; 1507 struct HandlerContext_ShutdownPeers *hc;
1457 struct Slave *slave; 1508 struct Slave *slave;
1458 struct ForwardedOperationContext *fo_ctxt; 1509 struct ForwardedOperationContext *fo_ctxt;
1459 uint64_t op_id; 1510 uint64_t op_id;
1460 unsigned int cnt; 1511 unsigned int cnt;
1461 1512
1462 msg = (const struct GNUNET_TESTBED_ShutdownPeersMessage *) message;
1463 LOG_DEBUG ("Received SHUTDOWN_PEERS\n"); 1513 LOG_DEBUG ("Received SHUTDOWN_PEERS\n");
1464 /* Stop and destroy all peers */ 1514 /* Stop and destroy all peers */
1465 GST_free_mctxq (); 1515 GST_free_mctxq ();
@@ -1481,7 +1531,6 @@ GST_handle_shutdown_peers (void *cls,
1481 LOG_DEBUG ("Forwarding SHUTDOWN_PEERS\n"); 1531 LOG_DEBUG ("Forwarding SHUTDOWN_PEERS\n");
1482 hc->nslaves++; 1532 hc->nslaves++;
1483 fo_ctxt = GNUNET_new (struct ForwardedOperationContext); 1533 fo_ctxt = GNUNET_new (struct ForwardedOperationContext);
1484 GNUNET_SERVER_client_keep (client);
1485 fo_ctxt->client = client; 1534 fo_ctxt->client = client;
1486 fo_ctxt->operation_id = op_id; 1535 fo_ctxt->operation_id = op_id;
1487 fo_ctxt->cls = hc; 1536 fo_ctxt->cls = hc;
@@ -1504,6 +1553,5 @@ GST_handle_shutdown_peers (void *cls,
1504 op_id); 1553 op_id);
1505 GNUNET_free (hc); 1554 GNUNET_free (hc);
1506 } 1555 }
1507 GNUNET_SERVER_receive_done (client, 1556 GNUNET_SERVICE_client_continue (client);
1508 GNUNET_OK);
1509} 1557}
diff --git a/src/testbed/test_testbed_api_barriers.c b/src/testbed/test_testbed_api_barriers.c
index 8ee9c41af..01c745a75 100644
--- a/src/testbed/test_testbed_api_barriers.c
+++ b/src/testbed/test_testbed_api_barriers.c
@@ -50,7 +50,7 @@ struct GNUNET_TESTBED_Barrier *barrier;
50/** 50/**
51 * Identifier for the shutdown task 51 * Identifier for the shutdown task
52 */ 52 */
53static struct GNUNET_SCHEDULER_Task * shutdown_task; 53static struct GNUNET_SCHEDULER_Task *shutdown_task;
54 54
55/** 55/**
56 * Result of this test case 56 * Result of this test case
@@ -85,9 +85,9 @@ do_shutdown (void *cls)
85 * @param cls the closure given to GNUNET_TESTBED_barrier_init() 85 * @param cls the closure given to GNUNET_TESTBED_barrier_init()
86 * @param name the name of the barrier 86 * @param name the name of the barrier
87 * @param barrier the barrier handle 87 * @param barrier the barrier handle
88 * @param status status of the barrier; GNUNET_OK if the barrier is crossed; 88 * @param status status of the barrier; #GNUNET_OK if the barrier is crossed;
89 * GNUNET_SYSERR upon error 89 * #GNUNET_SYSERR upon error
90 * @param emsg if the status were to be GNUNET_SYSERR, this parameter has the 90 * @param emsg if the status were to be #GNUNET_SYSERR, this parameter has the
91 * error messsage 91 * error messsage
92 */ 92 */
93static void 93static void
@@ -104,17 +104,20 @@ barrier_cb (void *cls,
104 switch (status) 104 switch (status)
105 { 105 {
106 case GNUNET_TESTBED_BARRIERSTATUS_INITIALISED: 106 case GNUNET_TESTBED_BARRIERSTATUS_INITIALISED:
107 LOG (GNUNET_ERROR_TYPE_INFO, "Barrier initialised\n"); 107 LOG (GNUNET_ERROR_TYPE_INFO,
108 "Barrier initialised\n");
108 old_status = status; 109 old_status = status;
109 return; 110 return;
110 case GNUNET_TESTBED_BARRIERSTATUS_ERROR: 111 case GNUNET_TESTBED_BARRIERSTATUS_ERROR:
111 LOG (GNUNET_ERROR_TYPE_ERROR, "Barrier initialisation failed: %s", 112 LOG (GNUNET_ERROR_TYPE_ERROR,
113 "Barrier initialisation failed: %s",
112 (NULL == emsg) ? "unknown reason" : emsg); 114 (NULL == emsg) ? "unknown reason" : emsg);
113 barrier = NULL; 115 barrier = NULL;
114 GNUNET_SCHEDULER_shutdown (); 116 GNUNET_SCHEDULER_shutdown ();
115 return; 117 return;
116 case GNUNET_TESTBED_BARRIERSTATUS_CROSSED: 118 case GNUNET_TESTBED_BARRIERSTATUS_CROSSED:
117 LOG (GNUNET_ERROR_TYPE_INFO, "Barrier crossed\n"); 119 LOG (GNUNET_ERROR_TYPE_INFO,
120 "Barrier crossed\n");
118 if (old_status == GNUNET_TESTBED_BARRIERSTATUS_INITIALISED) 121 if (old_status == GNUNET_TESTBED_BARRIERSTATUS_INITIALISED)
119 result = GNUNET_OK; 122 result = GNUNET_OK;
120 barrier = NULL; 123 barrier = NULL;
@@ -151,13 +154,17 @@ test_master (void *cls,
151 GNUNET_assert (NULL == cls); 154 GNUNET_assert (NULL == cls);
152 if (NULL == peers_) 155 if (NULL == peers_)
153 { 156 {
154 GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "Failing test due to timeout\n"); 157 GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
158 "Failing test due to timeout\n");
155 return; 159 return;
156 } 160 }
157 GNUNET_assert (NUM_PEERS == num_peers); 161 GNUNET_assert (NUM_PEERS == num_peers);
158 c = GNUNET_TESTBED_run_get_controller_handle (h); 162 c = GNUNET_TESTBED_run_get_controller_handle (h);
159 barrier = GNUNET_TESTBED_barrier_init (c, TEST_BARRIER_NAME, 100, 163 barrier = GNUNET_TESTBED_barrier_init (c,
160 &barrier_cb, NULL); 164 TEST_BARRIER_NAME,
165 100,
166 &barrier_cb,
167 NULL);
161 shutdown_task = 168 shutdown_task =
162 GNUNET_SCHEDULER_add_delayed (GNUNET_TIME_relative_multiply 169 GNUNET_SCHEDULER_add_delayed (GNUNET_TIME_relative_multiply
163 (GNUNET_TIME_UNIT_SECONDS, 170 (GNUNET_TIME_UNIT_SECONDS,
diff --git a/src/testbed/testbed_api.c b/src/testbed/testbed_api.c
index 53f70a1c0..3f2109ecd 100644
--- a/src/testbed/testbed_api.c
+++ b/src/testbed/testbed_api.c
@@ -1298,8 +1298,13 @@ handle_barrier_status (void *cls,
1298 GNUNET_assert (NULL != barrier->cb); 1298 GNUNET_assert (NULL != barrier->cb);
1299 if ((GNUNET_YES == barrier->echo) && 1299 if ((GNUNET_YES == barrier->echo) &&
1300 (GNUNET_TESTBED_BARRIERSTATUS_CROSSED == status)) 1300 (GNUNET_TESTBED_BARRIERSTATUS_CROSSED == status))
1301 GNUNET_TESTBED_queue_message_ (c, GNUNET_copy_message (&msg->header)); 1301 GNUNET_TESTBED_queue_message_ (c,
1302 barrier->cb (barrier->cls, name, barrier, status, emsg); 1302 GNUNET_copy_message (&msg->header));
1303 barrier->cb (barrier->cls,
1304 name,
1305 barrier,
1306 status,
1307 emsg);
1303 if (GNUNET_TESTBED_BARRIERSTATUS_INITIALISED == status) 1308 if (GNUNET_TESTBED_BARRIERSTATUS_INITIALISED == status)
1304 return; /* just initialised; skip cleanup */ 1309 return; /* just initialised; skip cleanup */
1305 1310
diff --git a/src/testbed/testbed_api_barriers.c b/src/testbed/testbed_api_barriers.c
index 3761fbbdf..1679756a1 100644
--- a/src/testbed/testbed_api_barriers.c
+++ b/src/testbed/testbed_api_barriers.c
@@ -105,6 +105,9 @@ handle_status (void *cls,
105{ 105{
106 struct GNUNET_TESTBED_BarrierWaitHandle *h = cls; 106 struct GNUNET_TESTBED_BarrierWaitHandle *h = cls;
107 107
108 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
109 "Got barrier status %d\n",
110 (int) ntohs (msg->status));
108 switch (ntohs (msg->status)) 111 switch (ntohs (msg->status))
109 { 112 {
110 case GNUNET_TESTBED_BARRIERSTATUS_ERROR: 113 case GNUNET_TESTBED_BARRIERSTATUS_ERROR:
@@ -206,6 +209,9 @@ GNUNET_TESTBED_barrier_wait (const char *name,
206 GNUNET_free (h); 209 GNUNET_free (h);
207 return NULL; 210 return NULL;
208 } 211 }
212 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
213 "Waiting on barrier `%s'\n",
214 name);
209 h->name = GNUNET_strdup (name); 215 h->name = GNUNET_strdup (name);
210 h->cb = cb; 216 h->cb = cb;
211 h->cb_cls = cb_cls; 217 h->cb_cls = cb_cls;
@@ -226,8 +232,8 @@ GNUNET_TESTBED_barrier_wait (const char *name,
226 name_len, 232 name_len,
227 GNUNET_MESSAGE_TYPE_TESTBED_BARRIER_WAIT); 233 GNUNET_MESSAGE_TYPE_TESTBED_BARRIER_WAIT);
228 GNUNET_memcpy (msg->name, 234 GNUNET_memcpy (msg->name,
229 name, 235 name,
230 name_len); 236 name_len);
231 GNUNET_MQ_send (h->mq, 237 GNUNET_MQ_send (h->mq,
232 env); 238 env);
233 return h; 239 return h;