diff options
Diffstat (limited to 'src')
-rw-r--r-- | src/util/Makefile.am | 3 | ||||
-rw-r--r-- | src/util/gnunet-service-resolver.c | 269 | ||||
-rw-r--r-- | src/util/resolver.h | 27 | ||||
-rw-r--r-- | src/util/resolver_api.c | 37 | ||||
-rw-r--r-- | src/util/test_resolver_api.c | 2 |
5 files changed, 293 insertions, 45 deletions
diff --git a/src/util/Makefile.am b/src/util/Makefile.am index 208cab07b..4296199db 100644 --- a/src/util/Makefile.am +++ b/src/util/Makefile.am | |||
@@ -199,6 +199,9 @@ gnunet_service_resolver_SOURCES = \ | |||
199 | gnunet_service_resolver_LDADD = \ | 199 | gnunet_service_resolver_LDADD = \ |
200 | libgnunetutil.la \ | 200 | libgnunetutil.la \ |
201 | $(GN_LIBINTL) | 201 | $(GN_LIBINTL) |
202 | if HAVE_GETADDRINFO_A | ||
203 | gnunet_service_resolver_LDADD += -lanl | ||
204 | endif | ||
202 | 205 | ||
203 | 206 | ||
204 | gnunet_resolver_SOURCES = \ | 207 | gnunet_resolver_SOURCES = \ |
diff --git a/src/util/gnunet-service-resolver.c b/src/util/gnunet-service-resolver.c index d26ec659f..d90d8ec10 100644 --- a/src/util/gnunet-service-resolver.c +++ b/src/util/gnunet-service-resolver.c | |||
@@ -84,6 +84,16 @@ static struct IPCache *cache_head; | |||
84 | */ | 84 | */ |
85 | static struct IPCache *cache_tail; | 85 | static struct IPCache *cache_tail; |
86 | 86 | ||
87 | /** | ||
88 | * Pipe for asynchronously notifying about resolve result | ||
89 | */ | ||
90 | static struct GNUNET_DISK_PipeHandle *resolve_result_pipe; | ||
91 | |||
92 | /** | ||
93 | * Task for reading from resolve_result_pipe | ||
94 | */ | ||
95 | static struct GNUNET_SCHEDULER_Task *resolve_result_pipe_task; | ||
96 | |||
87 | 97 | ||
88 | #if HAVE_GETNAMEINFO | 98 | #if HAVE_GETNAMEINFO |
89 | /** | 99 | /** |
@@ -223,14 +233,15 @@ notify_service_client_done (void *cls) | |||
223 | static void | 233 | static void |
224 | get_ip_as_string (struct GNUNET_SERVICE_Client *client, | 234 | get_ip_as_string (struct GNUNET_SERVICE_Client *client, |
225 | int af, | 235 | int af, |
226 | const void *ip) | 236 | const void *ip, |
237 | uint32_t request_id) | ||
227 | { | 238 | { |
228 | struct IPCache *pos; | 239 | struct IPCache *pos; |
229 | struct IPCache *next; | 240 | struct IPCache *next; |
230 | struct GNUNET_TIME_Absolute now; | 241 | struct GNUNET_TIME_Absolute now; |
231 | struct GNUNET_MQ_Envelope *env; | 242 | struct GNUNET_MQ_Envelope *env; |
232 | struct GNUNET_MQ_Handle *mq; | 243 | struct GNUNET_MQ_Handle *mq; |
233 | struct GNUNET_MessageHeader *msg; | 244 | struct GNUNET_RESOLVER_ResponseMessage *msg; |
234 | size_t ip_len; | 245 | size_t ip_len; |
235 | struct in6_addr ix; | 246 | struct in6_addr ix; |
236 | size_t alen; | 247 | size_t alen; |
@@ -304,13 +315,16 @@ get_ip_as_string (struct GNUNET_SERVICE_Client *client, | |||
304 | env = GNUNET_MQ_msg_extra (msg, | 315 | env = GNUNET_MQ_msg_extra (msg, |
305 | alen, | 316 | alen, |
306 | GNUNET_MESSAGE_TYPE_RESOLVER_RESPONSE); | 317 | GNUNET_MESSAGE_TYPE_RESOLVER_RESPONSE); |
318 | msg->id = request_id; | ||
307 | GNUNET_memcpy (&msg[1], | 319 | GNUNET_memcpy (&msg[1], |
308 | pos->addr, | 320 | pos->addr, |
309 | alen); | 321 | alen); |
310 | GNUNET_MQ_send (mq, | 322 | GNUNET_MQ_send (mq, |
311 | env); | 323 | env); |
324 | // send end message | ||
312 | env = GNUNET_MQ_msg (msg, | 325 | env = GNUNET_MQ_msg (msg, |
313 | GNUNET_MESSAGE_TYPE_RESOLVER_RESPONSE); | 326 | GNUNET_MESSAGE_TYPE_RESOLVER_RESPONSE); |
327 | msg->id = request_id; | ||
314 | GNUNET_MQ_notify_sent (env, | 328 | GNUNET_MQ_notify_sent (env, |
315 | ¬ify_service_client_done, | 329 | ¬ify_service_client_done, |
316 | client); | 330 | client); |
@@ -319,17 +333,152 @@ get_ip_as_string (struct GNUNET_SERVICE_Client *client, | |||
319 | } | 333 | } |
320 | 334 | ||
321 | 335 | ||
322 | #if HAVE_GETADDRINFO | 336 | #if HAVE_GETADDRINFO_A |
337 | struct AsyncCls | ||
338 | { | ||
339 | struct gaicb *host; | ||
340 | struct sigevent *sig; | ||
341 | struct GNUNET_MQ_Handle *mq; | ||
342 | uint32_t request_id; | ||
343 | }; | ||
344 | |||
345 | |||
346 | static void | ||
347 | resolve_result_pipe_cb (void *cls) | ||
348 | { | ||
349 | struct AsyncCls *async_cls; | ||
350 | struct gaicb *host; | ||
351 | struct GNUNET_RESOLVER_ResponseMessage *msg; | ||
352 | struct GNUNET_MQ_Envelope *env; | ||
353 | |||
354 | GNUNET_DISK_file_read (GNUNET_DISK_pipe_handle (resolve_result_pipe, | ||
355 | GNUNET_DISK_PIPE_END_READ), | ||
356 | &async_cls, | ||
357 | sizeof (struct AsyncCls *)); | ||
358 | resolve_result_pipe_task = | ||
359 | GNUNET_SCHEDULER_add_read_file (GNUNET_TIME_UNIT_FOREVER_REL, | ||
360 | GNUNET_DISK_pipe_handle (resolve_result_pipe, | ||
361 | GNUNET_DISK_PIPE_END_READ), | ||
362 | &resolve_result_pipe_cb, | ||
363 | NULL); | ||
364 | host = async_cls->host; | ||
365 | for (struct addrinfo *pos = host->ar_result; pos != NULL; pos = pos->ai_next) | ||
366 | { | ||
367 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, | ||
368 | "Lookup result for hostname %s: %s (request ID %u)\n", | ||
369 | host->ar_name, | ||
370 | GNUNET_a2s (pos->ai_addr, pos->ai_addrlen), | ||
371 | async_cls->request_id); | ||
372 | switch (pos->ai_family) | ||
373 | { | ||
374 | case AF_INET: | ||
375 | env = GNUNET_MQ_msg_extra (msg, | ||
376 | sizeof (struct in_addr), | ||
377 | GNUNET_MESSAGE_TYPE_RESOLVER_RESPONSE); | ||
378 | msg->id = async_cls->request_id; | ||
379 | GNUNET_memcpy (&msg[1], | ||
380 | &((struct sockaddr_in*) pos->ai_addr)->sin_addr, | ||
381 | sizeof (struct in_addr)); | ||
382 | GNUNET_MQ_send (async_cls->mq, | ||
383 | env); | ||
384 | break; | ||
385 | case AF_INET6: | ||
386 | env = GNUNET_MQ_msg_extra (msg, | ||
387 | sizeof (struct in6_addr), | ||
388 | GNUNET_MESSAGE_TYPE_RESOLVER_RESPONSE); | ||
389 | msg->id = async_cls->request_id; | ||
390 | GNUNET_memcpy (&msg[1], | ||
391 | &((struct sockaddr_in6*) pos->ai_addr)->sin6_addr, | ||
392 | sizeof (struct in6_addr)); | ||
393 | GNUNET_MQ_send (async_cls->mq, | ||
394 | env); | ||
395 | break; | ||
396 | default: | ||
397 | /* unsupported, skip */ | ||
398 | break; | ||
399 | } | ||
400 | } | ||
401 | // send end message | ||
402 | env = GNUNET_MQ_msg (msg, | ||
403 | GNUNET_MESSAGE_TYPE_RESOLVER_RESPONSE); | ||
404 | msg->id = async_cls->request_id; | ||
405 | GNUNET_MQ_send (async_cls->mq, | ||
406 | env); | ||
407 | freeaddrinfo (host->ar_result); | ||
408 | GNUNET_free ((struct gaicb *)host->ar_request); // free hints | ||
409 | GNUNET_free (host); | ||
410 | GNUNET_free (async_cls->sig); | ||
411 | GNUNET_free (async_cls); | ||
412 | } | ||
413 | |||
414 | |||
415 | static void | ||
416 | handle_async_result (union sigval val) | ||
417 | { | ||
418 | GNUNET_DISK_file_write (GNUNET_DISK_pipe_handle (resolve_result_pipe, | ||
419 | GNUNET_DISK_PIPE_END_WRITE), | ||
420 | &val.sival_ptr, | ||
421 | sizeof (val.sival_ptr)); | ||
422 | } | ||
423 | |||
424 | |||
425 | static int | ||
426 | getaddrinfo_a_resolve (struct GNUNET_MQ_Handle *mq, | ||
427 | const char *hostname, | ||
428 | int af, | ||
429 | uint32_t request_id) | ||
430 | { | ||
431 | int ret; | ||
432 | struct gaicb *host; | ||
433 | struct addrinfo *hints; | ||
434 | struct sigevent *sig; | ||
435 | struct AsyncCls *async_cls; | ||
436 | |||
437 | host = GNUNET_new (struct gaicb); | ||
438 | hints = GNUNET_new (struct addrinfo); | ||
439 | sig = GNUNET_new (struct sigevent); | ||
440 | async_cls = GNUNET_new (struct AsyncCls); | ||
441 | memset (hints, | ||
442 | 0, | ||
443 | sizeof (struct addrinfo)); | ||
444 | memset (sig, | ||
445 | 0, | ||
446 | sizeof (struct sigevent)); | ||
447 | hints->ai_family = af; | ||
448 | hints->ai_socktype = SOCK_STREAM; /* go for TCP */ | ||
449 | host->ar_name = hostname; | ||
450 | host->ar_service = NULL; | ||
451 | host->ar_request = hints; | ||
452 | host->ar_result = NULL; | ||
453 | sig->sigev_notify = SIGEV_THREAD; | ||
454 | sig->sigev_value.sival_ptr = async_cls; | ||
455 | sig->sigev_notify_function = &handle_async_result; | ||
456 | async_cls->host = host; | ||
457 | async_cls->sig = sig; | ||
458 | async_cls->mq = mq; | ||
459 | async_cls->request_id = request_id; | ||
460 | ret = getaddrinfo_a (GAI_NOWAIT, | ||
461 | &host, | ||
462 | 1, | ||
463 | sig); | ||
464 | if (0 != ret) | ||
465 | return GNUNET_SYSERR; | ||
466 | return GNUNET_OK; | ||
467 | } | ||
468 | |||
469 | |||
470 | #elif HAVE_GETADDRINFO | ||
323 | static int | 471 | static int |
324 | getaddrinfo_resolve (struct GNUNET_MQ_Handle *mq, | 472 | getaddrinfo_resolve (struct GNUNET_MQ_Handle *mq, |
325 | const char *hostname, | 473 | const char *hostname, |
326 | int af) | 474 | int af, |
475 | uint32_t request_id) | ||
327 | { | 476 | { |
328 | int s; | 477 | int s; |
329 | struct addrinfo hints; | 478 | struct addrinfo hints; |
330 | struct addrinfo *result; | 479 | struct addrinfo *result; |
331 | struct addrinfo *pos; | 480 | struct addrinfo *pos; |
332 | struct GNUNET_MessageHeader *msg; | 481 | struct GNUNET_RESOLVER_ResponseMessage *msg; |
333 | struct GNUNET_MQ_Envelope *env; | 482 | struct GNUNET_MQ_Envelope *env; |
334 | 483 | ||
335 | #ifdef WINDOWS | 484 | #ifdef WINDOWS |
@@ -340,10 +489,12 @@ getaddrinfo_resolve (struct GNUNET_MQ_Handle *mq, | |||
340 | int ret2; | 489 | int ret2; |
341 | ret1 = getaddrinfo_resolve (mq, | 490 | ret1 = getaddrinfo_resolve (mq, |
342 | hostname, | 491 | hostname, |
343 | AF_INET); | 492 | AF_INET, |
493 | request_id); | ||
344 | ret2 = getaddrinfo_resolve (mq, | 494 | ret2 = getaddrinfo_resolve (mq, |
345 | hostname, | 495 | hostname, |
346 | AF_INET6); | 496 | AF_INET6, |
497 | request_id); | ||
347 | if ( (ret1 == GNUNET_OK) || | 498 | if ( (ret1 == GNUNET_OK) || |
348 | (ret2 == GNUNET_OK) ) | 499 | (ret2 == GNUNET_OK) ) |
349 | return GNUNET_OK; | 500 | return GNUNET_OK; |
@@ -389,6 +540,7 @@ getaddrinfo_resolve (struct GNUNET_MQ_Handle *mq, | |||
389 | env = GNUNET_MQ_msg_extra (msg, | 540 | env = GNUNET_MQ_msg_extra (msg, |
390 | sizeof (struct in_addr), | 541 | sizeof (struct in_addr), |
391 | GNUNET_MESSAGE_TYPE_RESOLVER_RESPONSE); | 542 | GNUNET_MESSAGE_TYPE_RESOLVER_RESPONSE); |
543 | msg->id = request_id; | ||
392 | GNUNET_memcpy (&msg[1], | 544 | GNUNET_memcpy (&msg[1], |
393 | &((struct sockaddr_in*) pos->ai_addr)->sin_addr, | 545 | &((struct sockaddr_in*) pos->ai_addr)->sin_addr, |
394 | sizeof (struct in_addr)); | 546 | sizeof (struct in_addr)); |
@@ -399,6 +551,7 @@ getaddrinfo_resolve (struct GNUNET_MQ_Handle *mq, | |||
399 | env = GNUNET_MQ_msg_extra (msg, | 551 | env = GNUNET_MQ_msg_extra (msg, |
400 | sizeof (struct in6_addr), | 552 | sizeof (struct in6_addr), |
401 | GNUNET_MESSAGE_TYPE_RESOLVER_RESPONSE); | 553 | GNUNET_MESSAGE_TYPE_RESOLVER_RESPONSE); |
554 | msg->id = request_id; | ||
402 | GNUNET_memcpy (&msg[1], | 555 | GNUNET_memcpy (&msg[1], |
403 | &((struct sockaddr_in6*) pos->ai_addr)->sin6_addr, | 556 | &((struct sockaddr_in6*) pos->ai_addr)->sin6_addr, |
404 | sizeof (struct in6_addr)); | 557 | sizeof (struct in6_addr)); |
@@ -421,13 +574,14 @@ getaddrinfo_resolve (struct GNUNET_MQ_Handle *mq, | |||
421 | static int | 574 | static int |
422 | gethostbyname2_resolve (struct GNUNET_MQ_Handle *mq, | 575 | gethostbyname2_resolve (struct GNUNET_MQ_Handle *mq, |
423 | const char *hostname, | 576 | const char *hostname, |
424 | int af) | 577 | int af, |
578 | uint32_t request_id) | ||
425 | { | 579 | { |
426 | struct hostent *hp; | 580 | struct hostent *hp; |
427 | int ret1; | 581 | int ret1; |
428 | int ret2; | 582 | int ret2; |
429 | struct GNUNET_MQ_Envelope *env; | 583 | struct GNUNET_MQ_Envelope *env; |
430 | struct GNUNET_MessageHeader *msg; | 584 | struct GNUNET_RESOLVER_ResponseMessage *msg; |
431 | 585 | ||
432 | #ifdef WINDOWS | 586 | #ifdef WINDOWS |
433 | /* gethostbyname2() in plibc is a compat dummy that calls gethostbyname(). */ | 587 | /* gethostbyname2() in plibc is a compat dummy that calls gethostbyname(). */ |
@@ -438,10 +592,12 @@ gethostbyname2_resolve (struct GNUNET_MQ_Handle *mq, | |||
438 | { | 592 | { |
439 | ret1 = gethostbyname2_resolve (mq, | 593 | ret1 = gethostbyname2_resolve (mq, |
440 | hostname, | 594 | hostname, |
441 | AF_INET); | 595 | AF_INET, |
596 | request_id); | ||
442 | ret2 = gethostbyname2_resolve (mq, | 597 | ret2 = gethostbyname2_resolve (mq, |
443 | hostname, | 598 | hostname, |
444 | AF_INET6); | 599 | AF_INET6, |
600 | request_id); | ||
445 | if ( (ret1 == GNUNET_OK) || | 601 | if ( (ret1 == GNUNET_OK) || |
446 | (ret2 == GNUNET_OK) ) | 602 | (ret2 == GNUNET_OK) ) |
447 | return GNUNET_OK; | 603 | return GNUNET_OK; |
@@ -468,6 +624,7 @@ gethostbyname2_resolve (struct GNUNET_MQ_Handle *mq, | |||
468 | env = GNUNET_MQ_msg_extra (msg, | 624 | env = GNUNET_MQ_msg_extra (msg, |
469 | hp->h_length, | 625 | hp->h_length, |
470 | GNUNET_MESSAGE_TYPE_RESOLVER_RESPONSE); | 626 | GNUNET_MESSAGE_TYPE_RESOLVER_RESPONSE); |
627 | msg->id = request_id; | ||
471 | GNUNET_memcpy (&msg[1], | 628 | GNUNET_memcpy (&msg[1], |
472 | hp->h_addr_list[0], | 629 | hp->h_addr_list[0], |
473 | hp->h_length); | 630 | hp->h_length); |
@@ -479,6 +636,7 @@ gethostbyname2_resolve (struct GNUNET_MQ_Handle *mq, | |||
479 | env = GNUNET_MQ_msg_extra (msg, | 636 | env = GNUNET_MQ_msg_extra (msg, |
480 | hp->h_length, | 637 | hp->h_length, |
481 | GNUNET_MESSAGE_TYPE_RESOLVER_RESPONSE); | 638 | GNUNET_MESSAGE_TYPE_RESOLVER_RESPONSE); |
639 | msg->id = request_id; | ||
482 | GNUNET_memcpy (&msg[1], | 640 | GNUNET_memcpy (&msg[1], |
483 | hp->h_addr_list[0], | 641 | hp->h_addr_list[0], |
484 | hp->h_length); | 642 | hp->h_length); |
@@ -497,10 +655,11 @@ gethostbyname2_resolve (struct GNUNET_MQ_Handle *mq, | |||
497 | 655 | ||
498 | static int | 656 | static int |
499 | gethostbyname_resolve (struct GNUNET_MQ_Handle *mq, | 657 | gethostbyname_resolve (struct GNUNET_MQ_Handle *mq, |
500 | const char *hostname) | 658 | const char *hostname, |
659 | uint32_t request_id) | ||
501 | { | 660 | { |
502 | struct hostent *hp; | 661 | struct hostent *hp; |
503 | struct GNUNET_MessageHeader *msg; | 662 | struct GNUNET_RESOLVER_ResponseMessage *msg; |
504 | struct GNUNET_MQ_Envelope *env; | 663 | struct GNUNET_MQ_Envelope *env; |
505 | 664 | ||
506 | hp = GETHOSTBYNAME (hostname); | 665 | hp = GETHOSTBYNAME (hostname); |
@@ -521,6 +680,7 @@ gethostbyname_resolve (struct GNUNET_MQ_Handle *mq, | |||
521 | env = GNUNET_MQ_msg_extra (msg, | 680 | env = GNUNET_MQ_msg_extra (msg, |
522 | hp->h_length, | 681 | hp->h_length, |
523 | GNUNET_MESSAGE_TYPE_RESOLVER_RESPONSE); | 682 | GNUNET_MESSAGE_TYPE_RESOLVER_RESPONSE); |
683 | msg->id = request_id; | ||
524 | GNUNET_memcpy (&msg[1], | 684 | GNUNET_memcpy (&msg[1], |
525 | hp->h_addr_list[0], | 685 | hp->h_addr_list[0], |
526 | hp->h_length); | 686 | hp->h_length); |
@@ -541,34 +701,42 @@ gethostbyname_resolve (struct GNUNET_MQ_Handle *mq, | |||
541 | static void | 701 | static void |
542 | get_ip_from_hostname (struct GNUNET_SERVICE_Client *client, | 702 | get_ip_from_hostname (struct GNUNET_SERVICE_Client *client, |
543 | const char *hostname, | 703 | const char *hostname, |
544 | int af) | 704 | int af, |
705 | uint32_t request_id) | ||
545 | { | 706 | { |
546 | int ret; | ||
547 | struct GNUNET_MQ_Handle *mq; | ||
548 | struct GNUNET_MQ_Envelope *env; | 707 | struct GNUNET_MQ_Envelope *env; |
549 | struct GNUNET_MessageHeader *msg; | 708 | struct GNUNET_RESOLVER_ResponseMessage *msg; |
709 | struct GNUNET_MQ_Handle *mq; | ||
550 | 710 | ||
551 | mq = GNUNET_SERVICE_client_get_mq (client); | 711 | mq = GNUNET_SERVICE_client_get_mq (client); |
552 | ret = GNUNET_NO; | 712 | #if HAVE_GETADDRINFO_A |
553 | #if HAVE_GETADDRINFO | 713 | getaddrinfo_a_resolve (mq, |
554 | if (ret == GNUNET_NO) | 714 | hostname, |
555 | ret = getaddrinfo_resolve (mq, | 715 | af, |
556 | hostname, | 716 | request_id); |
557 | af); | 717 | GNUNET_SERVICE_client_continue (client); |
718 | return; | ||
719 | #elif HAVE_GETADDRINFO | ||
720 | getaddrinfo_resolve (mq, | ||
721 | hostname, | ||
722 | af, | ||
723 | request_id); | ||
558 | #elif HAVE_GETHOSTBYNAME2 | 724 | #elif HAVE_GETHOSTBYNAME2 |
559 | if (ret == GNUNET_NO) | 725 | gethostbyname2_resolve (mq, |
560 | ret = gethostbyname2_resolve (mq, | 726 | hostname, |
561 | hostname, | 727 | af, |
562 | af); | 728 | request_id); |
563 | #elif HAVE_GETHOSTBYNAME | 729 | #elif HAVE_GETHOSTBYNAME |
564 | if ( (ret == GNUNET_NO) && | 730 | if ( ( (af == AF_UNSPEC) || |
565 | ( (af == AF_UNSPEC) || | ||
566 | (af == PF_INET) ) ) | 731 | (af == PF_INET) ) ) |
567 | gethostbyname_resolve (mq, | 732 | gethostbyname_resolve (mq, |
568 | hostname); | 733 | hostname, |
734 | request_id); | ||
569 | #endif | 735 | #endif |
736 | // send end message | ||
570 | env = GNUNET_MQ_msg (msg, | 737 | env = GNUNET_MQ_msg (msg, |
571 | GNUNET_MESSAGE_TYPE_RESOLVER_RESPONSE); | 738 | GNUNET_MESSAGE_TYPE_RESOLVER_RESPONSE); |
739 | msg->id = request_id; | ||
572 | GNUNET_MQ_notify_sent (env, | 740 | GNUNET_MQ_notify_sent (env, |
573 | ¬ify_service_client_done, | 741 | ¬ify_service_client_done, |
574 | client); | 742 | client); |
@@ -647,21 +815,21 @@ handle_get (void *cls, | |||
647 | const void *ip; | 815 | const void *ip; |
648 | int direction; | 816 | int direction; |
649 | int af; | 817 | int af; |
818 | uint32_t id; | ||
650 | 819 | ||
651 | direction = ntohl (msg->direction); | 820 | direction = ntohl (msg->direction); |
652 | af = ntohl (msg->af); | 821 | af = ntohl (msg->af); |
822 | id = ntohl (msg->id); | ||
653 | if (GNUNET_NO == direction) | 823 | if (GNUNET_NO == direction) |
654 | { | 824 | { |
655 | /* IP from hostname */ | 825 | /* IP from hostname */ |
656 | const char *hostname; | 826 | const char *hostname; |
657 | 827 | ||
658 | hostname = (const char *) &msg[1]; | 828 | hostname = (const char *) &msg[1]; |
659 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, | ||
660 | "Resolver asked to look up `%s'.\n", | ||
661 | hostname); | ||
662 | get_ip_from_hostname (client, | 829 | get_ip_from_hostname (client, |
663 | hostname, | 830 | hostname, |
664 | af); | 831 | af, |
832 | id); | ||
665 | return; | 833 | return; |
666 | } | 834 | } |
667 | ip = &msg[1]; | 835 | ip = &msg[1]; |
@@ -671,16 +839,18 @@ handle_get (void *cls, | |||
671 | char buf[INET6_ADDRSTRLEN]; | 839 | char buf[INET6_ADDRSTRLEN]; |
672 | 840 | ||
673 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, | 841 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, |
674 | "Resolver asked to look up IP address `%s'.\n", | 842 | "Resolver asked to look up IP address `%s (request ID %u)'.\n", |
675 | inet_ntop (af, | 843 | inet_ntop (af, |
676 | ip, | 844 | ip, |
677 | buf, | 845 | buf, |
678 | sizeof (buf))); | 846 | sizeof (buf)), |
847 | id); | ||
679 | } | 848 | } |
680 | #endif | 849 | #endif |
681 | get_ip_as_string (client, | 850 | get_ip_as_string (client, |
682 | af, | 851 | af, |
683 | ip); | 852 | ip, |
853 | id); | ||
684 | } | 854 | } |
685 | 855 | ||
686 | 856 | ||
@@ -700,6 +870,19 @@ connect_cb (void *cls, | |||
700 | (void) cls; | 870 | (void) cls; |
701 | (void) mq; | 871 | (void) mq; |
702 | 872 | ||
873 | #if HAVE_GETADDRINFO_A | ||
874 | resolve_result_pipe = GNUNET_DISK_pipe (GNUNET_NO, | ||
875 | GNUNET_NO, | ||
876 | GNUNET_NO, | ||
877 | GNUNET_NO); | ||
878 | GNUNET_assert (NULL != resolve_result_pipe); | ||
879 | resolve_result_pipe_task = | ||
880 | GNUNET_SCHEDULER_add_read_file (GNUNET_TIME_UNIT_FOREVER_REL, | ||
881 | GNUNET_DISK_pipe_handle (resolve_result_pipe, | ||
882 | GNUNET_DISK_PIPE_END_READ), | ||
883 | &resolve_result_pipe_cb, | ||
884 | NULL); | ||
885 | #endif | ||
703 | return c; | 886 | return c; |
704 | } | 887 | } |
705 | 888 | ||
@@ -718,6 +901,18 @@ disconnect_cb (void *cls, | |||
718 | { | 901 | { |
719 | (void) cls; | 902 | (void) cls; |
720 | 903 | ||
904 | #if HAVE_GETADDRINFO_A | ||
905 | if (NULL != resolve_result_pipe_task) | ||
906 | { | ||
907 | GNUNET_SCHEDULER_cancel (resolve_result_pipe_task); | ||
908 | resolve_result_pipe_task = NULL; | ||
909 | } | ||
910 | if (NULL != resolve_result_pipe) | ||
911 | { | ||
912 | GNUNET_DISK_pipe_close (resolve_result_pipe); | ||
913 | resolve_result_pipe = NULL; | ||
914 | } | ||
915 | #endif | ||
721 | GNUNET_assert (c == internal_cls); | 916 | GNUNET_assert (c == internal_cls); |
722 | } | 917 | } |
723 | 918 | ||
diff --git a/src/util/resolver.h b/src/util/resolver.h index 0b137f085..a0f105afa 100644 --- a/src/util/resolver.h +++ b/src/util/resolver.h | |||
@@ -56,10 +56,37 @@ struct GNUNET_RESOLVER_GetMessage | |||
56 | */ | 56 | */ |
57 | int32_t af GNUNET_PACKED; | 57 | int32_t af GNUNET_PACKED; |
58 | 58 | ||
59 | /** | ||
60 | * identifies the request and is contained in the response message. The | ||
61 | * client has to match response to request by this identifier. | ||
62 | */ | ||
63 | uint32_t id GNUNET_PACKED; | ||
64 | |||
59 | /* followed by 0-terminated string for A/AAAA-lookup or | 65 | /* followed by 0-terminated string for A/AAAA-lookup or |
60 | by 'struct in_addr' / 'struct in6_addr' for reverse lookup */ | 66 | by 'struct in_addr' / 'struct in6_addr' for reverse lookup */ |
61 | 67 | ||
62 | }; | 68 | }; |
69 | |||
70 | |||
71 | struct GNUNET_RESOLVER_ResponseMessage | ||
72 | { | ||
73 | /** | ||
74 | * Type: GNUNET_MESSAGE_TYPE_RESOLVER_RESPONSE | ||
75 | */ | ||
76 | struct GNUNET_MessageHeader header; | ||
77 | |||
78 | /** | ||
79 | * identifies the request this message responds to. The client | ||
80 | * has to match response to request by this identifier. | ||
81 | */ | ||
82 | uint32_t id GNUNET_PACKED; | ||
83 | |||
84 | /* followed by 0-terminated string for response to a reverse lookup | ||
85 | * or by 'struct in_addr' / 'struct in6_addr' for response to | ||
86 | * A/AAAA-lookup | ||
87 | */ | ||
88 | }; | ||
89 | |||
63 | GNUNET_NETWORK_STRUCT_END | 90 | GNUNET_NETWORK_STRUCT_END |
64 | 91 | ||
65 | #endif | 92 | #endif |
diff --git a/src/util/resolver_api.c b/src/util/resolver_api.c index afebabf08..b94819f06 100644 --- a/src/util/resolver_api.c +++ b/src/util/resolver_api.c | |||
@@ -69,6 +69,11 @@ static struct GNUNET_RESOLVER_RequestHandle *req_head; | |||
69 | static struct GNUNET_RESOLVER_RequestHandle *req_tail; | 69 | static struct GNUNET_RESOLVER_RequestHandle *req_tail; |
70 | 70 | ||
71 | /** | 71 | /** |
72 | * ID of the last request we sent to the service | ||
73 | */ | ||
74 | static uint32_t last_request_id; | ||
75 | |||
76 | /** | ||
72 | * How long should we wait to reconnect? | 77 | * How long should we wait to reconnect? |
73 | */ | 78 | */ |
74 | static struct GNUNET_TIME_Relative backoff; | 79 | static struct GNUNET_TIME_Relative backoff; |
@@ -137,6 +142,11 @@ struct GNUNET_RESOLVER_RequestHandle | |||
137 | int af; | 142 | int af; |
138 | 143 | ||
139 | /** | 144 | /** |
145 | * Identifies the request. The response will contain this id. | ||
146 | */ | ||
147 | uint32_t id; | ||
148 | |||
149 | /** | ||
140 | * Has this request been transmitted to the service? | 150 | * Has this request been transmitted to the service? |
141 | * #GNUNET_YES if transmitted | 151 | * #GNUNET_YES if transmitted |
142 | * #GNUNET_YES if not transmitted | 152 | * #GNUNET_YES if not transmitted |
@@ -435,11 +445,13 @@ process_requests () | |||
435 | GNUNET_MESSAGE_TYPE_RESOLVER_REQUEST); | 445 | GNUNET_MESSAGE_TYPE_RESOLVER_REQUEST); |
436 | msg->direction = htonl (rh->direction); | 446 | msg->direction = htonl (rh->direction); |
437 | msg->af = htonl (rh->af); | 447 | msg->af = htonl (rh->af); |
448 | msg->id = htonl (rh->id); | ||
438 | GNUNET_memcpy (&msg[1], | 449 | GNUNET_memcpy (&msg[1], |
439 | &rh[1], | 450 | &rh[1], |
440 | rh->data_len); | 451 | rh->data_len); |
441 | LOG (GNUNET_ERROR_TYPE_DEBUG, | 452 | LOG (GNUNET_ERROR_TYPE_DEBUG, |
442 | "Transmitting DNS resolution request to DNS service\n"); | 453 | "Transmitting DNS resolution request (ID %u) to DNS service\n", |
454 | rh->id); | ||
443 | GNUNET_MQ_send (mq, | 455 | GNUNET_MQ_send (mq, |
444 | env); | 456 | env); |
445 | rh->was_transmitted = GNUNET_YES; | 457 | rh->was_transmitted = GNUNET_YES; |
@@ -454,7 +466,7 @@ process_requests () | |||
454 | */ | 466 | */ |
455 | static int | 467 | static int |
456 | check_response (void *cls, | 468 | check_response (void *cls, |
457 | const struct GNUNET_MessageHeader *msg) | 469 | const struct GNUNET_RESOLVER_ResponseMessage *msg) |
458 | { | 470 | { |
459 | (void) cls; | 471 | (void) cls; |
460 | (void) msg; | 472 | (void) msg; |
@@ -474,11 +486,18 @@ check_response (void *cls, | |||
474 | */ | 486 | */ |
475 | static void | 487 | static void |
476 | handle_response (void *cls, | 488 | handle_response (void *cls, |
477 | const struct GNUNET_MessageHeader *msg) | 489 | const struct GNUNET_RESOLVER_ResponseMessage *msg) |
478 | { | 490 | { |
479 | struct GNUNET_RESOLVER_RequestHandle *rh = req_head; | 491 | struct GNUNET_RESOLVER_RequestHandle *rh = req_head; |
480 | uint16_t size; | 492 | uint16_t size; |
481 | char *nret; | 493 | char *nret; |
494 | uint32_t request_id = msg->id; | ||
495 | |||
496 | for (; rh != NULL; rh = rh->next) | ||
497 | { | ||
498 | if (rh->id == request_id) | ||
499 | break; | ||
500 | } | ||
482 | 501 | ||
483 | (void) cls; | 502 | (void) cls; |
484 | if (NULL == rh) | 503 | if (NULL == rh) |
@@ -490,8 +509,8 @@ handle_response (void *cls, | |||
490 | reconnect (); | 509 | reconnect (); |
491 | return; | 510 | return; |
492 | } | 511 | } |
493 | size = ntohs (msg->size); | 512 | size = ntohs (msg->header.size); |
494 | if (size == sizeof (struct GNUNET_MessageHeader)) | 513 | if (size == sizeof (struct GNUNET_RESOLVER_ResponseMessage)) |
495 | { | 514 | { |
496 | LOG (GNUNET_ERROR_TYPE_DEBUG, | 515 | LOG (GNUNET_ERROR_TYPE_DEBUG, |
497 | "Received empty response from DNS service\n"); | 516 | "Received empty response from DNS service\n"); |
@@ -532,7 +551,7 @@ handle_response (void *cls, | |||
532 | const char *hostname; | 551 | const char *hostname; |
533 | 552 | ||
534 | hostname = (const char *) &msg[1]; | 553 | hostname = (const char *) &msg[1]; |
535 | if (hostname[size - sizeof (struct GNUNET_MessageHeader) - 1] != '\0') | 554 | if (hostname[size - sizeof (struct GNUNET_RESOLVER_ResponseMessage) - 1] != '\0') |
536 | { | 555 | { |
537 | GNUNET_break (0); | 556 | GNUNET_break (0); |
538 | if (GNUNET_SYSERR != rh->was_transmitted) | 557 | if (GNUNET_SYSERR != rh->was_transmitted) |
@@ -566,7 +585,7 @@ handle_response (void *cls, | |||
566 | size_t ip_len; | 585 | size_t ip_len; |
567 | 586 | ||
568 | ip = &msg[1]; | 587 | ip = &msg[1]; |
569 | ip_len = size - sizeof (struct GNUNET_MessageHeader); | 588 | ip_len = size - sizeof (struct GNUNET_RESOLVER_ResponseMessage); |
570 | if (ip_len == sizeof (struct in_addr)) | 589 | if (ip_len == sizeof (struct in_addr)) |
571 | { | 590 | { |
572 | memset (&v4, 0, sizeof (v4)); | 591 | memset (&v4, 0, sizeof (v4)); |
@@ -763,7 +782,7 @@ reconnect_task (void *cls) | |||
763 | struct GNUNET_MQ_MessageHandler handlers[] = { | 782 | struct GNUNET_MQ_MessageHandler handlers[] = { |
764 | GNUNET_MQ_hd_var_size (response, | 783 | GNUNET_MQ_hd_var_size (response, |
765 | GNUNET_MESSAGE_TYPE_RESOLVER_RESPONSE, | 784 | GNUNET_MESSAGE_TYPE_RESOLVER_RESPONSE, |
766 | struct GNUNET_MessageHeader, | 785 | struct GNUNET_RESOLVER_ResponseMessage, |
767 | NULL), | 786 | NULL), |
768 | GNUNET_MQ_handler_end () | 787 | GNUNET_MQ_handler_end () |
769 | }; | 788 | }; |
@@ -926,6 +945,7 @@ GNUNET_RESOLVER_ip_get (const char *hostname, | |||
926 | hostname); | 945 | hostname); |
927 | rh = GNUNET_malloc (sizeof (struct GNUNET_RESOLVER_RequestHandle) + slen); | 946 | rh = GNUNET_malloc (sizeof (struct GNUNET_RESOLVER_RequestHandle) + slen); |
928 | rh->af = af; | 947 | rh->af = af; |
948 | rh->id = ++last_request_id; | ||
929 | rh->addr_callback = callback; | 949 | rh->addr_callback = callback; |
930 | rh->cls = callback_cls; | 950 | rh->cls = callback_cls; |
931 | GNUNET_memcpy (&rh[1], | 951 | GNUNET_memcpy (&rh[1], |
@@ -1072,6 +1092,7 @@ GNUNET_RESOLVER_hostname_get (const struct sockaddr *sa, | |||
1072 | rh->name_callback = callback; | 1092 | rh->name_callback = callback; |
1073 | rh->cls = cls; | 1093 | rh->cls = cls; |
1074 | rh->af = sa->sa_family; | 1094 | rh->af = sa->sa_family; |
1095 | rh->id = ++last_request_id; | ||
1075 | rh->timeout = GNUNET_TIME_relative_to_absolute (timeout); | 1096 | rh->timeout = GNUNET_TIME_relative_to_absolute (timeout); |
1076 | GNUNET_memcpy (&rh[1], | 1097 | GNUNET_memcpy (&rh[1], |
1077 | ip, | 1098 | ip, |
diff --git a/src/util/test_resolver_api.c b/src/util/test_resolver_api.c index c89fad865..5a8f95093 100644 --- a/src/util/test_resolver_api.c +++ b/src/util/test_resolver_api.c | |||
@@ -258,6 +258,8 @@ run (void *cls, char *const *args, const char *cfgfile, | |||
258 | /* Resolve the same using GNUNET */ | 258 | /* Resolve the same using GNUNET */ |
259 | GNUNET_RESOLVER_ip_get (ROOTSERVER_NAME, AF_INET, timeout, | 259 | GNUNET_RESOLVER_ip_get (ROOTSERVER_NAME, AF_INET, timeout, |
260 | &check_rootserver_ip, cls); | 260 | &check_rootserver_ip, cls); |
261 | GNUNET_RESOLVER_ip_get (ROOTSERVER_NAME, AF_INET, timeout, | ||
262 | &check_rootserver_ip, cls); | ||
261 | 263 | ||
262 | /* | 264 | /* |
263 | * Success: forward lookups work as expected | 265 | * Success: forward lookups work as expected |