aboutsummaryrefslogtreecommitdiff
path: root/src/util/resolver_api.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/util/resolver_api.c')
-rw-r--r--src/util/resolver_api.c602
1 files changed, 302 insertions, 300 deletions
diff --git a/src/util/resolver_api.c b/src/util/resolver_api.c
index 913769ae1..3bdc40143 100644
--- a/src/util/resolver_api.c
+++ b/src/util/resolver_api.c
@@ -35,6 +35,8 @@
35 35
36#define LOG(kind,...) GNUNET_log_from (kind, "resolver-api", __VA_ARGS__) 36#define LOG(kind,...) GNUNET_log_from (kind, "resolver-api", __VA_ARGS__)
37 37
38#define LOG_STRERROR(kind,syscall) GNUNET_log_from_strerror (kind, "resolver-api", syscall)
39
38/** 40/**
39 * Maximum supported length for a hostname 41 * Maximum supported length for a hostname
40 */ 42 */
@@ -194,26 +196,26 @@ check_config ()
194#endif 196#endif
195 if (GNUNET_OK != 197 if (GNUNET_OK !=
196 GNUNET_CONFIGURATION_get_value_string (resolver_cfg, "resolver", 198 GNUNET_CONFIGURATION_get_value_string (resolver_cfg, "resolver",
197 "HOSTNAME", &hostname)) 199 "HOSTNAME", &hostname))
198 { 200 {
199 LOG (GNUNET_ERROR_TYPE_ERROR, 201 LOG (GNUNET_ERROR_TYPE_ERROR,
200 _("Must specify `%s' for `%s' in configuration!\n"), "HOSTNAME", 202 _("Must specify `%s' for `%s' in configuration!\n"), "HOSTNAME",
201 "resolver"); 203 "resolver");
202 GNUNET_assert (0); 204 GNUNET_assert (0);
203 } 205 }
204 if ((1 != inet_pton (AF_INET, hostname, &v4)) || 206 if ((1 != inet_pton (AF_INET, hostname, &v4)) ||
205 (1 != inet_pton (AF_INET6, hostname, &v6))) 207 (1 != inet_pton (AF_INET6, hostname, &v6)))
206 {
207 GNUNET_free (hostname);
208 return;
209 }
210 i = 0;
211 while (loopback[i] != NULL)
212 if (0 == strcasecmp (loopback[i++], hostname))
213 { 208 {
214 GNUNET_free (hostname); 209 GNUNET_free (hostname);
215 return; 210 return;
216 } 211 }
212 i = 0;
213 while (loopback[i] != NULL)
214 if (0 == strcasecmp (loopback[i++], hostname))
215 {
216 GNUNET_free (hostname);
217 return;
218 }
217 LOG (GNUNET_ERROR_TYPE_ERROR, 219 LOG (GNUNET_ERROR_TYPE_ERROR,
218 _ 220 _
219 ("Must specify `%s' or numeric IP address for `%s' of `%s' in configuration!\n"), 221 ("Must specify `%s' or numeric IP address for `%s' of `%s' in configuration!\n"),
@@ -247,23 +249,23 @@ GNUNET_RESOLVER_disconnect ()
247 GNUNET_assert (NULL == req_head); 249 GNUNET_assert (NULL == req_head);
248 GNUNET_assert (NULL == req_tail); 250 GNUNET_assert (NULL == req_tail);
249 if (NULL != client) 251 if (NULL != client)
250 { 252 {
251#if DEBUG_RESOLVER 253#if DEBUG_RESOLVER
252 LOG (GNUNET_ERROR_TYPE_DEBUG, "Disconnecting from DNS service\n"); 254 LOG (GNUNET_ERROR_TYPE_DEBUG, "Disconnecting from DNS service\n");
253#endif 255#endif
254 GNUNET_CLIENT_disconnect (client, GNUNET_NO); 256 GNUNET_CLIENT_disconnect (client, GNUNET_NO);
255 client = NULL; 257 client = NULL;
256 } 258 }
257 if (r_task != GNUNET_SCHEDULER_NO_TASK) 259 if (r_task != GNUNET_SCHEDULER_NO_TASK)
258 { 260 {
259 GNUNET_SCHEDULER_cancel (r_task); 261 GNUNET_SCHEDULER_cancel (r_task);
260 r_task = GNUNET_SCHEDULER_NO_TASK; 262 r_task = GNUNET_SCHEDULER_NO_TASK;
261 } 263 }
262 if (s_task != GNUNET_SCHEDULER_NO_TASK) 264 if (s_task != GNUNET_SCHEDULER_NO_TASK)
263 { 265 {
264 GNUNET_SCHEDULER_cancel (s_task); 266 GNUNET_SCHEDULER_cancel (s_task);
265 s_task = GNUNET_SCHEDULER_NO_TASK; 267 s_task = GNUNET_SCHEDULER_NO_TASK;
266 } 268 }
267} 269}
268 270
269 271
@@ -284,37 +286,35 @@ no_resolve (const struct sockaddr *sa, socklen_t salen)
284 if (salen < sizeof (struct sockaddr)) 286 if (salen < sizeof (struct sockaddr))
285 return NULL; 287 return NULL;
286 switch (sa->sa_family) 288 switch (sa->sa_family)
287 {
288 case AF_INET:
289 if (salen != sizeof (struct sockaddr_in))
290 return NULL;
291 if (NULL ==
292 inet_ntop (AF_INET, &((struct sockaddr_in *) sa)->sin_addr, inet4,
293 INET_ADDRSTRLEN))
294 { 289 {
295 GNUNET_log_from_strerror (GNUNET_ERROR_TYPE_WARNING, "resolver-api", 290 case AF_INET:
296 "inet_ntop"); 291 if (salen != sizeof (struct sockaddr_in))
297 return NULL; 292 return NULL;
298 } 293 if (NULL ==
299 ret = GNUNET_strdup (inet4); 294 inet_ntop (AF_INET, &((struct sockaddr_in *) sa)->sin_addr, inet4,
300 break; 295 INET_ADDRSTRLEN))
301 case AF_INET6: 296 {
302 if (salen != sizeof (struct sockaddr_in6)) 297 LOG_STRERROR (GNUNET_ERROR_TYPE_WARNING, "inet_ntop");
303 return NULL; 298 return NULL;
304 if (NULL == 299 }
305 inet_ntop (AF_INET6, &((struct sockaddr_in6 *) sa)->sin6_addr, inet6, 300 ret = GNUNET_strdup (inet4);
306 INET6_ADDRSTRLEN)) 301 break;
307 { 302 case AF_INET6:
308 GNUNET_log_from_strerror (GNUNET_ERROR_TYPE_WARNING, "resolver-api", 303 if (salen != sizeof (struct sockaddr_in6))
309 "inet_ntop"); 304 return NULL;
310 return NULL; 305 if (NULL ==
306 inet_ntop (AF_INET6, &((struct sockaddr_in6 *) sa)->sin6_addr,
307 inet6, INET6_ADDRSTRLEN))
308 {
309 LOG_STRERROR (GNUNET_ERROR_TYPE_WARNING, "inet_ntop");
310 return NULL;
311 }
312 ret = GNUNET_strdup (inet6);
313 break;
314 default:
315 ret = NULL;
316 break;
311 } 317 }
312 ret = GNUNET_strdup (inet6);
313 break;
314 default:
315 ret = NULL;
316 break;
317 }
318 return ret; 318 return ret;
319} 319}
320 320
@@ -322,15 +322,13 @@ no_resolve (const struct sockaddr *sa, socklen_t salen)
322/** 322/**
323 * Adjust exponential back-off and reconnect to the service. 323 * Adjust exponential back-off and reconnect to the service.
324 */ 324 */
325static void 325static void reconnect ();
326reconnect ();
327 326
328 327
329/** 328/**
330 * Process pending requests to the resolver. 329 * Process pending requests to the resolver.
331 */ 330 */
332static void 331static void process_requests ();
333process_requests ();
334 332
335 333
336/** 334/**
@@ -352,73 +350,32 @@ handle_response (void *cls, const struct GNUNET_MessageHeader *msg)
352 LOG (GNUNET_ERROR_TYPE_DEBUG, "Receiving response from DNS service\n"); 350 LOG (GNUNET_ERROR_TYPE_DEBUG, "Receiving response from DNS service\n");
353#endif 351#endif
354 if (msg == NULL) 352 if (msg == NULL)
355 {
356 if (NULL != rh->name_callback)
357 LOG (GNUNET_ERROR_TYPE_INFO,
358 _("Timeout trying to resolve IP address `%s'.\n"),
359 GNUNET_a2s ((const void *) &rh[1], rh->data_len));
360 else
361 LOG (GNUNET_ERROR_TYPE_INFO,
362 _("Timeout trying to resolve hostname `%s'.\n"),
363 (const char *) &rh[1]);
364 /* check if request was canceled */
365 if (rh->was_transmitted != GNUNET_SYSERR)
366 {
367 if (NULL != rh->name_callback)
368 {
369 /* no reverse lookup was successful, return ip as string */
370 if (rh->received_response == GNUNET_NO)
371 rh->name_callback (rh->cls,
372 no_resolve ((const struct sockaddr *) &rh[1],
373 rh->data_len));
374 /* at least one reverse lookup was successful */
375 else
376 rh->name_callback (rh->cls, NULL);
377 }
378 if (NULL != rh->addr_callback)
379 rh->addr_callback (rh->cls, NULL, 0);
380 }
381 GNUNET_CONTAINER_DLL_remove (req_head, req_tail, rh);
382 GNUNET_free (rh);
383 GNUNET_CLIENT_disconnect (client, GNUNET_NO);
384 client = NULL;
385 reconnect ();
386 return;
387 }
388 if (GNUNET_MESSAGE_TYPE_RESOLVER_RESPONSE != ntohs (msg->type))
389 {
390 GNUNET_break (0);
391 GNUNET_CLIENT_disconnect (client, GNUNET_NO);
392 client = NULL;
393 reconnect ();
394 return;
395 }
396 size = ntohs (msg->size);
397 /* message contains not data, just header */
398 if (size == sizeof (struct GNUNET_MessageHeader))
399 {
400 /* check if request was canceled */
401 if (rh->was_transmitted != GNUNET_SYSERR)
402 { 353 {
403 if (NULL != rh->name_callback) 354 if (NULL != rh->name_callback)
404 rh->name_callback (rh->cls, NULL); 355 LOG (GNUNET_ERROR_TYPE_INFO,
405 if (NULL != rh->addr_callback) 356 _("Timeout trying to resolve IP address `%s'.\n"),
406 rh->addr_callback (rh->cls, NULL, 0); 357 GNUNET_a2s ((const void *) &rh[1], rh->data_len));
407 } 358 else
408 GNUNET_CONTAINER_DLL_remove (req_head, req_tail, rh); 359 LOG (GNUNET_ERROR_TYPE_INFO,
409 GNUNET_free (rh); 360 _("Timeout trying to resolve hostname `%s'.\n"),
410 process_requests (); 361 (const char *) &rh[1]);
411 return; 362 /* check if request was canceled */
412 }
413 /* return reverse lookup results to caller */
414 if (NULL != rh->name_callback)
415 {
416 hostname = (const char *) &msg[1];
417 if (hostname[size - sizeof (struct GNUNET_MessageHeader) - 1] != '\0')
418 {
419 GNUNET_break (0);
420 if (rh->was_transmitted != GNUNET_SYSERR) 363 if (rh->was_transmitted != GNUNET_SYSERR)
421 rh->name_callback (rh->cls, NULL); 364 {
365 if (NULL != rh->name_callback)
366 {
367 /* no reverse lookup was successful, return ip as string */
368 if (rh->received_response == GNUNET_NO)
369 rh->name_callback (rh->cls,
370 no_resolve ((const struct sockaddr *)
371 &rh[1], rh->data_len));
372 /* at least one reverse lookup was successful */
373 else
374 rh->name_callback (rh->cls, NULL);
375 }
376 if (NULL != rh->addr_callback)
377 rh->addr_callback (rh->cls, NULL, 0);
378 }
422 GNUNET_CONTAINER_DLL_remove (req_head, req_tail, rh); 379 GNUNET_CONTAINER_DLL_remove (req_head, req_tail, rh);
423 GNUNET_free (rh); 380 GNUNET_free (rh);
424 GNUNET_CLIENT_disconnect (client, GNUNET_NO); 381 GNUNET_CLIENT_disconnect (client, GNUNET_NO);
@@ -426,46 +383,89 @@ handle_response (void *cls, const struct GNUNET_MessageHeader *msg)
426 reconnect (); 383 reconnect ();
427 return; 384 return;
428 } 385 }
429#if DEBUG_RESOLVER 386 if (GNUNET_MESSAGE_TYPE_RESOLVER_RESPONSE != ntohs (msg->type))
430 LOG (GNUNET_ERROR_TYPE_DEBUG, _("Resolver returns `%s' for IP `%s'.\n"),
431 hostname, GNUNET_a2s ((const void *) &rh[1], rh->data_len));
432#endif
433 if (rh->was_transmitted != GNUNET_SYSERR)
434 rh->name_callback (rh->cls, hostname);
435 rh->received_response = GNUNET_YES;
436 GNUNET_CLIENT_receive (client, &handle_response, rh,
437 GNUNET_TIME_absolute_get_remaining (rh->timeout));
438 }
439 /* return lookup results to caller */
440 if (NULL != rh->addr_callback)
441 {
442 sa = (const struct sockaddr *) &msg[1];
443 salen = size - sizeof (struct GNUNET_MessageHeader);
444 if (salen < sizeof (struct sockaddr))
445 { 387 {
446 GNUNET_break (0); 388 GNUNET_break (0);
447 if (rh->was_transmitted != GNUNET_SYSERR)
448 rh->addr_callback (rh->cls, NULL, 0);
449 GNUNET_CONTAINER_DLL_remove (req_head, req_tail, rh);
450 GNUNET_free (rh);
451 GNUNET_CLIENT_disconnect (client, GNUNET_NO); 389 GNUNET_CLIENT_disconnect (client, GNUNET_NO);
452 client = NULL; 390 client = NULL;
453 reconnect (); 391 reconnect ();
454 return; 392 return;
455 } 393 }
394 size = ntohs (msg->size);
395 /* message contains not data, just header */
396 if (size == sizeof (struct GNUNET_MessageHeader))
397 {
398 /* check if request was canceled */
399 if (rh->was_transmitted != GNUNET_SYSERR)
400 {
401 if (NULL != rh->name_callback)
402 rh->name_callback (rh->cls, NULL);
403 if (NULL != rh->addr_callback)
404 rh->addr_callback (rh->cls, NULL, 0);
405 }
406 GNUNET_CONTAINER_DLL_remove (req_head, req_tail, rh);
407 GNUNET_free (rh);
408 process_requests ();
409 return;
410 }
411 /* return reverse lookup results to caller */
412 if (NULL != rh->name_callback)
413 {
414 hostname = (const char *) &msg[1];
415 if (hostname[size - sizeof (struct GNUNET_MessageHeader) - 1] != '\0')
416 {
417 GNUNET_break (0);
418 if (rh->was_transmitted != GNUNET_SYSERR)
419 rh->name_callback (rh->cls, NULL);
420 GNUNET_CONTAINER_DLL_remove (req_head, req_tail, rh);
421 GNUNET_free (rh);
422 GNUNET_CLIENT_disconnect (client, GNUNET_NO);
423 client = NULL;
424 reconnect ();
425 return;
426 }
456#if DEBUG_RESOLVER 427#if DEBUG_RESOLVER
428 LOG (GNUNET_ERROR_TYPE_DEBUG, _("Resolver returns `%s' for IP `%s'.\n"),
429 hostname, GNUNET_a2s ((const void *) &rh[1], rh->data_len));
430#endif
431 if (rh->was_transmitted != GNUNET_SYSERR)
432 rh->name_callback (rh->cls, hostname);
433 rh->received_response = GNUNET_YES;
434 GNUNET_CLIENT_receive (client, &handle_response, rh,
435 GNUNET_TIME_absolute_get_remaining
436 (rh->timeout));
437 }
438 /* return lookup results to caller */
439 if (NULL != rh->addr_callback)
457 { 440 {
458 char *ips = no_resolve (sa, salen); 441 sa = (const struct sockaddr *) &msg[1];
442 salen = size - sizeof (struct GNUNET_MessageHeader);
443 if (salen < sizeof (struct sockaddr))
444 {
445 GNUNET_break (0);
446 if (rh->was_transmitted != GNUNET_SYSERR)
447 rh->addr_callback (rh->cls, NULL, 0);
448 GNUNET_CONTAINER_DLL_remove (req_head, req_tail, rh);
449 GNUNET_free (rh);
450 GNUNET_CLIENT_disconnect (client, GNUNET_NO);
451 client = NULL;
452 reconnect ();
453 return;
454 }
455#if DEBUG_RESOLVER
456 {
457 char *ips = no_resolve (sa, salen);
459 458
460 LOG (GNUNET_ERROR_TYPE_DEBUG, "Resolver returns `%s' for `%s'.\n", ips, 459 LOG (GNUNET_ERROR_TYPE_DEBUG, "Resolver returns `%s' for `%s'.\n",
461 (const char *) &rh[1]); 460 ips, (const char *) &rh[1]);
462 GNUNET_free (ips); 461 GNUNET_free (ips);
463 } 462 }
464#endif 463#endif
465 rh->addr_callback (rh->cls, sa, salen); 464 rh->addr_callback (rh->cls, sa, salen);
466 GNUNET_CLIENT_receive (client, &handle_response, rh, 465 GNUNET_CLIENT_receive (client, &handle_response, rh,
467 GNUNET_TIME_absolute_get_remaining (rh->timeout)); 466 GNUNET_TIME_absolute_get_remaining
468 } 467 (rh->timeout));
468 }
469} 469}
470 470
471 471
@@ -498,26 +498,27 @@ numeric_resolution (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc)
498 hostname = (const char *) &rh[1]; 498 hostname = (const char *) &rh[1];
499 if (((rh->domain == AF_UNSPEC) || (rh->domain == AF_INET)) && 499 if (((rh->domain == AF_UNSPEC) || (rh->domain == AF_INET)) &&
500 (1 == inet_pton (AF_INET, hostname, &v4.sin_addr))) 500 (1 == inet_pton (AF_INET, hostname, &v4.sin_addr)))
501 {
502 rh->addr_callback (rh->cls, (const struct sockaddr *) &v4, sizeof (v4));
503 if ((rh->domain == AF_UNSPEC) &&
504 (1 == inet_pton (AF_INET6, hostname, &v6.sin6_addr)))
505 { 501 {
506 /* this can happen on some systems IF "hostname" is "localhost" */ 502 rh->addr_callback (rh->cls, (const struct sockaddr *) &v4, sizeof (v4));
507 rh->addr_callback (rh->cls, (const struct sockaddr *) &v6, sizeof (v6)); 503 if ((rh->domain == AF_UNSPEC) &&
504 (1 == inet_pton (AF_INET6, hostname, &v6.sin6_addr)))
505 {
506 /* this can happen on some systems IF "hostname" is "localhost" */
507 rh->addr_callback (rh->cls, (const struct sockaddr *) &v6,
508 sizeof (v6));
509 }
510 rh->addr_callback (rh->cls, NULL, 0);
511 GNUNET_free (rh);
512 return;
508 } 513 }
509 rh->addr_callback (rh->cls, NULL, 0);
510 GNUNET_free (rh);
511 return;
512 }
513 if (((rh->domain == AF_UNSPEC) || (rh->domain == AF_INET6)) && 514 if (((rh->domain == AF_UNSPEC) || (rh->domain == AF_INET6)) &&
514 (1 == inet_pton (AF_INET6, hostname, &v6.sin6_addr))) 515 (1 == inet_pton (AF_INET6, hostname, &v6.sin6_addr)))
515 { 516 {
516 rh->addr_callback (rh->cls, (const struct sockaddr *) &v6, sizeof (v6)); 517 rh->addr_callback (rh->cls, (const struct sockaddr *) &v6, sizeof (v6));
517 rh->addr_callback (rh->cls, NULL, 0); 518 rh->addr_callback (rh->cls, NULL, 0);
518 GNUNET_free (rh); 519 GNUNET_free (rh);
519 return; 520 return;
520 } 521 }
521 /* why are we here? this task should not have been scheduled! */ 522 /* why are we here? this task should not have been scheduled! */
522 GNUNET_assert (0); 523 GNUNET_assert (0);
523 GNUNET_free (rh); 524 GNUNET_free (rh);
@@ -552,21 +553,21 @@ loopback_resolution (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc)
552#endif 553#endif
553 v6.sin6_addr = in6addr_loopback; 554 v6.sin6_addr = in6addr_loopback;
554 switch (rh->domain) 555 switch (rh->domain)
555 { 556 {
556 case AF_INET: 557 case AF_INET:
557 rh->addr_callback (rh->cls, (const struct sockaddr *) &v4, sizeof (v4)); 558 rh->addr_callback (rh->cls, (const struct sockaddr *) &v4, sizeof (v4));
558 break; 559 break;
559 case AF_INET6: 560 case AF_INET6:
560 rh->addr_callback (rh->cls, (const struct sockaddr *) &v6, sizeof (v6)); 561 rh->addr_callback (rh->cls, (const struct sockaddr *) &v6, sizeof (v6));
561 break; 562 break;
562 case AF_UNSPEC: 563 case AF_UNSPEC:
563 rh->addr_callback (rh->cls, (const struct sockaddr *) &v6, sizeof (v6)); 564 rh->addr_callback (rh->cls, (const struct sockaddr *) &v6, sizeof (v6));
564 rh->addr_callback (rh->cls, (const struct sockaddr *) &v4, sizeof (v4)); 565 rh->addr_callback (rh->cls, (const struct sockaddr *) &v4, sizeof (v4));
565 break; 566 break;
566 default: 567 default:
567 GNUNET_break (0); 568 GNUNET_break (0);
568 break; 569 break;
569 } 570 }
570 rh->addr_callback (rh->cls, NULL, 0); 571 rh->addr_callback (rh->cls, NULL, 0);
571 GNUNET_free (rh); 572 GNUNET_free (rh);
572} 573}
@@ -594,25 +595,25 @@ process_requests ()
594 struct GNUNET_RESOLVER_RequestHandle *rh; 595 struct GNUNET_RESOLVER_RequestHandle *rh;
595 596
596 if (NULL == client) 597 if (NULL == client)
597 { 598 {
598 reconnect (); 599 reconnect ();
599 return; 600 return;
600 } 601 }
601 rh = req_head; 602 rh = req_head;
602 if (NULL == rh) 603 if (NULL == rh)
603 { 604 {
604 /* nothing to do, release socket really soon if there is nothing 605 /* nothing to do, release socket really soon if there is nothing
605 * else happening... */ 606 * else happening... */
606 s_task = 607 s_task =
607 GNUNET_SCHEDULER_add_delayed (GNUNET_TIME_UNIT_MILLISECONDS, 608 GNUNET_SCHEDULER_add_delayed (GNUNET_TIME_UNIT_MILLISECONDS,
608 &shutdown_task, NULL); 609 &shutdown_task, NULL);
609 return; 610 return;
610 } 611 }
611 if (GNUNET_YES == rh->was_transmitted) 612 if (GNUNET_YES == rh->was_transmitted)
612 return; /* waiting for reply */ 613 return; /* waiting for reply */
613 msg = (struct GNUNET_RESOLVER_GetMessage *) buf; 614 msg = (struct GNUNET_RESOLVER_GetMessage *) buf;
614 msg->header.size = 615 msg->header.size =
615 htons (sizeof (struct GNUNET_RESOLVER_GetMessage) + rh->data_len); 616 htons (sizeof (struct GNUNET_RESOLVER_GetMessage) + rh->data_len);
616 msg->header.type = htons (GNUNET_MESSAGE_TYPE_RESOLVER_REQUEST); 617 msg->header.type = htons (GNUNET_MESSAGE_TYPE_RESOLVER_REQUEST);
617 msg->direction = htonl (rh->direction); 618 msg->direction = htonl (rh->direction);
618 msg->domain = htonl (rh->domain); 619 msg->domain = htonl (rh->domain);
@@ -623,15 +624,15 @@ process_requests ()
623#endif 624#endif
624 if (GNUNET_OK != 625 if (GNUNET_OK !=
625 GNUNET_CLIENT_transmit_and_get_response (client, &msg->header, 626 GNUNET_CLIENT_transmit_and_get_response (client, &msg->header,
626 GNUNET_TIME_absolute_get_remaining 627 GNUNET_TIME_absolute_get_remaining
627 (rh->timeout), GNUNET_YES, 628 (rh->timeout), GNUNET_YES,
628 &handle_response, rh)) 629 &handle_response, rh))
629 { 630 {
630 GNUNET_CLIENT_disconnect (client, GNUNET_NO); 631 GNUNET_CLIENT_disconnect (client, GNUNET_NO);
631 client = NULL; 632 client = NULL;
632 reconnect (); 633 reconnect ();
633 return; 634 return;
634 } 635 }
635 rh->was_transmitted = GNUNET_YES; 636 rh->was_transmitted = GNUNET_YES;
636} 637}
637 638
@@ -647,7 +648,7 @@ reconnect_task (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc)
647{ 648{
648 r_task = GNUNET_SCHEDULER_NO_TASK; 649 r_task = GNUNET_SCHEDULER_NO_TASK;
649 if (NULL == req_head) 650 if (NULL == req_head)
650 return; /* no work pending */ 651 return; /* no work pending */
651 if (0 != (tc->reason & GNUNET_SCHEDULER_REASON_SHUTDOWN)) 652 if (0 != (tc->reason & GNUNET_SCHEDULER_REASON_SHUTDOWN))
652 return; 653 return;
653#if DEBUG_RESOLVER 654#if DEBUG_RESOLVER
@@ -655,11 +656,12 @@ reconnect_task (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc)
655#endif 656#endif
656 client = GNUNET_CLIENT_connect ("resolver", resolver_cfg); 657 client = GNUNET_CLIENT_connect ("resolver", resolver_cfg);
657 if (NULL == client) 658 if (NULL == client)
658 { 659 {
659 LOG (GNUNET_ERROR_TYPE_DEBUG, "Failed to connect, will try again later\n"); 660 LOG (GNUNET_ERROR_TYPE_DEBUG,
660 reconnect (); 661 "Failed to connect, will try again later\n");
661 return; 662 reconnect ();
662 } 663 return;
664 }
663 process_requests (); 665 process_requests ();
664} 666}
665 667
@@ -676,26 +678,26 @@ reconnect ()
676 return; 678 return;
677 GNUNET_assert (NULL == client); 679 GNUNET_assert (NULL == client);
678 if (NULL != (rh = req_head)) 680 if (NULL != (rh = req_head))
679 {
680 switch (rh->was_transmitted)
681 { 681 {
682 case GNUNET_NO: 682 switch (rh->was_transmitted)
683 /* nothing more to do */ 683 {
684 break; 684 case GNUNET_NO:
685 case GNUNET_YES: 685 /* nothing more to do */
686 /* disconnected, transmit again! */ 686 break;
687 rh->was_transmitted = GNUNET_NO; 687 case GNUNET_YES:
688 break; 688 /* disconnected, transmit again! */
689 case GNUNET_SYSERR: 689 rh->was_transmitted = GNUNET_NO;
690 /* request was cancelled, remove entirely */ 690 break;
691 GNUNET_CONTAINER_DLL_remove (req_head, req_tail, rh); 691 case GNUNET_SYSERR:
692 GNUNET_free (rh); 692 /* request was cancelled, remove entirely */
693 break; 693 GNUNET_CONTAINER_DLL_remove (req_head, req_tail, rh);
694 default: 694 GNUNET_free (rh);
695 GNUNET_assert (0); 695 break;
696 break; 696 default:
697 GNUNET_assert (0);
698 break;
699 }
697 } 700 }
698 }
699#if DEBUG_RESOLVER 701#if DEBUG_RESOLVER
700 LOG (GNUNET_ERROR_TYPE_DEBUG, 702 LOG (GNUNET_ERROR_TYPE_DEBUG,
701 "Will try to connect to DNS service in %llu ms\n", 703 "Will try to connect to DNS service in %llu ms\n",
@@ -719,9 +721,9 @@ reconnect ()
719 */ 721 */
720struct GNUNET_RESOLVER_RequestHandle * 722struct GNUNET_RESOLVER_RequestHandle *
721GNUNET_RESOLVER_ip_get (const char *hostname, int domain, 723GNUNET_RESOLVER_ip_get (const char *hostname, int domain,
722 struct GNUNET_TIME_Relative timeout, 724 struct GNUNET_TIME_Relative timeout,
723 GNUNET_RESOLVER_AddressCallback callback, 725 GNUNET_RESOLVER_AddressCallback callback,
724 void *callback_cls) 726 void *callback_cls)
725{ 727{
726 struct GNUNET_RESOLVER_RequestHandle *rh; 728 struct GNUNET_RESOLVER_RequestHandle *rh;
727 size_t slen; 729 size_t slen;
@@ -732,10 +734,10 @@ GNUNET_RESOLVER_ip_get (const char *hostname, int domain,
732 slen = strlen (hostname) + 1; 734 slen = strlen (hostname) + 1;
733 if (slen + sizeof (struct GNUNET_RESOLVER_GetMessage) >= 735 if (slen + sizeof (struct GNUNET_RESOLVER_GetMessage) >=
734 GNUNET_SERVER_MAX_MESSAGE_SIZE) 736 GNUNET_SERVER_MAX_MESSAGE_SIZE)
735 { 737 {
736 GNUNET_break (0); 738 GNUNET_break (0);
737 return NULL; 739 return NULL;
738 } 740 }
739 rh = GNUNET_malloc (sizeof (struct GNUNET_RESOLVER_RequestHandle) + slen); 741 rh = GNUNET_malloc (sizeof (struct GNUNET_RESOLVER_RequestHandle) + slen);
740 rh->domain = domain; 742 rh->domain = domain;
741 rh->addr_callback = callback; 743 rh->addr_callback = callback;
@@ -749,25 +751,25 @@ GNUNET_RESOLVER_ip_get (const char *hostname, int domain,
749 ((domain == AF_INET) || (domain == AF_UNSPEC))) || 751 ((domain == AF_INET) || (domain == AF_UNSPEC))) ||
750 ((1 == inet_pton (AF_INET6, hostname, &v6)) && 752 ((1 == inet_pton (AF_INET6, hostname, &v6)) &&
751 ((domain == AF_INET6) || (domain == AF_UNSPEC)))) 753 ((domain == AF_INET6) || (domain == AF_UNSPEC))))
752 { 754 {
753 rh->task = GNUNET_SCHEDULER_add_now (&numeric_resolution, rh); 755 rh->task = GNUNET_SCHEDULER_add_now (&numeric_resolution, rh);
754 return rh; 756 return rh;
755 } 757 }
756 /* then, check if this is a loopback address */ 758 /* then, check if this is a loopback address */
757 i = 0; 759 i = 0;
758 while (loopback[i] != NULL) 760 while (loopback[i] != NULL)
759 if (0 == strcasecmp (loopback[i++], hostname)) 761 if (0 == strcasecmp (loopback[i++], hostname))
760 { 762 {
761 rh->task = GNUNET_SCHEDULER_add_now (&loopback_resolution, rh); 763 rh->task = GNUNET_SCHEDULER_add_now (&loopback_resolution, rh);
762 return rh; 764 return rh;
763 } 765 }
764 GNUNET_CONTAINER_DLL_insert_tail (req_head, req_tail, rh); 766 GNUNET_CONTAINER_DLL_insert_tail (req_head, req_tail, rh);
765 rh->was_queued = GNUNET_YES; 767 rh->was_queued = GNUNET_YES;
766 if (s_task != GNUNET_SCHEDULER_NO_TASK) 768 if (s_task != GNUNET_SCHEDULER_NO_TASK)
767 { 769 {
768 GNUNET_SCHEDULER_cancel (s_task); 770 GNUNET_SCHEDULER_cancel (s_task);
769 s_task = GNUNET_SCHEDULER_NO_TASK; 771 s_task = GNUNET_SCHEDULER_NO_TASK;
770 } 772 }
771 process_requests (); 773 process_requests ();
772 return rh; 774 return rh;
773} 775}
@@ -791,10 +793,10 @@ numeric_reverse (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc)
791 LOG (GNUNET_ERROR_TYPE_DEBUG, _("Resolver returns `%s'.\n"), result); 793 LOG (GNUNET_ERROR_TYPE_DEBUG, _("Resolver returns `%s'.\n"), result);
792#endif 794#endif
793 if (result != NULL) 795 if (result != NULL)
794 { 796 {
795 rh->name_callback (rh->cls, result); 797 rh->name_callback (rh->cls, result);
796 GNUNET_free (result); 798 GNUNET_free (result);
797 } 799 }
798 rh->name_callback (rh->cls, NULL); 800 rh->name_callback (rh->cls, NULL);
799 GNUNET_free (rh); 801 GNUNET_free (rh);
800} 802}
@@ -814,10 +816,10 @@ numeric_reverse (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc)
814 */ 816 */
815struct GNUNET_RESOLVER_RequestHandle * 817struct GNUNET_RESOLVER_RequestHandle *
816GNUNET_RESOLVER_hostname_get (const struct sockaddr *sa, socklen_t salen, 818GNUNET_RESOLVER_hostname_get (const struct sockaddr *sa, socklen_t salen,
817 int do_resolve, 819 int do_resolve,
818 struct GNUNET_TIME_Relative timeout, 820 struct GNUNET_TIME_Relative timeout,
819 GNUNET_RESOLVER_HostnameCallback callback, 821 GNUNET_RESOLVER_HostnameCallback callback,
820 void *cls) 822 void *cls)
821{ 823{
822 struct GNUNET_RESOLVER_RequestHandle *rh; 824 struct GNUNET_RESOLVER_RequestHandle *rh;
823 825
@@ -831,24 +833,24 @@ GNUNET_RESOLVER_hostname_get (const struct sockaddr *sa, socklen_t salen,
831 rh->direction = GNUNET_YES; 833 rh->direction = GNUNET_YES;
832 rh->received_response = GNUNET_NO; 834 rh->received_response = GNUNET_NO;
833 if (GNUNET_NO == do_resolve) 835 if (GNUNET_NO == do_resolve)
834 { 836 {
835 rh->task = GNUNET_SCHEDULER_add_now (&numeric_reverse, rh); 837 rh->task = GNUNET_SCHEDULER_add_now (&numeric_reverse, rh);
836 return rh; 838 return rh;
837 } 839 }
838 if (salen + sizeof (struct GNUNET_RESOLVER_GetMessage) >= 840 if (salen + sizeof (struct GNUNET_RESOLVER_GetMessage) >=
839 GNUNET_SERVER_MAX_MESSAGE_SIZE) 841 GNUNET_SERVER_MAX_MESSAGE_SIZE)
840 { 842 {
841 GNUNET_break (0); 843 GNUNET_break (0);
842 GNUNET_free (rh); 844 GNUNET_free (rh);
843 return NULL; 845 return NULL;
844 } 846 }
845 GNUNET_CONTAINER_DLL_insert_tail (req_head, req_tail, rh); 847 GNUNET_CONTAINER_DLL_insert_tail (req_head, req_tail, rh);
846 rh->was_queued = GNUNET_YES; 848 rh->was_queued = GNUNET_YES;
847 if (s_task != GNUNET_SCHEDULER_NO_TASK) 849 if (s_task != GNUNET_SCHEDULER_NO_TASK)
848 { 850 {
849 GNUNET_SCHEDULER_cancel (s_task); 851 GNUNET_SCHEDULER_cancel (s_task);
850 s_task = GNUNET_SCHEDULER_NO_TASK; 852 s_task = GNUNET_SCHEDULER_NO_TASK;
851 } 853 }
852 process_requests (); 854 process_requests ();
853 return rh; 855 return rh;
854} 856}
@@ -866,21 +868,21 @@ GNUNET_RESOLVER_local_fqdn_get ()
866 char hostname[GNUNET_OS_get_hostname_max_length () + 1]; 868 char hostname[GNUNET_OS_get_hostname_max_length () + 1];
867 869
868 if (0 != gethostname (hostname, sizeof (hostname) - 1)) 870 if (0 != gethostname (hostname, sizeof (hostname) - 1))
869 { 871 {
870 GNUNET_log_from_strerror (GNUNET_ERROR_TYPE_ERROR | GNUNET_ERROR_TYPE_BULK, 872 LOG_STRERROR (GNUNET_ERROR_TYPE_ERROR | GNUNET_ERROR_TYPE_BULK,
871 "resolver-api", "gethostname"); 873 "gethostname");
872 return NULL; 874 return NULL;
873 } 875 }
874#if DEBUG_RESOLVER 876#if DEBUG_RESOLVER
875 LOG (GNUNET_ERROR_TYPE_DEBUG, _("Resolving our FQDN `%s'\n"), hostname); 877 LOG (GNUNET_ERROR_TYPE_DEBUG, _("Resolving our FQDN `%s'\n"), hostname);
876#endif 878#endif
877 host = gethostbyname (hostname); 879 host = gethostbyname (hostname);
878 if (NULL == host) 880 if (NULL == host)
879 { 881 {
880 LOG (GNUNET_ERROR_TYPE_ERROR, _("Could not resolve our FQDN : %s\n"), 882 LOG (GNUNET_ERROR_TYPE_ERROR, _("Could not resolve our FQDN : %s\n"),
881 hstrerror (h_errno)); 883 hstrerror (h_errno));
882 return NULL; 884 return NULL;
883 } 885 }
884 return GNUNET_strdup (host->h_name); 886 return GNUNET_strdup (host->h_name);
885} 887}
886 888
@@ -896,18 +898,18 @@ GNUNET_RESOLVER_local_fqdn_get ()
896 */ 898 */
897struct GNUNET_RESOLVER_RequestHandle * 899struct GNUNET_RESOLVER_RequestHandle *
898GNUNET_RESOLVER_hostname_resolve (int domain, 900GNUNET_RESOLVER_hostname_resolve (int domain,
899 struct GNUNET_TIME_Relative timeout, 901 struct GNUNET_TIME_Relative timeout,
900 GNUNET_RESOLVER_AddressCallback callback, 902 GNUNET_RESOLVER_AddressCallback callback,
901 void *cls) 903 void *cls)
902{ 904{
903 char hostname[GNUNET_OS_get_hostname_max_length () + 1]; 905 char hostname[GNUNET_OS_get_hostname_max_length () + 1];
904 906
905 if (0 != gethostname (hostname, sizeof (hostname) - 1)) 907 if (0 != gethostname (hostname, sizeof (hostname) - 1))
906 { 908 {
907 GNUNET_log_from_strerror (GNUNET_ERROR_TYPE_ERROR | GNUNET_ERROR_TYPE_BULK, 909 LOG_STRERROR (GNUNET_ERROR_TYPE_ERROR | GNUNET_ERROR_TYPE_BULK,
908 "resolver-api", "gethostname"); 910 "gethostname");
909 return NULL; 911 return NULL;
910 } 912 }
911#if DEBUG_RESOLVER 913#if DEBUG_RESOLVER
912 LOG (GNUNET_ERROR_TYPE_DEBUG, _("Resolving our hostname `%s'\n"), hostname); 914 LOG (GNUNET_ERROR_TYPE_DEBUG, _("Resolving our hostname `%s'\n"), hostname);
913#endif 915#endif
@@ -927,19 +929,19 @@ void
927GNUNET_RESOLVER_request_cancel (struct GNUNET_RESOLVER_RequestHandle *rh) 929GNUNET_RESOLVER_request_cancel (struct GNUNET_RESOLVER_RequestHandle *rh)
928{ 930{
929 if (rh->task != GNUNET_SCHEDULER_NO_TASK) 931 if (rh->task != GNUNET_SCHEDULER_NO_TASK)
930 { 932 {
931 GNUNET_SCHEDULER_cancel (rh->task); 933 GNUNET_SCHEDULER_cancel (rh->task);
932 rh->task = GNUNET_SCHEDULER_NO_TASK; 934 rh->task = GNUNET_SCHEDULER_NO_TASK;
933 } 935 }
934 if (rh->was_transmitted == GNUNET_NO) 936 if (rh->was_transmitted == GNUNET_NO)
935 { 937 {
936 if (rh->was_queued == GNUNET_YES) 938 if (rh->was_queued == GNUNET_YES)
937 GNUNET_CONTAINER_DLL_remove (req_head, req_tail, rh); 939 GNUNET_CONTAINER_DLL_remove (req_head, req_tail, rh);
938 GNUNET_free (rh); 940 GNUNET_free (rh);
939 return; 941 return;
940 } 942 }
941 GNUNET_assert (rh->was_transmitted == GNUNET_YES); 943 GNUNET_assert (rh->was_transmitted == GNUNET_YES);
942 rh->was_transmitted = GNUNET_SYSERR; /* mark as cancelled */ 944 rh->was_transmitted = GNUNET_SYSERR; /* mark as cancelled */
943} 945}
944 946
945 947