aboutsummaryrefslogtreecommitdiff
path: root/src/util/resolver_api.c
diff options
context:
space:
mode:
authorChristian Grothoff <christian@grothoff.org>2016-07-25 21:34:47 +0000
committerChristian Grothoff <christian@grothoff.org>2016-07-25 21:34:47 +0000
commit6446293d028db5fe66c53f70ab8194f6c47f3fa1 (patch)
treea27ec7e92f6ac78ba90e582ea9d88dc702ab10c2 /src/util/resolver_api.c
parent59a1974b48463e363442bd4e8f81741ee86d4123 (diff)
downloadgnunet-6446293d028db5fe66c53f70ab8194f6c47f3fa1.tar.gz
gnunet-6446293d028db5fe66c53f70ab8194f6c47f3fa1.zip
-ensure clean DNS shutdown, fix DNS-STUN termination issues
Diffstat (limited to 'src/util/resolver_api.c')
-rw-r--r--src/util/resolver_api.c83
1 files changed, 66 insertions, 17 deletions
diff --git a/src/util/resolver_api.c b/src/util/resolver_api.c
index 299fdfef9..c4ce1ccc2 100644
--- a/src/util/resolver_api.c
+++ b/src/util/resolver_api.c
@@ -249,8 +249,16 @@ GNUNET_RESOLVER_connect (const struct GNUNET_CONFIGURATION_Handle *cfg)
249void 249void
250GNUNET_RESOLVER_disconnect () 250GNUNET_RESOLVER_disconnect ()
251{ 251{
252 GNUNET_assert (NULL == req_head); 252 struct GNUNET_RESOLVER_RequestHandle *rh;
253 GNUNET_assert (NULL == req_tail); 253
254 while (NULL != (rh = req_head))
255 {
256 GNUNET_assert (GNUNET_SYSERR == rh->was_transmitted);
257 GNUNET_CONTAINER_DLL_remove (req_head,
258 req_tail,
259 rh);
260 GNUNET_free (rh);
261 }
254 if (NULL != mq) 262 if (NULL != mq)
255 { 263 {
256 LOG (GNUNET_ERROR_TYPE_DEBUG, 264 LOG (GNUNET_ERROR_TYPE_DEBUG,
@@ -272,6 +280,42 @@ GNUNET_RESOLVER_disconnect ()
272 280
273 281
274/** 282/**
283 * Task executed on system shutdown.
284 */
285static void
286shutdown_task (void *cls)
287{
288 s_task = NULL;
289 GNUNET_RESOLVER_disconnect ();
290 backoff = GNUNET_TIME_UNIT_MILLISECONDS;
291}
292
293
294/**
295 * Consider disconnecting if we have no further requests pending.
296 */
297static void
298check_disconnect ()
299{
300 struct GNUNET_RESOLVER_RequestHandle *rh;
301
302 for (rh = req_head; NULL != rh; rh = rh->next)
303 if (GNUNET_SYSERR != rh->was_transmitted)
304 return;
305 if (NULL != r_task)
306 {
307 GNUNET_SCHEDULER_cancel (r_task);
308 r_task = NULL;
309 }
310 if (NULL != s_task)
311 return;
312 s_task = GNUNET_SCHEDULER_add_delayed (GNUNET_TIME_UNIT_MILLISECONDS,
313 &shutdown_task,
314 NULL);
315}
316
317
318/**
275 * Convert IP address to string without DNS resolution. 319 * Convert IP address to string without DNS resolution.
276 * 320 *
277 * @param af address family 321 * @param af address family
@@ -339,23 +383,13 @@ mq_error_handler (void *cls,
339{ 383{
340 GNUNET_MQ_destroy (mq); 384 GNUNET_MQ_destroy (mq);
341 mq = NULL; 385 mq = NULL;
386 LOG (GNUNET_ERROR_TYPE_DEBUG,
387 "MQ error, reconnecting\n");
342 reconnect (); 388 reconnect ();
343} 389}
344 390
345 391
346/** 392/**
347 * Task executed on system shutdown.
348 */
349static void
350shutdown_task (void *cls)
351{
352 s_task = NULL;
353 GNUNET_RESOLVER_disconnect ();
354 backoff = GNUNET_TIME_UNIT_MILLISECONDS;
355}
356
357
358/**
359 * Process pending requests to the resolver. 393 * Process pending requests to the resolver.
360 */ 394 */
361static void 395static void
@@ -599,7 +633,9 @@ numeric_resolution (void *cls)
599 } 633 }
600 if ( ( (rh->af == AF_UNSPEC) || 634 if ( ( (rh->af == AF_UNSPEC) ||
601 (rh->af == AF_INET6) ) && 635 (rh->af == AF_INET6) ) &&
602 (1 == inet_pton (AF_INET6, hostname, &v6.sin6_addr) ) ) 636 (1 == inet_pton (AF_INET6,
637 hostname,
638 &v6.sin6_addr) ) )
603 { 639 {
604 rh->addr_callback (rh->cls, 640 rh->addr_callback (rh->cls,
605 (const struct sockaddr *) &v6, 641 (const struct sockaddr *) &v6,
@@ -671,6 +707,9 @@ loopback_resolution (void *cls)
671 rh->addr_callback (rh->cls, 707 rh->addr_callback (rh->cls,
672 NULL, 708 NULL,
673 0); 709 0);
710 LOG (GNUNET_ERROR_TYPE_DEBUG,
711 "Finished resolving hostname `%s'.\n",
712 (const char *) &rh[1]);
674 GNUNET_free (rh); 713 GNUNET_free (rh);
675} 714}
676 715
@@ -740,6 +779,7 @@ reconnect ()
740 req_tail, 779 req_tail,
741 rh); 780 rh);
742 GNUNET_free (rh); 781 GNUNET_free (rh);
782 check_disconnect ();
743 break; 783 break;
744 default: 784 default:
745 GNUNET_assert (0); 785 GNUNET_assert (0);
@@ -841,13 +881,16 @@ GNUNET_RESOLVER_ip_get (const char *hostname,
841 GNUNET_break (0); 881 GNUNET_break (0);
842 return NULL; 882 return NULL;
843 } 883 }
884 LOG (GNUNET_ERROR_TYPE_DEBUG,
885 "Trying to resolve hostname `%s'.\n",
886 hostname);
844 rh = GNUNET_malloc (sizeof (struct GNUNET_RESOLVER_RequestHandle) + slen); 887 rh = GNUNET_malloc (sizeof (struct GNUNET_RESOLVER_RequestHandle) + slen);
845 rh->af = af; 888 rh->af = af;
846 rh->addr_callback = callback; 889 rh->addr_callback = callback;
847 rh->cls = callback_cls; 890 rh->cls = callback_cls;
848 GNUNET_memcpy (&rh[1], 891 GNUNET_memcpy (&rh[1],
849 hostname, 892 hostname,
850 slen); 893 slen);
851 rh->data_len = slen; 894 rh->data_len = slen;
852 rh->timeout = GNUNET_TIME_relative_to_absolute (timeout); 895 rh->timeout = GNUNET_TIME_relative_to_absolute (timeout);
853 rh->direction = GNUNET_NO; 896 rh->direction = GNUNET_NO;
@@ -1133,6 +1176,10 @@ GNUNET_RESOLVER_hostname_resolve (int af,
1133void 1176void
1134GNUNET_RESOLVER_request_cancel (struct GNUNET_RESOLVER_RequestHandle *rh) 1177GNUNET_RESOLVER_request_cancel (struct GNUNET_RESOLVER_RequestHandle *rh)
1135{ 1178{
1179 if (GNUNET_NO == rh->direction)
1180 LOG (GNUNET_ERROR_TYPE_DEBUG,
1181 "Asked to cancel request to resolve hostname `%s'.\n",
1182 (const char *) &rh[1]);
1136 if (NULL != rh->task) 1183 if (NULL != rh->task)
1137 { 1184 {
1138 GNUNET_SCHEDULER_cancel (rh->task); 1185 GNUNET_SCHEDULER_cancel (rh->task);
@@ -1145,10 +1192,12 @@ GNUNET_RESOLVER_request_cancel (struct GNUNET_RESOLVER_RequestHandle *rh)
1145 req_tail, 1192 req_tail,
1146 rh); 1193 rh);
1147 GNUNET_free (rh); 1194 GNUNET_free (rh);
1195 check_disconnect ();
1148 return; 1196 return;
1149 } 1197 }
1150 GNUNET_assert (GNUNET_YES == rh->was_transmitted); 1198 GNUNET_assert (GNUNET_YES == rh->was_transmitted);
1151 rh->was_transmitted = GNUNET_SYSERR; /* mark as cancelled */ 1199 rh->was_transmitted = GNUNET_SYSERR; /* mark as cancelled */
1200 check_disconnect ();
1152} 1201}
1153 1202
1154 1203