diff options
-rw-r--r-- | src/include/gnunet_mq_lib.h | 8 | ||||
-rw-r--r-- | src/include/gnunet_scheduler_lib.h | 2 | ||||
-rw-r--r-- | src/include/gnunet_service_lib.h | 36 | ||||
-rw-r--r-- | src/statistics/statistics_api.c | 33 | ||||
-rw-r--r-- | src/util/gnunet-service-resolver.c | 410 | ||||
-rw-r--r-- | src/util/mq.c | 13 |
6 files changed, 337 insertions, 165 deletions
diff --git a/src/include/gnunet_mq_lib.h b/src/include/gnunet_mq_lib.h index 86144abca..999ee4134 100644 --- a/src/include/gnunet_mq_lib.h +++ b/src/include/gnunet_mq_lib.h | |||
@@ -171,7 +171,13 @@ enum GNUNET_MQ_Error | |||
171 | * We received a message that was malformed and thus | 171 | * We received a message that was malformed and thus |
172 | * could not be passed to its handler. | 172 | * could not be passed to its handler. |
173 | */ | 173 | */ |
174 | GNUNET_MQ_ERROR_MALFORMED = 8 | 174 | GNUNET_MQ_ERROR_MALFORMED = 8, |
175 | |||
176 | /** | ||
177 | * We received a message for which we have no matching | ||
178 | * handler. | ||
179 | */ | ||
180 | GNUNET_MQ_ERROR_NO_MATCH = 16 | ||
175 | }; | 181 | }; |
176 | 182 | ||
177 | 183 | ||
diff --git a/src/include/gnunet_scheduler_lib.h b/src/include/gnunet_scheduler_lib.h index 87cb3b6f1..1a0438bed 100644 --- a/src/include/gnunet_scheduler_lib.h +++ b/src/include/gnunet_scheduler_lib.h | |||
@@ -346,7 +346,7 @@ GNUNET_SCHEDULER_add_delayed_with_priority (struct GNUNET_TIME_Relative delay, | |||
346 | * scheduled for execution once either the delay has expired or the | 346 | * scheduled for execution once either the delay has expired or the |
347 | * socket operation is ready. It will be run with the DEFAULT priority. | 347 | * socket operation is ready. It will be run with the DEFAULT priority. |
348 | * | 348 | * |
349 | * * @param delay when should this operation time out? | 349 | * @param delay when should this operation time out? |
350 | * @param rfd read file-descriptor | 350 | * @param rfd read file-descriptor |
351 | * @param task main function of the task | 351 | * @param task main function of the task |
352 | * @param task_cls closure of @a task | 352 | * @param task_cls closure of @a task |
diff --git a/src/include/gnunet_service_lib.h b/src/include/gnunet_service_lib.h index 797857ed8..9c7009ef4 100644 --- a/src/include/gnunet_service_lib.h +++ b/src/include/gnunet_service_lib.h | |||
@@ -336,16 +336,36 @@ GNUNET_SERVICE_ruN_ (int argc, | |||
336 | * @param connect_cb function to call whenever a client connects | 336 | * @param connect_cb function to call whenever a client connects |
337 | * @param disconnect_cb function to call whenever a client disconnects | 337 | * @param disconnect_cb function to call whenever a client disconnects |
338 | * @param cls closure argument for @a service_init_cb, @a connect_cb and @a disconnect_cb | 338 | * @param cls closure argument for @a service_init_cb, @a connect_cb and @a disconnect_cb |
339 | * @param handlers NULL-terminated array of message handlers for the service, | 339 | * @param ... array of message handlers for the service, terminated |
340 | * by #GNUNET_MQ_handler_end(); | ||
340 | * the closure will be set to the value returned by | 341 | * the closure will be set to the value returned by |
341 | * the @a connect_cb for the respective connection | 342 | * the @a connect_cb for the respective connection |
342 | * @return 0 on success, non-zero on error | 343 | * @return 0 on success, non-zero on error |
344 | * | ||
345 | * Sample invocation: | ||
346 | * <code> | ||
347 | * GNUNET_SERVICE_MAIN | ||
348 | * ("resolver", | ||
349 | * GNUNET_SERVICE_OPTION_NONE, | ||
350 | * &init_cb, | ||
351 | * &connect_cb, | ||
352 | * &disconnect_cb, | ||
353 | * closure_for_cb, | ||
354 | * GNUNET_MQ_hd_var_size (get, | ||
355 | * GNUNET_MESSAGE_TYPE_RESOLVER_REQUEST, | ||
356 | * struct GNUNET_RESOLVER_GetMessage, | ||
357 | * NULL), | ||
358 | * GNUNET_MQ_handler_end ()); | ||
359 | * </code> | ||
343 | */ | 360 | */ |
344 | #define GNUNET_SERVICE_MAIN(service_name,service_options,init_cb,connect_cb,disconnect_cb,cls,handlers) \ | 361 | #define GNUNET_SERVICE_MAIN(service_name,service_options,init_cb,connect_cb,disconnect_cb,cls,...) \ |
345 | int \ | 362 | int \ |
346 | main (int argc,\ | 363 | main (int argc,\ |
347 | char *const *argv)\ | 364 | char *const *argv)\ |
348 | { \ | 365 | { \ |
366 | struct GNUNET_MQ_MessageHandler mh[] = { \ | ||
367 | __VA_ARGS__ \ | ||
368 | }; \ | ||
349 | return GNUNET_SERVICE_ruN_ (argc, \ | 369 | return GNUNET_SERVICE_ruN_ (argc, \ |
350 | argv, \ | 370 | argv, \ |
351 | service_name, \ | 371 | service_name, \ |
@@ -354,7 +374,7 @@ GNUNET_SERVICE_ruN_ (int argc, | |||
354 | connect_cb, \ | 374 | connect_cb, \ |
355 | disconnect_cb, \ | 375 | disconnect_cb, \ |
356 | cls, \ | 376 | cls, \ |
357 | handlers); \ | 377 | mh); \ |
358 | } | 378 | } |
359 | 379 | ||
360 | 380 | ||
@@ -388,6 +408,16 @@ GNUNET_SERVICE_client_continue (struct GNUNET_SERVICE_Client *c); | |||
388 | 408 | ||
389 | 409 | ||
390 | /** | 410 | /** |
411 | * Obtain the message queue of @a c. Convenience function. | ||
412 | * | ||
413 | * @param c the client to continue receiving from | ||
414 | * @return the message queue of @a c | ||
415 | */ | ||
416 | struct GNUNET_MQ_Handle * | ||
417 | GNUNET_SERVICE_client_get_mq (struct GNUNET_SERVICE_Client *c); | ||
418 | |||
419 | |||
420 | /** | ||
391 | * Disable the warning the server issues if a message is not | 421 | * Disable the warning the server issues if a message is not |
392 | * acknowledged in a timely fashion. Use this call if a client is | 422 | * acknowledged in a timely fashion. Use this call if a client is |
393 | * intentionally delayed for a while. Only applies to the current | 423 | * intentionally delayed for a while. Only applies to the current |
diff --git a/src/statistics/statistics_api.c b/src/statistics/statistics_api.c index c8709145b..856873d00 100644 --- a/src/statistics/statistics_api.c +++ b/src/statistics/statistics_api.c | |||
@@ -295,12 +295,18 @@ update_memory_statistics (struct GNUNET_STATISTICS_Handle *h) | |||
295 | if (current_heap_size > h->peak_heap_size) | 295 | if (current_heap_size > h->peak_heap_size) |
296 | { | 296 | { |
297 | h->peak_heap_size = current_heap_size; | 297 | h->peak_heap_size = current_heap_size; |
298 | GNUNET_STATISTICS_set (h, "# peak heap size", current_heap_size, GNUNET_NO); | 298 | GNUNET_STATISTICS_set (h, |
299 | "# peak heap size", | ||
300 | current_heap_size, | ||
301 | GNUNET_NO); | ||
299 | } | 302 | } |
300 | if (current_rss > h->peak_rss) | 303 | if (current_rss > h->peak_rss) |
301 | { | 304 | { |
302 | h->peak_rss = current_rss; | 305 | h->peak_rss = current_rss; |
303 | GNUNET_STATISTICS_set (h, "# peak resident set size", current_rss, GNUNET_NO); | 306 | GNUNET_STATISTICS_set (h, |
307 | "# peak resident set size", | ||
308 | current_rss, | ||
309 | GNUNET_NO); | ||
304 | } | 310 | } |
305 | #endif | 311 | #endif |
306 | } | 312 | } |
@@ -739,7 +745,8 @@ reconnect_later (struct GNUNET_STATISTICS_Handle *h) | |||
739 | */ | 745 | */ |
740 | loss = GNUNET_NO; | 746 | loss = GNUNET_NO; |
741 | for (gh = h->action_head; NULL != gh; gh = gh->next) | 747 | for (gh = h->action_head; NULL != gh; gh = gh->next) |
742 | if ( (gh->make_persistent) && (ACTION_SET == gh->type) ) | 748 | if ( (gh->make_persistent) && |
749 | (ACTION_SET == gh->type) ) | ||
743 | loss = GNUNET_YES; | 750 | loss = GNUNET_YES; |
744 | if (GNUNET_YES == loss) | 751 | if (GNUNET_YES == loss) |
745 | GNUNET_log (GNUNET_ERROR_TYPE_WARNING, | 752 | GNUNET_log (GNUNET_ERROR_TYPE_WARNING, |
@@ -922,8 +929,7 @@ GNUNET_STATISTICS_destroy (struct GNUNET_STATISTICS_Handle *h, | |||
922 | GNUNET_assert (GNUNET_NO == h->do_destroy); /* Don't call twice. */ | 929 | GNUNET_assert (GNUNET_NO == h->do_destroy); /* Don't call twice. */ |
923 | if ( (sync_first) && | 930 | if ( (sync_first) && |
924 | (NULL != h->mq) && | 931 | (NULL != h->mq) && |
925 | (0 != GNUNET_MQ_get_length (h->mq)) && | 932 | (0 != GNUNET_MQ_get_length (h->mq)) ) |
926 | (GNUNET_YES == try_connect (h)) ) | ||
927 | { | 933 | { |
928 | if ( (NULL != h->current) && | 934 | if ( (NULL != h->current) && |
929 | (ACTION_GET == h->current->type) ) | 935 | (ACTION_GET == h->current->type) ) |
@@ -933,8 +939,7 @@ GNUNET_STATISTICS_destroy (struct GNUNET_STATISTICS_Handle *h, | |||
933 | { | 939 | { |
934 | next = pos->next; | 940 | next = pos->next; |
935 | if ( (ACTION_GET == pos->type) || | 941 | if ( (ACTION_GET == pos->type) || |
936 | (ACTION_WATCH == pos->type) || | 942 | (ACTION_WATCH == pos->type) ) |
937 | (GNUNET_NO == pos->make_persistent) ) | ||
938 | { | 943 | { |
939 | GNUNET_CONTAINER_DLL_remove (h->action_head, | 944 | GNUNET_CONTAINER_DLL_remove (h->action_head, |
940 | h->action_tail, | 945 | h->action_tail, |
@@ -1009,7 +1014,7 @@ schedule_action (void *cls) | |||
1009 | reconnect_later (h); | 1014 | reconnect_later (h); |
1010 | return; | 1015 | return; |
1011 | } | 1016 | } |
1012 | if (0 < GNUNET_MQ_get_length (h->mq) ) | 1017 | if (0 < GNUNET_MQ_get_length (h->mq)) |
1013 | return; /* Wait for queue to be reduced more */ | 1018 | return; /* Wait for queue to be reduced more */ |
1014 | /* schedule next action */ | 1019 | /* schedule next action */ |
1015 | while (NULL == h->current) | 1020 | while (NULL == h->current) |
@@ -1200,8 +1205,10 @@ GNUNET_STATISTICS_watch_cancel (struct GNUNET_STATISTICS_Handle *handle, | |||
1200 | continue; | 1205 | continue; |
1201 | if ( (w->proc == proc) && | 1206 | if ( (w->proc == proc) && |
1202 | (w->proc_cls == proc_cls) && | 1207 | (w->proc_cls == proc_cls) && |
1203 | (0 == strcmp (w->name, name)) && | 1208 | (0 == strcmp (w->name, |
1204 | (0 == strcmp (w->subsystem, subsystem)) ) | 1209 | name)) && |
1210 | (0 == strcmp (w->subsystem, | ||
1211 | subsystem)) ) | ||
1205 | { | 1212 | { |
1206 | GNUNET_free (w->name); | 1213 | GNUNET_free (w->name); |
1207 | GNUNET_free (w->subsystem); | 1214 | GNUNET_free (w->subsystem); |
@@ -1291,8 +1298,10 @@ add_setter_action (struct GNUNET_STATISTICS_Handle *h, | |||
1291 | ai->type = type; | 1298 | ai->type = type; |
1292 | } | 1299 | } |
1293 | } | 1300 | } |
1294 | ai->timeout = GNUNET_TIME_relative_to_absolute (SET_TRANSMIT_TIMEOUT); | 1301 | ai->timeout |
1295 | ai->make_persistent = make_persistent; | 1302 | = GNUNET_TIME_relative_to_absolute (SET_TRANSMIT_TIMEOUT); |
1303 | ai->make_persistent | ||
1304 | = make_persistent; | ||
1296 | return; | 1305 | return; |
1297 | } | 1306 | } |
1298 | /* no existing entry matches, create a fresh one */ | 1307 | /* no existing entry matches, create a fresh one */ |
diff --git a/src/util/gnunet-service-resolver.c b/src/util/gnunet-service-resolver.c index a87b1f5d0..12e484845 100644 --- a/src/util/gnunet-service-resolver.c +++ b/src/util/gnunet-service-resolver.c | |||
@@ -1,6 +1,6 @@ | |||
1 | /* | 1 | /* |
2 | This file is part of GNUnet. | 2 | This file is part of GNUnet. |
3 | Copyright (C) 2007-2013 GNUnet e.V. | 3 | Copyright (C) 2007-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 |
@@ -197,6 +197,22 @@ cache_resolve (struct IPCache *cache) | |||
197 | 197 | ||
198 | 198 | ||
199 | /** | 199 | /** |
200 | * Function called after the replies for the request have all | ||
201 | * been transmitted to the client, and we can now read the next | ||
202 | * request from the client. | ||
203 | * | ||
204 | * @param cls the `struct GNUNET_SERVICE_Client` to continue with | ||
205 | */ | ||
206 | static void | ||
207 | notify_service_client_done (void *cls) | ||
208 | { | ||
209 | struct GNUNET_SERVICE_Client *client = cls; | ||
210 | |||
211 | GNUNET_SERVICE_client_continue (client); | ||
212 | } | ||
213 | |||
214 | |||
215 | /** | ||
200 | * Get an IP address as a string (works for both IPv4 and IPv6). Note | 216 | * Get an IP address as a string (works for both IPv4 and IPv6). Note |
201 | * that the resolution happens asynchronously and that the first call | 217 | * that the resolution happens asynchronously and that the first call |
202 | * may not immediately result in the FQN (but instead in a | 218 | * may not immediately result in the FQN (but instead in a |
@@ -207,16 +223,19 @@ cache_resolve (struct IPCache *cache) | |||
207 | * @param ip `struct in_addr` or `struct in6_addr` | 223 | * @param ip `struct in_addr` or `struct in6_addr` |
208 | */ | 224 | */ |
209 | static void | 225 | static void |
210 | get_ip_as_string (struct GNUNET_SERVER_Client *client, | 226 | get_ip_as_string (struct GNUNET_SERVICE_Client *client, |
211 | int af, | 227 | int af, |
212 | const void *ip) | 228 | const void *ip) |
213 | { | 229 | { |
214 | struct IPCache *pos; | 230 | struct IPCache *pos; |
215 | struct IPCache *next; | 231 | struct IPCache *next; |
216 | struct GNUNET_TIME_Absolute now; | 232 | struct GNUNET_TIME_Absolute now; |
217 | struct GNUNET_SERVER_TransmitContext *tc; | 233 | struct GNUNET_MQ_Envelope *env; |
234 | struct GNUNET_MQ_Handle *mq; | ||
235 | struct GNUNET_MessageHeader *msg; | ||
218 | size_t ip_len; | 236 | size_t ip_len; |
219 | struct in6_addr ix; | 237 | struct in6_addr ix; |
238 | size_t alen; | ||
220 | 239 | ||
221 | switch (af) | 240 | switch (af) |
222 | { | 241 | { |
@@ -267,7 +286,9 @@ get_ip_as_string (struct GNUNET_SERVER_Client *client, | |||
267 | { | 286 | { |
268 | pos = GNUNET_malloc (sizeof (struct IPCache) + ip_len); | 287 | pos = GNUNET_malloc (sizeof (struct IPCache) + ip_len); |
269 | pos->ip = &pos[1]; | 288 | pos->ip = &pos[1]; |
270 | GNUNET_memcpy (&pos[1], ip, ip_len); | 289 | GNUNET_memcpy (&pos[1], |
290 | ip, | ||
291 | ip_len); | ||
271 | pos->last_request = now; | 292 | pos->last_request = now; |
272 | pos->last_refresh = now; | 293 | pos->last_refresh = now; |
273 | pos->ip_len = ip_len; | 294 | pos->ip_len = ip_len; |
@@ -277,29 +298,41 @@ get_ip_as_string (struct GNUNET_SERVER_Client *client, | |||
277 | pos); | 298 | pos); |
278 | cache_resolve (pos); | 299 | cache_resolve (pos); |
279 | } | 300 | } |
280 | tc = GNUNET_SERVER_transmit_context_create (client); | ||
281 | if (NULL != pos->addr) | 301 | if (NULL != pos->addr) |
282 | GNUNET_SERVER_transmit_context_append_data (tc, pos->addr, | 302 | alen = strlen (pos->addr) + 1; |
283 | strlen (pos->addr) + 1, | ||
284 | GNUNET_MESSAGE_TYPE_RESOLVER_RESPONSE); | ||
285 | else | 303 | else |
286 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, | 304 | alen = 0; |
287 | "Reverse lookup failed\n"); | 305 | mq = GNUNET_SERVICE_client_get_mq (client); |
288 | GNUNET_SERVER_transmit_context_append_data (tc, NULL, 0, | 306 | env = GNUNET_MQ_msg_extra (msg, |
289 | GNUNET_MESSAGE_TYPE_RESOLVER_RESPONSE); | 307 | alen, |
290 | GNUNET_SERVER_transmit_context_run (tc, GNUNET_TIME_UNIT_FOREVER_REL); | 308 | GNUNET_MESSAGE_TYPE_RESOLVER_RESPONSE); |
309 | GNUNET_memcpy (&msg[1], | ||
310 | pos->addr, | ||
311 | alen); | ||
312 | GNUNET_MQ_send (mq, | ||
313 | env); | ||
314 | env = GNUNET_MQ_msg (msg, | ||
315 | GNUNET_MESSAGE_TYPE_RESOLVER_RESPONSE); | ||
316 | GNUNET_MQ_notify_sent (env, | ||
317 | ¬ify_service_client_done, | ||
318 | client); | ||
319 | GNUNET_MQ_send (mq, | ||
320 | env); | ||
291 | } | 321 | } |
292 | 322 | ||
293 | 323 | ||
294 | #if HAVE_GETADDRINFO | 324 | #if HAVE_GETADDRINFO |
295 | static int | 325 | static int |
296 | getaddrinfo_resolve (struct GNUNET_SERVER_TransmitContext *tc, | 326 | getaddrinfo_resolve (struct GNUNET_MQ_Handle *mq, |
297 | const char *hostname, int af) | 327 | const char *hostname, |
328 | int af) | ||
298 | { | 329 | { |
299 | int s; | 330 | int s; |
300 | struct addrinfo hints; | 331 | struct addrinfo hints; |
301 | struct addrinfo *result; | 332 | struct addrinfo *result; |
302 | struct addrinfo *pos; | 333 | struct addrinfo *pos; |
334 | struct GNUNET_MessageHeader *msg; | ||
335 | struct GNUNET_MQ_Envelope *env; | ||
303 | 336 | ||
304 | #ifdef WINDOWS | 337 | #ifdef WINDOWS |
305 | /* Due to a bug, getaddrinfo will not return a mix of different families */ | 338 | /* Due to a bug, getaddrinfo will not return a mix of different families */ |
@@ -307,21 +340,32 @@ getaddrinfo_resolve (struct GNUNET_SERVER_TransmitContext *tc, | |||
307 | { | 340 | { |
308 | int ret1; | 341 | int ret1; |
309 | int ret2; | 342 | int ret2; |
310 | ret1 = getaddrinfo_resolve (tc, hostname, AF_INET); | 343 | ret1 = getaddrinfo_resolve (mq, |
311 | ret2 = getaddrinfo_resolve (tc, hostname, AF_INET6); | 344 | hostname, |
312 | if ((ret1 == GNUNET_OK) || (ret2 == GNUNET_OK)) | 345 | AF_INET); |
346 | ret2 = getaddrinfo_resolve (mq, | ||
347 | hostname, | ||
348 | AF_INET6); | ||
349 | if ( (ret1 == GNUNET_OK) || | ||
350 | (ret2 == GNUNET_OK) ) | ||
313 | return GNUNET_OK; | 351 | return GNUNET_OK; |
314 | if ((ret1 == GNUNET_SYSERR) || (ret2 == GNUNET_SYSERR)) | 352 | if ( (ret1 == GNUNET_SYSERR) || |
353 | (ret2 == GNUNET_SYSERR) ) | ||
315 | return GNUNET_SYSERR; | 354 | return GNUNET_SYSERR; |
316 | return GNUNET_NO; | 355 | return GNUNET_NO; |
317 | } | 356 | } |
318 | #endif | 357 | #endif |
319 | 358 | ||
320 | memset (&hints, 0, sizeof (struct addrinfo)); | 359 | memset (&hints, |
360 | 0, | ||
361 | sizeof (struct addrinfo)); | ||
321 | hints.ai_family = af; | 362 | hints.ai_family = af; |
322 | hints.ai_socktype = SOCK_STREAM; /* go for TCP */ | 363 | hints.ai_socktype = SOCK_STREAM; /* go for TCP */ |
323 | 364 | ||
324 | if (0 != (s = getaddrinfo (hostname, NULL, &hints, &result))) | 365 | if (0 != (s = getaddrinfo (hostname, |
366 | NULL, | ||
367 | &hints, | ||
368 | &result))) | ||
325 | { | 369 | { |
326 | GNUNET_log (GNUNET_ERROR_TYPE_INFO, | 370 | GNUNET_log (GNUNET_ERROR_TYPE_INFO, |
327 | _("Could not resolve `%s' (%s): %s\n"), | 371 | _("Could not resolve `%s' (%s): %s\n"), |
@@ -329,13 +373,11 @@ getaddrinfo_resolve (struct GNUNET_SERVER_TransmitContext *tc, | |||
329 | (af == | 373 | (af == |
330 | AF_INET) ? "IPv4" : ((af == AF_INET6) ? "IPv6" : "any"), | 374 | AF_INET) ? "IPv4" : ((af == AF_INET6) ? "IPv6" : "any"), |
331 | gai_strerror (s)); | 375 | gai_strerror (s)); |
332 | if ((s == EAI_BADFLAGS) || (s == EAI_MEMORY) | 376 | if ( (s == EAI_BADFLAGS) || |
333 | #ifndef WINDOWS | 377 | #ifndef WINDOWS |
334 | || (s == EAI_SYSTEM) | 378 | (s == EAI_SYSTEM) || |
335 | #else | ||
336 | || 1 | ||
337 | #endif | 379 | #endif |
338 | ) | 380 | (s == EAI_MEMORY) ) |
339 | return GNUNET_NO; /* other function may still succeed */ | 381 | return GNUNET_NO; /* other function may still succeed */ |
340 | return GNUNET_SYSERR; | 382 | return GNUNET_SYSERR; |
341 | } | 383 | } |
@@ -346,16 +388,24 @@ getaddrinfo_resolve (struct GNUNET_SERVER_TransmitContext *tc, | |||
346 | switch (pos->ai_family) | 388 | switch (pos->ai_family) |
347 | { | 389 | { |
348 | case AF_INET: | 390 | case AF_INET: |
349 | GNUNET_SERVER_transmit_context_append_data (tc, | 391 | env = GNUNET_MQ_msg_extra (msg, |
350 | &((struct sockaddr_in*) pos->ai_addr)->sin_addr, | 392 | sizeof (struct in_addr), |
351 | sizeof (struct in_addr), | 393 | GNUNET_MESSAGE_TYPE_RESOLVER_RESPONSE); |
352 | GNUNET_MESSAGE_TYPE_RESOLVER_RESPONSE); | 394 | GNUNET_memcpy (&msg[1], |
395 | &((struct sockaddr_in*) pos->ai_addr)->sin_addr, | ||
396 | sizeof (struct in_addr)); | ||
397 | GNUNET_MQ_send (mq, | ||
398 | env); | ||
353 | break; | 399 | break; |
354 | case AF_INET6: | 400 | case AF_INET6: |
355 | GNUNET_SERVER_transmit_context_append_data (tc, | 401 | env = GNUNET_MQ_msg_extra (msg, |
356 | &((struct sockaddr_in6*) pos->ai_addr)->sin6_addr, | 402 | sizeof (struct in6_addr), |
357 | sizeof (struct in6_addr), | 403 | GNUNET_MESSAGE_TYPE_RESOLVER_RESPONSE); |
358 | GNUNET_MESSAGE_TYPE_RESOLVER_RESPONSE); | 404 | GNUNET_memcpy (&msg[1], |
405 | &((struct sockaddr_in6*) pos->ai_addr)->sin6_addr, | ||
406 | sizeof (struct in6_addr)); | ||
407 | GNUNET_MQ_send (mq, | ||
408 | env); | ||
359 | break; | 409 | break; |
360 | default: | 410 | default: |
361 | /* unsupported, skip */ | 411 | /* unsupported, skip */ |
@@ -371,13 +421,15 @@ getaddrinfo_resolve (struct GNUNET_SERVER_TransmitContext *tc, | |||
371 | 421 | ||
372 | 422 | ||
373 | static int | 423 | static int |
374 | gethostbyname2_resolve (struct GNUNET_SERVER_TransmitContext *tc, | 424 | gethostbyname2_resolve (struct GNUNET_MQ_Handle *mq, |
375 | const char *hostname, | 425 | const char *hostname, |
376 | int af) | 426 | int af) |
377 | { | 427 | { |
378 | struct hostent *hp; | 428 | struct hostent *hp; |
379 | int ret1; | 429 | int ret1; |
380 | int ret2; | 430 | int ret2; |
431 | struct GNUNET_MQ_Envelope *env; | ||
432 | struct GNUNET_MessageHeader *msg; | ||
381 | 433 | ||
382 | #ifdef WINDOWS | 434 | #ifdef WINDOWS |
383 | /* gethostbyname2() in plibc is a compat dummy that calls gethostbyname(). */ | 435 | /* gethostbyname2() in plibc is a compat dummy that calls gethostbyname(). */ |
@@ -386,19 +438,27 @@ gethostbyname2_resolve (struct GNUNET_SERVER_TransmitContext *tc, | |||
386 | 438 | ||
387 | if (af == AF_UNSPEC) | 439 | if (af == AF_UNSPEC) |
388 | { | 440 | { |
389 | ret1 = gethostbyname2_resolve (tc, hostname, AF_INET); | 441 | ret1 = gethostbyname2_resolve (mq, |
390 | ret2 = gethostbyname2_resolve (tc, hostname, AF_INET6); | 442 | hostname, |
391 | if ((ret1 == GNUNET_OK) || (ret2 == GNUNET_OK)) | 443 | AF_INET); |
444 | ret2 = gethostbyname2_resolve (mq, | ||
445 | hostname, | ||
446 | AF_INET6); | ||
447 | if ( (ret1 == GNUNET_OK) || | ||
448 | (ret2 == GNUNET_OK) ) | ||
392 | return GNUNET_OK; | 449 | return GNUNET_OK; |
393 | if ((ret1 == GNUNET_SYSERR) || (ret2 == GNUNET_SYSERR)) | 450 | if ( (ret1 == GNUNET_SYSERR) || |
451 | (ret2 == GNUNET_SYSERR) ) | ||
394 | return GNUNET_SYSERR; | 452 | return GNUNET_SYSERR; |
395 | return GNUNET_NO; | 453 | return GNUNET_NO; |
396 | } | 454 | } |
397 | hp = gethostbyname2 (hostname, af); | 455 | hp = gethostbyname2 (hostname, |
456 | af); | ||
398 | if (hp == NULL) | 457 | if (hp == NULL) |
399 | { | 458 | { |
400 | GNUNET_log (GNUNET_ERROR_TYPE_INFO, | 459 | GNUNET_log (GNUNET_ERROR_TYPE_INFO, |
401 | _("Could not find IP of host `%s': %s\n"), hostname, | 460 | _("Could not find IP of host `%s': %s\n"), |
461 | hostname, | ||
402 | hstrerror (h_errno)); | 462 | hstrerror (h_errno)); |
403 | return GNUNET_SYSERR; | 463 | return GNUNET_SYSERR; |
404 | } | 464 | } |
@@ -407,17 +467,25 @@ gethostbyname2_resolve (struct GNUNET_SERVER_TransmitContext *tc, | |||
407 | { | 467 | { |
408 | case AF_INET: | 468 | case AF_INET: |
409 | GNUNET_assert (hp->h_length == sizeof (struct in_addr)); | 469 | GNUNET_assert (hp->h_length == sizeof (struct in_addr)); |
410 | GNUNET_SERVER_transmit_context_append_data (tc, | 470 | env = GNUNET_MQ_msg_extra (msg, |
411 | hp->h_addr_list[0], | 471 | hp->h_length, |
412 | hp->h_length, | 472 | GNUNET_MESSAGE_TYPE_RESOLVER_RESPONSE); |
413 | GNUNET_MESSAGE_TYPE_RESOLVER_RESPONSE); | 473 | GNUNET_memcpy (&msg[1], |
474 | hp->h_addr_list[0], | ||
475 | hp->h_length); | ||
476 | GNUNET_MQ_send (mq, | ||
477 | env); | ||
414 | break; | 478 | break; |
415 | case AF_INET6: | 479 | case AF_INET6: |
416 | GNUNET_assert (hp->h_length == sizeof (struct in6_addr)); | 480 | GNUNET_assert (hp->h_length == sizeof (struct in6_addr)); |
417 | GNUNET_SERVER_transmit_context_append_data (tc, | 481 | env = GNUNET_MQ_msg_extra (msg, |
418 | hp->h_addr_list[0], | 482 | hp->h_length, |
419 | hp->h_length, | 483 | GNUNET_MESSAGE_TYPE_RESOLVER_RESPONSE); |
420 | GNUNET_MESSAGE_TYPE_RESOLVER_RESPONSE); | 484 | GNUNET_memcpy (&msg[1], |
485 | hp->h_addr_list[0], | ||
486 | hp->h_length); | ||
487 | GNUNET_MQ_send (mq, | ||
488 | env); | ||
421 | break; | 489 | break; |
422 | default: | 490 | default: |
423 | GNUNET_break (0); | 491 | GNUNET_break (0); |
@@ -430,10 +498,12 @@ gethostbyname2_resolve (struct GNUNET_SERVER_TransmitContext *tc, | |||
430 | 498 | ||
431 | 499 | ||
432 | static int | 500 | static int |
433 | gethostbyname_resolve (struct GNUNET_SERVER_TransmitContext *tc, | 501 | gethostbyname_resolve (struct GNUNET_MQ_Handle *mq, |
434 | const char *hostname) | 502 | const char *hostname) |
435 | { | 503 | { |
436 | struct hostent *hp; | 504 | struct hostent *hp; |
505 | struct GNUNET_MessageHeader *msg; | ||
506 | struct GNUNET_MQ_Envelope *env; | ||
437 | 507 | ||
438 | hp = GETHOSTBYNAME (hostname); | 508 | hp = GETHOSTBYNAME (hostname); |
439 | if (NULL == hp) | 509 | if (NULL == hp) |
@@ -450,10 +520,14 @@ gethostbyname_resolve (struct GNUNET_SERVER_TransmitContext *tc, | |||
450 | return GNUNET_SYSERR; | 520 | return GNUNET_SYSERR; |
451 | } | 521 | } |
452 | GNUNET_assert (hp->h_length == sizeof (struct in_addr)); | 522 | GNUNET_assert (hp->h_length == sizeof (struct in_addr)); |
453 | GNUNET_SERVER_transmit_context_append_data (tc, | 523 | env = GNUNET_MQ_msg_extra (msg, |
454 | hp->h_addr_list[0], | 524 | hp->h_length, |
455 | hp->h_length, | 525 | GNUNET_MESSAGE_TYPE_RESOLVER_RESPONSE); |
456 | GNUNET_MESSAGE_TYPE_RESOLVER_RESPONSE); | 526 | GNUNET_memcpy (&msg[1], |
527 | hp->h_addr_list[0], | ||
528 | hp->h_length); | ||
529 | GNUNET_MQ_send (mq, | ||
530 | env); | ||
457 | return GNUNET_OK; | 531 | return GNUNET_OK; |
458 | } | 532 | } |
459 | #endif | 533 | #endif |
@@ -467,168 +541,197 @@ gethostbyname_resolve (struct GNUNET_SERVER_TransmitContext *tc, | |||
467 | * @param af AF_INET or AF_INET6; use AF_UNSPEC for "any" | 541 | * @param af AF_INET or AF_INET6; use AF_UNSPEC for "any" |
468 | */ | 542 | */ |
469 | static void | 543 | static void |
470 | get_ip_from_hostname (struct GNUNET_SERVER_Client *client, | 544 | get_ip_from_hostname (struct GNUNET_SERVICE_Client *client, |
471 | const char *hostname, | 545 | const char *hostname, |
472 | int af) | 546 | int af) |
473 | { | 547 | { |
474 | int ret; | 548 | int ret; |
475 | struct GNUNET_SERVER_TransmitContext *tc; | 549 | struct GNUNET_MQ_Handle *mq; |
550 | struct GNUNET_MQ_Envelope *env; | ||
551 | struct GNUNET_MessageHeader *msg; | ||
476 | 552 | ||
477 | tc = GNUNET_SERVER_transmit_context_create (client); | 553 | mq = GNUNET_SERVICE_client_get_mq (client); |
478 | ret = GNUNET_NO; | 554 | ret = GNUNET_NO; |
479 | #if HAVE_GETADDRINFO | 555 | #if HAVE_GETADDRINFO |
480 | if (ret == GNUNET_NO) | 556 | if (ret == GNUNET_NO) |
481 | ret = getaddrinfo_resolve (tc, hostname, af); | 557 | ret = getaddrinfo_resolve (mq, |
558 | hostname, | ||
559 | af); | ||
482 | #elif HAVE_GETHOSTBYNAME2 | 560 | #elif HAVE_GETHOSTBYNAME2 |
483 | if (ret == GNUNET_NO) | 561 | if (ret == GNUNET_NO) |
484 | ret = gethostbyname2_resolve (tc, hostname, af); | 562 | ret = gethostbyname2_resolve (mq, |
563 | hostname, | ||
564 | af); | ||
485 | #elif HAVE_GETHOSTBYNAME | 565 | #elif HAVE_GETHOSTBYNAME |
486 | if ((ret == GNUNET_NO) && ((af == AF_UNSPEC) || (af == PF_INET))) | 566 | if ( (ret == GNUNET_NO) && |
487 | gethostbyname_resolve (tc, hostname); | 567 | ( (af == AF_UNSPEC) || |
568 | (af == PF_INET) ) ) | ||
569 | gethostbyname_resolve (mq, | ||
570 | hostname); | ||
488 | #endif | 571 | #endif |
489 | GNUNET_SERVER_transmit_context_append_data (tc, NULL, 0, | 572 | env = GNUNET_MQ_msg (msg, |
490 | GNUNET_MESSAGE_TYPE_RESOLVER_RESPONSE); | 573 | GNUNET_MESSAGE_TYPE_RESOLVER_RESPONSE); |
491 | GNUNET_SERVER_transmit_context_run (tc, GNUNET_TIME_UNIT_FOREVER_REL); | 574 | GNUNET_MQ_notify_sent (env, |
575 | ¬ify_service_client_done, | ||
576 | client); | ||
577 | GNUNET_MQ_send (mq, | ||
578 | env); | ||
492 | } | 579 | } |
493 | 580 | ||
494 | 581 | ||
495 | /** | 582 | /** |
496 | * Handle GET-message. | 583 | * Verify well-formedness of GET-message. |
497 | * | 584 | * |
498 | * @param cls closure | 585 | * @param cls closure |
499 | * @param client identification of the client | 586 | * @param get the actual message |
500 | * @param message the actual message | 587 | * @return #GNUNET_OK if @a get is well-formed |
501 | */ | 588 | */ |
502 | static void | 589 | static int |
503 | handle_get (void *cls, | 590 | check_get (void *cls, |
504 | struct GNUNET_SERVER_Client *client, | 591 | const struct GNUNET_RESOLVER_GetMessage *get) |
505 | const struct GNUNET_MessageHeader *message) | ||
506 | { | 592 | { |
507 | uint16_t msize; | ||
508 | const struct GNUNET_RESOLVER_GetMessage *msg; | ||
509 | const void *ip; | ||
510 | uint16_t size; | 593 | uint16_t size; |
511 | int direction; | 594 | int direction; |
512 | int af; | 595 | int af; |
513 | 596 | ||
514 | msize = ntohs (message->size); | 597 | size = ntohs (get->header.size) - sizeof (*get); |
515 | if (msize < sizeof (struct GNUNET_RESOLVER_GetMessage)) | 598 | direction = ntohl (get->direction); |
516 | { | ||
517 | GNUNET_break (0); | ||
518 | GNUNET_SERVER_receive_done (client, | ||
519 | GNUNET_SYSERR); | ||
520 | return; | ||
521 | } | ||
522 | msg = (const struct GNUNET_RESOLVER_GetMessage *) message; | ||
523 | size = msize - sizeof (struct GNUNET_RESOLVER_GetMessage); | ||
524 | direction = ntohl (msg->direction); | ||
525 | af = ntohl (msg->af); | ||
526 | if (GNUNET_NO == direction) | 599 | if (GNUNET_NO == direction) |
527 | { | 600 | { |
528 | /* IP from hostname */ | 601 | /* IP from hostname */ |
529 | const char *hostname; | 602 | const char *hostname; |
530 | 603 | ||
531 | hostname = (const char *) &msg[1]; | 604 | hostname = (const char *) &get[1]; |
532 | if (hostname[size - 1] != '\0') | 605 | if (hostname[size - 1] != '\0') |
533 | { | 606 | { |
534 | GNUNET_break (0); | 607 | GNUNET_break (0); |
535 | GNUNET_SERVER_receive_done (client, | 608 | return GNUNET_SYSERR; |
536 | GNUNET_SYSERR); | ||
537 | return; | ||
538 | } | 609 | } |
539 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, | 610 | return GNUNET_OK; |
540 | "Resolver asked to look up `%s'.\n", | ||
541 | hostname); | ||
542 | get_ip_from_hostname (client, hostname, af); | ||
543 | return; | ||
544 | } | 611 | } |
545 | ip = &msg[1]; | 612 | af = ntohl (get->af); |
546 | switch (af) | 613 | switch (af) |
547 | { | 614 | { |
548 | case AF_INET: | 615 | case AF_INET: |
549 | if (size != sizeof (struct in_addr)) | 616 | if (size != sizeof (struct in_addr)) |
550 | { | 617 | { |
551 | GNUNET_break (0); | 618 | GNUNET_break (0); |
552 | GNUNET_SERVER_receive_done (client, | 619 | return GNUNET_SYSERR; |
553 | GNUNET_SYSERR); | ||
554 | return; | ||
555 | } | 620 | } |
556 | break; | 621 | break; |
557 | case AF_INET6: | 622 | case AF_INET6: |
558 | if (size != sizeof (struct in6_addr)) | 623 | if (size != sizeof (struct in6_addr)) |
559 | { | 624 | { |
560 | GNUNET_break (0); | 625 | GNUNET_break (0); |
561 | GNUNET_SERVER_receive_done (client, | 626 | return GNUNET_SYSERR; |
562 | GNUNET_SYSERR); | ||
563 | return; | ||
564 | } | 627 | } |
565 | break; | 628 | break; |
566 | default: | 629 | default: |
567 | GNUNET_break (0); | 630 | GNUNET_break (0); |
568 | GNUNET_SERVER_receive_done (client, | 631 | return GNUNET_SYSERR; |
569 | GNUNET_SYSERR); | 632 | } |
633 | return GNUNET_OK; | ||
634 | } | ||
635 | |||
636 | |||
637 | /** | ||
638 | * Handle GET-message. | ||
639 | * | ||
640 | * @param cls identification of the client | ||
641 | * @param msg the actual message | ||
642 | */ | ||
643 | static void | ||
644 | handle_get (void *cls, | ||
645 | const struct GNUNET_RESOLVER_GetMessage *msg) | ||
646 | { | ||
647 | struct GNUNET_SERVICE_Client *client = cls; | ||
648 | const void *ip; | ||
649 | int direction; | ||
650 | int af; | ||
651 | |||
652 | direction = ntohl (msg->direction); | ||
653 | af = ntohl (msg->af); | ||
654 | if (GNUNET_NO == direction) | ||
655 | { | ||
656 | /* IP from hostname */ | ||
657 | const char *hostname; | ||
658 | |||
659 | hostname = (const char *) &msg[1]; | ||
660 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, | ||
661 | "Resolver asked to look up `%s'.\n", | ||
662 | hostname); | ||
663 | get_ip_from_hostname (client, | ||
664 | hostname, | ||
665 | af); | ||
570 | return; | 666 | return; |
571 | } | 667 | } |
668 | ip = &msg[1]; | ||
572 | { | 669 | { |
573 | char buf[INET6_ADDRSTRLEN]; | 670 | char buf[INET6_ADDRSTRLEN]; |
574 | 671 | ||
575 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, | 672 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, |
576 | "Resolver asked to look up IP address `%s'.\n", | 673 | "Resolver asked to look up IP address `%s'.\n", |
577 | inet_ntop (af, ip, buf, sizeof (buf))); | 674 | inet_ntop (af, |
675 | ip, | ||
676 | buf, | ||
677 | sizeof (buf))); | ||
578 | } | 678 | } |
579 | get_ip_as_string (client, af, ip); | 679 | get_ip_as_string (client, |
680 | af, | ||
681 | ip); | ||
580 | } | 682 | } |
581 | 683 | ||
582 | 684 | ||
583 | /** | 685 | /** |
584 | * Process resolver requests. | 686 | * Callback called when a client connects to the service. |
585 | * | 687 | * |
586 | * @param cls closure | 688 | * @param cls closure for the service |
587 | * @param server the initialized server | 689 | * @param c the new client that connected to the service |
588 | * @param cfg configuration to use | 690 | * @param mq the message queue used to send messages to the client |
691 | * @return @a c | ||
589 | */ | 692 | */ |
590 | static void | 693 | static void * |
591 | run (void *cls, struct GNUNET_SERVER_Handle *server, | 694 | connect_cb (void *cls, |
592 | const struct GNUNET_CONFIGURATION_Handle *cfg) | 695 | struct GNUNET_SERVICE_Client *c, |
696 | struct GNUNET_MQ_Handle *mq) | ||
593 | { | 697 | { |
594 | static const struct GNUNET_SERVER_MessageHandler handlers[] = { | 698 | return c; |
595 | {&handle_get, NULL, GNUNET_MESSAGE_TYPE_RESOLVER_REQUEST, 0}, | ||
596 | {NULL, NULL, 0, 0} | ||
597 | }; | ||
598 | GNUNET_SERVER_add_handlers (server, handlers); | ||
599 | } | 699 | } |
600 | 700 | ||
601 | 701 | ||
602 | /** | 702 | /** |
603 | * The main function for the resolver service. | 703 | * Callback called when a client disconnected from the service |
604 | * | 704 | * |
605 | * @param argc number of arguments from the command line | 705 | * @param cls closure for the service |
606 | * @param argv command line arguments | 706 | * @param c the client that disconnected |
607 | * @return 0 ok, 1 on error | 707 | * @param internal_cls should be equal to @a c |
608 | */ | 708 | */ |
609 | int | 709 | static void |
610 | main (int argc, char *const *argv) | 710 | disconnect_cb (void *cls, |
711 | struct GNUNET_SERVICE_Client *c, | ||
712 | void *internal_cls) | ||
611 | { | 713 | { |
612 | struct IPCache *pos; | 714 | GNUNET_assert (c == internal_cls); |
613 | int ret; | ||
614 | |||
615 | ret = | ||
616 | (GNUNET_OK == | ||
617 | GNUNET_SERVICE_run (argc, argv, | ||
618 | "resolver", | ||
619 | GNUNET_SERVICE_OPTION_NONE, | ||
620 | &run, NULL)) ? 0 : 1; | ||
621 | while (NULL != (pos = cache_head)) | ||
622 | { | ||
623 | GNUNET_CONTAINER_DLL_remove (cache_head, | ||
624 | cache_tail, | ||
625 | pos); | ||
626 | GNUNET_free_non_null (pos->addr); | ||
627 | GNUNET_free (pos); | ||
628 | } | ||
629 | return ret; | ||
630 | } | 715 | } |
631 | 716 | ||
717 | |||
718 | /** | ||
719 | * Define "main" method using service macro. | ||
720 | */ | ||
721 | GNUNET_SERVICE_MAIN | ||
722 | ("resolver", | ||
723 | GNUNET_SERVICE_OPTION_NONE, | ||
724 | NULL, | ||
725 | &connect_cb, | ||
726 | &disconnect_cb, | ||
727 | NULL, | ||
728 | GNUNET_MQ_hd_var_size (get, | ||
729 | GNUNET_MESSAGE_TYPE_RESOLVER_REQUEST, | ||
730 | struct GNUNET_RESOLVER_GetMessage, | ||
731 | NULL), | ||
732 | GNUNET_MQ_handler_end ()); | ||
733 | |||
734 | |||
632 | #if defined(LINUX) && defined(__GLIBC__) | 735 | #if defined(LINUX) && defined(__GLIBC__) |
633 | #include <malloc.h> | 736 | #include <malloc.h> |
634 | 737 | ||
@@ -636,7 +739,7 @@ main (int argc, char *const *argv) | |||
636 | * MINIMIZE heap size (way below 128k) since this process doesn't need much. | 739 | * MINIMIZE heap size (way below 128k) since this process doesn't need much. |
637 | */ | 740 | */ |
638 | void __attribute__ ((constructor)) | 741 | void __attribute__ ((constructor)) |
639 | GNUNET_ARM_memory_init () | 742 | GNUNET_RESOLVER_memory_init () |
640 | { | 743 | { |
641 | mallopt (M_TRIM_THRESHOLD, 4 * 1024); | 744 | mallopt (M_TRIM_THRESHOLD, 4 * 1024); |
642 | mallopt (M_TOP_PAD, 1 * 1024); | 745 | mallopt (M_TOP_PAD, 1 * 1024); |
@@ -645,4 +748,23 @@ GNUNET_ARM_memory_init () | |||
645 | #endif | 748 | #endif |
646 | 749 | ||
647 | 750 | ||
751 | /** | ||
752 | * Free globals on exit. | ||
753 | */ | ||
754 | void __attribute__ ((destructor)) | ||
755 | GNUNET_RESOLVER_memory_done () | ||
756 | { | ||
757 | struct IPCache *pos; | ||
758 | |||
759 | while (NULL != (pos = cache_head)) | ||
760 | { | ||
761 | GNUNET_CONTAINER_DLL_remove (cache_head, | ||
762 | cache_tail, | ||
763 | pos); | ||
764 | GNUNET_free_non_null (pos->addr); | ||
765 | GNUNET_free (pos); | ||
766 | } | ||
767 | } | ||
768 | |||
769 | |||
648 | /* end of gnunet-service-resolver.c */ | 770 | /* end of gnunet-service-resolver.c */ |
diff --git a/src/util/mq.c b/src/util/mq.c index b22d97f59..e9dba3d9d 100644 --- a/src/util/mq.c +++ b/src/util/mq.c | |||
@@ -359,6 +359,7 @@ GNUNET_MQ_send (struct GNUNET_MQ_Handle *mq, | |||
359 | GNUNET_assert (NULL != mq); | 359 | GNUNET_assert (NULL != mq); |
360 | GNUNET_assert (NULL == ev->parent_queue); | 360 | GNUNET_assert (NULL == ev->parent_queue); |
361 | 361 | ||
362 | mq->queue_length++; | ||
362 | ev->parent_queue = mq; | 363 | ev->parent_queue = mq; |
363 | /* is the implementation busy? queue it! */ | 364 | /* is the implementation busy? queue it! */ |
364 | if (NULL != mq->current_envelope) | 365 | if (NULL != mq->current_envelope) |
@@ -366,11 +367,12 @@ GNUNET_MQ_send (struct GNUNET_MQ_Handle *mq, | |||
366 | GNUNET_CONTAINER_DLL_insert_tail (mq->envelope_head, | 367 | GNUNET_CONTAINER_DLL_insert_tail (mq->envelope_head, |
367 | mq->envelope_tail, | 368 | mq->envelope_tail, |
368 | ev); | 369 | ev); |
369 | mq->queue_length++; | ||
370 | return; | 370 | return; |
371 | } | 371 | } |
372 | mq->current_envelope = ev; | 372 | mq->current_envelope = ev; |
373 | mq->send_impl (mq, ev->mh, mq->impl_state); | 373 | mq->send_impl (mq, |
374 | ev->mh, | ||
375 | mq->impl_state); | ||
374 | } | 376 | } |
375 | 377 | ||
376 | 378 | ||
@@ -422,6 +424,8 @@ impl_send_continue (void *cls) | |||
422 | current_envelope = mq->current_envelope; | 424 | current_envelope = mq->current_envelope; |
423 | GNUNET_assert (NULL != current_envelope); | 425 | GNUNET_assert (NULL != current_envelope); |
424 | current_envelope->parent_queue = NULL; | 426 | current_envelope->parent_queue = NULL; |
427 | GNUNET_assert (0 < mq->queue_length); | ||
428 | mq->queue_length--; | ||
425 | if (NULL == mq->envelope_head) | 429 | if (NULL == mq->envelope_head) |
426 | { | 430 | { |
427 | mq->current_envelope = NULL; | 431 | mq->current_envelope = NULL; |
@@ -432,7 +436,6 @@ impl_send_continue (void *cls) | |||
432 | GNUNET_CONTAINER_DLL_remove (mq->envelope_head, | 436 | GNUNET_CONTAINER_DLL_remove (mq->envelope_head, |
433 | mq->envelope_tail, | 437 | mq->envelope_tail, |
434 | mq->current_envelope); | 438 | mq->current_envelope); |
435 | mq->queue_length--; | ||
436 | mq->send_impl (mq, | 439 | mq->send_impl (mq, |
437 | mq->current_envelope->mh, | 440 | mq->current_envelope->mh, |
438 | mq->impl_state); | 441 | mq->impl_state); |
@@ -973,7 +976,6 @@ GNUNET_MQ_destroy (struct GNUNET_MQ_Handle *mq) | |||
973 | mq->queue_length--; | 976 | mq->queue_length--; |
974 | GNUNET_MQ_discard (ev); | 977 | GNUNET_MQ_discard (ev); |
975 | } | 978 | } |
976 | GNUNET_assert (0 == mq->queue_length); | ||
977 | if (NULL != mq->current_envelope) | 979 | if (NULL != mq->current_envelope) |
978 | { | 980 | { |
979 | /* we can only discard envelopes that | 981 | /* we can only discard envelopes that |
@@ -981,7 +983,9 @@ GNUNET_MQ_destroy (struct GNUNET_MQ_Handle *mq) | |||
981 | mq->current_envelope->parent_queue = NULL; | 983 | mq->current_envelope->parent_queue = NULL; |
982 | GNUNET_MQ_discard (mq->current_envelope); | 984 | GNUNET_MQ_discard (mq->current_envelope); |
983 | mq->current_envelope = NULL; | 985 | mq->current_envelope = NULL; |
986 | mq->queue_length--; | ||
984 | } | 987 | } |
988 | GNUNET_assert (0 == mq->queue_length); | ||
985 | if (NULL != mq->assoc_map) | 989 | if (NULL != mq->assoc_map) |
986 | { | 990 | { |
987 | GNUNET_CONTAINER_multihashmap32_destroy (mq->assoc_map); | 991 | GNUNET_CONTAINER_multihashmap32_destroy (mq->assoc_map); |
@@ -1039,6 +1043,7 @@ GNUNET_MQ_send_cancel (struct GNUNET_MQ_Envelope *ev) | |||
1039 | { | 1043 | { |
1040 | // complex case, we already started with transmitting | 1044 | // complex case, we already started with transmitting |
1041 | // the message | 1045 | // the message |
1046 | mq->queue_length--; | ||
1042 | mq->cancel_impl (mq, | 1047 | mq->cancel_impl (mq, |
1043 | mq->impl_state); | 1048 | mq->impl_state); |
1044 | // continue sending the next message, if any | 1049 | // continue sending the next message, if any |