diff options
author | Christian Grothoff <christian@grothoff.org> | 2018-04-19 18:38:41 +0200 |
---|---|---|
committer | Christian Grothoff <christian@grothoff.org> | 2018-04-19 18:38:41 +0200 |
commit | ff4d7b51f37f61633766664647e9b148af1e4f0a (patch) | |
tree | 500aa14d9452ce90c19dbbb18cfaec0dd51e6ec2 /src/dns | |
parent | 9c699755967529e59815561d03b85e9a90d789f8 (diff) | |
download | gnunet-ff4d7b51f37f61633766664647e9b148af1e4f0a.tar.gz gnunet-ff4d7b51f37f61633766664647e9b148af1e4f0a.zip |
support multiple DNS resolvers for queries (in DNSSTUB and GNS2DNS resolution for now)
Diffstat (limited to 'src/dns')
-rw-r--r-- | src/dns/dnsstub.c | 683 | ||||
-rw-r--r-- | src/dns/gnunet-service-dns.c | 43 | ||||
-rw-r--r-- | src/dns/gnunet-zoneimport.c | 24 |
3 files changed, 418 insertions, 332 deletions
diff --git a/src/dns/dnsstub.c b/src/dns/dnsstub.c index 6aa2d7b8f..6eb3612c2 100644 --- a/src/dns/dnsstub.c +++ b/src/dns/dnsstub.c | |||
@@ -1,6 +1,6 @@ | |||
1 | /* | 1 | /* |
2 | This file is part of GNUnet. | 2 | This file is part of GNUnet. |
3 | Copyright (C) 2012 GNUnet e.V. | 3 | Copyright (C) 2012, 2018 GNUnet e.V. |
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 |
@@ -28,20 +28,15 @@ | |||
28 | #include "gnunet_dnsstub_lib.h" | 28 | #include "gnunet_dnsstub_lib.h" |
29 | 29 | ||
30 | /** | 30 | /** |
31 | * Timeout for an external (Internet-DNS) DNS resolution | ||
32 | */ | ||
33 | #define REQUEST_TIMEOUT GNUNET_TIME_relative_multiply (GNUNET_TIME_UNIT_SECONDS, 5) | ||
34 | |||
35 | /** | ||
36 | * Timeout for retrying DNS queries. | 31 | * Timeout for retrying DNS queries. |
37 | */ | 32 | */ |
38 | #define DNS_RETRANSMIT_DELAY GNUNET_TIME_relative_multiply (GNUNET_TIME_UNIT_MILLISECONDS, 250) | 33 | #define DNS_RETRANSMIT_DELAY GNUNET_TIME_relative_multiply (GNUNET_TIME_UNIT_MILLISECONDS, 250) |
39 | 34 | ||
35 | |||
40 | /** | 36 | /** |
41 | * How many DNS sockets do we open at most at the same time? | 37 | * DNS Server used for resolution. |
42 | * (technical socket maximum is this number x2 for IPv4+IPv6) | ||
43 | */ | 38 | */ |
44 | #define DNS_SOCKET_MAX 128 | 39 | struct DnsServer; |
45 | 40 | ||
46 | 41 | ||
47 | /** | 42 | /** |
@@ -81,19 +76,14 @@ struct GNUNET_DNSSTUB_RequestSocket | |||
81 | struct GNUNET_SCHEDULER_Task *retry_task; | 76 | struct GNUNET_SCHEDULER_Task *retry_task; |
82 | 77 | ||
83 | /** | 78 | /** |
84 | * When should this request time out? | 79 | * Next address we sent the DNS request to. |
85 | */ | ||
86 | struct GNUNET_TIME_Absolute timeout; | ||
87 | |||
88 | /** | ||
89 | * Address we sent the DNS request to. | ||
90 | */ | 80 | */ |
91 | struct sockaddr_storage addr; | 81 | struct DnsServer *ds_pos; |
92 | 82 | ||
93 | /** | 83 | /** |
94 | * Number of bytes in @e addr. | 84 | * Context this request executes in. |
95 | */ | 85 | */ |
96 | socklen_t addrlen; | 86 | struct GNUNET_DNSSTUB_Context *ctx; |
97 | 87 | ||
98 | /** | 88 | /** |
99 | * Query we sent to @e addr. | 89 | * Query we sent to @e addr. |
@@ -109,6 +99,29 @@ struct GNUNET_DNSSTUB_RequestSocket | |||
109 | 99 | ||
110 | 100 | ||
111 | /** | 101 | /** |
102 | * DNS Server used for resolution. | ||
103 | */ | ||
104 | struct DnsServer | ||
105 | { | ||
106 | |||
107 | /** | ||
108 | * Kept in a DLL. | ||
109 | */ | ||
110 | struct DnsServer *next; | ||
111 | |||
112 | /** | ||
113 | * Kept in a DLL. | ||
114 | */ | ||
115 | struct DnsServer *prev; | ||
116 | |||
117 | /** | ||
118 | * IP address of the DNS resolver. | ||
119 | */ | ||
120 | struct sockaddr_storage ss; | ||
121 | }; | ||
122 | |||
123 | |||
124 | /** | ||
112 | * Handle to the stub resolver. | 125 | * Handle to the stub resolver. |
113 | */ | 126 | */ |
114 | struct GNUNET_DNSSTUB_Context | 127 | struct GNUNET_DNSSTUB_Context |
@@ -117,13 +130,28 @@ struct GNUNET_DNSSTUB_Context | |||
117 | /** | 130 | /** |
118 | * Array of all open sockets for DNS requests. | 131 | * Array of all open sockets for DNS requests. |
119 | */ | 132 | */ |
120 | struct GNUNET_DNSSTUB_RequestSocket sockets[DNS_SOCKET_MAX]; | 133 | struct GNUNET_DNSSTUB_RequestSocket *sockets; |
134 | |||
135 | /** | ||
136 | * DLL of DNS resolvers we use. | ||
137 | */ | ||
138 | struct DnsServer *dns_head; | ||
139 | |||
140 | /** | ||
141 | * DLL of DNS resolvers we use. | ||
142 | */ | ||
143 | struct DnsServer *dns_tail; | ||
144 | |||
145 | /** | ||
146 | * How frequently do we retry requests? | ||
147 | */ | ||
148 | struct GNUNET_TIME_Relative retry_freq; | ||
121 | 149 | ||
122 | /** | 150 | /** |
123 | * IP address to use for the DNS server if we are a DNS exit service | 151 | * Length of @e sockets array. |
124 | * (for VPN via cadet); otherwise NULL. | ||
125 | */ | 152 | */ |
126 | char *dns_exit; | 153 | unsigned int num_sockets; |
154 | |||
127 | }; | 155 | }; |
128 | 156 | ||
129 | 157 | ||
@@ -212,33 +240,21 @@ open_socket (int af) | |||
212 | 240 | ||
213 | 241 | ||
214 | /** | 242 | /** |
215 | * Read a DNS response from the (unhindered) UDP-Socket | ||
216 | * | ||
217 | * @param cls socket to read from | ||
218 | */ | ||
219 | static void | ||
220 | read_response (void *cls); | ||
221 | |||
222 | |||
223 | /** | ||
224 | * Get a socket of the specified address family to send out a | 243 | * Get a socket of the specified address family to send out a |
225 | * UDP DNS request to the Internet. | 244 | * UDP DNS request to the Internet. |
226 | * | 245 | * |
227 | * @param ctx the DNSSTUB context | 246 | * @param ctx the DNSSTUB context |
228 | * @param af desired address family | 247 | * @return NULL on error |
229 | * @return NULL on error (given AF not "supported") | ||
230 | */ | 248 | */ |
231 | static struct GNUNET_DNSSTUB_RequestSocket * | 249 | static struct GNUNET_DNSSTUB_RequestSocket * |
232 | get_request_socket (struct GNUNET_DNSSTUB_Context *ctx, | 250 | get_request_socket (struct GNUNET_DNSSTUB_Context *ctx) |
233 | int af) | ||
234 | { | 251 | { |
235 | struct GNUNET_DNSSTUB_RequestSocket *rs; | 252 | struct GNUNET_DNSSTUB_RequestSocket *rs; |
236 | struct GNUNET_NETWORK_FDSet *rset; | ||
237 | 253 | ||
238 | for (unsigned int i=0;i<256;i++) | 254 | for (unsigned int i=0;i<256;i++) |
239 | { | 255 | { |
240 | rs = &ctx->sockets[GNUNET_CRYPTO_random_u32 (GNUNET_CRYPTO_QUALITY_NONCE, | 256 | rs = &ctx->sockets[GNUNET_CRYPTO_random_u32 (GNUNET_CRYPTO_QUALITY_NONCE, |
241 | DNS_SOCKET_MAX)]; | 257 | ctx->num_sockets)]; |
242 | if (NULL == rs->rc) | 258 | if (NULL == rs->rc) |
243 | break; | 259 | break; |
244 | } | 260 | } |
@@ -246,25 +262,10 @@ get_request_socket (struct GNUNET_DNSSTUB_Context *ctx, | |||
246 | { | 262 | { |
247 | /* signal "failure" */ | 263 | /* signal "failure" */ |
248 | rs->rc (rs->rc_cls, | 264 | rs->rc (rs->rc_cls, |
249 | rs, | ||
250 | NULL, | 265 | NULL, |
251 | 0); | 266 | 0); |
252 | rs->rc = NULL; | 267 | rs->rc = NULL; |
253 | } | 268 | } |
254 | rs->timeout = GNUNET_TIME_relative_to_absolute (REQUEST_TIMEOUT); | ||
255 | switch (af) | ||
256 | { | ||
257 | case AF_INET: | ||
258 | if (NULL == rs->dnsout4) | ||
259 | rs->dnsout4 = open_socket (AF_INET); | ||
260 | break; | ||
261 | case AF_INET6: | ||
262 | if (NULL == rs->dnsout6) | ||
263 | rs->dnsout6 = open_socket (AF_INET6); | ||
264 | break; | ||
265 | default: | ||
266 | return NULL; | ||
267 | } | ||
268 | if (NULL != rs->read_task) | 269 | if (NULL != rs->read_task) |
269 | { | 270 | { |
270 | GNUNET_SCHEDULER_cancel (rs->read_task); | 271 | GNUNET_SCHEDULER_cancel (rs->read_task); |
@@ -280,194 +281,7 @@ get_request_socket (struct GNUNET_DNSSTUB_Context *ctx, | |||
280 | GNUNET_free (rs->request); | 281 | GNUNET_free (rs->request); |
281 | rs->request = NULL; | 282 | rs->request = NULL; |
282 | } | 283 | } |
283 | if ( (NULL == rs->dnsout4) && | 284 | rs->ctx = ctx; |
284 | (NULL == rs->dnsout6) ) | ||
285 | return NULL; | ||
286 | rset = GNUNET_NETWORK_fdset_create (); | ||
287 | if (NULL != rs->dnsout4) | ||
288 | GNUNET_NETWORK_fdset_set (rset, | ||
289 | rs->dnsout4); | ||
290 | if (NULL != rs->dnsout6) | ||
291 | GNUNET_NETWORK_fdset_set (rset, | ||
292 | rs->dnsout6); | ||
293 | rs->read_task = GNUNET_SCHEDULER_add_select (GNUNET_SCHEDULER_PRIORITY_DEFAULT, | ||
294 | REQUEST_TIMEOUT, | ||
295 | rset, | ||
296 | NULL, | ||
297 | &read_response, | ||
298 | rs); | ||
299 | GNUNET_NETWORK_fdset_destroy (rset); | ||
300 | return rs; | ||
301 | } | ||
302 | |||
303 | |||
304 | /** | ||
305 | * Task to (re)transmit the DNS query, possibly repeatedly until | ||
306 | * we succeed. | ||
307 | * | ||
308 | * @param cls our `struct GNUNET_DNSSTUB_RequestSocket *` | ||
309 | */ | ||
310 | static void | ||
311 | transmit_query (void *cls) | ||
312 | { | ||
313 | struct GNUNET_DNSSTUB_RequestSocket *rs = cls; | ||
314 | struct GNUNET_NETWORK_Handle *ret; | ||
315 | |||
316 | rs->retry_task = NULL; | ||
317 | ret = (NULL != rs->dnsout4) ? rs->dnsout4 : rs->dnsout6; | ||
318 | GNUNET_assert (NULL != ret); | ||
319 | if (GNUNET_SYSERR == | ||
320 | GNUNET_NETWORK_socket_sendto (ret, | ||
321 | rs->request, | ||
322 | rs->request_len, | ||
323 | (struct sockaddr *) &rs->addr, | ||
324 | rs->addrlen)) | ||
325 | GNUNET_log (GNUNET_ERROR_TYPE_WARNING, | ||
326 | _("Failed to send DNS request to %s\n"), | ||
327 | GNUNET_a2s ((struct sockaddr *) &rs->addr, | ||
328 | rs->addrlen)); | ||
329 | else | ||
330 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, | ||
331 | _("Sent DNS request to %s\n"), | ||
332 | GNUNET_a2s ((struct sockaddr *) &rs->addr, | ||
333 | rs->addrlen)); | ||
334 | rs->retry_task = GNUNET_SCHEDULER_add_delayed (DNS_RETRANSMIT_DELAY, | ||
335 | &transmit_query, | ||
336 | rs); | ||
337 | } | ||
338 | |||
339 | |||
340 | /** | ||
341 | * Perform DNS resolution. | ||
342 | * | ||
343 | * @param ctx stub resolver to use | ||
344 | * @param sa the socket address | ||
345 | * @param sa_len the length of @a sa | ||
346 | * @param request DNS request to transmit | ||
347 | * @param request_len number of bytes in @a request | ||
348 | * @param rc function to call with result | ||
349 | * @param rc_cls closure for @a rc | ||
350 | * @return socket used for the request, NULL on error | ||
351 | */ | ||
352 | struct GNUNET_DNSSTUB_RequestSocket * | ||
353 | GNUNET_DNSSTUB_resolve (struct GNUNET_DNSSTUB_Context *ctx, | ||
354 | const struct sockaddr *sa, | ||
355 | socklen_t sa_len, | ||
356 | const void *request, | ||
357 | size_t request_len, | ||
358 | GNUNET_DNSSTUB_ResultCallback rc, | ||
359 | void *rc_cls) | ||
360 | { | ||
361 | struct GNUNET_DNSSTUB_RequestSocket *rs; | ||
362 | |||
363 | if (NULL == (rs = get_request_socket (ctx, | ||
364 | sa->sa_family))) | ||
365 | return NULL; | ||
366 | GNUNET_assert (NULL == rs->rc); | ||
367 | GNUNET_memcpy (&rs->addr, | ||
368 | sa, | ||
369 | sa_len); | ||
370 | rs->addrlen = sa_len; | ||
371 | rs->rc = rc; | ||
372 | rs->rc_cls = rc_cls; | ||
373 | rs->request = GNUNET_memdup (request, | ||
374 | request_len); | ||
375 | rs->request_len = request_len; | ||
376 | rs->retry_task = GNUNET_SCHEDULER_add_now (&transmit_query, | ||
377 | rs); | ||
378 | return rs; | ||
379 | } | ||
380 | |||
381 | |||
382 | /** | ||
383 | * Perform DNS resolution using our default IP from init. | ||
384 | * | ||
385 | * @param ctx stub resolver to use | ||
386 | * @param request DNS request to transmit | ||
387 | * @param request_len number of bytes in msg | ||
388 | * @param rc function to call with result | ||
389 | * @param rc_cls closure for 'rc' | ||
390 | * @return socket used for the request, NULL on error | ||
391 | */ | ||
392 | struct GNUNET_DNSSTUB_RequestSocket * | ||
393 | GNUNET_DNSSTUB_resolve2 (struct GNUNET_DNSSTUB_Context *ctx, | ||
394 | const void *request, | ||
395 | size_t request_len, | ||
396 | GNUNET_DNSSTUB_ResultCallback rc, | ||
397 | void *rc_cls) | ||
398 | { | ||
399 | int af; | ||
400 | struct sockaddr_in v4; | ||
401 | struct sockaddr_in6 v6; | ||
402 | struct sockaddr *sa; | ||
403 | socklen_t salen; | ||
404 | struct GNUNET_NETWORK_Handle *dnsout; | ||
405 | struct GNUNET_DNSSTUB_RequestSocket *rs; | ||
406 | |||
407 | memset (&v4, 0, sizeof (v4)); | ||
408 | memset (&v6, 0, sizeof (v6)); | ||
409 | if (1 == inet_pton (AF_INET, | ||
410 | ctx->dns_exit, | ||
411 | &v4.sin_addr)) | ||
412 | { | ||
413 | salen = sizeof (v4); | ||
414 | v4.sin_family = AF_INET; | ||
415 | v4.sin_port = htons (53); | ||
416 | #if HAVE_SOCKADDR_IN_SIN_LEN | ||
417 | v4.sin_len = (u_char) salen; | ||
418 | #endif | ||
419 | sa = (struct sockaddr *) &v4; | ||
420 | af = AF_INET; | ||
421 | } | ||
422 | else if (1 == inet_pton (AF_INET6, | ||
423 | ctx->dns_exit, | ||
424 | &v6.sin6_addr)) | ||
425 | { | ||
426 | salen = sizeof (v6); | ||
427 | v6.sin6_family = AF_INET6; | ||
428 | v6.sin6_port = htons (53); | ||
429 | #if HAVE_SOCKADDR_IN_SIN_LEN | ||
430 | v6.sin6_len = (u_char) salen; | ||
431 | #endif | ||
432 | sa = (struct sockaddr *) &v6; | ||
433 | af = AF_INET6; | ||
434 | } | ||
435 | else | ||
436 | { | ||
437 | GNUNET_break (0); | ||
438 | return NULL; | ||
439 | } | ||
440 | if (NULL == (rs = get_request_socket (ctx, | ||
441 | af))) | ||
442 | return NULL; | ||
443 | GNUNET_assert (NULL == rs->rc); | ||
444 | if (NULL != rs->dnsout4) | ||
445 | dnsout = rs->dnsout4; | ||
446 | else | ||
447 | dnsout = rs->dnsout6; | ||
448 | if (NULL == dnsout) | ||
449 | { | ||
450 | GNUNET_log (GNUNET_ERROR_TYPE_ERROR, | ||
451 | _("Configured DNS exit `%s' is not working / valid.\n"), | ||
452 | ctx->dns_exit); | ||
453 | return NULL; | ||
454 | } | ||
455 | GNUNET_memcpy (&rs->addr, | ||
456 | sa, | ||
457 | salen); | ||
458 | rs->addrlen = salen; | ||
459 | rs->rc = rc; | ||
460 | rs->rc_cls = rc_cls; | ||
461 | if (GNUNET_SYSERR == | ||
462 | GNUNET_NETWORK_socket_sendto (dnsout, | ||
463 | request, | ||
464 | request_len, | ||
465 | sa, | ||
466 | salen)) | ||
467 | GNUNET_log (GNUNET_ERROR_TYPE_WARNING, | ||
468 | _("Failed to send DNS request to %s\n"), | ||
469 | GNUNET_a2s (sa, salen)); | ||
470 | rs->timeout = GNUNET_TIME_relative_to_absolute (REQUEST_TIMEOUT); | ||
471 | return rs; | 285 | return rs; |
472 | } | 286 | } |
473 | 287 | ||
@@ -484,9 +298,7 @@ static int | |||
484 | do_dns_read (struct GNUNET_DNSSTUB_RequestSocket *rs, | 298 | do_dns_read (struct GNUNET_DNSSTUB_RequestSocket *rs, |
485 | struct GNUNET_NETWORK_Handle *dnsout) | 299 | struct GNUNET_NETWORK_Handle *dnsout) |
486 | { | 300 | { |
487 | struct sockaddr_storage addr; | 301 | struct GNUNET_DNSSTUB_Context *ctx = rs->ctx; |
488 | socklen_t addrlen; | ||
489 | struct GNUNET_TUN_DnsHeader *dns; | ||
490 | ssize_t r; | 302 | ssize_t r; |
491 | int len; | 303 | int len; |
492 | 304 | ||
@@ -507,9 +319,15 @@ do_dns_read (struct GNUNET_DNSSTUB_RequestSocket *rs, | |||
507 | len); | 319 | len); |
508 | { | 320 | { |
509 | unsigned char buf[len] GNUNET_ALIGN; | 321 | unsigned char buf[len] GNUNET_ALIGN; |
322 | int found; | ||
323 | struct sockaddr_storage addr; | ||
324 | socklen_t addrlen; | ||
325 | struct GNUNET_TUN_DnsHeader *dns; | ||
510 | 326 | ||
511 | addrlen = sizeof (addr); | 327 | addrlen = sizeof (addr); |
512 | memset (&addr, 0, sizeof (addr)); | 328 | memset (&addr, |
329 | 0, | ||
330 | sizeof (addr)); | ||
513 | r = GNUNET_NETWORK_socket_recvfrom (dnsout, | 331 | r = GNUNET_NETWORK_socket_recvfrom (dnsout, |
514 | buf, | 332 | buf, |
515 | sizeof (buf), | 333 | sizeof (buf), |
@@ -522,6 +340,24 @@ do_dns_read (struct GNUNET_DNSSTUB_RequestSocket *rs, | |||
522 | GNUNET_NETWORK_socket_close (dnsout); | 340 | GNUNET_NETWORK_socket_close (dnsout); |
523 | return GNUNET_SYSERR; | 341 | return GNUNET_SYSERR; |
524 | } | 342 | } |
343 | found = GNUNET_NO; | ||
344 | for (struct DnsServer *ds = ctx->dns_head; NULL != ds; ds = ds->next) | ||
345 | { | ||
346 | if (0 == memcmp (&addr, | ||
347 | &ds->ss, | ||
348 | GNUNET_MIN (sizeof (struct sockaddr_storage), | ||
349 | addrlen))) | ||
350 | { | ||
351 | found = GNUNET_YES; | ||
352 | break; | ||
353 | } | ||
354 | } | ||
355 | if (GNUNET_NO == found) | ||
356 | { | ||
357 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, | ||
358 | "Received DNS response from server we never asked (ignored)"); | ||
359 | return GNUNET_NO; | ||
360 | } | ||
525 | if (sizeof (struct GNUNET_TUN_DnsHeader) > r) | 361 | if (sizeof (struct GNUNET_TUN_DnsHeader) > r) |
526 | { | 362 | { |
527 | GNUNET_log (GNUNET_ERROR_TYPE_ERROR, | 363 | GNUNET_log (GNUNET_ERROR_TYPE_ERROR, |
@@ -530,22 +366,15 @@ do_dns_read (struct GNUNET_DNSSTUB_RequestSocket *rs, | |||
530 | return GNUNET_NO; | 366 | return GNUNET_NO; |
531 | } | 367 | } |
532 | dns = (struct GNUNET_TUN_DnsHeader *) buf; | 368 | dns = (struct GNUNET_TUN_DnsHeader *) buf; |
533 | if ( (addrlen != rs->addrlen) || | 369 | if (NULL == rs->rc) |
534 | (GNUNET_YES != | ||
535 | GNUNET_TUN_sockaddr_cmp ((struct sockaddr *) &rs->addr, | ||
536 | (struct sockaddr *) &addr, | ||
537 | GNUNET_YES)) || | ||
538 | (0 == GNUNET_TIME_absolute_get_remaining (rs->timeout).rel_value_us) ) | ||
539 | { | 370 | { |
540 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, | 371 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, |
541 | "Request timeout or invalid sender address; ignoring reply\n"); | 372 | "Request timeout or cancelled; ignoring reply\n"); |
542 | return GNUNET_NO; | 373 | return GNUNET_NO; |
543 | } | 374 | } |
544 | if (NULL != rs->rc) | 375 | rs->rc (rs->rc_cls, |
545 | rs->rc (rs->rc_cls, | 376 | dns, |
546 | rs, | 377 | r); |
547 | dns, | ||
548 | r); | ||
549 | } | 378 | } |
550 | return GNUNET_OK; | 379 | return GNUNET_OK; |
551 | } | 380 | } |
@@ -557,44 +386,21 @@ do_dns_read (struct GNUNET_DNSSTUB_RequestSocket *rs, | |||
557 | * @param cls socket to read from | 386 | * @param cls socket to read from |
558 | */ | 387 | */ |
559 | static void | 388 | static void |
560 | read_response (void *cls) | 389 | read_response (void *cls); |
390 | |||
391 | |||
392 | /** | ||
393 | * Schedule #read_response() task for @a rs. | ||
394 | * | ||
395 | * @param rs request to schedule read operation for | ||
396 | */ | ||
397 | static void | ||
398 | schedule_read (struct GNUNET_DNSSTUB_RequestSocket *rs) | ||
561 | { | 399 | { |
562 | struct GNUNET_DNSSTUB_RequestSocket *rs = cls; | ||
563 | struct GNUNET_NETWORK_FDSet *rset; | 400 | struct GNUNET_NETWORK_FDSet *rset; |
564 | const struct GNUNET_SCHEDULER_TaskContext *tc; | ||
565 | |||
566 | rs->read_task = NULL; | ||
567 | tc = GNUNET_SCHEDULER_get_task_context (); | ||
568 | if (0 == (tc->reason & GNUNET_SCHEDULER_REASON_READ_READY)) | ||
569 | { | ||
570 | /* signal "failure" (from timeout) */ | ||
571 | if (NULL != rs->rc) | ||
572 | { | ||
573 | rs->rc (rs->rc_cls, | ||
574 | rs, | ||
575 | NULL, | ||
576 | 0); | ||
577 | rs->rc = NULL; | ||
578 | } | ||
579 | /* timeout */ | ||
580 | cleanup_rs (rs); | ||
581 | return; | ||
582 | } | ||
583 | /* read and process ready sockets */ | ||
584 | if ((NULL != rs->dnsout4) && | ||
585 | (GNUNET_NETWORK_fdset_isset (tc->read_ready, | ||
586 | rs->dnsout4)) && | ||
587 | (GNUNET_SYSERR == do_dns_read (rs, | ||
588 | rs->dnsout4))) | ||
589 | rs->dnsout4 = NULL; | ||
590 | if ((NULL != rs->dnsout6) && | ||
591 | (GNUNET_NETWORK_fdset_isset (tc->read_ready, | ||
592 | rs->dnsout6)) && | ||
593 | (GNUNET_SYSERR == do_dns_read (rs, | ||
594 | rs->dnsout6))) | ||
595 | rs->dnsout6 = NULL; | ||
596 | 401 | ||
597 | /* re-schedule read task */ | 402 | if (NULL != rs->read_task) |
403 | GNUNET_SCHEDULER_cancel (rs->read_task); | ||
598 | rset = GNUNET_NETWORK_fdset_create (); | 404 | rset = GNUNET_NETWORK_fdset_create (); |
599 | if (NULL != rs->dnsout4) | 405 | if (NULL != rs->dnsout4) |
600 | GNUNET_NETWORK_fdset_set (rset, | 406 | GNUNET_NETWORK_fdset_set (rset, |
@@ -603,7 +409,7 @@ read_response (void *cls) | |||
603 | GNUNET_NETWORK_fdset_set (rset, | 409 | GNUNET_NETWORK_fdset_set (rset, |
604 | rs->dnsout6); | 410 | rs->dnsout6); |
605 | rs->read_task = GNUNET_SCHEDULER_add_select (GNUNET_SCHEDULER_PRIORITY_DEFAULT, | 411 | rs->read_task = GNUNET_SCHEDULER_add_select (GNUNET_SCHEDULER_PRIORITY_DEFAULT, |
606 | GNUNET_TIME_absolute_get_remaining (rs->timeout), | 412 | GNUNET_TIME_UNIT_FOREVER_REL, |
607 | rset, | 413 | rset, |
608 | NULL, | 414 | NULL, |
609 | &read_response, | 415 | &read_response, |
@@ -613,6 +419,151 @@ read_response (void *cls) | |||
613 | 419 | ||
614 | 420 | ||
615 | /** | 421 | /** |
422 | * Read a DNS response from the (unhindered) UDP-Socket | ||
423 | * | ||
424 | * @param cls `struct GNUNET_DNSSTUB_RequestSocket` to read from | ||
425 | */ | ||
426 | static void | ||
427 | read_response (void *cls) | ||
428 | { | ||
429 | struct GNUNET_DNSSTUB_RequestSocket *rs = cls; | ||
430 | const struct GNUNET_SCHEDULER_TaskContext *tc; | ||
431 | |||
432 | rs->read_task = NULL; | ||
433 | tc = GNUNET_SCHEDULER_get_task_context (); | ||
434 | /* read and process ready sockets */ | ||
435 | if ( (NULL != rs->dnsout4) && | ||
436 | (GNUNET_NETWORK_fdset_isset (tc->read_ready, | ||
437 | rs->dnsout4)) && | ||
438 | (GNUNET_SYSERR == | ||
439 | do_dns_read (rs, | ||
440 | rs->dnsout4)) ) | ||
441 | rs->dnsout4 = NULL; | ||
442 | if ( (NULL != rs->dnsout6) && | ||
443 | (GNUNET_NETWORK_fdset_isset (tc->read_ready, | ||
444 | rs->dnsout6)) && | ||
445 | (GNUNET_SYSERR == | ||
446 | do_dns_read (rs, | ||
447 | rs->dnsout6)) ) | ||
448 | rs->dnsout6 = NULL; | ||
449 | /* re-schedule read task */ | ||
450 | schedule_read (rs); | ||
451 | } | ||
452 | |||
453 | |||
454 | /** | ||
455 | * Task to (re)transmit the DNS query, possibly repeatedly until | ||
456 | * we succeed. | ||
457 | * | ||
458 | * @param cls our `struct GNUNET_DNSSTUB_RequestSocket *` | ||
459 | */ | ||
460 | static void | ||
461 | transmit_query (void *cls) | ||
462 | { | ||
463 | struct GNUNET_DNSSTUB_RequestSocket *rs = cls; | ||
464 | struct GNUNET_DNSSTUB_Context *ctx = rs->ctx; | ||
465 | const struct sockaddr *sa; | ||
466 | socklen_t salen; | ||
467 | struct DnsServer *ds; | ||
468 | struct GNUNET_NETWORK_Handle *dnsout; | ||
469 | |||
470 | rs->retry_task = GNUNET_SCHEDULER_add_delayed (ctx->retry_freq, | ||
471 | &transmit_query, | ||
472 | rs); | ||
473 | ds = rs->ds_pos; | ||
474 | rs->ds_pos = ds->next; | ||
475 | if (NULL == rs->ds_pos) | ||
476 | rs->ds_pos = ctx->dns_head; | ||
477 | GNUNET_assert (NULL != ds); | ||
478 | dnsout = NULL; | ||
479 | switch (ds->ss.ss_family) | ||
480 | { | ||
481 | case AF_INET: | ||
482 | if (NULL == rs->dnsout4) | ||
483 | rs->dnsout4 = open_socket (AF_INET); | ||
484 | dnsout = rs->dnsout4; | ||
485 | sa = (const struct sockaddr *) &ds->ss; | ||
486 | salen = sizeof (struct sockaddr_in); | ||
487 | break; | ||
488 | case AF_INET6: | ||
489 | if (NULL == rs->dnsout6) | ||
490 | rs->dnsout6 = open_socket (AF_INET6); | ||
491 | dnsout = rs->dnsout6; | ||
492 | sa = (const struct sockaddr *) &ds->ss; | ||
493 | salen = sizeof (struct sockaddr_in6); | ||
494 | break; | ||
495 | default: | ||
496 | return; | ||
497 | } | ||
498 | if (NULL == dnsout) | ||
499 | { | ||
500 | GNUNET_log (GNUNET_ERROR_TYPE_ERROR, | ||
501 | "Unable to use configure DNS server, skipping\n"); | ||
502 | return; | ||
503 | } | ||
504 | if (GNUNET_SYSERR == | ||
505 | GNUNET_NETWORK_socket_sendto (dnsout, | ||
506 | rs->request, | ||
507 | rs->request_len, | ||
508 | sa, | ||
509 | salen)) | ||
510 | GNUNET_log (GNUNET_ERROR_TYPE_WARNING, | ||
511 | _("Failed to send DNS request to %s\n"), | ||
512 | GNUNET_a2s (sa, | ||
513 | salen)); | ||
514 | else | ||
515 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, | ||
516 | _("Sent DNS request to %s\n"), | ||
517 | GNUNET_a2s (sa, | ||
518 | salen)); | ||
519 | schedule_read (rs); | ||
520 | } | ||
521 | |||
522 | |||
523 | /** | ||
524 | * Perform DNS resolution using our default IP from init. | ||
525 | * | ||
526 | * @param ctx stub resolver to use | ||
527 | * @param request DNS request to transmit | ||
528 | * @param request_len number of bytes in msg | ||
529 | * @param rc function to call with result | ||
530 | * @param rc_cls closure for 'rc' | ||
531 | * @return socket used for the request, NULL on error | ||
532 | */ | ||
533 | struct GNUNET_DNSSTUB_RequestSocket * | ||
534 | GNUNET_DNSSTUB_resolve (struct GNUNET_DNSSTUB_Context *ctx, | ||
535 | const void *request, | ||
536 | size_t request_len, | ||
537 | GNUNET_DNSSTUB_ResultCallback rc, | ||
538 | void *rc_cls) | ||
539 | { | ||
540 | struct GNUNET_DNSSTUB_RequestSocket *rs; | ||
541 | |||
542 | if (NULL == ctx->dns_head) | ||
543 | { | ||
544 | GNUNET_log (GNUNET_ERROR_TYPE_ERROR, | ||
545 | "No DNS server configured for resolution\n"); | ||
546 | return NULL; | ||
547 | } | ||
548 | if (NULL == (rs = get_request_socket (ctx))) | ||
549 | { | ||
550 | GNUNET_log (GNUNET_ERROR_TYPE_ERROR, | ||
551 | "No request socket available for DNS resolution\n"); | ||
552 | return NULL; | ||
553 | } | ||
554 | rs->ds_pos = ctx->dns_head; | ||
555 | rs->rc = rc; | ||
556 | rs->rc_cls = rc_cls; | ||
557 | rs->request = GNUNET_memdup (request, | ||
558 | request_len); | ||
559 | rs->request_len = request_len; | ||
560 | rs->retry_task = GNUNET_SCHEDULER_add_now (&transmit_query, | ||
561 | rs); | ||
562 | return rs; | ||
563 | } | ||
564 | |||
565 | |||
566 | /** | ||
616 | * Cancel DNS resolution. | 567 | * Cancel DNS resolution. |
617 | * | 568 | * |
618 | * @param rs resolution to cancel | 569 | * @param rs resolution to cancel |
@@ -626,28 +577,153 @@ GNUNET_DNSSTUB_resolve_cancel (struct GNUNET_DNSSTUB_RequestSocket *rs) | |||
626 | GNUNET_SCHEDULER_cancel (rs->retry_task); | 577 | GNUNET_SCHEDULER_cancel (rs->retry_task); |
627 | rs->retry_task = NULL; | 578 | rs->retry_task = NULL; |
628 | } | 579 | } |
580 | if (NULL != rs->read_task) | ||
581 | { | ||
582 | GNUNET_SCHEDULER_cancel (rs->read_task); | ||
583 | rs->read_task = NULL; | ||
584 | } | ||
629 | } | 585 | } |
630 | 586 | ||
631 | 587 | ||
632 | /** | 588 | /** |
633 | * Start a DNS stub resolver. | 589 | * Start a DNS stub resolver. |
634 | * | 590 | * |
635 | * @param dns_ip target IP address to use | 591 | * @param num_sockets how many sockets should we open |
592 | * in parallel for DNS queries for this stub? | ||
636 | * @return NULL on error | 593 | * @return NULL on error |
637 | */ | 594 | */ |
638 | struct GNUNET_DNSSTUB_Context * | 595 | struct GNUNET_DNSSTUB_Context * |
639 | GNUNET_DNSSTUB_start (const char *dns_ip) | 596 | GNUNET_DNSSTUB_start (unsigned int num_sockets) |
640 | { | 597 | { |
641 | struct GNUNET_DNSSTUB_Context *ctx; | 598 | struct GNUNET_DNSSTUB_Context *ctx; |
642 | 599 | ||
600 | if (0 == num_sockets) | ||
601 | { | ||
602 | GNUNET_break (0); | ||
603 | return NULL; | ||
604 | } | ||
643 | ctx = GNUNET_new (struct GNUNET_DNSSTUB_Context); | 605 | ctx = GNUNET_new (struct GNUNET_DNSSTUB_Context); |
644 | if (NULL != dns_ip) | 606 | ctx->num_sockets = num_sockets; |
645 | ctx->dns_exit = GNUNET_strdup (dns_ip); | 607 | ctx->sockets = GNUNET_new_array (num_sockets, |
608 | struct GNUNET_DNSSTUB_RequestSocket); | ||
609 | ctx->retry_freq = DNS_RETRANSMIT_DELAY; | ||
646 | return ctx; | 610 | return ctx; |
647 | } | 611 | } |
648 | 612 | ||
649 | 613 | ||
650 | /** | 614 | /** |
615 | * Add nameserver for use by the DNSSTUB. We will use | ||
616 | * all provided nameservers for resolution (round-robin). | ||
617 | * | ||
618 | * @param ctx resolver context to modify | ||
619 | * @param dns_ip target IP address to use (as string) | ||
620 | * @return #GNUNET_OK on success | ||
621 | */ | ||
622 | int | ||
623 | GNUNET_DNSSTUB_add_dns_ip (struct GNUNET_DNSSTUB_Context *ctx, | ||
624 | const char *dns_ip) | ||
625 | { | ||
626 | struct DnsServer *ds; | ||
627 | struct in_addr i4; | ||
628 | struct in6_addr i6; | ||
629 | |||
630 | ds = GNUNET_new (struct DnsServer); | ||
631 | if (1 == inet_pton (AF_INET, | ||
632 | dns_ip, | ||
633 | &i4)) | ||
634 | { | ||
635 | struct sockaddr_in *s4 = (struct sockaddr_in *) &ds->ss; | ||
636 | |||
637 | s4->sin_family = AF_INET; | ||
638 | s4->sin_port = htons (53); | ||
639 | s4->sin_addr = i4; | ||
640 | #if HAVE_SOCKADDR_IN_SIN_LEN | ||
641 | s4->sin_len = (u_char) sizeof (struct sockaddr_in); | ||
642 | #endif | ||
643 | } | ||
644 | else if (1 == inet_pton (AF_INET6, | ||
645 | dns_ip, | ||
646 | &i6)) | ||
647 | { | ||
648 | struct sockaddr_in6 *s6 = (struct sockaddr_in6 *) &ds->ss; | ||
649 | |||
650 | s6->sin6_family = AF_INET6; | ||
651 | s6->sin6_port = htons (53); | ||
652 | s6->sin6_addr = i6; | ||
653 | #if HAVE_SOCKADDR_IN_SIN_LEN | ||
654 | s6->sin6_len = (u_char) sizeof (struct sockaddr_in6); | ||
655 | #endif | ||
656 | } | ||
657 | else | ||
658 | { | ||
659 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, | ||
660 | "Malformed IP address `%s' for DNS server\n", | ||
661 | dns_ip); | ||
662 | GNUNET_free (ds); | ||
663 | return GNUNET_SYSERR; | ||
664 | } | ||
665 | GNUNET_CONTAINER_DLL_insert (ctx->dns_head, | ||
666 | ctx->dns_tail, | ||
667 | ds); | ||
668 | return GNUNET_OK; | ||
669 | } | ||
670 | |||
671 | |||
672 | /** | ||
673 | * Add nameserver for use by the DNSSTUB. We will use | ||
674 | * all provided nameservers for resolution (round-robin). | ||
675 | * | ||
676 | * @param ctx resolver context to modify | ||
677 | * @param sa socket address of DNS resolver to use | ||
678 | * @return #GNUNET_OK on success | ||
679 | */ | ||
680 | int | ||
681 | GNUNET_DNSSTUB_add_dns_sa (struct GNUNET_DNSSTUB_Context *ctx, | ||
682 | const struct sockaddr *sa) | ||
683 | { | ||
684 | struct DnsServer *ds; | ||
685 | |||
686 | ds = GNUNET_new (struct DnsServer); | ||
687 | switch (sa->sa_family) | ||
688 | { | ||
689 | case AF_INET: | ||
690 | memcpy (&ds->ss, | ||
691 | sa, | ||
692 | sizeof (struct sockaddr_in)); | ||
693 | break; | ||
694 | case AF_INET6: | ||
695 | memcpy (&ds->ss, | ||
696 | sa, | ||
697 | sizeof (struct sockaddr_in6)); | ||
698 | break; | ||
699 | default: | ||
700 | GNUNET_break (0); | ||
701 | GNUNET_free (ds); | ||
702 | return GNUNET_SYSERR; | ||
703 | } | ||
704 | GNUNET_CONTAINER_DLL_insert (ctx->dns_head, | ||
705 | ctx->dns_tail, | ||
706 | ds); | ||
707 | return GNUNET_OK; | ||
708 | } | ||
709 | |||
710 | |||
711 | /** | ||
712 | * How long should we try requests before timing out? | ||
713 | * Only effective for requests issued after this call. | ||
714 | * | ||
715 | * @param ctx resolver context to modify | ||
716 | * @param retry_freq how long to wait between retries | ||
717 | */ | ||
718 | void | ||
719 | GNUNET_DNSSTUB_set_retry (struct GNUNET_DNSSTUB_Context *ctx, | ||
720 | struct GNUNET_TIME_Relative retry_freq) | ||
721 | { | ||
722 | ctx->retry_freq = retry_freq; | ||
723 | } | ||
724 | |||
725 | |||
726 | /** | ||
651 | * Cleanup DNSSTUB resolver. | 727 | * Cleanup DNSSTUB resolver. |
652 | * | 728 | * |
653 | * @param ctx stub resolver to clean up | 729 | * @param ctx stub resolver to clean up |
@@ -655,15 +731,18 @@ GNUNET_DNSSTUB_start (const char *dns_ip) | |||
655 | void | 731 | void |
656 | GNUNET_DNSSTUB_stop (struct GNUNET_DNSSTUB_Context *ctx) | 732 | GNUNET_DNSSTUB_stop (struct GNUNET_DNSSTUB_Context *ctx) |
657 | { | 733 | { |
658 | unsigned int i; | 734 | struct DnsServer *ds; |
659 | 735 | ||
660 | for (i=0;i<DNS_SOCKET_MAX;i++) | 736 | while (NULL != (ds = ctx->dns_head)) |
661 | cleanup_rs (&ctx->sockets[i]); | ||
662 | if (NULL != ctx->dns_exit) | ||
663 | { | 737 | { |
664 | GNUNET_free (ctx->dns_exit); | 738 | GNUNET_CONTAINER_DLL_remove (ctx->dns_head, |
665 | ctx->dns_exit = NULL; | 739 | ctx->dns_tail, |
740 | ds); | ||
741 | GNUNET_free (ds); | ||
666 | } | 742 | } |
743 | for (unsigned int i=0;i<ctx->num_sockets;i++) | ||
744 | cleanup_rs (&ctx->sockets[i]); | ||
745 | GNUNET_free (ctx->sockets); | ||
667 | GNUNET_free (ctx); | 746 | GNUNET_free (ctx); |
668 | } | 747 | } |
669 | 748 | ||
diff --git a/src/dns/gnunet-service-dns.c b/src/dns/gnunet-service-dns.c index 9feaa8413..39ce7f6e5 100644 --- a/src/dns/gnunet-service-dns.c +++ b/src/dns/gnunet-service-dns.c | |||
@@ -508,13 +508,11 @@ send_request_to_client (struct RequestRecord *rr, | |||
508 | * succeeded. | 508 | * succeeded. |
509 | * | 509 | * |
510 | * @param cls NULL | 510 | * @param cls NULL |
511 | * @param rs the socket that received the response | ||
512 | * @param dns the response itself | 511 | * @param dns the response itself |
513 | * @param r number of bytes in dns | 512 | * @param r number of bytes in dns |
514 | */ | 513 | */ |
515 | static void | 514 | static void |
516 | process_dns_result (void *cls, | 515 | process_dns_result (void *cls, |
517 | struct GNUNET_DNSSTUB_RequestSocket *rs, | ||
518 | const struct GNUNET_TUN_DnsHeader *dns, | 516 | const struct GNUNET_TUN_DnsHeader *dns, |
519 | size_t r); | 517 | size_t r); |
520 | 518 | ||
@@ -530,7 +528,6 @@ next_phase (struct RequestRecord *rr) | |||
530 | { | 528 | { |
531 | struct ClientRecord *cr; | 529 | struct ClientRecord *cr; |
532 | int nz; | 530 | int nz; |
533 | socklen_t salen; | ||
534 | 531 | ||
535 | if (rr->phase == RP_DROP) | 532 | if (rr->phase == RP_DROP) |
536 | { | 533 | { |
@@ -582,22 +579,27 @@ next_phase (struct RequestRecord *rr) | |||
582 | next_phase (rr); | 579 | next_phase (rr); |
583 | return; | 580 | return; |
584 | case RP_QUERY: | 581 | case RP_QUERY: |
582 | #if 0 | ||
583 | /* TODO: optionally, use this to forward DNS requests to the | ||
584 | *original* DNS server instead of the one we have configured... | ||
585 | (but then we need to create a fresh dnsstub for each request | ||
586 | *and* manage the timeout) */ | ||
585 | switch (rr->dst_addr.ss_family) | 587 | switch (rr->dst_addr.ss_family) |
586 | { | 588 | { |
587 | case AF_INET: | 589 | case AF_INET: |
588 | salen = sizeof (struct sockaddr_in); | 590 | salen = sizeof (struct sockaddr_in); |
591 | sa = (const struct sockaddr *) &rr->dst_addr; | ||
589 | break; | 592 | break; |
590 | case AF_INET6: | 593 | case AF_INET6: |
591 | salen = sizeof (struct sockaddr_in6); | 594 | salen = sizeof (struct sockaddr_in6); |
595 | sa = (const struct sockaddr *) &rr->dst_addr; | ||
592 | break; | 596 | break; |
593 | default: | 597 | default: |
594 | GNUNET_assert (0); | 598 | GNUNET_assert (0); |
595 | } | 599 | } |
596 | 600 | #endif | |
597 | rr->phase = RP_INTERNET_DNS; | 601 | rr->phase = RP_INTERNET_DNS; |
598 | rr->rs = GNUNET_DNSSTUB_resolve (dnsstub, | 602 | rr->rs = GNUNET_DNSSTUB_resolve (dnsstub, |
599 | (struct sockaddr*) &rr->dst_addr, | ||
600 | salen, | ||
601 | rr->payload, | 603 | rr->payload, |
602 | rr->payload_length, | 604 | rr->payload_length, |
603 | &process_dns_result, | 605 | &process_dns_result, |
@@ -714,13 +716,11 @@ client_disconnect_cb (void *cls, | |||
714 | * succeeded. | 716 | * succeeded. |
715 | * | 717 | * |
716 | * @param cls NULL | 718 | * @param cls NULL |
717 | * @param rs the socket that received the response | ||
718 | * @param dns the response itself | 719 | * @param dns the response itself |
719 | * @param r number of bytes in dns | 720 | * @param r number of bytes in dns |
720 | */ | 721 | */ |
721 | static void | 722 | static void |
722 | process_dns_result (void *cls, | 723 | process_dns_result (void *cls, |
723 | struct GNUNET_DNSSTUB_RequestSocket *rs, | ||
724 | const struct GNUNET_TUN_DnsHeader *dns, | 724 | const struct GNUNET_TUN_DnsHeader *dns, |
725 | size_t r) | 725 | size_t r) |
726 | { | 726 | { |
@@ -733,8 +733,7 @@ process_dns_result (void *cls, | |||
733 | return; /* ignore */ | 733 | return; /* ignore */ |
734 | 734 | ||
735 | rr = &requests[dns->id]; | 735 | rr = &requests[dns->id]; |
736 | if ( (rr->phase != RP_INTERNET_DNS) || | 736 | if (rr->phase != RP_INTERNET_DNS) |
737 | (rr->rs != rs) ) | ||
738 | { | 737 | { |
739 | /* unexpected / bogus reply */ | 738 | /* unexpected / bogus reply */ |
740 | GNUNET_STATISTICS_update (stats, | 739 | GNUNET_STATISTICS_update (stats, |
@@ -1055,8 +1054,6 @@ run (void *cls, | |||
1055 | char *ipv4mask; | 1054 | char *ipv4mask; |
1056 | char *ipv6addr; | 1055 | char *ipv6addr; |
1057 | char *ipv6prefix; | 1056 | char *ipv6prefix; |
1058 | struct in_addr dns_exit4; | ||
1059 | struct in6_addr dns_exit6; | ||
1060 | char *dns_exit; | 1057 | char *dns_exit; |
1061 | char *binary; | 1058 | char *binary; |
1062 | int nortsetup; | 1059 | int nortsetup; |
@@ -1065,24 +1062,26 @@ run (void *cls, | |||
1065 | stats = GNUNET_STATISTICS_create ("dns", cfg); | 1062 | stats = GNUNET_STATISTICS_create ("dns", cfg); |
1066 | GNUNET_SCHEDULER_add_shutdown (&cleanup_task, | 1063 | GNUNET_SCHEDULER_add_shutdown (&cleanup_task, |
1067 | cls); | 1064 | cls); |
1065 | dnsstub = GNUNET_DNSSTUB_start (128); | ||
1066 | /* TODO: support multiple DNS_EXIT servers being configured */ | ||
1067 | /* TODO: see above TODO on using DNS server from original packet. | ||
1068 | Not sure which is best... */ | ||
1068 | dns_exit = NULL; | 1069 | dns_exit = NULL; |
1069 | if ( ( (GNUNET_OK != | 1070 | if ( (GNUNET_OK != |
1070 | GNUNET_CONFIGURATION_get_value_string (cfg, | 1071 | GNUNET_CONFIGURATION_get_value_string (cfg, |
1071 | "dns", | 1072 | "dns", |
1072 | "DNS_EXIT", | 1073 | "DNS_EXIT", |
1073 | &dns_exit)) || | 1074 | &dns_exit)) || |
1074 | ( (1 != inet_pton (AF_INET, dns_exit, &dns_exit4)) && | 1075 | (GNUNET_OK != |
1075 | (1 != inet_pton (AF_INET6, dns_exit, &dns_exit6)) ) ) ) | 1076 | GNUNET_DNSSTUB_add_dns_ip (dnsstub, |
1077 | dns_exit)) ) | ||
1076 | { | 1078 | { |
1077 | GNUNET_log_config_invalid (GNUNET_ERROR_TYPE_ERROR, | 1079 | GNUNET_log_config_invalid (GNUNET_ERROR_TYPE_ERROR, |
1078 | "dns", | 1080 | "dns", |
1079 | "DNS_EXIT", | 1081 | "DNS_EXIT", |
1080 | _("need a valid IPv4 or IPv6 address\n")); | 1082 | _("need a valid IPv4 or IPv6 address\n")); |
1081 | GNUNET_free_non_null (dns_exit); | 1083 | GNUNET_free_non_null (dns_exit); |
1082 | dns_exit = NULL; | ||
1083 | } | 1084 | } |
1084 | dnsstub = GNUNET_DNSSTUB_start (dns_exit); | ||
1085 | GNUNET_free_non_null (dns_exit); | ||
1086 | binary = GNUNET_OS_get_libexec_binary_path ("gnunet-helper-dns"); | 1085 | binary = GNUNET_OS_get_libexec_binary_path ("gnunet-helper-dns"); |
1087 | if (GNUNET_YES != | 1086 | if (GNUNET_YES != |
1088 | GNUNET_OS_check_helper_binary (binary, | 1087 | GNUNET_OS_check_helper_binary (binary, |
diff --git a/src/dns/gnunet-zoneimport.c b/src/dns/gnunet-zoneimport.c index 914868af4..860672e7a 100644 --- a/src/dns/gnunet-zoneimport.c +++ b/src/dns/gnunet-zoneimport.c | |||
@@ -290,13 +290,11 @@ process_record (struct Request *req, | |||
290 | * Function called with the result of a DNS resolution. | 290 | * Function called with the result of a DNS resolution. |
291 | * | 291 | * |
292 | * @param cls closure with the `struct Request` | 292 | * @param cls closure with the `struct Request` |
293 | * @param rs socket that received the response | ||
294 | * @param dns dns response, never NULL | 293 | * @param dns dns response, never NULL |
295 | * @param dns_len number of bytes in @a dns | 294 | * @param dns_len number of bytes in @a dns |
296 | */ | 295 | */ |
297 | static void | 296 | static void |
298 | process_result (void *cls, | 297 | process_result (void *cls, |
299 | struct GNUNET_DNSSTUB_RequestSocket *rs, | ||
300 | const struct GNUNET_TUN_DnsHeader *dns, | 298 | const struct GNUNET_TUN_DnsHeader *dns, |
301 | size_t dns_len) | 299 | size_t dns_len) |
302 | { | 300 | { |
@@ -407,11 +405,11 @@ submit_req (struct Request *req) | |||
407 | (pending >= THRESH) ) | 405 | (pending >= THRESH) ) |
408 | return GNUNET_SYSERR; | 406 | return GNUNET_SYSERR; |
409 | GNUNET_assert (NULL == req->rs); | 407 | GNUNET_assert (NULL == req->rs); |
410 | req->rs = GNUNET_DNSSTUB_resolve2 (ctx, | 408 | req->rs = GNUNET_DNSSTUB_resolve (ctx, |
411 | req->raw, | 409 | req->raw, |
412 | req->raw_len, | 410 | req->raw_len, |
413 | &process_result, | 411 | &process_result, |
414 | req); | 412 | req); |
415 | GNUNET_assert (NULL != req->rs); | 413 | GNUNET_assert (NULL != req->rs); |
416 | req->issue_num++; | 414 | req->issue_num++; |
417 | last_request = now; | 415 | last_request = now; |
@@ -561,13 +559,23 @@ main (int argc, | |||
561 | "Missing required configuration argument\n"); | 559 | "Missing required configuration argument\n"); |
562 | return -1; | 560 | return -1; |
563 | } | 561 | } |
564 | ctx = GNUNET_DNSSTUB_start (argv[1]); | 562 | ctx = GNUNET_DNSSTUB_start (256); |
565 | if (NULL == ctx) | 563 | if (NULL == ctx) |
566 | { | 564 | { |
567 | fprintf (stderr, | 565 | fprintf (stderr, |
568 | "Failed to initialize GNUnet DNS STUB\n"); | 566 | "Failed to initialize GNUnet DNS STUB\n"); |
569 | return 1; | 567 | return 1; |
570 | } | 568 | } |
569 | if (GNUNET_OK != | ||
570 | GNUNET_DNSSTUB_add_dns_ip (ctx, | ||
571 | argv[1])) | ||
572 | { | ||
573 | fprintf (stderr, | ||
574 | "Failed to use `%s' for DNS resolver\n", | ||
575 | argv[1]); | ||
576 | return 1; | ||
577 | } | ||
578 | |||
571 | while (NULL != | 579 | while (NULL != |
572 | fgets (hn, | 580 | fgets (hn, |
573 | sizeof (hn), | 581 | sizeof (hn), |