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