diff options
author | Christian Grothoff <christian@grothoff.org> | 2014-06-09 22:01:41 +0000 |
---|---|---|
committer | Christian Grothoff <christian@grothoff.org> | 2014-06-09 22:01:41 +0000 |
commit | c9f75566447fd3a9c5c304dbc8e31fd68b6aa3ed (patch) | |
tree | 3966560120dc3abbd2bd20983ccf95bc25b731d1 | |
parent | bc6a7f8d6cfbfc92128d1e6c495ee94c5508e26f (diff) | |
download | gnunet-c9f75566447fd3a9c5c304dbc8e31fd68b6aa3ed.tar.gz gnunet-c9f75566447fd3a9c5c304dbc8e31fd68b6aa3ed.zip |
-fix timeout handling for resolver
-rw-r--r-- | src/util/gnunet-service-resolver.c | 6 | ||||
-rw-r--r-- | src/util/resolver_api.c | 169 | ||||
-rw-r--r-- | src/util/test_resolver_api.c | 23 |
3 files changed, 139 insertions, 59 deletions
diff --git a/src/util/gnunet-service-resolver.c b/src/util/gnunet-service-resolver.c index 0392e0bf1..cade20738 100644 --- a/src/util/gnunet-service-resolver.c +++ b/src/util/gnunet-service-resolver.c | |||
@@ -152,7 +152,7 @@ gethostbyaddr_resolve (struct IPCache *cache) | |||
152 | ent = gethostbyaddr (cache->ip, | 152 | ent = gethostbyaddr (cache->ip, |
153 | cache->ip_len, | 153 | cache->ip_len, |
154 | cache->af); | 154 | cache->af); |
155 | if (ent != NULL) | 155 | if (NULL != ent) |
156 | cache->addr = GNUNET_strdup (ent->h_name); | 156 | cache->addr = GNUNET_strdup (ent->h_name); |
157 | } | 157 | } |
158 | #endif | 158 | #endif |
@@ -167,11 +167,11 @@ static void | |||
167 | cache_resolve (struct IPCache *cache) | 167 | cache_resolve (struct IPCache *cache) |
168 | { | 168 | { |
169 | #if HAVE_GETNAMEINFO | 169 | #if HAVE_GETNAMEINFO |
170 | if (cache->addr == NULL) | 170 | if (NULL == cache->addr) |
171 | getnameinfo_resolve (cache); | 171 | getnameinfo_resolve (cache); |
172 | #endif | 172 | #endif |
173 | #if HAVE_GETHOSTBYADDR | 173 | #if HAVE_GETHOSTBYADDR |
174 | if (cache->addr == NULL) | 174 | if (NULL == cache->addr) |
175 | gethostbyaddr_resolve (cache); | 175 | gethostbyaddr_resolve (cache); |
176 | #endif | 176 | #endif |
177 | } | 177 | } |
diff --git a/src/util/resolver_api.c b/src/util/resolver_api.c index d097cd6a5..83dad1eb9 100644 --- a/src/util/resolver_api.c +++ b/src/util/resolver_api.c | |||
@@ -1,6 +1,6 @@ | |||
1 | /* | 1 | /* |
2 | This file is part of GNUnet. | 2 | This file is part of GNUnet. |
3 | (C) 2009-2013 Christian Grothoff (and other contributing authors) | 3 | (C) 2009-2014 Christian Grothoff (and other contributing authors) |
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 |
@@ -128,7 +128,8 @@ struct GNUNET_RESOLVER_RequestHandle | |||
128 | struct GNUNET_TIME_Absolute timeout; | 128 | struct GNUNET_TIME_Absolute timeout; |
129 | 129 | ||
130 | /** | 130 | /** |
131 | * Task handle for numeric lookups. | 131 | * Task handle for making reply callbacks in numeric lookups |
132 | * asynchronous, and for timeout handling. | ||
132 | */ | 133 | */ |
133 | GNUNET_SCHEDULER_TaskIdentifier task; | 134 | GNUNET_SCHEDULER_TaskIdentifier task; |
134 | 135 | ||
@@ -191,11 +192,14 @@ check_config () | |||
191 | v6.sin6_len = sizeof (v6); | 192 | v6.sin6_len = sizeof (v6); |
192 | #endif | 193 | #endif |
193 | if (GNUNET_OK != | 194 | if (GNUNET_OK != |
194 | GNUNET_CONFIGURATION_get_value_string (resolver_cfg, "resolver", | 195 | GNUNET_CONFIGURATION_get_value_string (resolver_cfg, |
195 | "HOSTNAME", &hostname)) | 196 | "resolver", |
197 | "HOSTNAME", | ||
198 | &hostname)) | ||
196 | { | 199 | { |
197 | LOG (GNUNET_ERROR_TYPE_ERROR, | 200 | LOG (GNUNET_ERROR_TYPE_ERROR, |
198 | _("Must specify `%s' for `%s' in configuration!\n"), "HOSTNAME", | 201 | _("Must specify `%s' for `%s' in configuration!\n"), |
202 | "HOSTNAME", | ||
199 | "resolver"); | 203 | "resolver"); |
200 | GNUNET_assert (0); | 204 | GNUNET_assert (0); |
201 | } | 205 | } |
@@ -214,7 +218,9 @@ check_config () | |||
214 | } | 218 | } |
215 | LOG (GNUNET_ERROR_TYPE_ERROR, | 219 | LOG (GNUNET_ERROR_TYPE_ERROR, |
216 | _("Must specify `%s' or numeric IP address for `%s' of `%s' in configuration!\n"), | 220 | _("Must specify `%s' or numeric IP address for `%s' of `%s' in configuration!\n"), |
217 | "localhost", "HOSTNAME", "resolver"); | 221 | "localhost", |
222 | "HOSTNAME", | ||
223 | "resolver"); | ||
218 | GNUNET_free (hostname); | 224 | GNUNET_free (hostname); |
219 | GNUNET_assert (0); | 225 | GNUNET_assert (0); |
220 | } | 226 | } |
@@ -268,7 +274,7 @@ GNUNET_RESOLVER_disconnect () | |||
268 | * | 274 | * |
269 | * @param af address family | 275 | * @param af address family |
270 | * @param ip the address | 276 | * @param ip the address |
271 | * @param ip_len number of bytes in ip | 277 | * @param ip_len number of bytes in @a ip |
272 | * @return address as a string, NULL on error | 278 | * @return address as a string, NULL on error |
273 | */ | 279 | */ |
274 | static char * | 280 | static char * |
@@ -313,20 +319,20 @@ no_resolve (int af, | |||
313 | * Adjust exponential back-off and reconnect to the service. | 319 | * Adjust exponential back-off and reconnect to the service. |
314 | */ | 320 | */ |
315 | static void | 321 | static void |
316 | reconnect (); | 322 | reconnect (void); |
317 | 323 | ||
318 | 324 | ||
319 | /** | 325 | /** |
320 | * Process pending requests to the resolver. | 326 | * Process pending requests to the resolver. |
321 | */ | 327 | */ |
322 | static void | 328 | static void |
323 | process_requests (); | 329 | process_requests (void); |
324 | 330 | ||
325 | 331 | ||
326 | /** | 332 | /** |
327 | * Process response with a hostname for a DNS lookup. | 333 | * Process response with a hostname for a DNS lookup. |
328 | * | 334 | * |
329 | * @param cls our `struct GNUNET_RESOLVER_RequestHandle` context | 335 | * @param cls our `struct GNUNET_RESOLVER_RequestHandle *` context |
330 | * @param msg message with the hostname, NULL on error | 336 | * @param msg message with the hostname, NULL on error |
331 | */ | 337 | */ |
332 | static void | 338 | static void |
@@ -346,7 +352,10 @@ handle_response (void *cls, | |||
346 | if (NULL != rh->name_callback) | 352 | if (NULL != rh->name_callback) |
347 | LOG (GNUNET_ERROR_TYPE_INFO, | 353 | LOG (GNUNET_ERROR_TYPE_INFO, |
348 | _("Timeout trying to resolve IP address `%s'.\n"), | 354 | _("Timeout trying to resolve IP address `%s'.\n"), |
349 | inet_ntop (rh->af, (const void *) &rh[1], buf, sizeof(buf))); | 355 | inet_ntop (rh->af, |
356 | (const void *) &rh[1], | ||
357 | buf, | ||
358 | sizeof(buf))); | ||
350 | else | 359 | else |
351 | LOG (GNUNET_ERROR_TYPE_INFO, | 360 | LOG (GNUNET_ERROR_TYPE_INFO, |
352 | _("Timeout trying to resolve hostname `%s'.\n"), | 361 | _("Timeout trying to resolve hostname `%s'.\n"), |
@@ -356,22 +365,24 @@ handle_response (void *cls, | |||
356 | { | 365 | { |
357 | if (NULL != rh->name_callback) | 366 | if (NULL != rh->name_callback) |
358 | { | 367 | { |
359 | /* no reverse lookup was successful, return ip as string */ | 368 | /* no reverse lookup was successful, return IP as string */ |
360 | if (rh->received_response == GNUNET_NO) | 369 | if (GNUNET_NO == rh->received_response) |
361 | { | 370 | { |
362 | nret = no_resolve (rh->af, &rh[1], rh->data_len); | 371 | nret = no_resolve (rh->af, |
372 | &rh[1], | ||
373 | rh->data_len); | ||
363 | rh->name_callback (rh->cls, nret); | 374 | rh->name_callback (rh->cls, nret); |
364 | GNUNET_free (nret); | 375 | GNUNET_free (nret); |
365 | rh->name_callback (rh->cls, NULL); | ||
366 | } | 376 | } |
367 | /* at least one reverse lookup was successful */ | 377 | /* finally, make termination call */ |
368 | else | 378 | rh->name_callback (rh->cls, NULL); |
369 | rh->name_callback (rh->cls, NULL); | ||
370 | } | 379 | } |
371 | if (NULL != rh->addr_callback) | 380 | if (NULL != rh->addr_callback) |
372 | rh->addr_callback (rh->cls, NULL, 0); | 381 | rh->addr_callback (rh->cls, NULL, 0); |
373 | } | 382 | } |
374 | GNUNET_CONTAINER_DLL_remove (req_head, req_tail, rh); | 383 | GNUNET_CONTAINER_DLL_remove (req_head, req_tail, rh); |
384 | if (GNUNET_SCHEDULER_NO_TASK != rh->task) | ||
385 | GNUNET_SCHEDULER_cancel (rh->task); | ||
375 | GNUNET_free (rh); | 386 | GNUNET_free (rh); |
376 | GNUNET_CLIENT_disconnect (client); | 387 | GNUNET_CLIENT_disconnect (client); |
377 | client = NULL; | 388 | client = NULL; |
@@ -387,9 +398,9 @@ handle_response (void *cls, | |||
387 | return; | 398 | return; |
388 | } | 399 | } |
389 | size = ntohs (msg->size); | 400 | size = ntohs (msg->size); |
390 | /* message contains not data, just header */ | ||
391 | if (size == sizeof (struct GNUNET_MessageHeader)) | 401 | if (size == sizeof (struct GNUNET_MessageHeader)) |
392 | { | 402 | { |
403 | /* message contains not data, just header; end of replies */ | ||
393 | /* check if request was canceled */ | 404 | /* check if request was canceled */ |
394 | if (GNUNET_SYSERR != rh->was_transmitted) | 405 | if (GNUNET_SYSERR != rh->was_transmitted) |
395 | { | 406 | { |
@@ -399,6 +410,8 @@ handle_response (void *cls, | |||
399 | rh->addr_callback (rh->cls, NULL, 0); | 410 | rh->addr_callback (rh->cls, NULL, 0); |
400 | } | 411 | } |
401 | GNUNET_CONTAINER_DLL_remove (req_head, req_tail, rh); | 412 | GNUNET_CONTAINER_DLL_remove (req_head, req_tail, rh); |
413 | if (GNUNET_SCHEDULER_NO_TASK != rh->task) | ||
414 | GNUNET_SCHEDULER_cancel (rh->task); | ||
402 | GNUNET_free (rh); | 415 | GNUNET_free (rh); |
403 | process_requests (); | 416 | process_requests (); |
404 | return; | 417 | return; |
@@ -412,9 +425,11 @@ handle_response (void *cls, | |||
412 | if (hostname[size - sizeof (struct GNUNET_MessageHeader) - 1] != '\0') | 425 | if (hostname[size - sizeof (struct GNUNET_MessageHeader) - 1] != '\0') |
413 | { | 426 | { |
414 | GNUNET_break (0); | 427 | GNUNET_break (0); |
415 | if (rh->was_transmitted != GNUNET_SYSERR) | 428 | if (GNUNET_SYSERR != rh->was_transmitted) |
416 | rh->name_callback (rh->cls, NULL); | 429 | rh->name_callback (rh->cls, NULL); |
417 | GNUNET_CONTAINER_DLL_remove (req_head, req_tail, rh); | 430 | GNUNET_CONTAINER_DLL_remove (req_head, req_tail, rh); |
431 | if (GNUNET_SCHEDULER_NO_TASK != rh->task) | ||
432 | GNUNET_SCHEDULER_cancel (rh->task); | ||
418 | GNUNET_free (rh); | 433 | GNUNET_free (rh); |
419 | GNUNET_CLIENT_disconnect (client); | 434 | GNUNET_CLIENT_disconnect (client); |
420 | client = NULL; | 435 | client = NULL; |
@@ -429,8 +444,6 @@ handle_response (void *cls, | |||
429 | if (rh->was_transmitted != GNUNET_SYSERR) | 444 | if (rh->was_transmitted != GNUNET_SYSERR) |
430 | rh->name_callback (rh->cls, hostname); | 445 | rh->name_callback (rh->cls, hostname); |
431 | rh->received_response = GNUNET_YES; | 446 | rh->received_response = GNUNET_YES; |
432 | GNUNET_CLIENT_receive (client, &handle_response, rh, | ||
433 | GNUNET_TIME_absolute_get_remaining (rh->timeout)); | ||
434 | } | 447 | } |
435 | /* return lookup results to caller */ | 448 | /* return lookup results to caller */ |
436 | if (NULL != rh->addr_callback) | 449 | if (NULL != rh->addr_callback) |
@@ -469,9 +482,11 @@ handle_response (void *cls, | |||
469 | else | 482 | else |
470 | { | 483 | { |
471 | GNUNET_break (0); | 484 | GNUNET_break (0); |
472 | if (rh->was_transmitted != GNUNET_SYSERR) | 485 | if (GNUNET_SYSERR != rh->was_transmitted) |
473 | rh->addr_callback (rh->cls, NULL, 0); | 486 | rh->addr_callback (rh->cls, NULL, 0); |
474 | GNUNET_CONTAINER_DLL_remove (req_head, req_tail, rh); | 487 | GNUNET_CONTAINER_DLL_remove (req_head, req_tail, rh); |
488 | if (GNUNET_SCHEDULER_NO_TASK != rh->task) | ||
489 | GNUNET_SCHEDULER_cancel (rh->task); | ||
475 | GNUNET_free (rh); | 490 | GNUNET_free (rh); |
476 | GNUNET_CLIENT_disconnect (client); | 491 | GNUNET_CLIENT_disconnect (client); |
477 | client = NULL; | 492 | client = NULL; |
@@ -479,9 +494,11 @@ handle_response (void *cls, | |||
479 | return; | 494 | return; |
480 | } | 495 | } |
481 | rh->addr_callback (rh->cls, sa, salen); | 496 | rh->addr_callback (rh->cls, sa, salen); |
482 | GNUNET_CLIENT_receive (client, &handle_response, rh, | ||
483 | GNUNET_TIME_absolute_get_remaining (rh->timeout)); | ||
484 | } | 497 | } |
498 | GNUNET_CLIENT_receive (client, | ||
499 | &handle_response, | ||
500 | rh, | ||
501 | GNUNET_TIME_absolute_get_remaining (rh->timeout)); | ||
485 | } | 502 | } |
486 | 503 | ||
487 | 504 | ||
@@ -502,6 +519,7 @@ numeric_resolution (void *cls, | |||
502 | struct sockaddr_in6 v6; | 519 | struct sockaddr_in6 v6; |
503 | const char *hostname; | 520 | const char *hostname; |
504 | 521 | ||
522 | rh->task = GNUNET_SCHEDULER_NO_TASK; | ||
505 | memset (&v4, 0, sizeof (v4)); | 523 | memset (&v4, 0, sizeof (v4)); |
506 | v4.sin_family = AF_INET; | 524 | v4.sin_family = AF_INET; |
507 | #if HAVE_SOCKADDR_IN_SIN_LEN | 525 | #if HAVE_SOCKADDR_IN_SIN_LEN |
@@ -516,21 +534,28 @@ numeric_resolution (void *cls, | |||
516 | if (((rh->af == AF_UNSPEC) || (rh->af == AF_INET)) && | 534 | if (((rh->af == AF_UNSPEC) || (rh->af == AF_INET)) && |
517 | (1 == inet_pton (AF_INET, hostname, &v4.sin_addr))) | 535 | (1 == inet_pton (AF_INET, hostname, &v4.sin_addr))) |
518 | { | 536 | { |
519 | rh->addr_callback (rh->cls, (const struct sockaddr *) &v4, sizeof (v4)); | 537 | rh->addr_callback (rh->cls, |
538 | (const struct sockaddr *) &v4, | ||
539 | sizeof (v4)); | ||
520 | if ((rh->af == AF_UNSPEC) && | 540 | if ((rh->af == AF_UNSPEC) && |
521 | (1 == inet_pton (AF_INET6, hostname, &v6.sin6_addr))) | 541 | (1 == inet_pton (AF_INET6, hostname, &v6.sin6_addr))) |
522 | { | 542 | { |
523 | /* this can happen on some systems IF "hostname" is "localhost" */ | 543 | /* this can happen on some systems IF "hostname" is "localhost" */ |
524 | rh->addr_callback (rh->cls, (const struct sockaddr *) &v6, sizeof (v6)); | 544 | rh->addr_callback (rh->cls, |
545 | (const struct sockaddr *) &v6, | ||
546 | sizeof (v6)); | ||
525 | } | 547 | } |
526 | rh->addr_callback (rh->cls, NULL, 0); | 548 | rh->addr_callback (rh->cls, NULL, 0); |
527 | GNUNET_free (rh); | 549 | GNUNET_free (rh); |
528 | return; | 550 | return; |
529 | } | 551 | } |
530 | if (((rh->af == AF_UNSPEC) || (rh->af == AF_INET6)) && | 552 | if ( ( (rh->af == AF_UNSPEC) || |
531 | (1 == inet_pton (AF_INET6, hostname, &v6.sin6_addr))) | 553 | (rh->af == AF_INET6) ) && |
554 | (1 == inet_pton (AF_INET6, hostname, &v6.sin6_addr) ) ) | ||
532 | { | 555 | { |
533 | rh->addr_callback (rh->cls, (const struct sockaddr *) &v6, sizeof (v6)); | 556 | rh->addr_callback (rh->cls, |
557 | (const struct sockaddr *) &v6, | ||
558 | sizeof (v6)); | ||
534 | rh->addr_callback (rh->cls, NULL, 0); | 559 | rh->addr_callback (rh->cls, NULL, 0); |
535 | GNUNET_free (rh); | 560 | GNUNET_free (rh); |
536 | return; | 561 | return; |
@@ -557,6 +582,7 @@ loopback_resolution (void *cls, | |||
557 | struct sockaddr_in v4; | 582 | struct sockaddr_in v4; |
558 | struct sockaddr_in6 v6; | 583 | struct sockaddr_in6 v6; |
559 | 584 | ||
585 | rh->task = GNUNET_SCHEDULER_NO_TASK; | ||
560 | memset (&v4, 0, sizeof (v4)); | 586 | memset (&v4, 0, sizeof (v4)); |
561 | v4.sin_addr.s_addr = htonl (INADDR_LOOPBACK); | 587 | v4.sin_addr.s_addr = htonl (INADDR_LOOPBACK); |
562 | v4.sin_family = AF_INET; | 588 | v4.sin_family = AF_INET; |
@@ -585,7 +611,9 @@ loopback_resolution (void *cls, | |||
585 | GNUNET_break (0); | 611 | GNUNET_break (0); |
586 | break; | 612 | break; |
587 | } | 613 | } |
588 | rh->addr_callback (rh->cls, NULL, 0); | 614 | rh->addr_callback (rh->cls, |
615 | NULL, | ||
616 | 0); | ||
589 | GNUNET_free (rh); | 617 | GNUNET_free (rh); |
590 | } | 618 | } |
591 | 619 | ||
@@ -640,9 +668,10 @@ process_requests () | |||
640 | LOG (GNUNET_ERROR_TYPE_DEBUG, | 668 | LOG (GNUNET_ERROR_TYPE_DEBUG, |
641 | "Transmitting DNS resolution request to DNS service\n"); | 669 | "Transmitting DNS resolution request to DNS service\n"); |
642 | if (GNUNET_OK != | 670 | if (GNUNET_OK != |
643 | GNUNET_CLIENT_transmit_and_get_response (client, &msg->header, | 671 | GNUNET_CLIENT_transmit_and_get_response (client, |
644 | GNUNET_TIME_absolute_get_remaining | 672 | &msg->header, |
645 | (rh->timeout), GNUNET_YES, | 673 | GNUNET_TIME_absolute_get_remaining (rh->timeout), |
674 | GNUNET_YES, | ||
646 | &handle_response, rh)) | 675 | &handle_response, rh)) |
647 | { | 676 | { |
648 | GNUNET_CLIENT_disconnect (client); | 677 | GNUNET_CLIENT_disconnect (client); |
@@ -726,6 +755,26 @@ reconnect () | |||
726 | 755 | ||
727 | 756 | ||
728 | /** | 757 | /** |
758 | * A DNS resolution timed out. Notify the application. | ||
759 | * | ||
760 | * @param cls the `struct GNUNET_RESOLVER_RequestHandle *` | ||
761 | * @param tc scheduler context | ||
762 | */ | ||
763 | static void | ||
764 | handle_lookup_timeout (void *cls, | ||
765 | const struct GNUNET_SCHEDULER_TaskContext *tc) | ||
766 | { | ||
767 | struct GNUNET_RESOLVER_RequestHandle *rh = cls; | ||
768 | |||
769 | rh->task = GNUNET_SCHEDULER_NO_TASK; | ||
770 | rh->addr_callback (rh->cls, | ||
771 | NULL, | ||
772 | 0); | ||
773 | GNUNET_RESOLVER_request_cancel (rh); | ||
774 | } | ||
775 | |||
776 | |||
777 | /** | ||
729 | * Convert a string to one or more IP addresses. | 778 | * Convert a string to one or more IP addresses. |
730 | * | 779 | * |
731 | * @param hostname the hostname to resolve | 780 | * @param hostname the hostname to resolve |
@@ -758,7 +807,9 @@ GNUNET_RESOLVER_ip_get (const char *hostname, int af, | |||
758 | rh->af = af; | 807 | rh->af = af; |
759 | rh->addr_callback = callback; | 808 | rh->addr_callback = callback; |
760 | rh->cls = callback_cls; | 809 | rh->cls = callback_cls; |
761 | memcpy (&rh[1], hostname, slen); | 810 | memcpy (&rh[1], |
811 | hostname, | ||
812 | slen); | ||
762 | rh->data_len = slen; | 813 | rh->data_len = slen; |
763 | rh->timeout = GNUNET_TIME_relative_to_absolute (timeout); | 814 | rh->timeout = GNUNET_TIME_relative_to_absolute (timeout); |
764 | rh->direction = GNUNET_NO; | 815 | rh->direction = GNUNET_NO; |
@@ -768,7 +819,8 @@ GNUNET_RESOLVER_ip_get (const char *hostname, int af, | |||
768 | ((1 == inet_pton (AF_INET6, hostname, &v6)) && | 819 | ((1 == inet_pton (AF_INET6, hostname, &v6)) && |
769 | ((af == AF_INET6) || (af == AF_UNSPEC)))) | 820 | ((af == AF_INET6) || (af == AF_UNSPEC)))) |
770 | { | 821 | { |
771 | rh->task = GNUNET_SCHEDULER_add_now (&numeric_resolution, rh); | 822 | rh->task = GNUNET_SCHEDULER_add_now (&numeric_resolution, |
823 | rh); | ||
772 | return rh; | 824 | return rh; |
773 | } | 825 | } |
774 | /* then, check if this is a loopback address */ | 826 | /* then, check if this is a loopback address */ |
@@ -776,9 +828,13 @@ GNUNET_RESOLVER_ip_get (const char *hostname, int af, | |||
776 | while (NULL != loopback[i]) | 828 | while (NULL != loopback[i]) |
777 | if (0 == strcasecmp (loopback[i++], hostname)) | 829 | if (0 == strcasecmp (loopback[i++], hostname)) |
778 | { | 830 | { |
779 | rh->task = GNUNET_SCHEDULER_add_now (&loopback_resolution, rh); | 831 | rh->task = GNUNET_SCHEDULER_add_now (&loopback_resolution, |
832 | rh); | ||
780 | return rh; | 833 | return rh; |
781 | } | 834 | } |
835 | rh->task = GNUNET_SCHEDULER_add_delayed (timeout, | ||
836 | &handle_lookup_timeout, | ||
837 | rh); | ||
782 | GNUNET_CONTAINER_DLL_insert_tail (req_head, req_tail, rh); | 838 | GNUNET_CONTAINER_DLL_insert_tail (req_head, req_tail, rh); |
783 | rh->was_queued = GNUNET_YES; | 839 | rh->was_queued = GNUNET_YES; |
784 | if (s_task != GNUNET_SCHEDULER_NO_TASK) | 840 | if (s_task != GNUNET_SCHEDULER_NO_TASK) |
@@ -793,7 +849,9 @@ GNUNET_RESOLVER_ip_get (const char *hostname, int af, | |||
793 | 849 | ||
794 | /** | 850 | /** |
795 | * We've been asked to convert an address to a string without | 851 | * We've been asked to convert an address to a string without |
796 | * a reverse lookup. Do it. | 852 | * a reverse lookup, either because the client asked for it |
853 | * or because the DNS lookup hit a timeout. Do the numeric | ||
854 | * conversion and invoke the callback. | ||
797 | * | 855 | * |
798 | * @param cls `struct GNUNET_RESOLVER_RequestHandle` for the request | 856 | * @param cls `struct GNUNET_RESOLVER_RequestHandle` for the request |
799 | * @param tc unused scheduler context | 857 | * @param tc unused scheduler context |
@@ -805,7 +863,10 @@ numeric_reverse (void *cls, | |||
805 | struct GNUNET_RESOLVER_RequestHandle *rh = cls; | 863 | struct GNUNET_RESOLVER_RequestHandle *rh = cls; |
806 | char *result; | 864 | char *result; |
807 | 865 | ||
808 | result = no_resolve (rh->af, &rh[1], rh->data_len); | 866 | rh->task = GNUNET_SCHEDULER_NO_TASK; |
867 | result = no_resolve (rh->af, | ||
868 | &rh[1], | ||
869 | rh->data_len); | ||
809 | LOG (GNUNET_ERROR_TYPE_DEBUG, | 870 | LOG (GNUNET_ERROR_TYPE_DEBUG, |
810 | "Resolver returns `%s'.\n", | 871 | "Resolver returns `%s'.\n", |
811 | result); | 872 | result); |
@@ -872,7 +933,12 @@ GNUNET_RESOLVER_hostname_get (const struct sockaddr *sa, | |||
872 | rh->task = GNUNET_SCHEDULER_add_now (&numeric_reverse, rh); | 933 | rh->task = GNUNET_SCHEDULER_add_now (&numeric_reverse, rh); |
873 | return rh; | 934 | return rh; |
874 | } | 935 | } |
875 | GNUNET_CONTAINER_DLL_insert_tail (req_head, req_tail, rh); | 936 | rh->task = GNUNET_SCHEDULER_add_delayed (timeout, |
937 | &numeric_reverse, | ||
938 | rh); | ||
939 | GNUNET_CONTAINER_DLL_insert_tail (req_head, | ||
940 | req_tail, | ||
941 | rh); | ||
876 | rh->was_queued = GNUNET_YES; | 942 | rh->was_queued = GNUNET_YES; |
877 | if (s_task != GNUNET_SCHEDULER_NO_TASK) | 943 | if (s_task != GNUNET_SCHEDULER_NO_TASK) |
878 | { | 944 | { |
@@ -901,11 +967,14 @@ GNUNET_RESOLVER_local_fqdn_get () | |||
901 | "gethostname"); | 967 | "gethostname"); |
902 | return NULL; | 968 | return NULL; |
903 | } | 969 | } |
904 | LOG (GNUNET_ERROR_TYPE_DEBUG, "Resolving our FQDN `%s'\n", hostname); | 970 | LOG (GNUNET_ERROR_TYPE_DEBUG, |
971 | "Resolving our FQDN `%s'\n", | ||
972 | hostname); | ||
905 | host = gethostbyname (hostname); | 973 | host = gethostbyname (hostname); |
906 | if (NULL == host) | 974 | if (NULL == host) |
907 | { | 975 | { |
908 | LOG (GNUNET_ERROR_TYPE_ERROR, _("Could not resolve our FQDN : %s\n"), | 976 | LOG (GNUNET_ERROR_TYPE_ERROR, |
977 | _("Could not resolve our FQDN : %s\n"), | ||
909 | hstrerror (h_errno)); | 978 | hstrerror (h_errno)); |
910 | return NULL; | 979 | return NULL; |
911 | } | 980 | } |
@@ -917,9 +986,9 @@ GNUNET_RESOLVER_local_fqdn_get () | |||
917 | * Looking our own hostname. | 986 | * Looking our own hostname. |
918 | * | 987 | * |
919 | * @param af AF_INET or AF_INET6; use AF_UNSPEC for "any" | 988 | * @param af AF_INET or AF_INET6; use AF_UNSPEC for "any" |
989 | * @param timeout how long to try resolving | ||
920 | * @param callback function to call with addresses | 990 | * @param callback function to call with addresses |
921 | * @param cls closure for @a callback | 991 | * @param cls closure for @a callback |
922 | * @param timeout how long to try resolving | ||
923 | * @return handle that can be used to cancel the request, NULL on error | 992 | * @return handle that can be used to cancel the request, NULL on error |
924 | */ | 993 | */ |
925 | struct GNUNET_RESOLVER_RequestHandle * | 994 | struct GNUNET_RESOLVER_RequestHandle * |
@@ -939,7 +1008,11 @@ GNUNET_RESOLVER_hostname_resolve (int af, | |||
939 | LOG (GNUNET_ERROR_TYPE_DEBUG, | 1008 | LOG (GNUNET_ERROR_TYPE_DEBUG, |
940 | "Resolving our hostname `%s'\n", | 1009 | "Resolving our hostname `%s'\n", |
941 | hostname); | 1010 | hostname); |
942 | return GNUNET_RESOLVER_ip_get (hostname, af, timeout, callback, cls); | 1011 | return GNUNET_RESOLVER_ip_get (hostname, |
1012 | af, | ||
1013 | timeout, | ||
1014 | callback, | ||
1015 | cls); | ||
943 | } | 1016 | } |
944 | 1017 | ||
945 | 1018 | ||
@@ -959,14 +1032,16 @@ GNUNET_RESOLVER_request_cancel (struct GNUNET_RESOLVER_RequestHandle *rh) | |||
959 | GNUNET_SCHEDULER_cancel (rh->task); | 1032 | GNUNET_SCHEDULER_cancel (rh->task); |
960 | rh->task = GNUNET_SCHEDULER_NO_TASK; | 1033 | rh->task = GNUNET_SCHEDULER_NO_TASK; |
961 | } | 1034 | } |
962 | if (rh->was_transmitted == GNUNET_NO) | 1035 | if (GNUNET_NO == rh->was_transmitted) |
963 | { | 1036 | { |
964 | if (rh->was_queued == GNUNET_YES) | 1037 | if (rh->was_queued == GNUNET_YES) |
965 | GNUNET_CONTAINER_DLL_remove (req_head, req_tail, rh); | 1038 | GNUNET_CONTAINER_DLL_remove (req_head, |
1039 | req_tail, | ||
1040 | rh); | ||
966 | GNUNET_free (rh); | 1041 | GNUNET_free (rh); |
967 | return; | 1042 | return; |
968 | } | 1043 | } |
969 | GNUNET_assert (rh->was_transmitted == GNUNET_YES); | 1044 | GNUNET_assert (GNUNET_YES == rh->was_transmitted); |
970 | rh->was_transmitted = GNUNET_SYSERR; /* mark as cancelled */ | 1045 | rh->was_transmitted = GNUNET_SYSERR; /* mark as cancelled */ |
971 | } | 1046 | } |
972 | 1047 | ||
diff --git a/src/util/test_resolver_api.c b/src/util/test_resolver_api.c index 77dae50d2..f959fab77 100644 --- a/src/util/test_resolver_api.c +++ b/src/util/test_resolver_api.c | |||
@@ -27,6 +27,9 @@ | |||
27 | #include "resolver.h" | 27 | #include "resolver.h" |
28 | 28 | ||
29 | 29 | ||
30 | static int disable_rootserver_check; | ||
31 | |||
32 | |||
30 | /** | 33 | /** |
31 | * Using DNS root servers to check gnunet's resolver service | 34 | * Using DNS root servers to check gnunet's resolver service |
32 | * a.root-servers.net <-> 198.41.0.4 is a fix 1:1 mapping that should not change over years | 35 | * a.root-servers.net <-> 198.41.0.4 is a fix 1:1 mapping that should not change over years |
@@ -198,7 +201,8 @@ check_rootserver_ip (void *cls, const struct sockaddr *sa, socklen_t salen) | |||
198 | 201 | ||
199 | 202 | ||
200 | static void | 203 | static void |
201 | check_rootserver_name (void *cls, const char *hostname) | 204 | check_rootserver_name (void *cls, |
205 | const char *hostname) | ||
202 | { | 206 | { |
203 | int *ok = cls; | 207 | int *ok = cls; |
204 | 208 | ||
@@ -214,11 +218,11 @@ check_rootserver_name (void *cls, const char *hostname) | |||
214 | } | 218 | } |
215 | else | 219 | else |
216 | { | 220 | { |
217 | GNUNET_log (GNUNET_ERROR_TYPE_ERROR, | 221 | GNUNET_log (GNUNET_ERROR_TYPE_WARNING, |
218 | "Received invalid rootserver hostname `%s', expected `%s'\n", | 222 | "Received invalid rootserver hostname `%s', expected `%s'\n", |
219 | hostname, | 223 | hostname, |
220 | ROOTSERVER_NAME); | 224 | ROOTSERVER_NAME); |
221 | GNUNET_break (0); | 225 | GNUNET_break (disable_rootserver_check); |
222 | } | 226 | } |
223 | } | 227 | } |
224 | 228 | ||
@@ -271,7 +275,7 @@ run (void *cls, char *const *args, const char *cfgfile, | |||
271 | } | 275 | } |
272 | 276 | ||
273 | /* Counting returned IP addresses */ | 277 | /* Counting returned IP addresses */ |
274 | while (rootserver->h_addr_list[count_ips] != NULL) | 278 | while (NULL != rootserver->h_addr_list[count_ips]) |
275 | count_ips++; | 279 | count_ips++; |
276 | if (count_ips > 1) | 280 | if (count_ips > 1) |
277 | { | 281 | { |
@@ -315,18 +319,19 @@ run (void *cls, char *const *args, const char *cfgfile, | |||
315 | if (NULL == rootserver) | 319 | if (NULL == rootserver) |
316 | { | 320 | { |
317 | /* Error: resolving IP addresses does not work */ | 321 | /* Error: resolving IP addresses does not work */ |
318 | GNUNET_log (GNUNET_ERROR_TYPE_ERROR, | 322 | GNUNET_log (GNUNET_ERROR_TYPE_WARNING, |
319 | "gethostbyaddr() could not lookup hostname: %s\n", | 323 | "gethostbyaddr() could not lookup hostname: %s\n", |
320 | hstrerror (h_errno)); | 324 | hstrerror (h_errno)); |
321 | GNUNET_break (0); | 325 | disable_rootserver_check = GNUNET_YES; |
322 | } | 326 | } |
323 | else | 327 | else |
324 | { | 328 | { |
325 | if (0 != strcmp (rootserver->h_name, ROOTSERVER_NAME)) | 329 | if (0 != strcmp (rootserver->h_name, |
330 | ROOTSERVER_NAME)) | ||
326 | { | 331 | { |
327 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, | 332 | GNUNET_log (GNUNET_ERROR_TYPE_WARNING, |
328 | "Received hostname and hostname for root name server differ\n"); | 333 | "Received hostname and hostname for root name server differ\n"); |
329 | GNUNET_break (0); | 334 | disable_rootserver_check = GNUNET_YES; |
330 | } | 335 | } |
331 | } | 336 | } |
332 | 337 | ||