diff options
author | Christian Grothoff <christian@grothoff.org> | 2012-01-27 12:46:51 +0000 |
---|---|---|
committer | Christian Grothoff <christian@grothoff.org> | 2012-01-27 12:46:51 +0000 |
commit | fae775b8e3ebc6e19b97156d3a3008ee91c3b64b (patch) | |
tree | 12c7d0f18bc3f1f00f356df0f493c71ee006dda3 /src/util/resolver_api.c | |
parent | f4c1249ba12461abe0616963959b9470a41e1de5 (diff) | |
download | gnunet-fae775b8e3ebc6e19b97156d3a3008ee91c3b64b.tar.gz gnunet-fae775b8e3ebc6e19b97156d3a3008ee91c3b64b.zip |
-fixing #2116
Diffstat (limited to 'src/util/resolver_api.c')
-rw-r--r-- | src/util/resolver_api.c | 102 |
1 files changed, 71 insertions, 31 deletions
diff --git a/src/util/resolver_api.c b/src/util/resolver_api.c index 03dc2ce89..371b2165a 100644 --- a/src/util/resolver_api.c +++ b/src/util/resolver_api.c | |||
@@ -139,7 +139,7 @@ struct GNUNET_RESOLVER_RequestHandle | |||
139 | /** | 139 | /** |
140 | * Desired address family. | 140 | * Desired address family. |
141 | */ | 141 | */ |
142 | int domain; | 142 | int af; |
143 | 143 | ||
144 | /** | 144 | /** |
145 | * Has this request been transmitted to the service? | 145 | * Has this request been transmitted to the service? |
@@ -344,19 +344,18 @@ handle_response (void *cls, const struct GNUNET_MessageHeader *msg) | |||
344 | { | 344 | { |
345 | struct GNUNET_RESOLVER_RequestHandle *rh = cls; | 345 | struct GNUNET_RESOLVER_RequestHandle *rh = cls; |
346 | uint16_t size; | 346 | uint16_t size; |
347 | const char *hostname; | ||
348 | const struct sockaddr *sa; | ||
349 | socklen_t salen; | ||
350 | 347 | ||
351 | #if DEBUG_RESOLVER | 348 | #if DEBUG_RESOLVER |
352 | LOG (GNUNET_ERROR_TYPE_DEBUG, "Receiving response from DNS service\n"); | 349 | LOG (GNUNET_ERROR_TYPE_DEBUG, "Receiving response from DNS service\n"); |
353 | #endif | 350 | #endif |
354 | if (msg == NULL) | 351 | if (msg == NULL) |
355 | { | 352 | { |
353 | char buf[INET6_ADDRSTRLEN]; | ||
354 | |||
356 | if (NULL != rh->name_callback) | 355 | if (NULL != rh->name_callback) |
357 | LOG (GNUNET_ERROR_TYPE_INFO, | 356 | LOG (GNUNET_ERROR_TYPE_INFO, |
358 | _("Timeout trying to resolve IP address `%s'.\n"), | 357 | _("Timeout trying to resolve IP address `%s'.\n"), |
359 | GNUNET_a2s ((const void *) &rh[1], rh->data_len)); | 358 | inet_ntop (rh->af, (const void *) &rh[1], buf, sizeof(buf))); |
360 | else | 359 | else |
361 | LOG (GNUNET_ERROR_TYPE_INFO, | 360 | LOG (GNUNET_ERROR_TYPE_INFO, |
362 | _("Timeout trying to resolve hostname `%s'.\n"), | 361 | _("Timeout trying to resolve hostname `%s'.\n"), |
@@ -413,6 +412,8 @@ handle_response (void *cls, const struct GNUNET_MessageHeader *msg) | |||
413 | /* return reverse lookup results to caller */ | 412 | /* return reverse lookup results to caller */ |
414 | if (NULL != rh->name_callback) | 413 | if (NULL != rh->name_callback) |
415 | { | 414 | { |
415 | const char *hostname; | ||
416 | |||
416 | hostname = (const char *) &msg[1]; | 417 | hostname = (const char *) &msg[1]; |
417 | if (hostname[size - sizeof (struct GNUNET_MessageHeader) - 1] != '\0') | 418 | if (hostname[size - sizeof (struct GNUNET_MessageHeader) - 1] != '\0') |
418 | { | 419 | { |
@@ -439,9 +440,38 @@ handle_response (void *cls, const struct GNUNET_MessageHeader *msg) | |||
439 | /* return lookup results to caller */ | 440 | /* return lookup results to caller */ |
440 | if (NULL != rh->addr_callback) | 441 | if (NULL != rh->addr_callback) |
441 | { | 442 | { |
442 | sa = (const struct sockaddr *) &msg[1]; | 443 | struct sockaddr_in v4; |
443 | salen = size - sizeof (struct GNUNET_MessageHeader); | 444 | struct sockaddr_in6 v6; |
444 | if (salen < sizeof (struct sockaddr)) | 445 | const struct sockaddr *sa; |
446 | socklen_t salen; | ||
447 | const void *ip; | ||
448 | size_t ip_len; | ||
449 | |||
450 | ip = &msg[1]; | ||
451 | ip_len = size - sizeof (struct GNUNET_MessageHeader); | ||
452 | if (ip_len == sizeof (struct in_addr)) | ||
453 | { | ||
454 | memset (&v4, 0, sizeof (v4)); | ||
455 | v4.sin_family = AF_INET; | ||
456 | v4.sin_addr = *(struct in_addr*) ip; | ||
457 | #if HAVE_SOCKADDR_IN_SIN_LEN | ||
458 | v4.sin_len = sizeof (v4); | ||
459 | #endif | ||
460 | salen = sizeof (v4); | ||
461 | sa = (const struct sockaddr *) &v4; | ||
462 | } | ||
463 | else if (ip_len == sizeof (struct in6_addr)) | ||
464 | { | ||
465 | memset (&v6, 0, sizeof (v6)); | ||
466 | v6.sin6_family = AF_INET6; | ||
467 | v6.sin6_addr = *(struct in6_addr*) ip; | ||
468 | #if HAVE_SOCKADDR_IN_SIN_LEN | ||
469 | v6.sin6_len = sizeof (v6); | ||
470 | #endif | ||
471 | salen = sizeof (v6); | ||
472 | sa = (const struct sockaddr *) &v6; | ||
473 | } | ||
474 | else | ||
445 | { | 475 | { |
446 | GNUNET_break (0); | 476 | GNUNET_break (0); |
447 | if (rh->was_transmitted != GNUNET_SYSERR) | 477 | if (rh->was_transmitted != GNUNET_SYSERR) |
@@ -496,11 +526,11 @@ numeric_resolution (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc) | |||
496 | v6.sin6_len = sizeof (v6); | 526 | v6.sin6_len = sizeof (v6); |
497 | #endif | 527 | #endif |
498 | hostname = (const char *) &rh[1]; | 528 | hostname = (const char *) &rh[1]; |
499 | if (((rh->domain == AF_UNSPEC) || (rh->domain == AF_INET)) && | 529 | if (((rh->af == AF_UNSPEC) || (rh->af == AF_INET)) && |
500 | (1 == inet_pton (AF_INET, hostname, &v4.sin_addr))) | 530 | (1 == inet_pton (AF_INET, hostname, &v4.sin_addr))) |
501 | { | 531 | { |
502 | rh->addr_callback (rh->cls, (const struct sockaddr *) &v4, sizeof (v4)); | 532 | rh->addr_callback (rh->cls, (const struct sockaddr *) &v4, sizeof (v4)); |
503 | if ((rh->domain == AF_UNSPEC) && | 533 | if ((rh->af == AF_UNSPEC) && |
504 | (1 == inet_pton (AF_INET6, hostname, &v6.sin6_addr))) | 534 | (1 == inet_pton (AF_INET6, hostname, &v6.sin6_addr))) |
505 | { | 535 | { |
506 | /* this can happen on some systems IF "hostname" is "localhost" */ | 536 | /* this can happen on some systems IF "hostname" is "localhost" */ |
@@ -510,7 +540,7 @@ numeric_resolution (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc) | |||
510 | GNUNET_free (rh); | 540 | GNUNET_free (rh); |
511 | return; | 541 | return; |
512 | } | 542 | } |
513 | if (((rh->domain == AF_UNSPEC) || (rh->domain == AF_INET6)) && | 543 | if (((rh->af == AF_UNSPEC) || (rh->af == AF_INET6)) && |
514 | (1 == inet_pton (AF_INET6, hostname, &v6.sin6_addr))) | 544 | (1 == inet_pton (AF_INET6, hostname, &v6.sin6_addr))) |
515 | { | 545 | { |
516 | rh->addr_callback (rh->cls, (const struct sockaddr *) &v6, sizeof (v6)); | 546 | rh->addr_callback (rh->cls, (const struct sockaddr *) &v6, sizeof (v6)); |
@@ -551,7 +581,7 @@ loopback_resolution (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc) | |||
551 | v6.sin6_len = sizeof (v6); | 581 | v6.sin6_len = sizeof (v6); |
552 | #endif | 582 | #endif |
553 | v6.sin6_addr = in6addr_loopback; | 583 | v6.sin6_addr = in6addr_loopback; |
554 | switch (rh->domain) | 584 | switch (rh->af) |
555 | { | 585 | { |
556 | case AF_INET: | 586 | case AF_INET: |
557 | rh->addr_callback (rh->cls, (const struct sockaddr *) &v4, sizeof (v4)); | 587 | rh->addr_callback (rh->cls, (const struct sockaddr *) &v4, sizeof (v4)); |
@@ -615,7 +645,7 @@ process_requests () | |||
615 | htons (sizeof (struct GNUNET_RESOLVER_GetMessage) + rh->data_len); | 645 | htons (sizeof (struct GNUNET_RESOLVER_GetMessage) + rh->data_len); |
616 | msg->header.type = htons (GNUNET_MESSAGE_TYPE_RESOLVER_REQUEST); | 646 | msg->header.type = htons (GNUNET_MESSAGE_TYPE_RESOLVER_REQUEST); |
617 | msg->direction = htonl (rh->direction); | 647 | msg->direction = htonl (rh->direction); |
618 | msg->domain = htonl (rh->domain); | 648 | msg->af = htonl (rh->af); |
619 | memcpy (&msg[1], &rh[1], rh->data_len); | 649 | memcpy (&msg[1], &rh[1], rh->data_len); |
620 | #if DEBUG_RESOLVER | 650 | #if DEBUG_RESOLVER |
621 | LOG (GNUNET_ERROR_TYPE_DEBUG, | 651 | LOG (GNUNET_ERROR_TYPE_DEBUG, |
@@ -711,14 +741,14 @@ reconnect () | |||
711 | * Convert a string to one or more IP addresses. | 741 | * Convert a string to one or more IP addresses. |
712 | * | 742 | * |
713 | * @param hostname the hostname to resolve | 743 | * @param hostname the hostname to resolve |
714 | * @param domain AF_INET or AF_INET6; use AF_UNSPEC for "any" | 744 | * @param af AF_INET or AF_INET6; use AF_UNSPEC for "any" |
715 | * @param callback function to call with addresses | 745 | * @param callback function to call with addresses |
716 | * @param callback_cls closure for callback | 746 | * @param callback_cls closure for callback |
717 | * @param timeout how long to try resolving | 747 | * @param timeout how long to try resolving |
718 | * @return handle that can be used to cancel the request, NULL on error | 748 | * @return handle that can be used to cancel the request, NULL on error |
719 | */ | 749 | */ |
720 | struct GNUNET_RESOLVER_RequestHandle * | 750 | struct GNUNET_RESOLVER_RequestHandle * |
721 | GNUNET_RESOLVER_ip_get (const char *hostname, int domain, | 751 | GNUNET_RESOLVER_ip_get (const char *hostname, int af, |
722 | struct GNUNET_TIME_Relative timeout, | 752 | struct GNUNET_TIME_Relative timeout, |
723 | GNUNET_RESOLVER_AddressCallback callback, | 753 | GNUNET_RESOLVER_AddressCallback callback, |
724 | void *callback_cls) | 754 | void *callback_cls) |
@@ -737,7 +767,7 @@ GNUNET_RESOLVER_ip_get (const char *hostname, int domain, | |||
737 | return NULL; | 767 | return NULL; |
738 | } | 768 | } |
739 | rh = GNUNET_malloc (sizeof (struct GNUNET_RESOLVER_RequestHandle) + slen); | 769 | rh = GNUNET_malloc (sizeof (struct GNUNET_RESOLVER_RequestHandle) + slen); |
740 | rh->domain = domain; | 770 | rh->af = af; |
741 | rh->addr_callback = callback; | 771 | rh->addr_callback = callback; |
742 | rh->cls = callback_cls; | 772 | rh->cls = callback_cls; |
743 | memcpy (&rh[1], hostname, slen); | 773 | memcpy (&rh[1], hostname, slen); |
@@ -746,9 +776,9 @@ GNUNET_RESOLVER_ip_get (const char *hostname, int domain, | |||
746 | rh->direction = GNUNET_NO; | 776 | rh->direction = GNUNET_NO; |
747 | /* first, check if this is a numeric address */ | 777 | /* first, check if this is a numeric address */ |
748 | if (((1 == inet_pton (AF_INET, hostname, &v4)) && | 778 | if (((1 == inet_pton (AF_INET, hostname, &v4)) && |
749 | ((domain == AF_INET) || (domain == AF_UNSPEC))) || | 779 | ((af == AF_INET) || (af == AF_UNSPEC))) || |
750 | ((1 == inet_pton (AF_INET6, hostname, &v6)) && | 780 | ((1 == inet_pton (AF_INET6, hostname, &v6)) && |
751 | ((domain == AF_INET6) || (domain == AF_UNSPEC)))) | 781 | ((af == AF_INET6) || (af == AF_UNSPEC)))) |
752 | { | 782 | { |
753 | rh->task = GNUNET_SCHEDULER_add_now (&numeric_resolution, rh); | 783 | rh->task = GNUNET_SCHEDULER_add_now (&numeric_resolution, rh); |
754 | return rh; | 784 | return rh; |
@@ -820,14 +850,31 @@ GNUNET_RESOLVER_hostname_get (const struct sockaddr *sa, socklen_t salen, | |||
820 | void *cls) | 850 | void *cls) |
821 | { | 851 | { |
822 | struct GNUNET_RESOLVER_RequestHandle *rh; | 852 | struct GNUNET_RESOLVER_RequestHandle *rh; |
853 | size_t ip_len; | ||
854 | const void *ip; | ||
823 | 855 | ||
824 | check_config (); | 856 | check_config (); |
857 | switch (sa->sa_family) | ||
858 | { | ||
859 | case AF_INET: | ||
860 | ip_len = sizeof (struct in_addr); | ||
861 | ip = &((const struct sockaddr_in*)sa)->sin_addr; | ||
862 | break; | ||
863 | case AF_INET6: | ||
864 | ip_len = sizeof (struct in6_addr); | ||
865 | ip = &((const struct sockaddr_in6*)sa)->sin6_addr; | ||
866 | break; | ||
867 | default: | ||
868 | GNUNET_break (0); | ||
869 | return NULL; | ||
870 | } | ||
825 | rh = GNUNET_malloc (sizeof (struct GNUNET_RESOLVER_RequestHandle) + salen); | 871 | rh = GNUNET_malloc (sizeof (struct GNUNET_RESOLVER_RequestHandle) + salen); |
826 | rh->name_callback = callback; | 872 | rh->name_callback = callback; |
827 | rh->cls = cls; | 873 | rh->cls = cls; |
874 | rh->af = sa->sa_family; | ||
828 | rh->timeout = GNUNET_TIME_relative_to_absolute (timeout); | 875 | rh->timeout = GNUNET_TIME_relative_to_absolute (timeout); |
829 | memcpy (&rh[1], sa, salen); | 876 | memcpy (&rh[1], ip, ip_len); |
830 | rh->data_len = salen; | 877 | rh->data_len = ip_len; |
831 | rh->direction = GNUNET_YES; | 878 | rh->direction = GNUNET_YES; |
832 | rh->received_response = GNUNET_NO; | 879 | rh->received_response = GNUNET_NO; |
833 | if (GNUNET_NO == do_resolve) | 880 | if (GNUNET_NO == do_resolve) |
@@ -835,13 +882,6 @@ GNUNET_RESOLVER_hostname_get (const struct sockaddr *sa, socklen_t salen, | |||
835 | rh->task = GNUNET_SCHEDULER_add_now (&numeric_reverse, rh); | 882 | rh->task = GNUNET_SCHEDULER_add_now (&numeric_reverse, rh); |
836 | return rh; | 883 | return rh; |
837 | } | 884 | } |
838 | if (salen + sizeof (struct GNUNET_RESOLVER_GetMessage) >= | ||
839 | GNUNET_SERVER_MAX_MESSAGE_SIZE) | ||
840 | { | ||
841 | GNUNET_break (0); | ||
842 | GNUNET_free (rh); | ||
843 | return NULL; | ||
844 | } | ||
845 | GNUNET_CONTAINER_DLL_insert_tail (req_head, req_tail, rh); | 885 | GNUNET_CONTAINER_DLL_insert_tail (req_head, req_tail, rh); |
846 | rh->was_queued = GNUNET_YES; | 886 | rh->was_queued = GNUNET_YES; |
847 | if (s_task != GNUNET_SCHEDULER_NO_TASK) | 887 | if (s_task != GNUNET_SCHEDULER_NO_TASK) |
@@ -855,7 +895,7 @@ GNUNET_RESOLVER_hostname_get (const struct sockaddr *sa, socklen_t salen, | |||
855 | 895 | ||
856 | 896 | ||
857 | /** | 897 | /** |
858 | * Get local fully qualified domain name | 898 | * Get local fully qualified af name |
859 | * | 899 | * |
860 | * @return fqdn | 900 | * @return fqdn |
861 | */ | 901 | */ |
@@ -888,14 +928,14 @@ GNUNET_RESOLVER_local_fqdn_get () | |||
888 | /** | 928 | /** |
889 | * Looking our own hostname. | 929 | * Looking our own hostname. |
890 | * | 930 | * |
891 | * @param domain AF_INET or AF_INET6; use AF_UNSPEC for "any" | 931 | * @param af AF_INET or AF_INET6; use AF_UNSPEC for "any" |
892 | * @param callback function to call with addresses | 932 | * @param callback function to call with addresses |
893 | * @param cls closure for callback | 933 | * @param cls closure for callback |
894 | * @param timeout how long to try resolving | 934 | * @param timeout how long to try resolving |
895 | * @return handle that can be used to cancel the request, NULL on error | 935 | * @return handle that can be used to cancel the request, NULL on error |
896 | */ | 936 | */ |
897 | struct GNUNET_RESOLVER_RequestHandle * | 937 | struct GNUNET_RESOLVER_RequestHandle * |
898 | GNUNET_RESOLVER_hostname_resolve (int domain, | 938 | GNUNET_RESOLVER_hostname_resolve (int af, |
899 | struct GNUNET_TIME_Relative timeout, | 939 | struct GNUNET_TIME_Relative timeout, |
900 | GNUNET_RESOLVER_AddressCallback callback, | 940 | GNUNET_RESOLVER_AddressCallback callback, |
901 | void *cls) | 941 | void *cls) |
@@ -911,7 +951,7 @@ GNUNET_RESOLVER_hostname_resolve (int domain, | |||
911 | #if DEBUG_RESOLVER | 951 | #if DEBUG_RESOLVER |
912 | LOG (GNUNET_ERROR_TYPE_DEBUG, _("Resolving our hostname `%s'\n"), hostname); | 952 | LOG (GNUNET_ERROR_TYPE_DEBUG, _("Resolving our hostname `%s'\n"), hostname); |
913 | #endif | 953 | #endif |
914 | return GNUNET_RESOLVER_ip_get (hostname, domain, timeout, callback, cls); | 954 | return GNUNET_RESOLVER_ip_get (hostname, af, timeout, callback, cls); |
915 | } | 955 | } |
916 | 956 | ||
917 | 957 | ||