diff options
Diffstat (limited to 'src/dns/gnunet-service-dns.c')
-rw-r--r-- | src/dns/gnunet-service-dns.c | 468 |
1 files changed, 76 insertions, 392 deletions
diff --git a/src/dns/gnunet-service-dns.c b/src/dns/gnunet-service-dns.c index 76ea1390f..b13f156a9 100644 --- a/src/dns/gnunet-service-dns.c +++ b/src/dns/gnunet-service-dns.c | |||
@@ -45,23 +45,13 @@ | |||
45 | #include "dns.h" | 45 | #include "dns.h" |
46 | #include "gnunet_dns_service.h" | 46 | #include "gnunet_dns_service.h" |
47 | #include "gnunet_dnsparser_lib.h" | 47 | #include "gnunet_dnsparser_lib.h" |
48 | #include "gnunet_dnsstub_lib.h" | ||
48 | #include "gnunet_mesh_service.h" | 49 | #include "gnunet_mesh_service.h" |
49 | #include "gnunet_statistics_service.h" | 50 | #include "gnunet_statistics_service.h" |
50 | #include "gnunet_tun_lib.h" | 51 | #include "gnunet_tun_lib.h" |
51 | 52 | ||
52 | 53 | ||
53 | /** | 54 | /** |
54 | * Timeout for an external (Internet-DNS) DNS resolution | ||
55 | */ | ||
56 | #define REQUEST_TIMEOUT GNUNET_TIME_relative_multiply (GNUNET_TIME_UNIT_SECONDS, 5) | ||
57 | |||
58 | /** | ||
59 | * How many DNS sockets do we open at most at the same time? | ||
60 | * (technical socket maximum is this number x2 for IPv4+IPv6) | ||
61 | */ | ||
62 | #define DNS_SOCKET_MAX 128 | ||
63 | |||
64 | /** | ||
65 | * Phases each request goes through. | 55 | * Phases each request goes through. |
66 | */ | 56 | */ |
67 | enum RequestPhase | 57 | enum RequestPhase |
@@ -137,34 +127,6 @@ struct ClientRecord | |||
137 | 127 | ||
138 | 128 | ||
139 | /** | 129 | /** |
140 | * UDP socket we are using for sending DNS requests to the Internet. | ||
141 | */ | ||
142 | struct RequestSocket | ||
143 | { | ||
144 | |||
145 | /** | ||
146 | * UDP socket we use for this request for IPv4 | ||
147 | */ | ||
148 | struct GNUNET_NETWORK_Handle *dnsout4; | ||
149 | |||
150 | /** | ||
151 | * UDP socket we use for this request for IPv6 | ||
152 | */ | ||
153 | struct GNUNET_NETWORK_Handle *dnsout6; | ||
154 | |||
155 | /** | ||
156 | * Task for reading from dnsout4 and dnsout6. | ||
157 | */ | ||
158 | GNUNET_SCHEDULER_TaskIdentifier read_task; | ||
159 | |||
160 | /** | ||
161 | * When should this socket be closed? | ||
162 | */ | ||
163 | struct GNUNET_TIME_Absolute timeout; | ||
164 | }; | ||
165 | |||
166 | |||
167 | /** | ||
168 | * Entry we keep for each active request. | 130 | * Entry we keep for each active request. |
169 | */ | 131 | */ |
170 | struct RequestRecord | 132 | struct RequestRecord |
@@ -184,10 +146,9 @@ struct RequestRecord | |||
184 | 146 | ||
185 | /** | 147 | /** |
186 | * Socket we are using to transmit this request (must match if we receive | 148 | * Socket we are using to transmit this request (must match if we receive |
187 | * a response). Must NOT be freed as part of this request record (as it | 149 | * a response). |
188 | * might be shared with other requests). | ||
189 | */ | 150 | */ |
190 | struct GNUNET_NETWORK_Handle *dnsout; | 151 | struct GNUNET_DNSSTUB_RequestSocket *rs; |
191 | 152 | ||
192 | /** | 153 | /** |
193 | * Source address of the original request (for sending response). | 154 | * Source address of the original request (for sending response). |
@@ -200,11 +161,6 @@ struct RequestRecord | |||
200 | struct sockaddr_storage dst_addr; | 161 | struct sockaddr_storage dst_addr; |
201 | 162 | ||
202 | /** | 163 | /** |
203 | * When should this request time out? | ||
204 | */ | ||
205 | struct GNUNET_TIME_Absolute timeout; | ||
206 | |||
207 | /** | ||
208 | * ID of this request, also basis for hashing. Lowest 16 bit will | 164 | * ID of this request, also basis for hashing. Lowest 16 bit will |
209 | * be our message ID when doing a global DNS request and our index | 165 | * be our message ID when doing a global DNS request and our index |
210 | * into the 'requests' array. | 166 | * into the 'requests' array. |
@@ -252,25 +208,9 @@ struct TunnelState | |||
252 | 208 | ||
253 | /** | 209 | /** |
254 | * Socket we are using to transmit this request (must match if we receive | 210 | * Socket we are using to transmit this request (must match if we receive |
255 | * a response). Must NOT be freed as part of this request record (as it | 211 | * a response). |
256 | * might be shared with other requests). | ||
257 | */ | ||
258 | struct GNUNET_NETWORK_Handle *dnsout; | ||
259 | |||
260 | /** | ||
261 | * Address we sent the DNS request to. | ||
262 | */ | ||
263 | struct sockaddr_storage addr; | ||
264 | |||
265 | /** | ||
266 | * When should this request time out? | ||
267 | */ | 212 | */ |
268 | struct GNUNET_TIME_Absolute timeout; | 213 | struct GNUNET_DNSSTUB_RequestSocket *rs; |
269 | |||
270 | /** | ||
271 | * Number of bytes in 'addr'. | ||
272 | */ | ||
273 | socklen_t addrlen; | ||
274 | 214 | ||
275 | /** | 215 | /** |
276 | * Number of bytes in 'reply'. | 216 | * Number of bytes in 'reply'. |
@@ -330,19 +270,14 @@ static struct ClientRecord *clients_tail; | |||
330 | static struct GNUNET_SERVER_NotificationContext *nc; | 270 | static struct GNUNET_SERVER_NotificationContext *nc; |
331 | 271 | ||
332 | /** | 272 | /** |
333 | * Array of all open requests. | ||
334 | */ | ||
335 | static struct RequestRecord requests[UINT16_MAX + 1]; | ||
336 | |||
337 | /** | ||
338 | * Array of all open requests from tunnels. | 273 | * Array of all open requests from tunnels. |
339 | */ | 274 | */ |
340 | static struct TunnelState *tunnels[UINT16_MAX + 1]; | 275 | static struct TunnelState *tunnels[UINT16_MAX + 1]; |
341 | 276 | ||
342 | /** | 277 | /** |
343 | * Array of all open sockets for DNS requests. | 278 | * Array of all open requests. |
344 | */ | 279 | */ |
345 | static struct RequestSocket sockets[DNS_SOCKET_MAX]; | 280 | static struct RequestRecord requests[UINT16_MAX + 1]; |
346 | 281 | ||
347 | /** | 282 | /** |
348 | * Generator for unique request IDs. | 283 | * Generator for unique request IDs. |
@@ -350,42 +285,15 @@ static struct RequestSocket sockets[DNS_SOCKET_MAX]; | |||
350 | static uint64_t request_id_gen; | 285 | static uint64_t request_id_gen; |
351 | 286 | ||
352 | /** | 287 | /** |
353 | * IP address to use for the DNS server if we are a DNS exit service | ||
354 | * (for VPN via mesh); otherwise NULL. | ||
355 | */ | ||
356 | static char *dns_exit; | ||
357 | |||
358 | /** | ||
359 | * Handle to the MESH service (for receiving DNS queries), or NULL | 288 | * Handle to the MESH service (for receiving DNS queries), or NULL |
360 | * if we are not a DNS exit. | 289 | * if we are not a DNS exit. |
361 | */ | 290 | */ |
362 | static struct GNUNET_MESH_Handle *mesh; | 291 | static struct GNUNET_MESH_Handle *mesh; |
363 | 292 | ||
364 | |||
365 | /** | 293 | /** |
366 | * We're done with a RequestSocket, close it for now. | 294 | * Handle to the DNS Stub resolver. |
367 | * | ||
368 | * @param rs request socket to clean up | ||
369 | */ | 295 | */ |
370 | static void | 296 | static struct GNUNET_DNSSTUB_Context *dnsstub; |
371 | cleanup_rs (struct RequestSocket *rs) | ||
372 | { | ||
373 | if (NULL != rs->dnsout4) | ||
374 | { | ||
375 | GNUNET_NETWORK_socket_close (rs->dnsout4); | ||
376 | rs->dnsout4 = NULL; | ||
377 | } | ||
378 | if (NULL != rs->dnsout6) | ||
379 | { | ||
380 | GNUNET_NETWORK_socket_close (rs->dnsout6); | ||
381 | rs->dnsout6 = NULL; | ||
382 | } | ||
383 | if (GNUNET_SCHEDULER_NO_TASK != rs->read_task) | ||
384 | { | ||
385 | GNUNET_SCHEDULER_cancel (rs->read_task); | ||
386 | rs->read_task = GNUNET_SCHEDULER_NO_TASK; | ||
387 | } | ||
388 | } | ||
389 | 297 | ||
390 | 298 | ||
391 | /** | 299 | /** |
@@ -430,10 +338,10 @@ cleanup_task (void *cls GNUNET_UNUSED, | |||
430 | GNUNET_STATISTICS_destroy (stats, GNUNET_NO); | 338 | GNUNET_STATISTICS_destroy (stats, GNUNET_NO); |
431 | stats = NULL; | 339 | stats = NULL; |
432 | } | 340 | } |
433 | if (NULL != dns_exit) | 341 | if (NULL != dnsstub) |
434 | { | 342 | { |
435 | GNUNET_free (dns_exit); | 343 | GNUNET_DNSSTUB_stop (dnsstub); |
436 | dns_exit = NULL; | 344 | dnsstub = NULL; |
437 | } | 345 | } |
438 | if (NULL != mesh) | 346 | if (NULL != mesh) |
439 | { | 347 | { |
@@ -444,54 +352,6 @@ cleanup_task (void *cls GNUNET_UNUSED, | |||
444 | 352 | ||
445 | 353 | ||
446 | /** | 354 | /** |
447 | * Open source port for sending DNS requests | ||
448 | * | ||
449 | * @param af AF_INET or AF_INET6 | ||
450 | * @return GNUNET_OK on success | ||
451 | */ | ||
452 | static struct GNUNET_NETWORK_Handle * | ||
453 | open_socket (int af) | ||
454 | { | ||
455 | struct sockaddr_in a4; | ||
456 | struct sockaddr_in6 a6; | ||
457 | struct sockaddr *sa; | ||
458 | socklen_t alen; | ||
459 | struct GNUNET_NETWORK_Handle *ret; | ||
460 | |||
461 | ret = GNUNET_NETWORK_socket_create (af, SOCK_DGRAM, 0); | ||
462 | if (NULL == ret) | ||
463 | return NULL; | ||
464 | switch (af) | ||
465 | { | ||
466 | case AF_INET: | ||
467 | memset (&a4, 0, alen = sizeof (struct sockaddr_in)); | ||
468 | sa = (struct sockaddr *) &a4; | ||
469 | break; | ||
470 | case AF_INET6: | ||
471 | memset (&a6, 0, alen = sizeof (struct sockaddr_in6)); | ||
472 | sa = (struct sockaddr *) &a6; | ||
473 | break; | ||
474 | default: | ||
475 | GNUNET_break (0); | ||
476 | GNUNET_NETWORK_socket_close (ret); | ||
477 | return NULL; | ||
478 | } | ||
479 | sa->sa_family = af; | ||
480 | if (GNUNET_OK != GNUNET_NETWORK_socket_bind (ret, | ||
481 | sa, | ||
482 | alen)) | ||
483 | { | ||
484 | GNUNET_log (GNUNET_ERROR_TYPE_ERROR, | ||
485 | _("Could not bind to any port: %s\n"), | ||
486 | STRERROR (errno)); | ||
487 | GNUNET_NETWORK_socket_close (ret); | ||
488 | return NULL; | ||
489 | } | ||
490 | return ret; | ||
491 | } | ||
492 | |||
493 | |||
494 | /** | ||
495 | * We're done with some request, finish processing. | 355 | * We're done with some request, finish processing. |
496 | * | 356 | * |
497 | * @param rr request send to the network or just clean up. | 357 | * @param rr request send to the network or just clean up. |
@@ -677,70 +537,21 @@ send_request_to_client (struct RequestRecord *rr, | |||
677 | } | 537 | } |
678 | 538 | ||
679 | 539 | ||
680 | /** | ||
681 | * Read a DNS response from the (unhindered) UDP-Socket | ||
682 | * | ||
683 | * @param cls socket to read from | ||
684 | * @param tc scheduler context (must be shutdown or read ready) | ||
685 | */ | ||
686 | static void | ||
687 | read_response (void *cls, | ||
688 | const struct GNUNET_SCHEDULER_TaskContext *tc); | ||
689 | |||
690 | 540 | ||
691 | /** | 541 | /** |
692 | * Get a socket of the specified address family to send out a | 542 | * Callback called from DNSSTUB resolver when a resolution |
693 | * UDP DNS request to the Internet. | 543 | * succeeded. |
694 | * | 544 | * |
695 | * @param af desired address family | 545 | * @param cls NULL |
696 | * @return NULL on error (given AF not "supported") | 546 | * @param rs the socket that received the response |
547 | * @param dns the response itself | ||
548 | * @param r number of bytes in dns | ||
697 | */ | 549 | */ |
698 | static struct GNUNET_NETWORK_Handle * | 550 | static void |
699 | get_request_socket (int af) | 551 | process_dns_result (void *cls, |
700 | { | 552 | struct GNUNET_DNSSTUB_RequestSocket *rs, |
701 | struct RequestSocket *rs; | 553 | const struct GNUNET_TUN_DnsHeader *dns, |
702 | struct GNUNET_NETWORK_FDSet *rset; | 554 | size_t r); |
703 | static struct GNUNET_NETWORK_Handle *ret; | ||
704 | |||
705 | rs = &sockets[GNUNET_CRYPTO_random_u32 (GNUNET_CRYPTO_QUALITY_NONCE, | ||
706 | DNS_SOCKET_MAX)]; | ||
707 | rs->timeout = GNUNET_TIME_relative_to_absolute (REQUEST_TIMEOUT); | ||
708 | switch (af) | ||
709 | { | ||
710 | case AF_INET: | ||
711 | if (NULL == rs->dnsout4) | ||
712 | rs->dnsout4 = open_socket (AF_INET); | ||
713 | ret = rs->dnsout4; | ||
714 | break; | ||
715 | case AF_INET6: | ||
716 | if (NULL == rs->dnsout6) | ||
717 | rs->dnsout6 = open_socket (AF_INET6); | ||
718 | ret = rs->dnsout6; | ||
719 | break; | ||
720 | default: | ||
721 | return NULL; | ||
722 | } | ||
723 | if (GNUNET_SCHEDULER_NO_TASK != rs->read_task) | ||
724 | { | ||
725 | GNUNET_SCHEDULER_cancel (rs->read_task); | ||
726 | rs->read_task = GNUNET_SCHEDULER_NO_TASK; | ||
727 | } | ||
728 | if ( (NULL == rs->dnsout4) && | ||
729 | (NULL == rs->dnsout6) ) | ||
730 | return NULL; | ||
731 | rset = GNUNET_NETWORK_fdset_create (); | ||
732 | if (NULL != rs->dnsout4) | ||
733 | GNUNET_NETWORK_fdset_set (rset, rs->dnsout4); | ||
734 | if (NULL != rs->dnsout6) | ||
735 | GNUNET_NETWORK_fdset_set (rset, rs->dnsout6); | ||
736 | rs->read_task = GNUNET_SCHEDULER_add_select (GNUNET_SCHEDULER_PRIORITY_DEFAULT, | ||
737 | REQUEST_TIMEOUT, | ||
738 | rset, | ||
739 | NULL, | ||
740 | &read_response, rs); | ||
741 | GNUNET_NETWORK_fdset_destroy (rset); | ||
742 | return ret; | ||
743 | } | ||
744 | 555 | ||
745 | 556 | ||
746 | /** | 557 | /** |
@@ -815,8 +626,14 @@ next_phase (struct RequestRecord *rr) | |||
815 | } | 626 | } |
816 | 627 | ||
817 | rr->phase = RP_INTERNET_DNS; | 628 | rr->phase = RP_INTERNET_DNS; |
818 | rr->dnsout = get_request_socket (rr->dst_addr.ss_family); | 629 | rr->rs = GNUNET_DNSSTUB_resolve (dnsstub, |
819 | if (NULL == rr->dnsout) | 630 | (struct sockaddr*) &rr->dst_addr, |
631 | salen, | ||
632 | rr->payload, | ||
633 | rr->payload_length, | ||
634 | &process_dns_result, | ||
635 | NULL); | ||
636 | if (NULL == rr->rs) | ||
820 | { | 637 | { |
821 | GNUNET_STATISTICS_update (stats, | 638 | GNUNET_STATISTICS_update (stats, |
822 | gettext_noop ("# DNS exit failed (failed to open socket)"), | 639 | gettext_noop ("# DNS exit failed (failed to open socket)"), |
@@ -824,12 +641,6 @@ next_phase (struct RequestRecord *rr) | |||
824 | cleanup_rr (rr); | 641 | cleanup_rr (rr); |
825 | return; | 642 | return; |
826 | } | 643 | } |
827 | GNUNET_NETWORK_socket_sendto (rr->dnsout, | ||
828 | rr->payload, | ||
829 | rr->payload_length, | ||
830 | (struct sockaddr*) &rr->dst_addr, | ||
831 | salen); | ||
832 | rr->timeout = GNUNET_TIME_relative_to_absolute (REQUEST_TIMEOUT); | ||
833 | return; | 644 | return; |
834 | case RP_INTERNET_DNS: | 645 | case RP_INTERNET_DNS: |
835 | rr->phase = RP_MODIFY; | 646 | rr->phase = RP_MODIFY; |
@@ -956,68 +767,32 @@ transmit_reply_to_mesh (void *cls, | |||
956 | } | 767 | } |
957 | 768 | ||
958 | 769 | ||
770 | |||
959 | /** | 771 | /** |
960 | * Actually do the reading of a DNS packet from our UDP socket and see | 772 | * Callback called from DNSSTUB resolver when a resolution |
961 | * if we have a valid, matching, pending request. | 773 | * succeeded. |
962 | * | 774 | * |
963 | * @param dnsout socket to read from | 775 | * @param cls NULL |
964 | * @return GNUNET_OK on success, GNUNET_NO on drop, GNUNET_SYSERR on IO-errors (closed socket) | 776 | * @param rs the socket that received the response |
777 | * @param dns the response itself | ||
778 | * @param r number of bytes in dns | ||
965 | */ | 779 | */ |
966 | static int | 780 | static void |
967 | do_dns_read (struct GNUNET_NETWORK_Handle *dnsout) | 781 | process_dns_result (void *cls, |
782 | struct GNUNET_DNSSTUB_RequestSocket *rs, | ||
783 | const struct GNUNET_TUN_DnsHeader *dns, | ||
784 | size_t r) | ||
968 | { | 785 | { |
969 | struct sockaddr_storage addr; | ||
970 | socklen_t addrlen; | ||
971 | struct GNUNET_TUN_DnsHeader *dns; | ||
972 | struct RequestRecord *rr; | 786 | struct RequestRecord *rr; |
973 | struct TunnelState *ts; | 787 | struct TunnelState *ts; |
974 | ssize_t r; | 788 | |
975 | int len; | 789 | GNUNET_assert (NULL == cls); |
976 | 790 | /* Handle case that this is a reply to a request from a MESH DNS tunnel */ | |
977 | #ifndef MINGW | 791 | ts = tunnels[dns->id]; |
978 | if (0 != ioctl (GNUNET_NETWORK_get_fd (dnsout), FIONREAD, &len)) | 792 | if ( (NULL == ts) || |
979 | { | 793 | (ts->rs != rs) ) |
980 | /* conservative choice: */ | 794 | ts = NULL; /* DNS responder address missmatch */ |
981 | len = UINT16_MAX; | 795 | if (NULL != ts) |
982 | } | ||
983 | #else | ||
984 | /* port the code above? */ | ||
985 | len = UINT16_MAX; | ||
986 | #endif | ||
987 | |||
988 | { | ||
989 | unsigned char buf[len] GNUNET_ALIGN; | ||
990 | |||
991 | addrlen = sizeof (addr); | ||
992 | memset (&addr, 0, sizeof (addr)); | ||
993 | r = GNUNET_NETWORK_socket_recvfrom (dnsout, | ||
994 | buf, sizeof (buf), | ||
995 | (struct sockaddr*) &addr, &addrlen); | ||
996 | if (-1 == r) | ||
997 | { | ||
998 | GNUNET_log_strerror (GNUNET_ERROR_TYPE_ERROR, "recvfrom"); | ||
999 | GNUNET_NETWORK_socket_close (dnsout); | ||
1000 | return GNUNET_SYSERR; | ||
1001 | } | ||
1002 | if (sizeof (struct GNUNET_TUN_DnsHeader) > r) | ||
1003 | { | ||
1004 | GNUNET_log (GNUNET_ERROR_TYPE_ERROR, | ||
1005 | _("Received DNS response that is too small (%u bytes)"), | ||
1006 | r); | ||
1007 | return GNUNET_NO; | ||
1008 | } | ||
1009 | dns = (struct GNUNET_TUN_DnsHeader *) buf; | ||
1010 | /* Handle case that this is a reply to a request from a MESH DNS tunnel */ | ||
1011 | ts = tunnels[dns->id]; | ||
1012 | if ( (NULL == ts) || | ||
1013 | (ts->dnsout != dnsout) || | ||
1014 | (addrlen != ts->addrlen) || | ||
1015 | (0 != memcmp (&ts->addr, | ||
1016 | &addr, | ||
1017 | addrlen)) || | ||
1018 | (0 == GNUNET_TIME_absolute_get_remaining (ts->timeout).rel_value) ) | ||
1019 | ts = NULL; /* DNS responder address missmatch */ | ||
1020 | if (NULL != ts) | ||
1021 | { | 796 | { |
1022 | tunnels[dns->id] = NULL; | 797 | tunnels[dns->id] = NULL; |
1023 | GNUNET_free_non_null (ts->reply); | 798 | GNUNET_free_non_null (ts->reply); |
@@ -1034,76 +809,25 @@ do_dns_read (struct GNUNET_NETWORK_Handle *dnsout) | |||
1034 | &transmit_reply_to_mesh, | 809 | &transmit_reply_to_mesh, |
1035 | ts); | 810 | ts); |
1036 | } | 811 | } |
1037 | /* Handle case that this is a reply to a local request (intercepted from TUN interface) */ | 812 | /* Handle case that this is a reply to a local request (intercepted from TUN interface) */ |
1038 | rr = &requests[dns->id]; | 813 | rr = &requests[dns->id]; |
1039 | if ( (rr->phase != RP_INTERNET_DNS) || | 814 | if ( (rr->phase != RP_INTERNET_DNS) || |
1040 | (rr->dnsout != dnsout) || | 815 | (rr->rs != rs) ) |
1041 | (0 != memcmp (&rr->dst_addr, | ||
1042 | &addr, | ||
1043 | addrlen)) || | ||
1044 | (0 == GNUNET_TIME_absolute_get_remaining (rr->timeout).rel_value) ) | ||
1045 | { | 816 | { |
1046 | if (NULL == ts) | 817 | if (NULL == ts) |
1047 | { | 818 | { |
1048 | /* unexpected / bogus reply */ | 819 | /* unexpected / bogus reply */ |
1049 | GNUNET_STATISTICS_update (stats, | 820 | GNUNET_STATISTICS_update (stats, |
1050 | gettext_noop ("# External DNS response discarded (no matching request)"), | 821 | gettext_noop ("# External DNS response discarded (no matching request)"), |
1051 | 1, GNUNET_NO); | 822 | 1, GNUNET_NO); |
1052 | } | 823 | } |
1053 | return GNUNET_NO; | 824 | return; |
1054 | } | 825 | } |
1055 | GNUNET_free_non_null (rr->payload); | 826 | GNUNET_free_non_null (rr->payload); |
1056 | rr->payload = GNUNET_malloc (r); | 827 | rr->payload = GNUNET_malloc (r); |
1057 | memcpy (rr->payload, buf, r); | 828 | memcpy (rr->payload, dns, r); |
1058 | rr->payload_length = r; | 829 | rr->payload_length = r; |
1059 | next_phase (rr); | 830 | next_phase (rr); |
1060 | } | ||
1061 | return GNUNET_OK; | ||
1062 | } | ||
1063 | |||
1064 | |||
1065 | /** | ||
1066 | * Read a DNS response from the (unhindered) UDP-Socket | ||
1067 | * | ||
1068 | * @param cls socket to read from | ||
1069 | * @param tc scheduler context (must be shutdown or read ready) | ||
1070 | */ | ||
1071 | static void | ||
1072 | read_response (void *cls, | ||
1073 | const struct GNUNET_SCHEDULER_TaskContext *tc) | ||
1074 | { | ||
1075 | struct RequestSocket *rs = cls; | ||
1076 | struct GNUNET_NETWORK_FDSet *rset; | ||
1077 | |||
1078 | rs->read_task = GNUNET_SCHEDULER_NO_TASK; | ||
1079 | if (0 == (tc->reason & GNUNET_SCHEDULER_REASON_READ_READY)) | ||
1080 | { | ||
1081 | /* timeout or shutdown */ | ||
1082 | cleanup_rs (rs); | ||
1083 | return; | ||
1084 | } | ||
1085 | /* read and process ready sockets */ | ||
1086 | if ((NULL != rs->dnsout4) && | ||
1087 | (GNUNET_NETWORK_fdset_isset (tc->read_ready, rs->dnsout4)) && | ||
1088 | (GNUNET_SYSERR == do_dns_read (rs->dnsout4))) | ||
1089 | rs->dnsout4 = NULL; | ||
1090 | if ((NULL != rs->dnsout6) && | ||
1091 | (GNUNET_NETWORK_fdset_isset (tc->read_ready, rs->dnsout6)) && | ||
1092 | (GNUNET_SYSERR == do_dns_read (rs->dnsout6))) | ||
1093 | rs->dnsout6 = NULL; | ||
1094 | |||
1095 | /* re-schedule read task */ | ||
1096 | rset = GNUNET_NETWORK_fdset_create (); | ||
1097 | if (NULL != rs->dnsout4) | ||
1098 | GNUNET_NETWORK_fdset_set (rset, rs->dnsout4); | ||
1099 | if (NULL != rs->dnsout6) | ||
1100 | GNUNET_NETWORK_fdset_set (rset, rs->dnsout6); | ||
1101 | rs->read_task = GNUNET_SCHEDULER_add_select (GNUNET_SCHEDULER_PRIORITY_DEFAULT, | ||
1102 | GNUNET_TIME_absolute_get_remaining (rs->timeout), | ||
1103 | rset, | ||
1104 | NULL, | ||
1105 | &read_response, rs); | ||
1106 | GNUNET_NETWORK_fdset_destroy (rset); | ||
1107 | } | 831 | } |
1108 | 832 | ||
1109 | 833 | ||
@@ -1410,11 +1134,7 @@ receive_dns_request (void *cls GNUNET_UNUSED, struct GNUNET_MESH_Tunnel *tunnel, | |||
1410 | size_t dlen = mlen - sizeof (struct GNUNET_MessageHeader); | 1134 | size_t dlen = mlen - sizeof (struct GNUNET_MessageHeader); |
1411 | char buf[dlen] GNUNET_ALIGN; | 1135 | char buf[dlen] GNUNET_ALIGN; |
1412 | struct GNUNET_TUN_DnsHeader *dout; | 1136 | struct GNUNET_TUN_DnsHeader *dout; |
1413 | struct sockaddr_in v4; | 1137 | |
1414 | struct sockaddr_in6 v6; | ||
1415 | struct sockaddr *so; | ||
1416 | socklen_t salen; | ||
1417 | |||
1418 | if (dlen < sizeof (struct GNUNET_TUN_DnsHeader)) | 1138 | if (dlen < sizeof (struct GNUNET_TUN_DnsHeader)) |
1419 | { | 1139 | { |
1420 | GNUNET_break_op (0); | 1140 | GNUNET_break_op (0); |
@@ -1428,51 +1148,14 @@ receive_dns_request (void *cls GNUNET_UNUSED, struct GNUNET_MESH_Tunnel *tunnel, | |||
1428 | UINT16_MAX + 1); | 1148 | UINT16_MAX + 1); |
1429 | tunnels[ts->my_id] = ts; | 1149 | tunnels[ts->my_id] = ts; |
1430 | memcpy (buf, dns, dlen); | 1150 | memcpy (buf, dns, dlen); |
1431 | dout = (struct GNUNET_TUN_DnsHeader*) buf; | 1151 | dout = (struct GNUNET_TUN_DnsHeader *) buf; |
1432 | dout->id = ts->my_id; | 1152 | dout->id = ts->my_id; |
1433 | memset (&v4, 0, sizeof (v4)); | 1153 | ts->rs = GNUNET_DNSSTUB_resolve2 (dnsstub, |
1434 | memset (&v6, 0, sizeof (v6)); | 1154 | buf, dlen, |
1435 | if (1 == inet_pton (AF_INET, dns_exit, &v4.sin_addr)) | 1155 | &process_dns_result, |
1436 | { | 1156 | NULL); |
1437 | salen = sizeof (v4); | 1157 | if (NULL == ts->rs) |
1438 | v4.sin_family = AF_INET; | ||
1439 | v4.sin_port = htons (53); | ||
1440 | #if HAVE_SOCKADDR_IN_SIN_LEN | ||
1441 | v4.sin_len = (u_char) salen; | ||
1442 | #endif | ||
1443 | so = (struct sockaddr *) &v4; | ||
1444 | ts->dnsout = get_request_socket (AF_INET); | ||
1445 | } | ||
1446 | else if (1 == inet_pton (AF_INET6, dns_exit, &v6.sin6_addr)) | ||
1447 | { | ||
1448 | salen = sizeof (v6); | ||
1449 | v6.sin6_family = AF_INET6; | ||
1450 | v6.sin6_port = htons (53); | ||
1451 | #if HAVE_SOCKADDR_IN_SIN_LEN | ||
1452 | v6.sin6_len = (u_char) salen; | ||
1453 | #endif | ||
1454 | so = (struct sockaddr *) &v6; | ||
1455 | ts->dnsout = get_request_socket (AF_INET6); | ||
1456 | } | ||
1457 | else | ||
1458 | { | ||
1459 | GNUNET_break (0); | ||
1460 | return GNUNET_SYSERR; | 1158 | return GNUNET_SYSERR; |
1461 | } | ||
1462 | if (NULL == ts->dnsout) | ||
1463 | { | ||
1464 | GNUNET_log (GNUNET_ERROR_TYPE_ERROR, | ||
1465 | _("Configured DNS exit `%s' is not working / valid.\n"), | ||
1466 | dns_exit); | ||
1467 | return GNUNET_SYSERR; | ||
1468 | } | ||
1469 | memcpy (&ts->addr, | ||
1470 | so, | ||
1471 | salen); | ||
1472 | ts->addrlen = salen; | ||
1473 | GNUNET_NETWORK_socket_sendto (ts->dnsout, | ||
1474 | buf, dlen, so, salen); | ||
1475 | ts->timeout = GNUNET_TIME_relative_to_absolute (REQUEST_TIMEOUT); | ||
1476 | return GNUNET_OK; | 1159 | return GNUNET_OK; |
1477 | } | 1160 | } |
1478 | 1161 | ||
@@ -1552,6 +1235,7 @@ run (void *cls, struct GNUNET_SERVER_Handle *server, | |||
1552 | char *ipv6prefix; | 1235 | char *ipv6prefix; |
1553 | struct in_addr dns_exit4; | 1236 | struct in_addr dns_exit4; |
1554 | struct in6_addr dns_exit6; | 1237 | struct in6_addr dns_exit6; |
1238 | char *dns_exit; | ||
1555 | 1239 | ||
1556 | cfg = cfg_; | 1240 | cfg = cfg_; |
1557 | if (GNUNET_YES != | 1241 | if (GNUNET_YES != |
@@ -1582,7 +1266,7 @@ run (void *cls, struct GNUNET_SERVER_Handle *server, | |||
1582 | GNUNET_free_non_null (dns_exit); | 1266 | GNUNET_free_non_null (dns_exit); |
1583 | dns_exit = NULL; | 1267 | dns_exit = NULL; |
1584 | } | 1268 | } |
1585 | 1269 | dnsstub = GNUNET_DNSSTUB_start (dns_exit); | |
1586 | helper_argv[0] = GNUNET_strdup ("gnunet-dns"); | 1270 | helper_argv[0] = GNUNET_strdup ("gnunet-dns"); |
1587 | if (GNUNET_SYSERR == | 1271 | if (GNUNET_SYSERR == |
1588 | GNUNET_CONFIGURATION_get_value_string (cfg, "dns", "IFNAME", &ifc_name)) | 1272 | GNUNET_CONFIGURATION_get_value_string (cfg, "dns", "IFNAME", &ifc_name)) |