aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/ats/ats_api_scheduling.c35
-rw-r--r--src/conversation/conversation_api.c88
-rw-r--r--src/include/gnunet_client_lib.h59
-rw-r--r--src/include/gnunet_mq_lib.h235
-rw-r--r--src/include/gnunet_server_lib.h10
-rw-r--r--src/set/set_api.c195
-rw-r--r--src/util/mq.c107
-rw-r--r--src/util/perf_crypto_asymmetric.c2
8 files changed, 468 insertions, 263 deletions
diff --git a/src/ats/ats_api_scheduling.c b/src/ats/ats_api_scheduling.c
index 0d0d102db..bc730b248 100644
--- a/src/ats/ats_api_scheduling.c
+++ b/src/ats/ats_api_scheduling.c
@@ -357,16 +357,14 @@ release_session (struct GNUNET_ATS_SchedulingHandle *sh,
357 * message from the service. 357 * message from the service.
358 * 358 *
359 * @param cls the `struct GNUNET_ATS_SchedulingHandle` 359 * @param cls the `struct GNUNET_ATS_SchedulingHandle`
360 * @param msg message received, NULL on timeout or fatal error 360 * @param srm message received
361 */ 361 */
362static void 362static void
363process_ats_session_release_message (void *cls, 363handle_ats_session_release (void *cls,
364 const struct GNUNET_MessageHeader *msg) 364 const struct GNUNET_ATS_SessionReleaseMessage *srm)
365{ 365{
366 struct GNUNET_ATS_SchedulingHandle *sh = cls; 366 struct GNUNET_ATS_SchedulingHandle *sh = cls;
367 const struct GNUNET_ATS_SessionReleaseMessage *srm;
368 367
369 srm = (const struct GNUNET_ATS_SessionReleaseMessage *) msg;
370 /* Note: peer field in srm not necessary right now, 368 /* Note: peer field in srm not necessary right now,
371 but might be good to have in the future */ 369 but might be good to have in the future */
372 release_session (sh, 370 release_session (sh,
@@ -379,18 +377,16 @@ process_ats_session_release_message (void *cls,
379 * message from the service. 377 * message from the service.
380 * 378 *
381 * @param cls the `struct GNUNET_ATS_SchedulingHandle` 379 * @param cls the `struct GNUNET_ATS_SchedulingHandle`
382 * @param msg message received, NULL on timeout or fatal error 380 * @param m message received
383 */ 381 */
384static void 382static void
385process_ats_address_suggestion_message (void *cls, 383handle_ats_address_suggestion (void *cls,
386 const struct GNUNET_MessageHeader *msg) 384 const struct AddressSuggestionMessage *m)
387{ 385{
388 struct GNUNET_ATS_SchedulingHandle *sh = cls; 386 struct GNUNET_ATS_SchedulingHandle *sh = cls;
389 const struct AddressSuggestionMessage *m;
390 struct GNUNET_ATS_AddressRecord *ar; 387 struct GNUNET_ATS_AddressRecord *ar;
391 uint32_t session_id; 388 uint32_t session_id;
392 389
393 m = (const struct AddressSuggestionMessage *) msg;
394 session_id = ntohl (m->session_id); 390 session_id = ntohl (m->session_id);
395 if (0 == session_id) 391 if (0 == session_id)
396 { 392 {
@@ -528,14 +524,17 @@ send_add_address_message (struct GNUNET_ATS_SchedulingHandle *sh,
528static void 524static void
529reconnect (struct GNUNET_ATS_SchedulingHandle *sh) 525reconnect (struct GNUNET_ATS_SchedulingHandle *sh)
530{ 526{
531 static const struct GNUNET_MQ_MessageHandler handlers[] = 527 GNUNET_MQ_hd_fixed_size (ats_session_release,
532 { { &process_ats_session_release_message, 528 GNUNET_MESSAGE_TYPE_ATS_SESSION_RELEASE,
533 GNUNET_MESSAGE_TYPE_ATS_SESSION_RELEASE, 529 struct GNUNET_ATS_SessionReleaseMessage);
534 sizeof (struct GNUNET_ATS_SessionReleaseMessage) }, 530 GNUNET_MQ_hd_fixed_size (ats_address_suggestion,
535 { &process_ats_address_suggestion_message, 531 GNUNET_MESSAGE_TYPE_ATS_ADDRESS_SUGGESTION,
536 GNUNET_MESSAGE_TYPE_ATS_ADDRESS_SUGGESTION, 532 struct AddressSuggestionMessage);
537 sizeof (struct AddressSuggestionMessage) }, 533 struct GNUNET_MQ_MessageHandler handlers[] = {
538 { NULL, 0, 0 } }; 534 make_ats_session_release_handler (sh),
535 make_ats_address_suggestion_handler (sh),
536 GNUNET_MQ_handler_end ()
537 };
539 struct GNUNET_MQ_Envelope *ev; 538 struct GNUNET_MQ_Envelope *ev;
540 struct ClientStartMessage *init; 539 struct ClientStartMessage *init;
541 unsigned int i; 540 unsigned int i;
diff --git a/src/conversation/conversation_api.c b/src/conversation/conversation_api.c
index f28e71a98..a9dc1f27f 100644
--- a/src/conversation/conversation_api.c
+++ b/src/conversation/conversation_api.c
@@ -252,17 +252,15 @@ transmit_phone_audio (void *cls,
252 * We received a `struct ClientPhoneRingMessage` 252 * We received a `struct ClientPhoneRingMessage`
253 * 253 *
254 * @param cls the `struct GNUNET_CONVERSATION_Phone` 254 * @param cls the `struct GNUNET_CONVERSATION_Phone`
255 * @param msg the message 255 * @param ring the message
256 */ 256 */
257static void 257static void
258handle_phone_ring (void *cls, 258handle_phone_ring (void *cls,
259 const struct GNUNET_MessageHeader *msg) 259 const struct ClientPhoneRingMessage *ring)
260{ 260{
261 struct GNUNET_CONVERSATION_Phone *phone = cls; 261 struct GNUNET_CONVERSATION_Phone *phone = cls;
262 const struct ClientPhoneRingMessage *ring;
263 struct GNUNET_CONVERSATION_Caller *caller; 262 struct GNUNET_CONVERSATION_Caller *caller;
264 263
265 ring = (const struct ClientPhoneRingMessage *) msg;
266 switch (phone->state) 264 switch (phone->state)
267 { 265 {
268 case PS_REGISTER: 266 case PS_REGISTER:
@@ -294,13 +292,11 @@ handle_phone_ring (void *cls,
294 */ 292 */
295static void 293static void
296handle_phone_hangup (void *cls, 294handle_phone_hangup (void *cls,
297 const struct GNUNET_MessageHeader *msg) 295 const struct ClientPhoneHangupMessage *hang)
298{ 296{
299 struct GNUNET_CONVERSATION_Phone *phone = cls; 297 struct GNUNET_CONVERSATION_Phone *phone = cls;
300 const struct ClientPhoneHangupMessage *hang;
301 struct GNUNET_CONVERSATION_Caller *caller; 298 struct GNUNET_CONVERSATION_Caller *caller;
302 299
303 hang = (const struct ClientPhoneHangupMessage *) msg;
304 for (caller = phone->caller_head; NULL != caller; caller = caller->next) 300 for (caller = phone->caller_head; NULL != caller; caller = caller->next)
305 if (hang->cid == caller->cid) 301 if (hang->cid == caller->cid)
306 break; 302 break;
@@ -351,17 +347,15 @@ handle_phone_hangup (void *cls,
351 * We received a `struct ClientPhoneSuspendMessage`. 347 * We received a `struct ClientPhoneSuspendMessage`.
352 * 348 *
353 * @param cls the `struct GNUNET_CONVERSATION_Phone` 349 * @param cls the `struct GNUNET_CONVERSATION_Phone`
354 * @param msg the message 350 * @param suspend the message
355 */ 351 */
356static void 352static void
357handle_phone_suspend (void *cls, 353handle_phone_suspend (void *cls,
358 const struct GNUNET_MessageHeader *msg) 354 const struct ClientPhoneSuspendMessage *suspend)
359{ 355{
360 struct GNUNET_CONVERSATION_Phone *phone = cls; 356 struct GNUNET_CONVERSATION_Phone *phone = cls;
361 struct GNUNET_CONVERSATION_Caller *caller; 357 struct GNUNET_CONVERSATION_Caller *caller;
362 const struct ClientPhoneSuspendMessage *suspend;
363 358
364 suspend = (const struct ClientPhoneSuspendMessage *) msg;
365 for (caller = phone->caller_head; NULL != caller; caller = caller->next) 359 for (caller = phone->caller_head; NULL != caller; caller = caller->next)
366 if (suspend->cid == caller->cid) 360 if (suspend->cid == caller->cid)
367 break; 361 break;
@@ -396,17 +390,15 @@ handle_phone_suspend (void *cls,
396 * We received a `struct ClientPhoneResumeMessage`. 390 * We received a `struct ClientPhoneResumeMessage`.
397 * 391 *
398 * @param cls the `struct GNUNET_CONVERSATION_Phone` 392 * @param cls the `struct GNUNET_CONVERSATION_Phone`
399 * @param msg the message 393 * @param resume the message
400 */ 394 */
401static void 395static void
402handle_phone_resume (void *cls, 396handle_phone_resume (void *cls,
403 const struct GNUNET_MessageHeader *msg) 397 const struct ClientPhoneResumeMessage *resume)
404{ 398{
405 struct GNUNET_CONVERSATION_Phone *phone = cls; 399 struct GNUNET_CONVERSATION_Phone *phone = cls;
406 struct GNUNET_CONVERSATION_Caller *caller; 400 struct GNUNET_CONVERSATION_Caller *caller;
407 const struct ClientPhoneResumeMessage *resume;
408 401
409 resume = (const struct ClientPhoneResumeMessage *) msg;
410 for (caller = phone->caller_head; NULL != caller; caller = caller->next) 402 for (caller = phone->caller_head; NULL != caller; caller = caller->next)
411 if (resume->cid == caller->cid) 403 if (resume->cid == caller->cid)
412 break; 404 break;
@@ -440,20 +432,34 @@ handle_phone_resume (void *cls,
440 432
441 433
442/** 434/**
435 * We received a `struct ClientAudioMessage`, check it is well-formed.
436 *
437 * @param cls the `struct GNUNET_CONVERSATION_Phone`
438 * @param am the message
439 * @return #GNUNET_OK if @a am is well-formed
440 */
441static int
442check_phone_audio (void *cls,
443 const struct ClientAudioMessage *am)
444{
445 /* any variable-size payload is OK */
446 return GNUNET_OK;
447}
448
449
450/**
443 * We received a `struct ClientAudioMessage` 451 * We received a `struct ClientAudioMessage`
444 * 452 *
445 * @param cls the `struct GNUNET_CONVERSATION_Phone` 453 * @param cls the `struct GNUNET_CONVERSATION_Phone`
446 * @param msg the message 454 * @param am the message
447 */ 455 */
448static void 456static void
449handle_phone_audio_message (void *cls, 457handle_phone_audio (void *cls,
450 const struct GNUNET_MessageHeader *msg) 458 const struct ClientAudioMessage *am)
451{ 459{
452 struct GNUNET_CONVERSATION_Phone *phone = cls; 460 struct GNUNET_CONVERSATION_Phone *phone = cls;
453 const struct ClientAudioMessage *am;
454 struct GNUNET_CONVERSATION_Caller *caller; 461 struct GNUNET_CONVERSATION_Caller *caller;
455 462
456 am = (const struct ClientAudioMessage *) msg;
457 for (caller = phone->caller_head; NULL != caller; caller = caller->next) 463 for (caller = phone->caller_head; NULL != caller; caller = caller->next)
458 if (am->cid == caller->cid) 464 if (am->cid == caller->cid)
459 break; 465 break;
@@ -466,7 +472,7 @@ handle_phone_audio_message (void *cls,
466 break; 472 break;
467 case CS_ACTIVE: 473 case CS_ACTIVE:
468 caller->speaker->play (caller->speaker->cls, 474 caller->speaker->play (caller->speaker->cls,
469 ntohs (msg->size) - sizeof (struct ClientAudioMessage), 475 ntohs (am->header.size) - sizeof (struct ClientAudioMessage),
470 &am[1]); 476 &am[1]);
471 break; 477 break;
472 case CS_CALLEE_SUSPENDED: 478 case CS_CALLEE_SUSPENDED:
@@ -531,24 +537,28 @@ clean_up_callers (struct GNUNET_CONVERSATION_Phone *phone)
531static void 537static void
532reconnect_phone (struct GNUNET_CONVERSATION_Phone *phone) 538reconnect_phone (struct GNUNET_CONVERSATION_Phone *phone)
533{ 539{
534 static struct GNUNET_MQ_MessageHandler handlers[] = 540 GNUNET_MQ_hd_fixed_size (phone_ring,
535 { 541 GNUNET_MESSAGE_TYPE_CONVERSATION_CS_PHONE_RING,
536 { &handle_phone_ring, 542 struct ClientPhoneRingMessage);
537 GNUNET_MESSAGE_TYPE_CONVERSATION_CS_PHONE_RING, 543 GNUNET_MQ_hd_fixed_size (phone_hangup,
538 sizeof (struct ClientPhoneRingMessage) }, 544 GNUNET_MESSAGE_TYPE_CONVERSATION_CS_PHONE_HANG_UP,
539 { &handle_phone_hangup, 545 struct ClientPhoneHangupMessage);
540 GNUNET_MESSAGE_TYPE_CONVERSATION_CS_PHONE_HANG_UP, 546 GNUNET_MQ_hd_fixed_size (phone_suspend,
541 sizeof (struct ClientPhoneHangupMessage) }, 547 GNUNET_MESSAGE_TYPE_CONVERSATION_CS_PHONE_SUSPEND,
542 { &handle_phone_suspend, 548 struct ClientPhoneSuspendMessage);
543 GNUNET_MESSAGE_TYPE_CONVERSATION_CS_PHONE_SUSPEND, 549 GNUNET_MQ_hd_fixed_size (phone_resume,
544 sizeof (struct ClientPhoneSuspendMessage) }, 550 GNUNET_MESSAGE_TYPE_CONVERSATION_CS_PHONE_RESUME,
545 { &handle_phone_resume, 551 struct ClientPhoneResumeMessage);
546 GNUNET_MESSAGE_TYPE_CONVERSATION_CS_PHONE_RESUME, 552 GNUNET_MQ_hd_var_size (phone_audio,
547 sizeof (struct ClientPhoneResumeMessage) }, 553 GNUNET_MESSAGE_TYPE_CONVERSATION_CS_AUDIO,
548 { &handle_phone_audio_message, 554 struct ClientAudioMessage);
549 GNUNET_MESSAGE_TYPE_CONVERSATION_CS_AUDIO, 555 struct GNUNET_MQ_MessageHandler handlers[] = {
550 0 }, 556 make_phone_ring_handler (phone),
551 { NULL, 0, 0 } 557 make_phone_hangup_handler (phone),
558 make_phone_suspend_handler (phone),
559 make_phone_resume_handler (phone),
560 make_phone_audio_handler (phone),
561 GNUNET_MQ_handler_end ()
552 }; 562 };
553 struct GNUNET_MQ_Envelope *e; 563 struct GNUNET_MQ_Envelope *e;
554 struct ClientPhoneRegisterMessage *reg; 564 struct ClientPhoneRegisterMessage *reg;
diff --git a/src/include/gnunet_client_lib.h b/src/include/gnunet_client_lib.h
index 93c2a3f9c..4bac4d5f3 100644
--- a/src/include/gnunet_client_lib.h
+++ b/src/include/gnunet_client_lib.h
@@ -43,18 +43,57 @@ extern "C"
43#endif 43#endif
44#endif 44#endif
45 45
46#include "gnunet_mq_lib.h"
46 47
47/** 48/**
48 * Opaque handle for a connection to a service. 49 * Opaque handle for a connection to a service.
49 */ 50 */
50struct GNUNET_CLIENT_Connection; 51struct GNUNET_CLIENT_Connection;
51 52
53
54/**
55 * Create a message queue to connect to a GNUnet service.
56 * If handlers are specfied, receive messages from the connection.
57 *
58 * @param connection the client connection
59 * @param handlers handlers for receiving messages, can be NULL
60 * @param error_handler error handler
61 * @param error_handler_cls closure for the @a error_handler
62 * @return the message queue
63 */
64struct GNUNET_MQ_Handle *
65GNUNET_CLIENT_connect2 (const char *service_name,
66 const struct GNUNET_CONFIGURATION_Handle *cfg,
67 const struct GNUNET_MQ_MessageHandler *handlers,
68 GNUNET_MQ_ErrorHandler error_handler,
69 void *error_handler_cls);
70
71
72/**
73 * Create a message queue for a GNUNET_CLIENT_Connection.
74 * If handlers are specfied, receive messages from the connection.
75 *
76 * @param connection the client connection
77 * @param handlers handlers for receiving messages
78 * @param error_handler error handler
79 * @param error_handler_cls closure for the @a error_handler
80 * @return the message queue
81 * @deprecated use #GNUNET_CLIENT_connect2
82 */
83struct GNUNET_MQ_Handle *
84GNUNET_MQ_queue_for_connection_client (struct GNUNET_CLIENT_Connection *connection,
85 const struct GNUNET_MQ_MessageHandler *handlers,
86 GNUNET_MQ_ErrorHandler error_handler,
87 void *error_handler_cls);
88
89
52/** 90/**
53 * Get a connection with a service. 91 * Get a connection with a service.
54 * 92 *
55 * @param service_name name of the service 93 * @param service_name name of the service
56 * @param cfg configuration to use 94 * @param cfg configuration to use
57 * @return NULL on error (service unknown to configuration) 95 * @return NULL on error (service unknown to configuration)
96 * @deprecated use #GNUNET_CLIENT_connect2
58 */ 97 */
59struct GNUNET_CLIENT_Connection * 98struct GNUNET_CLIENT_Connection *
60GNUNET_CLIENT_connect (const char *service_name, 99GNUNET_CLIENT_connect (const char *service_name,
@@ -73,6 +112,7 @@ GNUNET_CLIENT_connect (const char *service_name,
73 * which case the message may still be lost). 112 * which case the message may still be lost).
74 * 113 *
75 * @param client handle to the service connection 114 * @param client handle to the service connection
115 * @deprecated
76 */ 116 */
77void 117void
78GNUNET_CLIENT_disconnect (struct GNUNET_CLIENT_Connection *client); 118GNUNET_CLIENT_disconnect (struct GNUNET_CLIENT_Connection *client);
@@ -85,8 +125,9 @@ GNUNET_CLIENT_disconnect (struct GNUNET_CLIENT_Connection *client);
85 * @param cls closure 125 * @param cls closure
86 * @param msg message received, NULL on timeout or fatal error 126 * @param msg message received, NULL on timeout or fatal error
87 */ 127 */
88typedef void (*GNUNET_CLIENT_MessageHandler) (void *cls, 128typedef void
89 const struct GNUNET_MessageHeader *msg); 129(*GNUNET_CLIENT_MessageHandler) (void *cls,
130 const struct GNUNET_MessageHeader *msg);
90 131
91 132
92/** 133/**
@@ -96,10 +137,12 @@ typedef void (*GNUNET_CLIENT_MessageHandler) (void *cls,
96 * @param handler function to call with the message 137 * @param handler function to call with the message
97 * @param handler_cls closure for @a handler 138 * @param handler_cls closure for @a handler
98 * @param timeout how long to wait until timing out 139 * @param timeout how long to wait until timing out
140 * @deprecated
99 */ 141 */
100void 142void
101GNUNET_CLIENT_receive (struct GNUNET_CLIENT_Connection *client, 143GNUNET_CLIENT_receive (struct GNUNET_CLIENT_Connection *client,
102 GNUNET_CLIENT_MessageHandler handler, void *handler_cls, 144 GNUNET_CLIENT_MessageHandler handler,
145 void *handler_cls,
103 struct GNUNET_TIME_Relative timeout); 146 struct GNUNET_TIME_Relative timeout);
104 147
105 148
@@ -128,6 +171,7 @@ struct GNUNET_CLIENT_TransmitHandle;
128 * @return NULL if someone else is already waiting to be notified 171 * @return NULL if someone else is already waiting to be notified
129 * non-NULL if the notify callback was queued (can be used to cancel 172 * non-NULL if the notify callback was queued (can be used to cancel
130 * using #GNUNET_CONNECTION_notify_transmit_ready_cancel) 173 * using #GNUNET_CONNECTION_notify_transmit_ready_cancel)
174 * @deprecated
131 */ 175 */
132struct GNUNET_CLIENT_TransmitHandle * 176struct GNUNET_CLIENT_TransmitHandle *
133GNUNET_CLIENT_notify_transmit_ready (struct GNUNET_CLIENT_Connection *client, 177GNUNET_CLIENT_notify_transmit_ready (struct GNUNET_CLIENT_Connection *client,
@@ -142,6 +186,7 @@ GNUNET_CLIENT_notify_transmit_ready (struct GNUNET_CLIENT_Connection *client,
142 * Cancel a request for notification. 186 * Cancel a request for notification.
143 * 187 *
144 * @param th handle from the original request. 188 * @param th handle from the original request.
189 * @deprecated
145 */ 190 */
146void 191void
147GNUNET_CLIENT_notify_transmit_ready_cancel (struct GNUNET_CLIENT_TransmitHandle 192GNUNET_CLIENT_notify_transmit_ready_cancel (struct GNUNET_CLIENT_TransmitHandle
@@ -168,6 +213,7 @@ GNUNET_CLIENT_notify_transmit_ready_cancel (struct GNUNET_CLIENT_TransmitHandle
168 * @param rn_cls closure for @a rn 213 * @param rn_cls closure for @a rn
169 * @return #GNUNET_OK on success, #GNUNET_SYSERR if a request 214 * @return #GNUNET_OK on success, #GNUNET_SYSERR if a request
170 * is already pending 215 * is already pending
216 * @deprecated
171 */ 217 */
172int 218int
173GNUNET_CLIENT_transmit_and_get_response (struct GNUNET_CLIENT_Connection *client, 219GNUNET_CLIENT_transmit_and_get_response (struct GNUNET_CLIENT_Connection *client,
@@ -191,8 +237,9 @@ struct GNUNET_CLIENT_TestHandle;
191 * #GNUNET_NO if the service is not running 237 * #GNUNET_NO if the service is not running
192 * #GNUNET_SYSERR if the configuration is invalid 238 * #GNUNET_SYSERR if the configuration is invalid
193 */ 239 */
194typedef void (*GNUNET_CLIENT_TestResultCallback)(void *cls, 240typedef void
195 int result); 241(*GNUNET_CLIENT_TestResultCallback)(void *cls,
242 int result);
196 243
197 244
198/** 245/**
@@ -207,6 +254,7 @@ typedef void (*GNUNET_CLIENT_TestResultCallback)(void *cls,
207 * @param cb function to call with the result 254 * @param cb function to call with the result
208 * @param cb_cls closure for @a cb 255 * @param cb_cls closure for @a cb
209 * @return handle to cancel the test 256 * @return handle to cancel the test
257 * @deprecated
210 */ 258 */
211struct GNUNET_CLIENT_TestHandle * 259struct GNUNET_CLIENT_TestHandle *
212GNUNET_CLIENT_service_test (const char *service, 260GNUNET_CLIENT_service_test (const char *service,
@@ -219,6 +267,7 @@ GNUNET_CLIENT_service_test (const char *service,
219 * Abort testing for service. 267 * Abort testing for service.
220 * 268 *
221 * @param th test handle 269 * @param th test handle
270 * @deprecated
222 */ 271 */
223void 272void
224GNUNET_CLIENT_service_test_cancel (struct GNUNET_CLIENT_TestHandle *th); 273GNUNET_CLIENT_service_test_cancel (struct GNUNET_CLIENT_TestHandle *th);
diff --git a/src/include/gnunet_mq_lib.h b/src/include/gnunet_mq_lib.h
index 971c87b18..38ebf6b17 100644
--- a/src/include/gnunet_mq_lib.h
+++ b/src/include/gnunet_mq_lib.h
@@ -1,6 +1,6 @@
1/* 1/*
2 This file is part of GNUnet. 2 This file is part of GNUnet.
3 Copyright (C) 2012-2013 GNUnet e.V. 3 Copyright (C) 2012-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
@@ -20,6 +20,7 @@
20 20
21/** 21/**
22 * @author Florian Dold 22 * @author Florian Dold
23 * @author Christian Grothoff
23 * 24 *
24 * @file 25 * @file
25 * General-purpose message queue 26 * General-purpose message queue
@@ -117,7 +118,7 @@ GNUNET_MQ_extract_nested_mh_ (const struct GNUNET_MessageHeader *mh,
117 118
118 119
119/** 120/**
120 * Implementation of the GNUNET_MQ_msg_nested_mh macro. 121 * Implementation of the #GNUNET_MQ_msg_nested_mh macro.
121 * 122 *
122 * @param mhp pointer to the message header pointer that will be changed to allocate at 123 * @param mhp pointer to the message header pointer that will be changed to allocate at
123 * the newly allocated space for the message. 124 * the newly allocated space for the message.
@@ -132,13 +133,6 @@ GNUNET_MQ_msg_nested_mh_ (struct GNUNET_MessageHeader **mhp,
132 const struct GNUNET_MessageHeader *nested_mh); 133 const struct GNUNET_MessageHeader *nested_mh);
133 134
134 135
135
136/**
137 * End-marker for the handlers array
138 */
139#define GNUNET_MQ_HANDLERS_END {NULL, 0, 0}
140
141
142/** 136/**
143 * Opaque handle to a message queue. 137 * Opaque handle to a message queue.
144 */ 138 */
@@ -156,7 +150,9 @@ struct GNUNET_MQ_Envelope;
156enum GNUNET_MQ_Error 150enum GNUNET_MQ_Error
157{ 151{
158 /** 152 /**
159 * FIXME: document! 153 * Failed to read message from the network.
154 * FIXME: Likely not properly distinguished
155 * from TIMEOUT case in the code!
160 */ 156 */
161 GNUNET_MQ_ERROR_READ = 1, 157 GNUNET_MQ_ERROR_READ = 1,
162 158
@@ -168,7 +164,13 @@ enum GNUNET_MQ_Error
168 /** 164 /**
169 * FIXME: document! 165 * FIXME: document!
170 */ 166 */
171 GNUNET_MQ_ERROR_TIMEOUT = 4 167 GNUNET_MQ_ERROR_TIMEOUT = 4,
168
169 /**
170 * We received a message that was malformed and thus
171 * could not be passed to its handler.
172 */
173 GNUNET_MQ_ERROR_MALFORMED = 8
172}; 174};
173 175
174 176
@@ -184,6 +186,19 @@ typedef void
184 186
185 187
186/** 188/**
189 * Called when a message needs to be validated.
190 *
191 * @param cls closure
192 * @param msg the received message
193 * @return #GNUNET_OK if the message is well-formed,
194 * #GNUNET_SYSERR if not
195 */
196typedef int
197(*GNUNET_MQ_MessageValidationCallback) (void *cls,
198 const struct GNUNET_MessageHeader *msg);
199
200
201/**
187 * Signature of functions implementing the 202 * Signature of functions implementing the
188 * sending functionality of a message queue. 203 * sending functionality of a message queue.
189 * 204 *
@@ -251,26 +266,136 @@ typedef void
251struct GNUNET_MQ_MessageHandler 266struct GNUNET_MQ_MessageHandler
252{ 267{
253 /** 268 /**
269 * Callback to validate a message of the specified @e type.
270 * The closure given to @e mv will be this struct (not @e ctx).
271 * Using NULL means only size-validation using
272 * @e expected_size. In this case, @e expected_size must
273 * be non-zero.
274 */
275 GNUNET_MQ_MessageValidationCallback mv;
276
277 /**
254 * Callback, called every time a new message of 278 * Callback, called every time a new message of
255 * the specified type has been receied. 279 * the specified @e type has been receied.
280 * The closure given to @e mv will be this struct (not @e ctx).
256 */ 281 */
257 GNUNET_MQ_MessageCallback cb; 282 GNUNET_MQ_MessageCallback cb;
258 283
259 /** 284 /**
260 * Type of the message this handler covers. 285 * Closure for @e mv and @e cb.
286 */
287 void *cls;
288
289 /**
290 * Type of the message this handler covers, in host byte order.
261 */ 291 */
262 uint16_t type; 292 uint16_t type;
263 293
264 /** 294 /**
265 * Expected size of messages of this type. Use 0 for 295 * Expected size of messages of this type. Minimum size of the
266 * variable-size. If non-zero, messages of the given 296 * message if @e mv is non-NULL. Messages of the given type will be
267 * type will be discarded (and the connection closed) 297 * discarded (and the connection closed with an error reported to
268 * if they do not have the right size. 298 * the application) if they do not have the right size.
269 */ 299 */
270 uint16_t expected_size; 300 uint16_t expected_size;
271}; 301};
272 302
273 303
304/**
305 * End-marker for the handlers array
306 */
307#define GNUNET_MQ_handler_end() {NULL, NULL, NULL, 0, 0}
308
309
310/**
311 * Defines a static function @a name which takes as a single argument
312 * a message handler for fixed-sized messages of type @a code and with
313 * a message type argument of @a str. Given such an argument, the
314 * function @name will return a `struct GNUNET_MQ_MessageHandler`
315 * for the given message type.
316 *
317 * The macro is to be used as follows:
318 * <code>
319 * struct GNUNET_MessageTest { ... }; // must be fixed size
320 * GNUNET_MQ_hd_fixed_size(test_message,
321 * GNUNET_MESSAGE_TYPE_TEST,
322 * struct GNUNET_MessageTest);
323 * static void
324 * handle_test_message (void *cls, // the struct GNUNET_MQ_MessageHandler
325 * const struct GNUNET_MessageTest *msg)
326 * { ... }
327 *
328 * struct GNUNET_MQ_MessageHandler handlers[] = {
329 * make_test_message_handler (),
330 * GNUNET_MQ_handler_end()
331 * };
332 *
333 * @param name unique basename for the functions
334 * @param code message type constant
335 * @param str type of the message (a struct)
336 */
337#define GNUNET_MQ_hd_fixed_size(name,code,str) \
338 struct GNUNET_MQ_MessageHandler \
339 make_##name##_handler (void *cls) { \
340 void (*cb)(void *cls, const str *msg) = &handle_##name; \
341 struct GNUNET_MQ_MessageHandler mh = { \
342 NULL, (GNUNET_MQ_MessageCallback) cb, \
343 cls, code, sizeof (str) }; \
344 return mh; \
345 }
346
347
348/**
349 * Defines a static function @a name which takes two arguments and a
350 * context-pointer for validating and handling variable-sized messages
351 * of type @a code and with a message type argument of @a str. Given
352 * such arguments, the function @name will return a `struct
353 * GNUNET_MQ_MessageHandler` for the given message type.
354 *
355 * The macro is to be used as follows:
356 * <code>
357 * struct GNUNET_MessageTest { ... }; // can be variable size
358 * GNUNET_MQ_hd_var_size(test_message,
359 * GNUNET_MESSAGE_TYPE_TEST,
360 * struct GNUNET_MessageTest);
361 * static int
362 * check_test (void *cls,
363 * const struct GNUNET_MessageTest *msg)
364 * {
365 * const char *ctx = cls;
366 * GNUNET_assert (0 == strcmp ("context", ctx));
367 * // ...
368 * }
369 * static void
370 * handle_test (void *cls,
371 * const struct GNUNET_MessageTest *msg)
372 * {
373 * const char *ctx = cls;
374 * GNUNET_assert (0 == strcmp ("context", ctx));
375 * // ...
376 * }
377 *
378 * struct GNUNET_MQ_MessageHandler handlers[] = {
379 * make_test_message_handler ("context"),
380 * GNUNET_MQ_handler_end()
381 * };
382 *
383 * @param name unique basename for the functions
384 * @param code message type constant
385 * @param str type of the message (a struct)
386 */
387#define GNUNET_MQ_hd_var_size(name,code,str) \
388 struct GNUNET_MQ_MessageHandler \
389 make_##name##_handler (void *ctx) { \
390 int (*mv)(void *cls, const str *msg) = &check_##name; \
391 void (*cb)(void *cls, const str *msg) = &handle_##name;\
392 struct GNUNET_MQ_MessageHandler mh = \
393 { (GNUNET_MQ_MessageValidationCallback) mv, \
394 (GNUNET_MQ_MessageCallback) cb, \
395 ctx, code, sizeof (str) }; \
396 return mh; \
397 }
398
274 399
275/** 400/**
276 * Create a new envelope. 401 * Create a new envelope.
@@ -321,17 +446,18 @@ GNUNET_MQ_send_cancel (struct GNUNET_MQ_Envelope *ev);
321 446
322 447
323/** 448/**
324 * Associate the assoc_data in mq with a unique request id. 449 * Associate the assoc_data in @a mq with a unique request id.
325 * 450 *
326 * @param mq message queue, id will be unique for the queue 451 * @param mq message queue, id will be unique for the queue
327 * @param assoc_data to associate 452 * @param assoc_data to associate
328 */ 453 */
329uint32_t 454uint32_t
330GNUNET_MQ_assoc_add (struct GNUNET_MQ_Handle *mq, void *assoc_data); 455GNUNET_MQ_assoc_add (struct GNUNET_MQ_Handle *mq,
456 void *assoc_data);
331 457
332 458
333/** 459/**
334 * Get the data associated with a request id in a queue 460 * Get the data associated with a @a request_id in a queue
335 * 461 *
336 * @param mq the message queue with the association 462 * @param mq the message queue with the association
337 * @param request_id the request id we are interested in 463 * @param request_id the request id we are interested in
@@ -343,7 +469,7 @@ GNUNET_MQ_assoc_get (struct GNUNET_MQ_Handle *mq,
343 469
344 470
345/** 471/**
346 * Remove the association for a request id 472 * Remove the association for a @a request_id
347 * 473 *
348 * @param mq the message queue with the association 474 * @param mq the message queue with the association
349 * @param request_id the request id we want to remove 475 * @param request_id the request id we want to remove
@@ -355,33 +481,6 @@ GNUNET_MQ_assoc_remove (struct GNUNET_MQ_Handle *mq,
355 481
356 482
357/** 483/**
358 * Create a message queue for a GNUNET_CLIENT_Connection.
359 * If handlers are specfied, receive messages from the connection.
360 *
361 * @param connection the client connection
362 * @param handlers handlers for receiving messages
363 * @param error_handler error handler
364 * @param cls closure for the handlers
365 * @return the message queue
366 */
367struct GNUNET_MQ_Handle *
368GNUNET_MQ_queue_for_connection_client (struct GNUNET_CLIENT_Connection *connection,
369 const struct GNUNET_MQ_MessageHandler *handlers,
370 GNUNET_MQ_ErrorHandler error_handler,
371 void *cls);
372
373
374/**
375 * Create a message queue for a GNUNET_SERVER_Client.
376 *
377 * @param client the client
378 * @return the message queue
379 */
380struct GNUNET_MQ_Handle *
381GNUNET_MQ_queue_for_server_client (struct GNUNET_SERVER_Client *client);
382
383
384/**
385 * Create a message queue for the specified handlers. 484 * Create a message queue for the specified handlers.
386 * 485 *
387 * @param send function the implements sending messages 486 * @param send function the implements sending messages
@@ -404,24 +503,6 @@ GNUNET_MQ_queue_for_callbacks (GNUNET_MQ_SendImpl send,
404 503
405 504
406/** 505/**
407 * Replace the handlers of a message queue with new handlers. Takes
408 * effect immediately, even for messages that already have been
409 * received, but for with the handler has not been called.
410 *
411 * If the message queue does not support receiving messages,
412 * this function has no effect.
413 *
414 * @param mq message queue
415 * @param new_handlers new handlers
416 * @param cls new closure for the handlers
417 */
418void
419GNUNET_MQ_replace_handlers (struct GNUNET_MQ_Handle *mq,
420 const struct GNUNET_MQ_MessageHandler *new_handlers,
421 void *cls);
422
423
424/**
425 * Call a callback once the envelope has been sent, that is, 506 * Call a callback once the envelope has been sent, that is,
426 * sending it can not be canceled anymore. 507 * sending it can not be canceled anymore.
427 * There can be only one notify sent callback per envelope. 508 * There can be only one notify sent callback per envelope.
@@ -476,10 +557,9 @@ GNUNET_MQ_inject_error (struct GNUNET_MQ_Handle *mq,
476 557
477 558
478/** 559/**
479 * Call the send implementation for the next queued message, 560 * Call the send implementation for the next queued message, if any.
480 * if any. 561 * Only useful for implementing message queues, results in undefined
481 * Only useful for implementing message queues, 562 * behavior if not used carefully.
482 * results in undefined behavior if not used carefully.
483 * 563 *
484 * @param mq message queue to send the next message with 564 * @param mq message queue to send the next message with
485 */ 565 */
@@ -488,15 +568,14 @@ GNUNET_MQ_impl_send_continue (struct GNUNET_MQ_Handle *mq);
488 568
489 569
490/** 570/**
491 * Get the message that should currently be sent. 571 * Get the message that should currently be sent. The returned
492 * The returned message is only valid until #GNUNET_MQ_impl_send_continue 572 * message is only valid until #GNUNET_MQ_impl_send_continue is
493 * is called. 573 * called. Fails if there is no current message. Only useful for
494 * Fails if there is no current message. 574 * implementing message queues, results in undefined behavior if not
495 * Only useful for implementing message queues, 575 * used carefully.
496 * results in undefined behavior if not used carefully.
497 * 576 *
498 * @param mq message queue with the current message, only valid 577 * @param mq message queue with the current message, only valid
499 * until #GNUNET_MQ_impl_send_continue is called 578 * until #GNUNET_MQ_impl_send_continue() is called
500 * @return message to send, never NULL 579 * @return message to send, never NULL
501 */ 580 */
502const struct GNUNET_MessageHeader * 581const struct GNUNET_MessageHeader *
@@ -511,7 +590,7 @@ GNUNET_MQ_impl_current (struct GNUNET_MQ_Handle *mq);
511 * implementation state, continuations that are scheduled 590 * implementation state, continuations that are scheduled
512 * by the implementation function often only have one closure 591 * by the implementation function often only have one closure
513 * argument, with this function it is possible to get at the 592 * argument, with this function it is possible to get at the
514 * implementation state when only passing the GNUNET_MQ_Handle 593 * implementation state when only passing the `struct GNUNET_MQ_Handle`
515 * as closure. 594 * as closure.
516 * 595 *
517 * @param mq message queue with the current message 596 * @param mq message queue with the current message
diff --git a/src/include/gnunet_server_lib.h b/src/include/gnunet_server_lib.h
index 1ad2fc8b7..0ea9a18eb 100644
--- a/src/include/gnunet_server_lib.h
+++ b/src/include/gnunet_server_lib.h
@@ -729,6 +729,16 @@ GNUNET_SERVER_notification_context_get_size (struct GNUNET_SERVER_NotificationCo
729 729
730 730
731/** 731/**
732 * Create a message queue for a server's client.
733 *
734 * @param client the client
735 * @return the message queue
736 */
737struct GNUNET_MQ_Handle *
738GNUNET_MQ_queue_for_server_client (struct GNUNET_SERVER_Client *client);
739
740
741/**
732 * Handle to a message stream tokenizer. 742 * Handle to a message stream tokenizer.
733 */ 743 */
734struct GNUNET_SERVER_MessageStreamTokenizer; 744struct GNUNET_SERVER_MessageStreamTokenizer;
diff --git a/src/set/set_api.c b/src/set/set_api.c
index 794ae57b7..343b5f881 100644
--- a/src/set/set_api.c
+++ b/src/set/set_api.c
@@ -1,6 +1,6 @@
1/* 1/*
2 This file is part of GNUnet. 2 This file is part of GNUnet.
3 Copyright (C) 2012-2014 GNUnet e.V. 3 Copyright (C) 2012-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
@@ -243,7 +243,7 @@ struct GNUNET_SET_ListenHandle
243static struct GNUNET_SET_Handle * 243static struct GNUNET_SET_Handle *
244create_internal (const struct GNUNET_CONFIGURATION_Handle *cfg, 244create_internal (const struct GNUNET_CONFIGURATION_Handle *cfg,
245 enum GNUNET_SET_OperationType op, 245 enum GNUNET_SET_OperationType op,
246 uint32_t *cookie); 246 const uint32_t *cookie);
247 247
248 248
249/** 249/**
@@ -251,21 +251,17 @@ create_internal (const struct GNUNET_CONFIGURATION_Handle *cfg,
251 * iterator and sends an acknowledgement to the service. 251 * iterator and sends an acknowledgement to the service.
252 * 252 *
253 * @param cls the `struct GNUNET_SET_Handle *` 253 * @param cls the `struct GNUNET_SET_Handle *`
254 * @param mh the message 254 * @param msg the message
255 */ 255 */
256static void 256static void
257handle_copy_lazy (void *cls, 257handle_copy_lazy (void *cls,
258 const struct GNUNET_MessageHeader *mh) 258 const struct GNUNET_SET_CopyLazyResponseMessage *msg)
259{ 259{
260 struct GNUNET_SET_CopyLazyResponseMessage *msg;
261 struct GNUNET_SET_Handle *set = cls; 260 struct GNUNET_SET_Handle *set = cls;
262 struct SetCopyRequest *req; 261 struct SetCopyRequest *req;
263 struct GNUNET_SET_Handle *new_set; 262 struct GNUNET_SET_Handle *new_set;
264 263
265 msg = (struct GNUNET_SET_CopyLazyResponseMessage *) mh;
266
267 req = set->copy_req_head; 264 req = set->copy_req_head;
268
269 if (NULL == req) 265 if (NULL == req)
270 { 266 {
271 /* Service sent us unsolicited lazy copy response */ 267 /* Service sent us unsolicited lazy copy response */
@@ -275,53 +271,54 @@ handle_copy_lazy (void *cls,
275 271
276 LOG (GNUNET_ERROR_TYPE_DEBUG, 272 LOG (GNUNET_ERROR_TYPE_DEBUG,
277 "Handling response to lazy copy\n"); 273 "Handling response to lazy copy\n");
278
279 GNUNET_CONTAINER_DLL_remove (set->copy_req_head, 274 GNUNET_CONTAINER_DLL_remove (set->copy_req_head,
280 set->copy_req_tail, 275 set->copy_req_tail,
281 req); 276 req);
282
283
284 // We pass none as operation here, since it doesn't matter when 277 // We pass none as operation here, since it doesn't matter when
285 // cloning. 278 // cloning.
286 new_set = create_internal (set->cfg, GNUNET_SET_OPERATION_NONE, &msg->cookie); 279 new_set = create_internal (set->cfg,
287 280 GNUNET_SET_OPERATION_NONE,
281 &msg->cookie);
288 req->cb (req->cls, new_set); 282 req->cb (req->cls, new_set);
289
290 GNUNET_free (req); 283 GNUNET_free (req);
291} 284}
292 285
293 286
294/** 287/**
288 * Check that the given @a msg is well-formed.
289 *
290 * @param cls closure
291 * @param msg message to check
292 * @return #GNUNET_OK if message is well-formed
293 */
294static int
295check_iter_element (void *cls,
296 const struct GNUNET_SET_IterResponseMessage *msg)
297{
298 /* minimum size was already checked, everything else is OK! */
299 return GNUNET_OK;
300}
301
302
303/**
295 * Handle element for iteration over the set. Notifies the 304 * Handle element for iteration over the set. Notifies the
296 * iterator and sends an acknowledgement to the service. 305 * iterator and sends an acknowledgement to the service.
297 * 306 *
298 * @param cls the `struct GNUNET_SET_Handle *` 307 * @param cls the `struct GNUNET_SET_Handle *`
299 * @param mh the message 308 * @param mh the message
300 */ 309 */
301static void 310 static void
302handle_iter_element (void *cls, 311 handle_iter_element (void *cls,
303 const struct GNUNET_MessageHeader *mh) 312 const struct GNUNET_SET_IterResponseMessage *msg)
304{ 313{
305 struct GNUNET_SET_Handle *set = cls; 314 struct GNUNET_SET_Handle *set = cls;
306 GNUNET_SET_ElementIterator iter = set->iterator; 315 GNUNET_SET_ElementIterator iter = set->iterator;
307 struct GNUNET_SET_Element element; 316 struct GNUNET_SET_Element element;
308 const struct GNUNET_SET_IterResponseMessage *msg;
309 struct GNUNET_SET_IterAckMessage *ack_msg; 317 struct GNUNET_SET_IterAckMessage *ack_msg;
310 struct GNUNET_MQ_Envelope *ev; 318 struct GNUNET_MQ_Envelope *ev;
311 uint16_t msize; 319 uint16_t msize;
312 320
313 msize = ntohs (mh->size); 321 msize = ntohs (msg->header.size);
314 if (msize < sizeof (sizeof (struct GNUNET_SET_IterResponseMessage)))
315 {
316 /* message malformed */
317 GNUNET_break (0);
318 set->iterator = NULL;
319 set->iteration_id++;
320 iter (set->iterator_cls,
321 NULL);
322 iter = NULL;
323 }
324 msg = (const struct GNUNET_SET_IterResponseMessage *) mh;
325 if (set->iteration_id != ntohs (msg->iteration_id)) 322 if (set->iteration_id != ntohs (msg->iteration_id))
326 { 323 {
327 /* element from a previous iteration, skip! */ 324 /* element from a previous iteration, skip! */
@@ -366,6 +363,22 @@ handle_iter_done (void *cls,
366 363
367 364
368/** 365/**
366 * Check that the given @a msg is well-formed.
367 *
368 * @param cls closure
369 * @param msg message to check
370 * @return #GNUNET_OK if message is well-formed
371 */
372static int
373check_result (void *cls,
374 const struct GNUNET_SET_ResultMessage *msg)
375{
376 /* minimum size was already checked, everything else is OK! */
377 return GNUNET_OK;
378}
379
380
381/**
369 * Handle result message for a set operation. 382 * Handle result message for a set operation.
370 * 383 *
371 * @param cls the set 384 * @param cls the set
@@ -373,15 +386,13 @@ handle_iter_done (void *cls,
373 */ 386 */
374static void 387static void
375handle_result (void *cls, 388handle_result (void *cls,
376 const struct GNUNET_MessageHeader *mh) 389 const struct GNUNET_SET_ResultMessage *msg)
377{ 390{
378 struct GNUNET_SET_Handle *set = cls; 391 struct GNUNET_SET_Handle *set = cls;
379 const struct GNUNET_SET_ResultMessage *msg;
380 struct GNUNET_SET_OperationHandle *oh; 392 struct GNUNET_SET_OperationHandle *oh;
381 struct GNUNET_SET_Element e; 393 struct GNUNET_SET_Element e;
382 enum GNUNET_SET_Status result_status; 394 enum GNUNET_SET_Status result_status;
383 395
384 msg = (const struct GNUNET_SET_ResultMessage *) mh;
385 GNUNET_assert (NULL != set->mq); 396 GNUNET_assert (NULL != set->mq);
386 result_status = ntohs (msg->result_status); 397 result_status = ntohs (msg->result_status);
387 LOG (GNUNET_ERROR_TYPE_DEBUG, 398 LOG (GNUNET_ERROR_TYPE_DEBUG,
@@ -442,7 +453,7 @@ do_element:
442 LOG (GNUNET_ERROR_TYPE_DEBUG, 453 LOG (GNUNET_ERROR_TYPE_DEBUG,
443 "Treating result as element\n"); 454 "Treating result as element\n");
444 e.data = &msg[1]; 455 e.data = &msg[1];
445 e.size = ntohs (mh->size) - sizeof (struct GNUNET_SET_ResultMessage); 456 e.size = ntohs (msg->header.size) - sizeof (struct GNUNET_SET_ResultMessage);
446 e.element_type = ntohs (msg->element_type); 457 e.element_type = ntohs (msg->element_type);
447 if (NULL != oh->result_cb) 458 if (NULL != oh->result_cb)
448 oh->result_cb (oh->result_cls, 459 oh->result_cb (oh->result_cls,
@@ -522,7 +533,8 @@ handle_client_set_error (void *cls,
522 enum GNUNET_MQ_Error error) 533 enum GNUNET_MQ_Error error)
523{ 534{
524 struct GNUNET_SET_Handle *set = cls; 535 struct GNUNET_SET_Handle *set = cls;
525 536 GNUNET_SET_ElementIterator iter = set->iterator;
537
526 LOG (GNUNET_ERROR_TYPE_DEBUG, 538 LOG (GNUNET_ERROR_TYPE_DEBUG,
527 "Handling client set error %d\n", 539 "Handling client set error %d\n",
528 error); 540 error);
@@ -534,6 +546,11 @@ handle_client_set_error (void *cls,
534 GNUNET_SET_STATUS_FAILURE); 546 GNUNET_SET_STATUS_FAILURE);
535 set_operation_destroy (set->ops_head); 547 set_operation_destroy (set->ops_head);
536 } 548 }
549 set->iterator = NULL;
550 set->iteration_id++;
551 if (NULL != iter)
552 iter (set->iterator_cls,
553 NULL);
537 set->invalid = GNUNET_YES; 554 set->invalid = GNUNET_YES;
538 if (GNUNET_YES == set->destroy_requested) 555 if (GNUNET_YES == set->destroy_requested)
539 { 556 {
@@ -547,31 +564,34 @@ handle_client_set_error (void *cls,
547static struct GNUNET_SET_Handle * 564static struct GNUNET_SET_Handle *
548create_internal (const struct GNUNET_CONFIGURATION_Handle *cfg, 565create_internal (const struct GNUNET_CONFIGURATION_Handle *cfg,
549 enum GNUNET_SET_OperationType op, 566 enum GNUNET_SET_OperationType op,
550 uint32_t *cookie) 567 const uint32_t *cookie)
551{ 568{
552 static const struct GNUNET_MQ_MessageHandler mq_handlers[] = { 569 GNUNET_MQ_hd_var_size (result,
553 { &handle_result, 570 GNUNET_MESSAGE_TYPE_SET_RESULT,
554 GNUNET_MESSAGE_TYPE_SET_RESULT, 571 struct GNUNET_SET_ResultMessage);
555 0 }, 572 GNUNET_MQ_hd_var_size (iter_element,
556 { &handle_iter_element, 573 GNUNET_MESSAGE_TYPE_SET_ITER_ELEMENT,
557 GNUNET_MESSAGE_TYPE_SET_ITER_ELEMENT, 574 struct GNUNET_SET_IterResponseMessage);
558 0 }, 575 GNUNET_MQ_hd_fixed_size (iter_done,
559 { &handle_iter_done, 576 GNUNET_MESSAGE_TYPE_SET_ITER_DONE,
560 GNUNET_MESSAGE_TYPE_SET_ITER_DONE, 577 struct GNUNET_MessageHeader);
561 sizeof (struct GNUNET_MessageHeader) }, 578 GNUNET_MQ_hd_fixed_size (copy_lazy,
562 { &handle_copy_lazy, 579 GNUNET_MESSAGE_TYPE_SET_COPY_LAZY_RESPONSE,
563 GNUNET_MESSAGE_TYPE_SET_COPY_LAZY_RESPONSE, 580 struct GNUNET_SET_CopyLazyResponseMessage);
564 sizeof (struct GNUNET_SET_CopyLazyResponseMessage) }, 581 struct GNUNET_SET_Handle *set = GNUNET_new (struct GNUNET_SET_Handle);
565 GNUNET_MQ_HANDLERS_END 582 struct GNUNET_MQ_MessageHandler mq_handlers[] = {
583 make_result_handler (set),
584 make_iter_element_handler (set),
585 make_iter_done_handler (set),
586 make_copy_lazy_handler (set),
587 GNUNET_MQ_handler_end ()
566 }; 588 };
567 struct GNUNET_SET_Handle *set;
568 struct GNUNET_MQ_Envelope *mqm; 589 struct GNUNET_MQ_Envelope *mqm;
569 struct GNUNET_SET_CreateMessage *create_msg; 590 struct GNUNET_SET_CreateMessage *create_msg;
570 struct GNUNET_SET_CopyLazyConnectMessage *copy_msg; 591 struct GNUNET_SET_CopyLazyConnectMessage *copy_msg;
571 592
572 set = GNUNET_new (struct GNUNET_SET_Handle);
573 set->client = GNUNET_CLIENT_connect ("set", cfg);
574 set->cfg = cfg; 593 set->cfg = cfg;
594 set->client = GNUNET_CLIENT_connect ("set", cfg);
575 if (NULL == set->client) 595 if (NULL == set->client)
576 { 596 {
577 GNUNET_free (set); 597 GNUNET_free (set);
@@ -796,41 +816,48 @@ listen_connect (void *cls);
796 816
797 817
798/** 818/**
819 * Check validity of request message for a listen operation
820 *
821 * @param cls the listen handle
822 * @param msg the message
823 * @return #GNUNET_OK if the message is well-formed
824 */
825static int
826check_request (void *cls,
827 const struct GNUNET_SET_RequestMessage *msg)
828{
829 const struct GNUNET_MessageHeader *context_msg;
830
831 context_msg = GNUNET_MQ_extract_nested_mh (msg);
832 if (NULL == context_msg)
833 {
834 GNUNET_break_op (0);
835 return GNUNET_SYSERR;
836 }
837 return GNUNET_OK;
838}
839
840
841/**
799 * Handle request message for a listen operation 842 * Handle request message for a listen operation
800 * 843 *
801 * @param cls the listen handle 844 * @param cls the listen handle
802 * @param mh the message 845 * @param msg the message
803 */ 846 */
804static void 847static void
805handle_request (void *cls, 848handle_request (void *cls,
806 const struct GNUNET_MessageHeader *mh) 849 const struct GNUNET_SET_RequestMessage *msg)
807{ 850{
808 struct GNUNET_SET_ListenHandle *lh = cls; 851 struct GNUNET_SET_ListenHandle *lh = cls;
809 const struct GNUNET_SET_RequestMessage *msg;
810 struct GNUNET_SET_Request req; 852 struct GNUNET_SET_Request req;
811 const struct GNUNET_MessageHeader *context_msg; 853 const struct GNUNET_MessageHeader *context_msg;
812 uint16_t msize;
813 struct GNUNET_MQ_Envelope *mqm; 854 struct GNUNET_MQ_Envelope *mqm;
814 struct GNUNET_SET_RejectMessage *rmsg; 855 struct GNUNET_SET_RejectMessage *rmsg;
815 856
816 LOG (GNUNET_ERROR_TYPE_DEBUG, 857 LOG (GNUNET_ERROR_TYPE_DEBUG,
817 "Processing incoming operation request\n"); 858 "Processing incoming operation request\n");
818 msize = ntohs (mh->size);
819 if (msize < sizeof (struct GNUNET_SET_RequestMessage))
820 {
821 GNUNET_break (0);
822 GNUNET_CLIENT_disconnect (lh->client);
823 lh->client = NULL;
824 GNUNET_MQ_destroy (lh->mq);
825 lh->mq = NULL;
826 lh->reconnect_task = GNUNET_SCHEDULER_add_delayed (lh->reconnect_backoff,
827 &listen_connect, lh);
828 lh->reconnect_backoff = GNUNET_TIME_STD_BACKOFF (lh->reconnect_backoff);
829 return;
830 }
831 /* we got another valid request => reset the backoff */ 859 /* we got another valid request => reset the backoff */
832 lh->reconnect_backoff = GNUNET_TIME_UNIT_MILLISECONDS; 860 lh->reconnect_backoff = GNUNET_TIME_UNIT_MILLISECONDS;
833 msg = (const struct GNUNET_SET_RequestMessage *) mh;
834 req.accept_id = ntohl (msg->accept_id); 861 req.accept_id = ntohl (msg->accept_id);
835 req.accepted = GNUNET_NO; 862 req.accepted = GNUNET_NO;
836 context_msg = GNUNET_MQ_extract_nested_mh (msg); 863 context_msg = GNUNET_MQ_extract_nested_mh (msg);
@@ -871,7 +898,8 @@ handle_client_listener_error (void *cls,
871 GNUNET_MQ_destroy (lh->mq); 898 GNUNET_MQ_destroy (lh->mq);
872 lh->mq = NULL; 899 lh->mq = NULL;
873 lh->reconnect_task = GNUNET_SCHEDULER_add_delayed (lh->reconnect_backoff, 900 lh->reconnect_task = GNUNET_SCHEDULER_add_delayed (lh->reconnect_backoff,
874 &listen_connect, lh); 901 &listen_connect,
902 lh);
875 lh->reconnect_backoff = GNUNET_TIME_STD_BACKOFF (lh->reconnect_backoff); 903 lh->reconnect_backoff = GNUNET_TIME_STD_BACKOFF (lh->reconnect_backoff);
876} 904}
877 905
@@ -883,12 +911,15 @@ handle_client_listener_error (void *cls,
883 */ 911 */
884static void 912static void
885listen_connect (void *cls) 913listen_connect (void *cls)
886{ 914{
887 static const struct GNUNET_MQ_MessageHandler mq_handlers[] = { 915 GNUNET_MQ_hd_var_size (request,
888 { &handle_request, GNUNET_MESSAGE_TYPE_SET_REQUEST }, 916 GNUNET_MESSAGE_TYPE_SET_REQUEST,
889 GNUNET_MQ_HANDLERS_END 917 struct GNUNET_SET_RequestMessage);
890 };
891 struct GNUNET_SET_ListenHandle *lh = cls; 918 struct GNUNET_SET_ListenHandle *lh = cls;
919 struct GNUNET_MQ_MessageHandler mq_handlers[] = {
920 make_request_handler (lh),
921 GNUNET_MQ_handler_end ()
922 };
892 struct GNUNET_MQ_Envelope *mqm; 923 struct GNUNET_MQ_Envelope *mqm;
893 struct GNUNET_SET_ListenMessage *msg; 924 struct GNUNET_SET_ListenMessage *msg;
894 925
@@ -900,7 +931,8 @@ listen_connect (void *cls)
900 GNUNET_assert (NULL == lh->mq); 931 GNUNET_assert (NULL == lh->mq);
901 lh->mq = GNUNET_MQ_queue_for_connection_client (lh->client, 932 lh->mq = GNUNET_MQ_queue_for_connection_client (lh->client,
902 mq_handlers, 933 mq_handlers,
903 &handle_client_listener_error, lh); 934 &handle_client_listener_error,
935 lh);
904 mqm = GNUNET_MQ_msg (msg, GNUNET_MESSAGE_TYPE_SET_LISTEN); 936 mqm = GNUNET_MQ_msg (msg, GNUNET_MESSAGE_TYPE_SET_LISTEN);
905 msg->operation = htonl (lh->operation); 937 msg->operation = htonl (lh->operation);
906 msg->app_id = lh->app_id; 938 msg->app_id = lh->app_id;
@@ -1133,11 +1165,12 @@ GNUNET_SET_element_dup (const struct GNUNET_SET_Element *element)
1133 * Hash a set element. 1165 * Hash a set element.
1134 * 1166 *
1135 * @param element the element that should be hashed 1167 * @param element the element that should be hashed
1136 * @param ret_hash a pointer to where the hash of @a element 1168 * @param[out] ret_hash a pointer to where the hash of @a element
1137 * should be stored 1169 * should be stored
1138 */ 1170 */
1139void 1171void
1140GNUNET_SET_element_hash (const struct GNUNET_SET_Element *element, struct GNUNET_HashCode *ret_hash) 1172GNUNET_SET_element_hash (const struct GNUNET_SET_Element *element,
1173 struct GNUNET_HashCode *ret_hash)
1141{ 1174{
1142 struct GNUNET_HashContext *ctx = GNUNET_CRYPTO_hash_context_start (); 1175 struct GNUNET_HashContext *ctx = GNUNET_CRYPTO_hash_context_start ();
1143 1176
diff --git a/src/util/mq.c b/src/util/mq.c
index 6f8c04224..4170338ad 100644
--- a/src/util/mq.c
+++ b/src/util/mq.c
@@ -74,13 +74,7 @@ struct GNUNET_MQ_Handle
74 /** 74 /**
75 * Handlers array, or NULL if the queue should not receive messages 75 * Handlers array, or NULL if the queue should not receive messages
76 */ 76 */
77 const struct GNUNET_MQ_MessageHandler *handlers; 77 struct GNUNET_MQ_MessageHandler *handlers;
78
79 /**
80 * Closure for the handler callbacks,
81 * as well as for the error handler.
82 */
83 void *handlers_cls;
84 78
85 /** 79 /**
86 * Actual implementation of message sending, 80 * Actual implementation of message sending,
@@ -109,6 +103,11 @@ struct GNUNET_MQ_Handle
109 GNUNET_MQ_ErrorHandler error_handler; 103 GNUNET_MQ_ErrorHandler error_handler;
110 104
111 /** 105 /**
106 * Closure for the error handler.
107 */
108 void *error_handler_cls;
109
110 /**
112 * Linked list of messages pending to be sent 111 * Linked list of messages pending to be sent
113 */ 112 */
114 struct GNUNET_MQ_Envelope *envelope_head; 113 struct GNUNET_MQ_Envelope *envelope_head;
@@ -133,7 +132,7 @@ struct GNUNET_MQ_Handle
133 /** 132 /**
134 * Task scheduled during #GNUNET_MQ_impl_send_continue. 133 * Task scheduled during #GNUNET_MQ_impl_send_continue.
135 */ 134 */
136 struct GNUNET_SCHEDULER_Task * continue_task; 135 struct GNUNET_SCHEDULER_Task *continue_task;
137 136
138 /** 137 /**
139 * Next id that should be used for the @e assoc_map, 138 * Next id that should be used for the @e assoc_map,
@@ -206,23 +205,42 @@ GNUNET_MQ_inject_message (struct GNUNET_MQ_Handle *mq,
206{ 205{
207 const struct GNUNET_MQ_MessageHandler *handler; 206 const struct GNUNET_MQ_MessageHandler *handler;
208 int handled = GNUNET_NO; 207 int handled = GNUNET_NO;
209 208 uint16_t ms = ntohs (mh->size);
209
210 if (NULL == mq->handlers) 210 if (NULL == mq->handlers)
211 { 211 goto done;
212 LOG (GNUNET_ERROR_TYPE_WARNING,
213 "No handler for message of type %d\n",
214 ntohs (mh->type));
215 return;
216 }
217 for (handler = mq->handlers; NULL != handler->cb; handler++) 212 for (handler = mq->handlers; NULL != handler->cb; handler++)
218 { 213 {
219 if (handler->type == ntohs (mh->type)) 214 if (handler->type == ntohs (mh->type))
220 { 215 {
221 handler->cb (mq->handlers_cls, mh);
222 handled = GNUNET_YES; 216 handled = GNUNET_YES;
217 if ( (handler->expected_size > ms) ||
218 ( (handler->expected_size != ms) &&
219 (NULL == handler->mv) ) )
220 {
221 /* Too small, or not an exact size and
222 no 'mv' handler to check rest */
223 GNUNET_MQ_inject_error (mq,
224 GNUNET_MQ_ERROR_MALFORMED);
225 break;
226 }
227 if ( (NULL == handler->mv) ||
228 (GNUNET_OK ==
229 handler->mv (handler->cls, mh)) )
230 {
231 /* message well-formed, pass to handler */
232 handler->cb (handler->cls, mh);
233 }
234 else
235 {
236 /* Message rejected by check routine */
237 GNUNET_MQ_inject_error (mq,
238 GNUNET_MQ_ERROR_MALFORMED);
239 }
223 break; 240 break;
224 } 241 }
225 } 242 }
243 done:
226 if (GNUNET_NO == handled) 244 if (GNUNET_NO == handled)
227 LOG (GNUNET_ERROR_TYPE_WARNING, 245 LOG (GNUNET_ERROR_TYPE_WARNING,
228 "No handler for message of type %d\n", 246 "No handler for message of type %d\n",
@@ -251,7 +269,7 @@ GNUNET_MQ_inject_error (struct GNUNET_MQ_Handle *mq,
251 (int) error); 269 (int) error);
252 return; 270 return;
253 } 271 }
254 mq->error_handler (mq->handlers_cls, error); 272 mq->error_handler (mq->error_handler_cls, error);
255} 273}
256 274
257 275
@@ -355,7 +373,7 @@ GNUNET_MQ_impl_send_continue (struct GNUNET_MQ_Handle *mq)
355 * @param impl_state for the queue, passed to 'send' and 'destroy' 373 * @param impl_state for the queue, passed to 'send' and 'destroy'
356 * @param handlers array of message handlers 374 * @param handlers array of message handlers
357 * @param error_handler handler for read and write errors 375 * @param error_handler handler for read and write errors
358 * @param cls closure for message handlers and error handler 376 * @param error_handler_cls closure for @a error_handler
359 * @return a new message queue 377 * @return a new message queue
360 */ 378 */
361struct GNUNET_MQ_Handle * 379struct GNUNET_MQ_Handle *
@@ -365,16 +383,26 @@ GNUNET_MQ_queue_for_callbacks (GNUNET_MQ_SendImpl send,
365 void *impl_state, 383 void *impl_state,
366 const struct GNUNET_MQ_MessageHandler *handlers, 384 const struct GNUNET_MQ_MessageHandler *handlers,
367 GNUNET_MQ_ErrorHandler error_handler, 385 GNUNET_MQ_ErrorHandler error_handler,
368 void *cls) 386 void *error_handler_cls)
369{ 387{
370 struct GNUNET_MQ_Handle *mq; 388 struct GNUNET_MQ_Handle *mq;
389 unsigned int i;
371 390
372 mq = GNUNET_new (struct GNUNET_MQ_Handle); 391 mq = GNUNET_new (struct GNUNET_MQ_Handle);
373 mq->send_impl = send; 392 mq->send_impl = send;
374 mq->destroy_impl = destroy; 393 mq->destroy_impl = destroy;
375 mq->cancel_impl = cancel; 394 mq->cancel_impl = cancel;
376 mq->handlers = handlers; 395 if (NULL != handlers)
377 mq->handlers_cls = cls; 396 {
397 for (i=0;NULL != handlers[i].cb; i++) ;
398 mq->handlers = GNUNET_new_array (i,
399 struct GNUNET_MQ_MessageHandler);
400 memcpy (mq->handlers,
401 handlers,
402 i * sizeof (struct GNUNET_MQ_MessageHandler));
403 }
404 mq->error_handler = error_handler;
405 mq->error_handler_cls = error_handler_cls;
378 mq->impl_state = impl_state; 406 mq->impl_state = impl_state;
379 407
380 return mq; 408 return mq;
@@ -572,7 +600,6 @@ handle_client_message (void *cls,
572 struct ClientConnectionState *state; 600 struct ClientConnectionState *state;
573 601
574 state = mq->impl_state; 602 state = mq->impl_state;
575
576 if (NULL == msg) 603 if (NULL == msg)
577 { 604 {
578 GNUNET_MQ_inject_error (mq, GNUNET_MQ_ERROR_READ); 605 GNUNET_MQ_inject_error (mq, GNUNET_MQ_ERROR_READ);
@@ -617,7 +644,9 @@ connection_client_transmit_queued (void *cls,
617 (GNUNET_NO == state->receive_active) ) 644 (GNUNET_NO == state->receive_active) )
618 { 645 {
619 state->receive_active = GNUNET_YES; 646 state->receive_active = GNUNET_YES;
620 GNUNET_CLIENT_receive (state->connection, handle_client_message, mq, 647 GNUNET_CLIENT_receive (state->connection,
648 &handle_client_message,
649 mq,
621 GNUNET_TIME_UNIT_FOREVER_REL); 650 GNUNET_TIME_UNIT_FOREVER_REL);
622 } 651 }
623 652
@@ -673,17 +702,24 @@ struct GNUNET_MQ_Handle *
673GNUNET_MQ_queue_for_connection_client (struct GNUNET_CLIENT_Connection *connection, 702GNUNET_MQ_queue_for_connection_client (struct GNUNET_CLIENT_Connection *connection,
674 const struct GNUNET_MQ_MessageHandler *handlers, 703 const struct GNUNET_MQ_MessageHandler *handlers,
675 GNUNET_MQ_ErrorHandler error_handler, 704 GNUNET_MQ_ErrorHandler error_handler,
676 void *cls) 705 void *error_handler_cls)
677{ 706{
678 struct GNUNET_MQ_Handle *mq; 707 struct GNUNET_MQ_Handle *mq;
679 struct ClientConnectionState *state; 708 struct ClientConnectionState *state;
680 709 unsigned int i;
681 GNUNET_assert (NULL != connection);
682 710
683 mq = GNUNET_new (struct GNUNET_MQ_Handle); 711 mq = GNUNET_new (struct GNUNET_MQ_Handle);
684 mq->handlers = handlers; 712 if (NULL != handlers)
713 {
714 for (i=0;NULL != handlers[i].cb; i++) ;
715 mq->handlers = GNUNET_new_array (i,
716 struct GNUNET_MQ_MessageHandler);
717 memcpy (mq->handlers,
718 handlers,
719 i * sizeof (struct GNUNET_MQ_MessageHandler));
720 }
685 mq->error_handler = error_handler; 721 mq->error_handler = error_handler;
686 mq->handlers_cls = cls; 722 mq->error_handler_cls = error_handler_cls;
687 state = GNUNET_new (struct ClientConnectionState); 723 state = GNUNET_new (struct ClientConnectionState);
688 state->connection = connection; 724 state->connection = connection;
689 mq->impl_state = state; 725 mq->impl_state = state;
@@ -697,18 +733,6 @@ GNUNET_MQ_queue_for_connection_client (struct GNUNET_CLIENT_Connection *connecti
697} 733}
698 734
699 735
700void
701GNUNET_MQ_replace_handlers (struct GNUNET_MQ_Handle *mq,
702 const struct GNUNET_MQ_MessageHandler *new_handlers,
703 void *cls)
704{
705 /* FIXME: notify implementation? */
706 /* FIXME: what about NULL handlers? abort receive? */
707 mq->handlers = new_handlers;
708 mq->handlers_cls = cls;
709}
710
711
712/** 736/**
713 * Associate the assoc_data in mq with a unique request id. 737 * Associate the assoc_data in mq with a unique request id.
714 * 738 *
@@ -784,6 +808,7 @@ GNUNET_MQ_destroy (struct GNUNET_MQ_Handle *mq)
784 while (NULL != mq->envelope_head) 808 while (NULL != mq->envelope_head)
785 { 809 {
786 struct GNUNET_MQ_Envelope *ev; 810 struct GNUNET_MQ_Envelope *ev;
811
787 ev = mq->envelope_head; 812 ev = mq->envelope_head;
788 ev->parent_queue = NULL; 813 ev->parent_queue = NULL;
789 GNUNET_CONTAINER_DLL_remove (mq->envelope_head, 814 GNUNET_CONTAINER_DLL_remove (mq->envelope_head,
@@ -804,7 +829,7 @@ GNUNET_MQ_destroy (struct GNUNET_MQ_Handle *mq)
804 GNUNET_CONTAINER_multihashmap32_destroy (mq->assoc_map); 829 GNUNET_CONTAINER_multihashmap32_destroy (mq->assoc_map);
805 mq->assoc_map = NULL; 830 mq->assoc_map = NULL;
806 } 831 }
807 832 GNUNET_free_non_null (mq->handlers);
808 GNUNET_free (mq); 833 GNUNET_free (mq);
809} 834}
810 835
diff --git a/src/util/perf_crypto_asymmetric.c b/src/util/perf_crypto_asymmetric.c
index 6e9c40e02..418d6dab3 100644
--- a/src/util/perf_crypto_asymmetric.c
+++ b/src/util/perf_crypto_asymmetric.c
@@ -88,7 +88,7 @@ main (int argc, char *argv[])
88 start = GNUNET_TIME_absolute_get(); 88 start = GNUNET_TIME_absolute_get();
89 for (i = 0; i < l; i++) 89 for (i = 0; i < l; i++)
90 GNUNET_CRYPTO_eddsa_key_get_public (eddsa[i], &dspub[i]); 90 GNUNET_CRYPTO_eddsa_key_get_public (eddsa[i], &dspub[i]);
91 log_duration ("EdDSA", "get pubilc"); 91 log_duration ("EdDSA", "get public");
92 92
93 start = GNUNET_TIME_absolute_get(); 93 start = GNUNET_TIME_absolute_get();
94 for (i = 0; i < l; i++) 94 for (i = 0; i < l; i++)