diff options
author | Christian Grothoff <christian@grothoff.org> | 2011-06-16 10:09:47 +0000 |
---|---|---|
committer | Christian Grothoff <christian@grothoff.org> | 2011-06-16 10:09:47 +0000 |
commit | 007b8443b0cb0d67bf8b176a1a175ad4bc37f1f3 (patch) | |
tree | b42d56110ae349eb2977673690c072dcf75b32a4 /src/util | |
parent | 94c41ff98d293d8c041c4bbbe8d19dbf8ccd6f3f (diff) | |
download | gnunet-007b8443b0cb0d67bf8b176a1a175ad4bc37f1f3.tar.gz gnunet-007b8443b0cb0d67bf8b176a1a175ad4bc37f1f3.zip |
resolver API change
Diffstat (limited to 'src/util')
-rw-r--r-- | src/util/client.c | 6 | ||||
-rw-r--r-- | src/util/connection.c | 3 | ||||
-rw-r--r-- | src/util/gnunet-resolver.c | 3 | ||||
-rw-r--r-- | src/util/program.c | 5 | ||||
-rw-r--r-- | src/util/resolver_api.c | 630 |
5 files changed, 416 insertions, 231 deletions
diff --git a/src/util/client.c b/src/util/client.c index 9458cc94b..7461a0fe2 100644 --- a/src/util/client.c +++ b/src/util/client.c | |||
@@ -151,9 +151,8 @@ struct GNUNET_CLIENT_Connection | |||
151 | 151 | ||
152 | /** | 152 | /** |
153 | * Our configuration. | 153 | * Our configuration. |
154 | * FIXME: why do we DUP the configuration? Avoid this! | ||
155 | */ | 154 | */ |
156 | struct GNUNET_CONFIGURATION_Handle *cfg; | 155 | const struct GNUNET_CONFIGURATION_Handle *cfg; |
157 | 156 | ||
158 | /** | 157 | /** |
159 | * Name of the service we interact with. | 158 | * Name of the service we interact with. |
@@ -377,7 +376,7 @@ GNUNET_CLIENT_connect (const char *service_name, | |||
377 | ret->attempts = 1; | 376 | ret->attempts = 1; |
378 | ret->sock = sock; | 377 | ret->sock = sock; |
379 | ret->service_name = GNUNET_strdup (service_name); | 378 | ret->service_name = GNUNET_strdup (service_name); |
380 | ret->cfg = GNUNET_CONFIGURATION_dup (cfg); | 379 | ret->cfg = cfg; |
381 | ret->back_off = GNUNET_TIME_UNIT_MILLISECONDS; | 380 | ret->back_off = GNUNET_TIME_UNIT_MILLISECONDS; |
382 | return ret; | 381 | return ret; |
383 | } | 382 | } |
@@ -447,7 +446,6 @@ GNUNET_CLIENT_disconnect (struct GNUNET_CLIENT_Connection *sock, | |||
447 | } | 446 | } |
448 | GNUNET_array_grow (sock->received_buf, sock->received_size, 0); | 447 | GNUNET_array_grow (sock->received_buf, sock->received_size, 0); |
449 | GNUNET_free (sock->service_name); | 448 | GNUNET_free (sock->service_name); |
450 | GNUNET_CONFIGURATION_destroy (sock->cfg); | ||
451 | GNUNET_free (sock); | 449 | GNUNET_free (sock); |
452 | } | 450 | } |
453 | 451 | ||
diff --git a/src/util/connection.c b/src/util/connection.c index dae049eeb..b28c7c3e6 100644 --- a/src/util/connection.c +++ b/src/util/connection.c | |||
@@ -901,8 +901,7 @@ GNUNET_CONNECTION_create_from_connect (const struct | |||
901 | ret->write_buffer = GNUNET_malloc(ret->write_buffer_size); | 901 | ret->write_buffer = GNUNET_malloc(ret->write_buffer_size); |
902 | ret->port = port; | 902 | ret->port = port; |
903 | ret->hostname = GNUNET_strdup (hostname); | 903 | ret->hostname = GNUNET_strdup (hostname); |
904 | ret->dns_active = GNUNET_RESOLVER_ip_get (cfg, | 904 | ret->dns_active = GNUNET_RESOLVER_ip_get (ret->hostname, |
905 | ret->hostname, | ||
906 | AF_UNSPEC, | 905 | AF_UNSPEC, |
907 | GNUNET_CONNECTION_CONNECT_RETRY_TIMEOUT, | 906 | GNUNET_CONNECTION_CONNECT_RETRY_TIMEOUT, |
908 | &try_connect_using_address, ret); | 907 | &try_connect_using_address, ret); |
diff --git a/src/util/gnunet-resolver.c b/src/util/gnunet-resolver.c index 18ce232f2..85aedcacf 100644 --- a/src/util/gnunet-resolver.c +++ b/src/util/gnunet-resolver.c | |||
@@ -61,8 +61,7 @@ run (void *cls, | |||
61 | { | 61 | { |
62 | if (args[0] == NULL) | 62 | if (args[0] == NULL) |
63 | return; | 63 | return; |
64 | GNUNET_RESOLVER_ip_get (cfg, | 64 | GNUNET_RESOLVER_ip_get (args[0], |
65 | args[0], | ||
66 | AF_UNSPEC, | 65 | AF_UNSPEC, |
67 | GET_TIMEOUT, | 66 | GET_TIMEOUT, |
68 | &printer, | 67 | &printer, |
diff --git a/src/util/program.c b/src/util/program.c index 6f8467837..8fd77637f 100644 --- a/src/util/program.c +++ b/src/util/program.c | |||
@@ -32,6 +32,7 @@ | |||
32 | #include "gnunet_getopt_lib.h" | 32 | #include "gnunet_getopt_lib.h" |
33 | #include "gnunet_os_lib.h" | 33 | #include "gnunet_os_lib.h" |
34 | #include "gnunet_program_lib.h" | 34 | #include "gnunet_program_lib.h" |
35 | #include "gnunet_resolver_service.h" | ||
35 | #include "gnunet_scheduler_lib.h" | 36 | #include "gnunet_scheduler_lib.h" |
36 | #include <gcrypt.h> | 37 | #include <gcrypt.h> |
37 | 38 | ||
@@ -77,6 +78,7 @@ program_main (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc) | |||
77 | { | 78 | { |
78 | struct CommandContext *cc = cls; | 79 | struct CommandContext *cc = cls; |
79 | 80 | ||
81 | GNUNET_RESOLVER_connect (cc->cfg); | ||
80 | cc->task (cc->task_cls, cc->args, cc->cfgfile, cc->cfg); | 82 | cc->task (cc->task_cls, cc->args, cc->cfgfile, cc->cfg); |
81 | } | 83 | } |
82 | 84 | ||
@@ -212,7 +214,6 @@ GNUNET_PROGRAM_run (int argc, | |||
212 | loglev, | 214 | loglev, |
213 | logfile)) || | 215 | logfile)) || |
214 | (GNUNET_OK != GNUNET_CONFIGURATION_load (cfg, cc.cfgfile)))) | 216 | (GNUNET_OK != GNUNET_CONFIGURATION_load (cfg, cc.cfgfile)))) |
215 | |||
216 | { | 217 | { |
217 | GNUNET_CONFIGURATION_destroy (cfg); | 218 | GNUNET_CONFIGURATION_destroy (cfg); |
218 | GNUNET_free_non_null (cc.cfgfile); | 219 | GNUNET_free_non_null (cc.cfgfile); |
@@ -221,7 +222,7 @@ GNUNET_PROGRAM_run (int argc, | |||
221 | return GNUNET_SYSERR; | 222 | return GNUNET_SYSERR; |
222 | } | 223 | } |
223 | GNUNET_free (allopts); | 224 | GNUNET_free (allopts); |
224 | 225 | ||
225 | /* run */ | 226 | /* run */ |
226 | cc.args = &argv[ret]; | 227 | cc.args = &argv[ret]; |
227 | GNUNET_SCHEDULER_run (&program_main, &cc); | 228 | GNUNET_SCHEDULER_run (&program_main, &cc); |
diff --git a/src/util/resolver_api.c b/src/util/resolver_api.c index 7daaaf1cc..5c0973f86 100644 --- a/src/util/resolver_api.c +++ b/src/util/resolver_api.c | |||
@@ -27,6 +27,7 @@ | |||
27 | #include "gnunet_getopt_lib.h" | 27 | #include "gnunet_getopt_lib.h" |
28 | #include "gnunet_os_lib.h" | 28 | #include "gnunet_os_lib.h" |
29 | #include "gnunet_client_lib.h" | 29 | #include "gnunet_client_lib.h" |
30 | #include "gnunet_container_lib.h" | ||
30 | #include "gnunet_protocols.h" | 31 | #include "gnunet_protocols.h" |
31 | #include "gnunet_resolver_service.h" | 32 | #include "gnunet_resolver_service.h" |
32 | #include "gnunet_server_lib.h" | 33 | #include "gnunet_server_lib.h" |
@@ -50,6 +51,44 @@ static const char *loopback[] = { | |||
50 | 51 | ||
51 | 52 | ||
52 | /** | 53 | /** |
54 | * Configuration. | ||
55 | */ | ||
56 | static const struct GNUNET_CONFIGURATION_Handle *cfg; | ||
57 | |||
58 | /** | ||
59 | * Our connection to the resolver service, created on-demand, but then | ||
60 | * persists until error or shutdown. | ||
61 | */ | ||
62 | static struct GNUNET_CLIENT_Connection *client; | ||
63 | |||
64 | /** | ||
65 | * Head of DLL of requests. | ||
66 | */ | ||
67 | static struct GNUNET_RESOLVER_RequestHandle *req_head; | ||
68 | |||
69 | /** | ||
70 | * Tail of DLL of requests. | ||
71 | */ | ||
72 | static struct GNUNET_RESOLVER_RequestHandle *req_tail; | ||
73 | |||
74 | /** | ||
75 | * How long should we wait to reconnect? | ||
76 | */ | ||
77 | static struct GNUNET_TIME_Relative backoff; | ||
78 | |||
79 | /** | ||
80 | * Task for reconnecting. | ||
81 | */ | ||
82 | static GNUNET_SCHEDULER_TaskIdentifier r_task; | ||
83 | |||
84 | /** | ||
85 | * Task ID of shutdown task; only present while we have a | ||
86 | * connection to the resolver service. | ||
87 | */ | ||
88 | static GNUNET_SCHEDULER_TaskIdentifier s_task; | ||
89 | |||
90 | |||
91 | /** | ||
53 | * Handle to a request given to the resolver. Can be used to cancel | 92 | * Handle to a request given to the resolver. Can be used to cancel |
54 | * the request prior to the timeout or successful execution. Also | 93 | * the request prior to the timeout or successful execution. Also |
55 | * used to track our internal state for the request. | 94 | * used to track our internal state for the request. |
@@ -58,6 +97,16 @@ struct GNUNET_RESOLVER_RequestHandle | |||
58 | { | 97 | { |
59 | 98 | ||
60 | /** | 99 | /** |
100 | * Next entry in DLL of requests. | ||
101 | */ | ||
102 | struct GNUNET_RESOLVER_RequestHandle *next; | ||
103 | |||
104 | /** | ||
105 | * Previous entry in DLL of requests. | ||
106 | */ | ||
107 | struct GNUNET_RESOLVER_RequestHandle *prev; | ||
108 | |||
109 | /** | ||
61 | * Callback if this is an name resolution request, | 110 | * Callback if this is an name resolution request, |
62 | * otherwise NULL. | 111 | * otherwise NULL. |
63 | */ | 112 | */ |
@@ -75,16 +124,6 @@ struct GNUNET_RESOLVER_RequestHandle | |||
75 | void *cls; | 124 | void *cls; |
76 | 125 | ||
77 | /** | 126 | /** |
78 | * Our connection to the resolver service. | ||
79 | */ | ||
80 | struct GNUNET_CLIENT_Connection *client; | ||
81 | |||
82 | /** | ||
83 | * Name of the host that we are resolving. | ||
84 | */ | ||
85 | const char *hostname; | ||
86 | |||
87 | /** | ||
88 | * When should this request time out? | 127 | * When should this request time out? |
89 | */ | 128 | */ |
90 | struct GNUNET_TIME_Absolute timeout; | 129 | struct GNUNET_TIME_Absolute timeout; |
@@ -100,10 +139,24 @@ struct GNUNET_RESOLVER_RequestHandle | |||
100 | int domain; | 139 | int domain; |
101 | 140 | ||
102 | /** | 141 | /** |
103 | * Length of the "struct sockaddr" that follows this | 142 | * Has this request been transmitted to the service? |
104 | * struct (only for reverse lookup). | ||
105 | */ | 143 | */ |
106 | socklen_t salen; | 144 | int was_transmitted; |
145 | |||
146 | /** | ||
147 | * Did we add this request to the queue? | ||
148 | */ | ||
149 | int was_queued; | ||
150 | |||
151 | /** | ||
152 | * Desired direction (IP to name or name to IP) | ||
153 | */ | ||
154 | int direction; | ||
155 | |||
156 | /** | ||
157 | * Length of the data that follows this struct. | ||
158 | */ | ||
159 | size_t data_len; | ||
107 | }; | 160 | }; |
108 | 161 | ||
109 | 162 | ||
@@ -164,6 +217,45 @@ check_config (const struct GNUNET_CONFIGURATION_Handle *cfg) | |||
164 | 217 | ||
165 | 218 | ||
166 | /** | 219 | /** |
220 | * Create the connection to the resolver service. | ||
221 | * | ||
222 | * @param c configuration to use | ||
223 | */ | ||
224 | void | ||
225 | GNUNET_RESOLVER_connect (const struct GNUNET_CONFIGURATION_Handle *c) | ||
226 | { | ||
227 | check_config (c); | ||
228 | cfg = c; | ||
229 | } | ||
230 | |||
231 | |||
232 | /** | ||
233 | * Destroy the connection to the resolver service. | ||
234 | */ | ||
235 | void | ||
236 | GNUNET_RESOLVER_disconnect () | ||
237 | { | ||
238 | GNUNET_assert (NULL == req_head); | ||
239 | GNUNET_assert (NULL == req_tail); | ||
240 | if (NULL != client) | ||
241 | { | ||
242 | GNUNET_CLIENT_disconnect (client, GNUNET_NO); | ||
243 | client = NULL; | ||
244 | } | ||
245 | if (r_task != GNUNET_SCHEDULER_NO_TASK) | ||
246 | { | ||
247 | GNUNET_SCHEDULER_cancel (r_task); | ||
248 | r_task = GNUNET_SCHEDULER_NO_TASK; | ||
249 | } | ||
250 | if (s_task != GNUNET_SCHEDULER_NO_TASK) | ||
251 | { | ||
252 | GNUNET_SCHEDULER_cancel (s_task); | ||
253 | s_task = GNUNET_SCHEDULER_NO_TASK; | ||
254 | } | ||
255 | } | ||
256 | |||
257 | |||
258 | /** | ||
167 | * Convert IP address to string without DNS resolution. | 259 | * Convert IP address to string without DNS resolution. |
168 | * | 260 | * |
169 | * @param sa the address | 261 | * @param sa the address |
@@ -216,76 +308,146 @@ no_resolve (const struct sockaddr *sa, socklen_t salen) | |||
216 | 308 | ||
217 | 309 | ||
218 | /** | 310 | /** |
219 | * Process the reply from the resolver (which is presumably | 311 | * Adjust exponential back-off and reconnect to the service. |
220 | * the numeric IP address for a name resolution request). | 312 | */ |
313 | static void | ||
314 | reconnect (); | ||
315 | |||
316 | |||
317 | /** | ||
318 | * Process pending requests to the resolver. | ||
221 | * | 319 | * |
222 | * @param cls the "GNUNET_RESOLVER_RequestHandle" for which this is a reply | 320 | * @param h handle to the resolver |
223 | * @param msg reply from the resolver or NULL on error | 321 | */ |
322 | static void | ||
323 | process_requests (); | ||
324 | |||
325 | |||
326 | /** | ||
327 | * Process response with a hostname for a DNS lookup. | ||
328 | * | ||
329 | * @param cls our "struct GNUNET_RESOLVER_RequestHandle" context | ||
330 | * @param msg message with the hostname, NULL on error | ||
224 | */ | 331 | */ |
225 | static void | 332 | static void |
226 | handle_address_response (void *cls, const struct GNUNET_MessageHeader *msg) | 333 | handle_response (void *cls, |
334 | const struct GNUNET_MessageHeader *msg) | ||
227 | { | 335 | { |
228 | struct GNUNET_RESOLVER_RequestHandle *rh = cls; | 336 | struct GNUNET_RESOLVER_RequestHandle *rh = cls; |
229 | uint16_t size; | 337 | uint16_t size; |
338 | const char *hostname; | ||
230 | const struct sockaddr *sa; | 339 | const struct sockaddr *sa; |
231 | socklen_t salen; | 340 | socklen_t salen; |
232 | 341 | ||
233 | if (msg == NULL) | 342 | if (msg == NULL) |
234 | { | 343 | { |
235 | GNUNET_log (GNUNET_ERROR_TYPE_INFO, | 344 | GNUNET_log (GNUNET_ERROR_TYPE_INFO, |
236 | _("Timeout trying to resolve hostname `%s'.\n"), | 345 | _("Timeout trying to resolve IP address `%s'.\n"), |
237 | rh->hostname); | 346 | GNUNET_a2s ((const void*) &rh[1], rh->data_len)); |
238 | rh->addr_callback (rh->cls, NULL, 0); | 347 | if (rh->was_transmitted != GNUNET_SYSERR) |
239 | GNUNET_CLIENT_disconnect (rh->client, GNUNET_NO); | 348 | { |
349 | if (NULL != rh->name_callback) | ||
350 | rh->name_callback (rh->cls, NULL); | ||
351 | if (NULL != rh->addr_callback) | ||
352 | rh->addr_callback (rh->cls, NULL, 0); | ||
353 | } | ||
354 | GNUNET_CONTAINER_DLL_remove (req_head, | ||
355 | req_tail, | ||
356 | rh); | ||
240 | GNUNET_free (rh); | 357 | GNUNET_free (rh); |
358 | GNUNET_CLIENT_disconnect (client, GNUNET_NO); | ||
359 | client = NULL; | ||
360 | reconnect (); | ||
241 | return; | 361 | return; |
242 | } | 362 | } |
243 | if (GNUNET_MESSAGE_TYPE_RESOLVER_RESPONSE != ntohs (msg->type)) | 363 | if (GNUNET_MESSAGE_TYPE_RESOLVER_RESPONSE != ntohs (msg->type)) |
244 | { | 364 | { |
245 | GNUNET_break (0); | 365 | GNUNET_break (0); |
246 | rh->addr_callback (rh->cls, NULL, 0); | 366 | GNUNET_CLIENT_disconnect (client, GNUNET_NO); |
247 | GNUNET_CLIENT_disconnect (rh->client, GNUNET_NO); | 367 | client = NULL; |
248 | GNUNET_free (rh); | 368 | reconnect (); |
249 | return; | 369 | return; |
250 | } | 370 | } |
251 | |||
252 | size = ntohs (msg->size); | 371 | size = ntohs (msg->size); |
253 | if (size == sizeof (struct GNUNET_MessageHeader)) | 372 | if (size == sizeof (struct GNUNET_MessageHeader)) |
254 | { | 373 | { |
255 | #if DEBUG_RESOLVER | 374 | if (rh->was_transmitted != GNUNET_SYSERR) |
256 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, | 375 | { |
257 | _("Received end message resolving hostname `%s'.\n"), | 376 | if (NULL != rh->name_callback) |
258 | rh->hostname); | 377 | rh->name_callback (rh->cls, NULL); |
259 | #endif | 378 | if (NULL != rh->addr_callback) |
260 | rh->addr_callback (rh->cls, NULL, 0); | 379 | rh->addr_callback (rh->cls, NULL, 0); |
261 | GNUNET_CLIENT_disconnect (rh->client, GNUNET_NO); | 380 | } |
381 | GNUNET_CONTAINER_DLL_remove (req_head, | ||
382 | req_tail, | ||
383 | rh); | ||
262 | GNUNET_free (rh); | 384 | GNUNET_free (rh); |
385 | process_requests (); | ||
263 | return; | 386 | return; |
264 | } | 387 | } |
265 | sa = (const struct sockaddr *) &msg[1]; | 388 | if (NULL != rh->name_callback) |
266 | salen = size - sizeof (struct GNUNET_MessageHeader); | ||
267 | if (salen < sizeof (struct sockaddr)) | ||
268 | { | 389 | { |
269 | GNUNET_break (0); | 390 | hostname = (const char *) &msg[1]; |
270 | rh->addr_callback (rh->cls, NULL, 0); | 391 | if (hostname[size - sizeof (struct GNUNET_MessageHeader) - 1] != '\0') |
271 | GNUNET_CLIENT_disconnect (rh->client, GNUNET_NO); | 392 | { |
272 | GNUNET_free (rh); | 393 | GNUNET_break (0); |
273 | return; | 394 | if (rh->was_transmitted != GNUNET_SYSERR) |
395 | rh->name_callback (rh->cls, NULL); | ||
396 | GNUNET_CONTAINER_DLL_remove (req_head, | ||
397 | req_tail, | ||
398 | rh); | ||
399 | GNUNET_free (rh); | ||
400 | GNUNET_CLIENT_disconnect (client, GNUNET_NO); | ||
401 | client = NULL; | ||
402 | reconnect (); | ||
403 | return; | ||
404 | } | ||
405 | #if DEBUG_RESOLVER | ||
406 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, | ||
407 | _("Resolver returns `%s' for IP `%s'.\n"), | ||
408 | hostname, | ||
409 | GNUNET_a2s ((const void*) &rh[1], rh->data_len)); | ||
410 | #endif | ||
411 | if (rh->was_transmitted != GNUNET_SYSERR) | ||
412 | rh->name_callback (rh->cls, hostname); | ||
413 | GNUNET_CLIENT_receive (client, | ||
414 | &handle_response, | ||
415 | rh, | ||
416 | GNUNET_TIME_absolute_get_remaining (rh->timeout)); | ||
274 | } | 417 | } |
418 | if (NULL != rh->addr_callback) | ||
419 | { | ||
420 | sa = (const struct sockaddr *) &msg[1]; | ||
421 | salen = size - sizeof (struct GNUNET_MessageHeader); | ||
422 | if (salen < sizeof (struct sockaddr)) | ||
423 | { | ||
424 | GNUNET_break (0); | ||
425 | if (rh->was_transmitted != GNUNET_SYSERR) | ||
426 | rh->addr_callback (rh->cls, NULL, 0); | ||
427 | GNUNET_CONTAINER_DLL_remove (req_head, | ||
428 | req_tail, | ||
429 | rh); | ||
430 | GNUNET_free (rh); | ||
431 | GNUNET_CLIENT_disconnect (client, GNUNET_NO); | ||
432 | client = NULL; | ||
433 | reconnect (); | ||
434 | return; | ||
435 | } | ||
275 | #if DEBUG_RESOLVER | 436 | #if DEBUG_RESOLVER |
276 | { | 437 | { |
277 | char *ips = no_resolve (sa, salen); | 438 | char *ips = no_resolve (sa, salen); |
278 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, | 439 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, |
279 | "Resolver returns `%s' for `%s'.\n", ips, | 440 | "Resolver returns `%s' for `%s'.\n", ips, |
280 | rh->hostname); | 441 | rh->hostname); |
281 | GNUNET_free (ips); | 442 | GNUNET_free (ips); |
282 | } | 443 | } |
283 | #endif | 444 | #endif |
284 | rh->addr_callback (rh->cls, sa, salen); | 445 | rh->addr_callback (rh->cls, sa, salen); |
285 | GNUNET_CLIENT_receive (rh->client, | 446 | GNUNET_CLIENT_receive (client, |
286 | &handle_address_response, | 447 | &handle_response, |
287 | rh, | 448 | rh, |
288 | GNUNET_TIME_absolute_get_remaining (rh->timeout)); | 449 | GNUNET_TIME_absolute_get_remaining (rh->timeout)); |
450 | } | ||
289 | } | 451 | } |
290 | 452 | ||
291 | 453 | ||
@@ -303,6 +465,7 @@ numeric_resolution (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc) | |||
303 | struct GNUNET_RESOLVER_RequestHandle *rh = cls; | 465 | struct GNUNET_RESOLVER_RequestHandle *rh = cls; |
304 | struct sockaddr_in v4; | 466 | struct sockaddr_in v4; |
305 | struct sockaddr_in6 v6; | 467 | struct sockaddr_in6 v6; |
468 | const char *hostname; | ||
306 | 469 | ||
307 | memset (&v4, 0, sizeof (v4)); | 470 | memset (&v4, 0, sizeof (v4)); |
308 | v4.sin_family = AF_INET; | 471 | v4.sin_family = AF_INET; |
@@ -314,13 +477,13 @@ numeric_resolution (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc) | |||
314 | #if HAVE_SOCKADDR_IN_SIN_LEN | 477 | #if HAVE_SOCKADDR_IN_SIN_LEN |
315 | v6.sin6_len = sizeof (v6); | 478 | v6.sin6_len = sizeof (v6); |
316 | #endif | 479 | #endif |
317 | 480 | hostname = (const char*) &rh[1]; | |
318 | if (((rh->domain == AF_UNSPEC) || (rh->domain == AF_INET)) && | 481 | if (((rh->domain == AF_UNSPEC) || (rh->domain == AF_INET)) && |
319 | (1 == inet_pton (AF_INET, rh->hostname, &v4.sin_addr))) | 482 | (1 == inet_pton (AF_INET, hostname, &v4.sin_addr))) |
320 | { | 483 | { |
321 | rh->addr_callback (rh->cls, (const struct sockaddr *) &v4, sizeof (v4)); | 484 | rh->addr_callback (rh->cls, (const struct sockaddr *) &v4, sizeof (v4)); |
322 | if ((rh->domain == AF_UNSPEC) && | 485 | if ((rh->domain == AF_UNSPEC) && |
323 | (1 == inet_pton (AF_INET6, rh->hostname, &v6.sin6_addr))) | 486 | (1 == inet_pton (AF_INET6, hostname, &v6.sin6_addr))) |
324 | { | 487 | { |
325 | /* this can happen on some systems IF "hostname" is "localhost" */ | 488 | /* this can happen on some systems IF "hostname" is "localhost" */ |
326 | rh->addr_callback (rh->cls, | 489 | rh->addr_callback (rh->cls, |
@@ -331,7 +494,7 @@ numeric_resolution (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc) | |||
331 | return; | 494 | return; |
332 | } | 495 | } |
333 | if (((rh->domain == AF_UNSPEC) || (rh->domain == AF_INET6)) && | 496 | if (((rh->domain == AF_UNSPEC) || (rh->domain == AF_INET6)) && |
334 | (1 == inet_pton (AF_INET6, rh->hostname, &v6.sin6_addr))) | 497 | (1 == inet_pton (AF_INET6, hostname, &v6.sin6_addr))) |
335 | { | 498 | { |
336 | rh->addr_callback (rh->cls, (const struct sockaddr *) &v6, sizeof (v6)); | 499 | rh->addr_callback (rh->cls, (const struct sockaddr *) &v6, sizeof (v6)); |
337 | rh->addr_callback (rh->cls, NULL, 0); | 500 | rh->addr_callback (rh->cls, NULL, 0); |
@@ -344,7 +507,6 @@ numeric_resolution (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc) | |||
344 | } | 507 | } |
345 | 508 | ||
346 | 509 | ||
347 | |||
348 | /** | 510 | /** |
349 | * We've been asked to lookup the address for a hostname and were | 511 | * We've been asked to lookup the address for a hostname and were |
350 | * given a variant of "loopback". Perform the callbacks for the | 512 | * given a variant of "loopback". Perform the callbacks for the |
@@ -394,9 +556,138 @@ loopback_resolution (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc) | |||
394 | 556 | ||
395 | 557 | ||
396 | /** | 558 | /** |
559 | * Task executed on system shutdown. | ||
560 | */ | ||
561 | static void | ||
562 | shutdown_task (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc) | ||
563 | { | ||
564 | s_task = GNUNET_SCHEDULER_NO_TASK; | ||
565 | GNUNET_RESOLVER_disconnect (); | ||
566 | } | ||
567 | |||
568 | |||
569 | /** | ||
570 | * Process pending requests to the resolver. | ||
571 | * | ||
572 | * @param h handle to the resolver | ||
573 | */ | ||
574 | static void | ||
575 | process_requests () | ||
576 | { | ||
577 | struct GNUNET_RESOLVER_GetMessage *msg; | ||
578 | char buf[GNUNET_SERVER_MAX_MESSAGE_SIZE - 1]; | ||
579 | struct GNUNET_RESOLVER_RequestHandle *rh; | ||
580 | |||
581 | if (NULL == client) | ||
582 | { | ||
583 | reconnect (); | ||
584 | return; | ||
585 | } | ||
586 | rh = req_head; | ||
587 | if (NULL == rh) | ||
588 | { | ||
589 | /* nothing to do, release socket really soon if there is nothing | ||
590 | else happening... */ | ||
591 | s_task = GNUNET_SCHEDULER_add_delayed (GNUNET_TIME_UNIT_MILLISECONDS, | ||
592 | &shutdown_task, NULL); | ||
593 | return; | ||
594 | } | ||
595 | if (GNUNET_YES == rh->was_transmitted) | ||
596 | return; /* waiting for reply */ | ||
597 | msg = (struct GNUNET_RESOLVER_GetMessage *) buf; | ||
598 | msg->header.size = | ||
599 | htons (sizeof (struct GNUNET_RESOLVER_GetMessage) + rh->data_len); | ||
600 | msg->header.type = htons (GNUNET_MESSAGE_TYPE_RESOLVER_REQUEST); | ||
601 | msg->direction = htonl (rh->direction); | ||
602 | msg->domain = htonl (rh->domain); | ||
603 | memcpy (&msg[1], &rh[1], rh->data_len); | ||
604 | |||
605 | if (GNUNET_OK != | ||
606 | GNUNET_CLIENT_transmit_and_get_response (client, | ||
607 | &msg->header, | ||
608 | GNUNET_TIME_absolute_get_remaining (rh->timeout), | ||
609 | GNUNET_YES, | ||
610 | &handle_response, rh)) | ||
611 | { | ||
612 | GNUNET_CLIENT_disconnect (client, GNUNET_NO); | ||
613 | client = NULL; | ||
614 | reconnect (); | ||
615 | return; | ||
616 | } | ||
617 | rh->was_transmitted = GNUNET_YES; | ||
618 | } | ||
619 | |||
620 | |||
621 | /** | ||
622 | * Now try to reconnect to the resolver service. | ||
623 | * | ||
624 | * @param cls NULL | ||
625 | * @param tc scheduler context | ||
626 | */ | ||
627 | static void | ||
628 | reconnect_task (void *cls, | ||
629 | const struct GNUNET_SCHEDULER_TaskContext *tc) | ||
630 | { | ||
631 | r_task = GNUNET_SCHEDULER_NO_TASK; | ||
632 | if (NULL == req_head) | ||
633 | return; /* no work pending */ | ||
634 | if (0 != (tc->reason & GNUNET_SCHEDULER_REASON_SHUTDOWN)) | ||
635 | return; | ||
636 | client = GNUNET_CLIENT_connect ("resolver", cfg); | ||
637 | if (NULL == client) | ||
638 | { | ||
639 | reconnect (); | ||
640 | return; | ||
641 | } | ||
642 | process_requests (); | ||
643 | } | ||
644 | |||
645 | |||
646 | /** | ||
647 | * Adjust exponential back-off and reconnect to the service. | ||
648 | */ | ||
649 | static void | ||
650 | reconnect () | ||
651 | { | ||
652 | struct GNUNET_RESOLVER_RequestHandle *rh; | ||
653 | |||
654 | if (GNUNET_SCHEDULER_NO_TASK != r_task) | ||
655 | return; | ||
656 | GNUNET_assert (NULL == client); | ||
657 | if (NULL != (rh = req_head)) | ||
658 | { | ||
659 | switch (rh->was_transmitted) | ||
660 | { | ||
661 | case GNUNET_NO: | ||
662 | /* nothing more to do */ | ||
663 | break; | ||
664 | case GNUNET_YES: | ||
665 | /* disconnected, transmit again! */ | ||
666 | rh->was_transmitted = GNUNET_NO; | ||
667 | break; | ||
668 | case GNUNET_SYSERR: | ||
669 | /* request was cancelled, remove entirely */ | ||
670 | GNUNET_CONTAINER_DLL_remove (req_head, | ||
671 | req_tail, | ||
672 | rh); | ||
673 | GNUNET_free (rh); | ||
674 | break; | ||
675 | default: | ||
676 | GNUNET_assert (0); | ||
677 | break; | ||
678 | } | ||
679 | } | ||
680 | r_task = GNUNET_SCHEDULER_add_delayed (backoff, | ||
681 | &reconnect_task, | ||
682 | NULL); | ||
683 | backoff = GNUNET_TIME_relative_max (GNUNET_TIME_UNIT_SECONDS, | ||
684 | GNUNET_TIME_relative_multiply (backoff, 2)); | ||
685 | } | ||
686 | |||
687 | |||
688 | /** | ||
397 | * Convert a string to one or more IP addresses. | 689 | * Convert a string to one or more IP addresses. |
398 | * | 690 | * |
399 | * @param cfg configuration to use | ||
400 | * @param hostname the hostname to resolve | 691 | * @param hostname the hostname to resolve |
401 | * @param domain AF_INET or AF_INET6; use AF_UNSPEC for "any" | 692 | * @param domain AF_INET or AF_INET6; use AF_UNSPEC for "any" |
402 | * @param callback function to call with addresses | 693 | * @param callback function to call with addresses |
@@ -405,23 +696,18 @@ loopback_resolution (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc) | |||
405 | * @return handle that can be used to cancel the request, NULL on error | 696 | * @return handle that can be used to cancel the request, NULL on error |
406 | */ | 697 | */ |
407 | struct GNUNET_RESOLVER_RequestHandle * | 698 | struct GNUNET_RESOLVER_RequestHandle * |
408 | GNUNET_RESOLVER_ip_get (const struct GNUNET_CONFIGURATION_Handle *cfg, | 699 | GNUNET_RESOLVER_ip_get (const char *hostname, |
409 | const char *hostname, | ||
410 | int domain, | 700 | int domain, |
411 | struct GNUNET_TIME_Relative timeout, | 701 | struct GNUNET_TIME_Relative timeout, |
412 | GNUNET_RESOLVER_AddressCallback callback, | 702 | GNUNET_RESOLVER_AddressCallback callback, |
413 | void *callback_cls) | 703 | void *callback_cls) |
414 | { | 704 | { |
415 | struct GNUNET_CLIENT_Connection *client; | ||
416 | struct GNUNET_RESOLVER_GetMessage *msg; | ||
417 | struct GNUNET_RESOLVER_RequestHandle *rh; | 705 | struct GNUNET_RESOLVER_RequestHandle *rh; |
418 | size_t slen; | 706 | size_t slen; |
419 | unsigned int i; | 707 | unsigned int i; |
420 | struct in_addr v4; | 708 | struct in_addr v4; |
421 | struct in6_addr v6; | 709 | struct in6_addr v6; |
422 | char buf[GNUNET_SERVER_MAX_MESSAGE_SIZE - 1]; | ||
423 | 710 | ||
424 | check_config (cfg); | ||
425 | slen = strlen (hostname) + 1; | 711 | slen = strlen (hostname) + 1; |
426 | if (slen + sizeof (struct GNUNET_RESOLVER_GetMessage) >= GNUNET_SERVER_MAX_MESSAGE_SIZE) | 712 | if (slen + sizeof (struct GNUNET_RESOLVER_GetMessage) >= GNUNET_SERVER_MAX_MESSAGE_SIZE) |
427 | { | 713 | { |
@@ -433,9 +719,9 @@ GNUNET_RESOLVER_ip_get (const struct GNUNET_CONFIGURATION_Handle *cfg, | |||
433 | rh->addr_callback = callback; | 719 | rh->addr_callback = callback; |
434 | rh->cls = callback_cls; | 720 | rh->cls = callback_cls; |
435 | memcpy (&rh[1], hostname, slen); | 721 | memcpy (&rh[1], hostname, slen); |
436 | rh->hostname = (const char *) &rh[1]; | 722 | rh->data_len = slen; |
437 | rh->timeout = GNUNET_TIME_relative_to_absolute (timeout); | 723 | rh->timeout = GNUNET_TIME_relative_to_absolute (timeout); |
438 | 724 | rh->direction = GNUNET_NO; | |
439 | /* first, check if this is a numeric address */ | 725 | /* first, check if this is a numeric address */ |
440 | if (((1 == inet_pton (AF_INET, | 726 | if (((1 == inet_pton (AF_INET, |
441 | hostname, | 727 | hostname, |
@@ -457,104 +743,21 @@ GNUNET_RESOLVER_ip_get (const struct GNUNET_CONFIGURATION_Handle *cfg, | |||
457 | rh->task = GNUNET_SCHEDULER_add_now (&loopback_resolution, rh); | 743 | rh->task = GNUNET_SCHEDULER_add_now (&loopback_resolution, rh); |
458 | return rh; | 744 | return rh; |
459 | } | 745 | } |
460 | 746 | GNUNET_CONTAINER_DLL_insert_tail (req_head, | |
461 | client = GNUNET_CLIENT_connect ("resolver", cfg); | 747 | req_tail, |
462 | if (client == NULL) | 748 | rh); |
463 | { | 749 | rh->was_queued = GNUNET_YES; |
464 | GNUNET_free (rh); | 750 | if (s_task != GNUNET_SCHEDULER_NO_TASK) |
465 | return NULL; | ||
466 | } | ||
467 | rh->client = client; | ||
468 | |||
469 | msg = (struct GNUNET_RESOLVER_GetMessage *) buf; | ||
470 | msg->header.size = | ||
471 | htons (sizeof (struct GNUNET_RESOLVER_GetMessage) + slen); | ||
472 | msg->header.type = htons (GNUNET_MESSAGE_TYPE_RESOLVER_REQUEST); | ||
473 | msg->direction = htonl (GNUNET_NO); | ||
474 | msg->domain = htonl (domain); | ||
475 | memcpy (&msg[1], hostname, slen); | ||
476 | |||
477 | #if DEBUG_RESOLVER | ||
478 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, | ||
479 | _("Resolver requests DNS resolution of hostname `%s'.\n"), | ||
480 | hostname); | ||
481 | #endif | ||
482 | if (GNUNET_OK != | ||
483 | GNUNET_CLIENT_transmit_and_get_response (client, | ||
484 | &msg->header, | ||
485 | timeout, | ||
486 | GNUNET_YES, | ||
487 | &handle_address_response, rh)) | ||
488 | { | 751 | { |
489 | GNUNET_free (rh); | 752 | GNUNET_SCHEDULER_cancel (s_task); |
490 | GNUNET_CLIENT_disconnect (client, GNUNET_NO); | 753 | s_task = GNUNET_SCHEDULER_NO_TASK; |
491 | return NULL; | ||
492 | } | 754 | } |
755 | process_requests (); | ||
493 | return rh; | 756 | return rh; |
494 | } | 757 | } |
495 | 758 | ||
496 | 759 | ||
497 | /** | 760 | /** |
498 | * Process response with a hostname for a reverse DNS lookup. | ||
499 | * | ||
500 | * @param cls our "struct GNUNET_RESOLVER_RequestHandle" context | ||
501 | * @param msg message with the hostname, NULL on error | ||
502 | */ | ||
503 | static void | ||
504 | handle_hostname_response (void *cls, const struct GNUNET_MessageHeader *msg) | ||
505 | { | ||
506 | struct GNUNET_RESOLVER_RequestHandle *rh = cls; | ||
507 | uint16_t size; | ||
508 | const char *hostname; | ||
509 | |||
510 | if (msg == NULL) | ||
511 | { | ||
512 | GNUNET_log (GNUNET_ERROR_TYPE_INFO, | ||
513 | _("Timeout trying to resolve IP address `%s'.\n"), | ||
514 | GNUNET_a2s ((const void*) &rh[1], rh->salen)); | ||
515 | rh->name_callback (rh->cls, NULL); | ||
516 | GNUNET_CLIENT_disconnect (rh->client, GNUNET_NO); | ||
517 | GNUNET_free (rh); | ||
518 | return; | ||
519 | } | ||
520 | size = ntohs (msg->size); | ||
521 | if (size == sizeof (struct GNUNET_MessageHeader)) | ||
522 | { | ||
523 | #if DEBUG_RESOLVER | ||
524 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, | ||
525 | _("Received end message resolving IP address `%s'.\n"), | ||
526 | GNUNET_a2s ((const void*) &rh[1], rh->salen)); | ||
527 | #endif | ||
528 | rh->name_callback (rh->cls, NULL); | ||
529 | GNUNET_CLIENT_disconnect (rh->client, GNUNET_NO); | ||
530 | GNUNET_free (rh); | ||
531 | return; | ||
532 | } | ||
533 | hostname = (const char *) &msg[1]; | ||
534 | if (hostname[size - sizeof (struct GNUNET_MessageHeader) - 1] != '\0') | ||
535 | { | ||
536 | GNUNET_break (0); | ||
537 | rh->name_callback (rh->cls, NULL); | ||
538 | GNUNET_CLIENT_disconnect (rh->client, GNUNET_NO); | ||
539 | GNUNET_free (rh); | ||
540 | return; | ||
541 | } | ||
542 | #if DEBUG_RESOLVER | ||
543 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, | ||
544 | _("Resolver returns `%s' for IP `%s'.\n"), | ||
545 | hostname, | ||
546 | GNUNET_a2s ((const void*) &rh[1], rh->salen)); | ||
547 | #endif | ||
548 | rh->name_callback (rh->cls, hostname); | ||
549 | GNUNET_CLIENT_receive (rh->client, | ||
550 | &handle_hostname_response, | ||
551 | rh, | ||
552 | GNUNET_TIME_absolute_get_remaining (rh->timeout)); | ||
553 | } | ||
554 | |||
555 | |||
556 | |||
557 | /** | ||
558 | * We've been asked to convert an address to a string without | 761 | * We've been asked to convert an address to a string without |
559 | * a reverse lookup. Do it. | 762 | * a reverse lookup. Do it. |
560 | * | 763 | * |
@@ -562,12 +765,13 @@ handle_hostname_response (void *cls, const struct GNUNET_MessageHeader *msg) | |||
562 | * @param tc unused scheduler context | 765 | * @param tc unused scheduler context |
563 | */ | 766 | */ |
564 | static void | 767 | static void |
565 | numeric_reverse (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc) | 768 | numeric_reverse (void *cls, |
769 | const struct GNUNET_SCHEDULER_TaskContext *tc) | ||
566 | { | 770 | { |
567 | struct GNUNET_RESOLVER_RequestHandle *rh = cls; | 771 | struct GNUNET_RESOLVER_RequestHandle *rh = cls; |
568 | char *result; | 772 | char *result; |
569 | 773 | ||
570 | result = no_resolve ((const struct sockaddr *) &rh[1], rh->salen); | 774 | result = no_resolve ((const struct sockaddr *) &rh[1], rh->data_len); |
571 | #if DEBUG_RESOLVER | 775 | #if DEBUG_RESOLVER |
572 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, _("Resolver returns `%s'.\n"), result); | 776 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, _("Resolver returns `%s'.\n"), result); |
573 | #endif | 777 | #endif |
@@ -581,11 +785,9 @@ numeric_reverse (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc) | |||
581 | } | 785 | } |
582 | 786 | ||
583 | 787 | ||
584 | |||
585 | /** | 788 | /** |
586 | * Get an IP address as a string. | 789 | * Get an IP address as a string. |
587 | * | 790 | * |
588 | * @param cfg configuration to use | ||
589 | * @param sa host address | 791 | * @param sa host address |
590 | * @param salen length of host address | 792 | * @param salen length of host address |
591 | * @param do_resolve use GNUNET_NO to return numeric hostname | 793 | * @param do_resolve use GNUNET_NO to return numeric hostname |
@@ -595,27 +797,23 @@ numeric_reverse (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc) | |||
595 | * @return handle that can be used to cancel the request | 797 | * @return handle that can be used to cancel the request |
596 | */ | 798 | */ |
597 | struct GNUNET_RESOLVER_RequestHandle * | 799 | struct GNUNET_RESOLVER_RequestHandle * |
598 | GNUNET_RESOLVER_hostname_get (const struct GNUNET_CONFIGURATION_Handle *cfg, | 800 | GNUNET_RESOLVER_hostname_get (const struct sockaddr *sa, |
599 | const struct sockaddr *sa, | ||
600 | socklen_t salen, | 801 | socklen_t salen, |
601 | int do_resolve, | 802 | int do_resolve, |
602 | struct GNUNET_TIME_Relative timeout, | 803 | struct GNUNET_TIME_Relative timeout, |
603 | GNUNET_RESOLVER_HostnameCallback callback, | 804 | GNUNET_RESOLVER_HostnameCallback callback, |
604 | void *cls) | 805 | void *cls) |
605 | { | 806 | { |
606 | struct GNUNET_CLIENT_Connection *client; | ||
607 | struct GNUNET_RESOLVER_GetMessage *msg; | ||
608 | struct GNUNET_RESOLVER_RequestHandle *rh; | 807 | struct GNUNET_RESOLVER_RequestHandle *rh; |
609 | char buf[GNUNET_SERVER_MAX_MESSAGE_SIZE - 1]; | ||
610 | 808 | ||
611 | check_config (cfg); | 809 | check_config (cfg); |
612 | rh = GNUNET_malloc (sizeof (struct GNUNET_RESOLVER_RequestHandle) + salen); | 810 | rh = GNUNET_malloc (sizeof (struct GNUNET_RESOLVER_RequestHandle) + salen); |
613 | rh->name_callback = callback; | 811 | rh->name_callback = callback; |
614 | rh->cls = cls; | 812 | rh->cls = cls; |
615 | rh->timeout = GNUNET_TIME_relative_to_absolute (timeout); | 813 | rh->timeout = GNUNET_TIME_relative_to_absolute (timeout); |
616 | rh->salen = salen; | ||
617 | memcpy (&rh[1], sa, salen); | 814 | memcpy (&rh[1], sa, salen); |
618 | 815 | rh->data_len = salen; | |
816 | rh->direction = GNUNET_YES; | ||
619 | if (GNUNET_NO == do_resolve) | 817 | if (GNUNET_NO == do_resolve) |
620 | { | 818 | { |
621 | rh->task = GNUNET_SCHEDULER_add_now (&numeric_reverse, rh); | 819 | rh->task = GNUNET_SCHEDULER_add_now (&numeric_reverse, rh); |
@@ -627,51 +825,31 @@ GNUNET_RESOLVER_hostname_get (const struct GNUNET_CONFIGURATION_Handle *cfg, | |||
627 | GNUNET_free (rh); | 825 | GNUNET_free (rh); |
628 | return NULL; | 826 | return NULL; |
629 | } | 827 | } |
630 | client = GNUNET_CLIENT_connect ("resolver", cfg); | 828 | GNUNET_CONTAINER_DLL_insert_tail (req_head, |
631 | if (client == NULL) | 829 | req_tail, |
830 | rh); | ||
831 | rh->was_queued = GNUNET_YES; | ||
832 | if (s_task != GNUNET_SCHEDULER_NO_TASK) | ||
632 | { | 833 | { |
633 | GNUNET_free (rh); | 834 | GNUNET_SCHEDULER_cancel (s_task); |
634 | return NULL; | 835 | s_task = GNUNET_SCHEDULER_NO_TASK; |
635 | } | ||
636 | rh->client = client; | ||
637 | |||
638 | msg = (struct GNUNET_RESOLVER_GetMessage *) buf; | ||
639 | msg->header.size = | ||
640 | htons (sizeof (struct GNUNET_RESOLVER_GetMessage) + salen); | ||
641 | msg->header.type = htons (GNUNET_MESSAGE_TYPE_RESOLVER_REQUEST); | ||
642 | msg->direction = htonl (GNUNET_YES); | ||
643 | msg->domain = htonl (sa->sa_family); | ||
644 | memcpy (&msg[1], sa, salen); | ||
645 | #if DEBUG_RESOLVER | ||
646 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, | ||
647 | _("Resolver requests DNS resolution of IP address.\n")); | ||
648 | #endif | ||
649 | if (GNUNET_OK != | ||
650 | GNUNET_CLIENT_transmit_and_get_response (client, | ||
651 | &msg->header, | ||
652 | timeout, | ||
653 | GNUNET_YES, | ||
654 | &handle_hostname_response, rh)) | ||
655 | { | ||
656 | GNUNET_CLIENT_disconnect (client, GNUNET_NO); | ||
657 | GNUNET_free (rh); | ||
658 | return NULL; | ||
659 | } | 836 | } |
837 | process_requests (); | ||
660 | return rh; | 838 | return rh; |
661 | } | 839 | } |
662 | 840 | ||
663 | 841 | ||
664 | /** | 842 | /** |
665 | * Get local fully qualified domain name | 843 | * Get local fully qualified domain name |
844 | * | ||
666 | * @return fqdn | 845 | * @return fqdn |
667 | */ | 846 | */ |
668 | char * | 847 | char * |
669 | GNUNET_RESOLVER_local_fqdn_get ( void ) | 848 | GNUNET_RESOLVER_local_fqdn_get () |
670 | { | 849 | { |
671 | struct hostent *host; | 850 | struct hostent *host; |
672 | char hostname[GNUNET_OS_get_hostname_max_length() + 1]; | 851 | char hostname[GNUNET_OS_get_hostname_max_length() + 1]; |
673 | 852 | ||
674 | |||
675 | if (0 != gethostname (hostname, sizeof (hostname) - 1)) | 853 | if (0 != gethostname (hostname, sizeof (hostname) - 1)) |
676 | { | 854 | { |
677 | GNUNET_log_strerror (GNUNET_ERROR_TYPE_ERROR | | 855 | GNUNET_log_strerror (GNUNET_ERROR_TYPE_ERROR | |
@@ -682,21 +860,21 @@ GNUNET_RESOLVER_local_fqdn_get ( void ) | |||
682 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, | 860 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, |
683 | _("Resolving our FQDN `%s'\n"), hostname); | 861 | _("Resolving our FQDN `%s'\n"), hostname); |
684 | #endif | 862 | #endif |
685 | host = gethostbyname ( hostname ); | 863 | host = gethostbyname (hostname); |
686 | if ( NULL == host) | 864 | if (NULL == host) |
687 | { | 865 | { |
688 | GNUNET_log (GNUNET_ERROR_TYPE_ERROR, | 866 | GNUNET_log (GNUNET_ERROR_TYPE_ERROR, |
689 | _("Could not resolve our FQDN : %s\n"), | 867 | _("Could not resolve our FQDN : %s\n"), |
690 | hstrerror (h_errno)); | 868 | hstrerror (h_errno)); |
691 | return NULL; | 869 | return NULL; |
692 | } | 870 | } |
693 | return GNUNET_strdup (host->h_name); | 871 | return GNUNET_strdup (host->h_name); |
694 | } | 872 | } |
695 | 873 | ||
874 | |||
696 | /** | 875 | /** |
697 | * Looking our own hostname. | 876 | * Looking our own hostname. |
698 | * | 877 | * |
699 | * @param cfg configuration to use | ||
700 | * @param domain AF_INET or AF_INET6; use AF_UNSPEC for "any" | 878 | * @param domain AF_INET or AF_INET6; use AF_UNSPEC for "any" |
701 | * @param callback function to call with addresses | 879 | * @param callback function to call with addresses |
702 | * @param cls closure for callback | 880 | * @param cls closure for callback |
@@ -704,15 +882,13 @@ GNUNET_RESOLVER_local_fqdn_get ( void ) | |||
704 | * @return handle that can be used to cancel the request, NULL on error | 882 | * @return handle that can be used to cancel the request, NULL on error |
705 | */ | 883 | */ |
706 | struct GNUNET_RESOLVER_RequestHandle * | 884 | struct GNUNET_RESOLVER_RequestHandle * |
707 | GNUNET_RESOLVER_hostname_resolve (const struct GNUNET_CONFIGURATION_Handle | 885 | GNUNET_RESOLVER_hostname_resolve (int domain, |
708 | *cfg, int domain, | ||
709 | struct GNUNET_TIME_Relative timeout, | 886 | struct GNUNET_TIME_Relative timeout, |
710 | GNUNET_RESOLVER_AddressCallback callback, | 887 | GNUNET_RESOLVER_AddressCallback callback, |
711 | void *cls) | 888 | void *cls) |
712 | { | 889 | { |
713 | char hostname[GNUNET_OS_get_hostname_max_length() + 1]; | 890 | char hostname[GNUNET_OS_get_hostname_max_length() + 1]; |
714 | 891 | ||
715 | check_config (cfg); | ||
716 | if (0 != gethostname (hostname, sizeof (hostname) - 1)) | 892 | if (0 != gethostname (hostname, sizeof (hostname) - 1)) |
717 | { | 893 | { |
718 | GNUNET_log_strerror (GNUNET_ERROR_TYPE_ERROR | | 894 | GNUNET_log_strerror (GNUNET_ERROR_TYPE_ERROR | |
@@ -723,8 +899,10 @@ GNUNET_RESOLVER_hostname_resolve (const struct GNUNET_CONFIGURATION_Handle | |||
723 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, | 899 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, |
724 | _("Resolving our hostname `%s'\n"), hostname); | 900 | _("Resolving our hostname `%s'\n"), hostname); |
725 | #endif | 901 | #endif |
726 | return GNUNET_RESOLVER_ip_get (cfg, hostname, domain, timeout, callback, | 902 | return GNUNET_RESOLVER_ip_get (hostname, |
727 | cls); | 903 | domain, |
904 | timeout, | ||
905 | callback, cls); | ||
728 | } | 906 | } |
729 | 907 | ||
730 | 908 | ||
@@ -734,18 +912,28 @@ GNUNET_RESOLVER_hostname_resolve (const struct GNUNET_CONFIGURATION_Handle | |||
734 | * been completed (i.e, the callback has been called to | 912 | * been completed (i.e, the callback has been called to |
735 | * signal timeout or the final result). | 913 | * signal timeout or the final result). |
736 | * | 914 | * |
737 | * @param h handle of request to cancel | 915 | * @param rh handle of request to cancel |
738 | */ | 916 | */ |
739 | void | 917 | void |
740 | GNUNET_RESOLVER_request_cancel (struct GNUNET_RESOLVER_RequestHandle *h) | 918 | GNUNET_RESOLVER_request_cancel (struct GNUNET_RESOLVER_RequestHandle *rh) |
741 | { | 919 | { |
742 | if (h->client != NULL) | 920 | if (rh->task != GNUNET_SCHEDULER_NO_TASK) |
743 | GNUNET_CLIENT_disconnect (h->client, GNUNET_NO); | 921 | { |
744 | if (h->task != GNUNET_SCHEDULER_NO_TASK) | 922 | GNUNET_SCHEDULER_cancel (rh->task); |
745 | GNUNET_SCHEDULER_cancel (h->task); | 923 | rh->task = GNUNET_SCHEDULER_NO_TASK; |
746 | GNUNET_free (h); | 924 | } |
925 | if (rh->was_transmitted == GNUNET_NO) | ||
926 | { | ||
927 | if (rh->was_queued == GNUNET_YES) | ||
928 | GNUNET_CONTAINER_DLL_remove (req_head, | ||
929 | req_tail, | ||
930 | rh); | ||
931 | GNUNET_free (rh); | ||
932 | return; | ||
933 | } | ||
934 | GNUNET_assert (rh->was_transmitted == GNUNET_YES); | ||
935 | rh->was_transmitted = GNUNET_SYSERR; /* mark as cancelled */ | ||
747 | } | 936 | } |
748 | 937 | ||
749 | 938 | ||
750 | |||
751 | /* end of resolver_api.c */ | 939 | /* end of resolver_api.c */ |