aboutsummaryrefslogtreecommitdiff
path: root/src/util/gnunet-service-resolver.c
diff options
context:
space:
mode:
authorlurchi <lurchi@strangeplace.net>2018-06-24 23:31:07 +0200
committerlurchi <lurchi@strangeplace.net>2018-06-24 23:31:07 +0200
commitc38455c65f9968ccf7e870c3cce30fa19f319376 (patch)
tree523075af0d81a9f460d60b90b51557ad83bd5b42 /src/util/gnunet-service-resolver.c
parent92e03f9117f5dc29909d73707897d28d8e27e048 (diff)
downloadgnunet-c38455c65f9968ccf7e870c3cce30fa19f319376.tar.gz
gnunet-c38455c65f9968ccf7e870c3cce30fa19f319376.zip
use the asynchronous DNS resolution API (getaddrinfo_a) in the resolver module
Diffstat (limited to 'src/util/gnunet-service-resolver.c')
-rw-r--r--src/util/gnunet-service-resolver.c269
1 files changed, 232 insertions, 37 deletions
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 */
85static struct IPCache *cache_tail; 85static struct IPCache *cache_tail;
86 86
87/**
88 * Pipe for asynchronously notifying about resolve result
89 */
90static struct GNUNET_DISK_PipeHandle *resolve_result_pipe;
91
92/**
93 * Task for reading from resolve_result_pipe
94 */
95static 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)
223static void 233static void
224get_ip_as_string (struct GNUNET_SERVICE_Client *client, 234get_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 &notify_service_client_done, 329 &notify_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
337struct AsyncCls
338{
339 struct gaicb *host;
340 struct sigevent *sig;
341 struct GNUNET_MQ_Handle *mq;
342 uint32_t request_id;
343};
344
345
346static void
347resolve_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
415static void
416handle_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
425static int
426getaddrinfo_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
323static int 471static int
324getaddrinfo_resolve (struct GNUNET_MQ_Handle *mq, 472getaddrinfo_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,
421static int 574static int
422gethostbyname2_resolve (struct GNUNET_MQ_Handle *mq, 575gethostbyname2_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
498static int 656static int
499gethostbyname_resolve (struct GNUNET_MQ_Handle *mq, 657gethostbyname_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,
541static void 701static void
542get_ip_from_hostname (struct GNUNET_SERVICE_Client *client, 702get_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 &notify_service_client_done, 741 &notify_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