diff options
Diffstat (limited to 'src/util/resolver_api.c')
-rw-r--r-- | src/util/resolver_api.c | 602 |
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 | */ |
325 | static void | 325 | static void reconnect (); |
326 | reconnect (); | ||
327 | 326 | ||
328 | 327 | ||
329 | /** | 328 | /** |
330 | * Process pending requests to the resolver. | 329 | * Process pending requests to the resolver. |
331 | */ | 330 | */ |
332 | static void | 331 | static void process_requests (); |
333 | process_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 | */ |
720 | struct GNUNET_RESOLVER_RequestHandle * | 722 | struct GNUNET_RESOLVER_RequestHandle * |
721 | GNUNET_RESOLVER_ip_get (const char *hostname, int domain, | 723 | GNUNET_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 | */ |
815 | struct GNUNET_RESOLVER_RequestHandle * | 817 | struct GNUNET_RESOLVER_RequestHandle * |
816 | GNUNET_RESOLVER_hostname_get (const struct sockaddr *sa, socklen_t salen, | 818 | GNUNET_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 | */ |
897 | struct GNUNET_RESOLVER_RequestHandle * | 899 | struct GNUNET_RESOLVER_RequestHandle * |
898 | GNUNET_RESOLVER_hostname_resolve (int domain, | 900 | GNUNET_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 | |||
927 | GNUNET_RESOLVER_request_cancel (struct GNUNET_RESOLVER_RequestHandle *rh) | 929 | GNUNET_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 | ||