aboutsummaryrefslogtreecommitdiff
path: root/src
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
parent59a1974b48463e363442bd4e8f81741ee86d4123 (diff)
downloadgnunet-6446293d028db5fe66c53f70ab8194f6c47f3fa1.tar.gz
gnunet-6446293d028db5fe66c53f70ab8194f6c47f3fa1.zip
-ensure clean DNS shutdown, fix DNS-STUN termination issues
Diffstat (limited to 'src')
-rw-r--r--src/nat/nat.c92
-rw-r--r--src/nat/nat_stun.c44
-rw-r--r--src/util/resolver_api.c83
3 files changed, 142 insertions, 77 deletions
diff --git a/src/nat/nat.c b/src/nat/nat.c
index 6e9fcfd0e..9a9ae18ac 100644
--- a/src/nat/nat.c
+++ b/src/nat/nat.c
@@ -429,7 +429,7 @@ struct GNUNET_NAT_Handle
429 /** 429 /**
430 * STUN request task 430 * STUN request task
431 */ 431 */
432 struct GNUNET_SCHEDULER_Task * stun_task; 432 struct GNUNET_SCHEDULER_Task *stun_task;
433 433
434 /** 434 /**
435 * Head of List of STUN servers 435 * Head of List of STUN servers
@@ -460,15 +460,6 @@ start_gnunet_nat_server (struct GNUNET_NAT_Handle *h);
460 460
461 461
462/** 462/**
463 * Call task to process STUN
464 *
465 * @param cls handle to NAT
466 */
467static void
468process_stun (void *cls);
469
470
471/**
472 * Remove all addresses from the list of 'local' addresses 463 * Remove all addresses from the list of 'local' addresses
473 * that originated from the given source. 464 * that originated from the given source.
474 * 465 *
@@ -688,7 +679,8 @@ process_external_ip (void *cls,
688 /* Current iteration is over, remove 'old' IPs now */ 679 /* Current iteration is over, remove 'old' IPs now */
689 LOG (GNUNET_ERROR_TYPE_DEBUG, 680 LOG (GNUNET_ERROR_TYPE_DEBUG,
690 "Purging old IPs for external address\n"); 681 "Purging old IPs for external address\n");
691 remove_from_address_list_by_source (h, LAL_EXTERNAL_IP_OLD); 682 remove_from_address_list_by_source (h,
683 LAL_EXTERNAL_IP_OLD);
692 if (1 == inet_pton (AF_INET, 684 if (1 == inet_pton (AF_INET,
693 h->external_address, 685 h->external_address,
694 &dummy)) 686 &dummy))
@@ -704,9 +696,13 @@ process_external_ip (void *cls,
704 } 696 }
705 LOG (GNUNET_ERROR_TYPE_DEBUG, 697 LOG (GNUNET_ERROR_TYPE_DEBUG,
706 "Got IP `%s' for external address `%s'\n", 698 "Got IP `%s' for external address `%s'\n",
707 GNUNET_a2s (addr, addrlen), 699 GNUNET_a2s (addr,
700 addrlen),
708 h->external_address); 701 h->external_address);
709 add_to_address_list (h, LAL_EXTERNAL_IP, addr, addrlen); 702 add_to_address_list (h,
703 LAL_EXTERNAL_IP,
704 addr,
705 addrlen);
710} 706}
711 707
712 708
@@ -740,10 +736,14 @@ process_hostname_ip (void *cls,
740 h->hostname_dns = NULL; 736 h->hostname_dns = NULL;
741 h->hostname_task = 737 h->hostname_task =
742 GNUNET_SCHEDULER_add_delayed (h->hostname_dns_frequency, 738 GNUNET_SCHEDULER_add_delayed (h->hostname_dns_frequency,
743 &resolve_hostname, h); 739 &resolve_hostname,
740 h);
744 return; 741 return;
745 } 742 }
746 add_to_address_list (h, LAL_HOSTNAME_DNS, addr, addrlen); 743 add_to_address_list (h,
744 LAL_HOSTNAME_DNS,
745 addr,
746 addrlen);
747} 747}
748 748
749 749
@@ -1204,7 +1204,7 @@ static void
1204process_stun (void *cls) 1204process_stun (void *cls)
1205{ 1205{
1206 struct GNUNET_NAT_Handle *h = cls; 1206 struct GNUNET_NAT_Handle *h = cls;
1207 struct StunServerList* elem = h->actual_stun_server; 1207 struct StunServerList *elem = h->actual_stun_server;
1208 1208
1209 h->stun_task = NULL; 1209 h->stun_task = NULL;
1210 /* Make the request */ 1210 /* Make the request */
@@ -1260,9 +1260,12 @@ resolve_hostname (void *cls)
1260 1260
1261 h->hostname_task = NULL; 1261 h->hostname_task = NULL;
1262 remove_from_address_list_by_source (h, LAL_HOSTNAME_DNS); 1262 remove_from_address_list_by_source (h, LAL_HOSTNAME_DNS);
1263 GNUNET_assert (NULL == h->hostname_dns);
1263 h->hostname_dns = 1264 h->hostname_dns =
1264 GNUNET_RESOLVER_hostname_resolve (AF_UNSPEC, HOSTNAME_RESOLVE_TIMEOUT, 1265 GNUNET_RESOLVER_hostname_resolve (AF_UNSPEC,
1265 &process_hostname_ip, h); 1266 HOSTNAME_RESOLVE_TIMEOUT,
1267 &process_hostname_ip,
1268 h);
1266} 1269}
1267 1270
1268 1271
@@ -1285,10 +1288,13 @@ resolve_dns (void *cls)
1285 LOG (GNUNET_ERROR_TYPE_DEBUG, 1288 LOG (GNUNET_ERROR_TYPE_DEBUG,
1286 "Resolving external address `%s'\n", 1289 "Resolving external address `%s'\n",
1287 h->external_address); 1290 h->external_address);
1291 GNUNET_assert (NULL == h->ext_dns);
1288 h->ext_dns = 1292 h->ext_dns =
1289 GNUNET_RESOLVER_ip_get (h->external_address, AF_INET, 1293 GNUNET_RESOLVER_ip_get (h->external_address,
1294 AF_INET,
1290 GNUNET_TIME_UNIT_MINUTES, 1295 GNUNET_TIME_UNIT_MINUTES,
1291 &process_external_ip, h); 1296 &process_external_ip,
1297 h);
1292} 1298}
1293 1299
1294 1300
@@ -1636,7 +1642,6 @@ GNUNET_NAT_register (const struct GNUNET_CONFIGURATION_Handle *cfg,
1636 size_t pos_port; 1642 size_t pos_port;
1637 1643
1638 h->socket = sock; 1644 h->socket = sock;
1639 h->actual_stun_server = NULL;
1640 stun_servers = NULL; 1645 stun_servers = NULL;
1641 /* Lets process the servers*/ 1646 /* Lets process the servers*/
1642 (void) GNUNET_CONFIGURATION_get_value_string (cfg, 1647 (void) GNUNET_CONFIGURATION_get_value_string (cfg,
@@ -1644,9 +1649,6 @@ GNUNET_NAT_register (const struct GNUNET_CONFIGURATION_Handle *cfg,
1644 "STUN_SERVERS", 1649 "STUN_SERVERS",
1645 &stun_servers); 1650 &stun_servers);
1646 urls = 0; 1651 urls = 0;
1647 h->stun_servers_head = NULL;
1648 h->stun_servers_tail = NULL;
1649 h->actual_stun_server = NULL;
1650 if ( (NULL != stun_servers) && 1652 if ( (NULL != stun_servers) &&
1651 (strlen (stun_servers) > 0) ) 1653 (strlen (stun_servers) > 0) )
1652 { 1654 {
@@ -1665,8 +1667,8 @@ GNUNET_NAT_register (const struct GNUNET_CONFIGURATION_Handle *cfg,
1665 { 1667 {
1666 struct StunServerList *ml; 1668 struct StunServerList *ml;
1667 1669
1668 /*Check if we do have a port*/ 1670 /* Check if we do have a port */
1669 if((0 == pos_port) || (pos_port <= pos)) 1671 if ((0 == pos_port) || (pos_port <= pos))
1670 { 1672 {
1671 LOG (GNUNET_ERROR_TYPE_WARNING, 1673 LOG (GNUNET_ERROR_TYPE_WARNING,
1672 "STUN server format mistake\n"); 1674 "STUN server format mistake\n");
@@ -1677,7 +1679,7 @@ GNUNET_NAT_register (const struct GNUNET_CONFIGURATION_Handle *cfg,
1677 ml->port = atoi (&stun_servers[pos_port]); 1679 ml->port = atoi (&stun_servers[pos_port]);
1678 1680
1679 /* Remove trailing space */ 1681 /* Remove trailing space */
1680 if(stun_servers[pos] == ' ') 1682 if (stun_servers[pos] == ' ')
1681 ml->address = GNUNET_strdup (&stun_servers[pos + 1]); 1683 ml->address = GNUNET_strdup (&stun_servers[pos + 1]);
1682 else 1684 else
1683 ml->address = GNUNET_strdup (&stun_servers[pos]); 1685 ml->address = GNUNET_strdup (&stun_servers[pos]);
@@ -1688,6 +1690,7 @@ GNUNET_NAT_register (const struct GNUNET_CONFIGURATION_Handle *cfg,
1688 GNUNET_CONTAINER_DLL_insert (h->stun_servers_head, 1690 GNUNET_CONTAINER_DLL_insert (h->stun_servers_head,
1689 h->stun_servers_tail, 1691 h->stun_servers_tail,
1690 ml); 1692 ml);
1693 stun_servers[pos] = '\0';
1691 } 1694 }
1692 } 1695 }
1693 } 1696 }
@@ -1767,9 +1770,30 @@ GNUNET_NAT_unregister (struct GNUNET_NAT_Handle *h)
1767 unsigned int i; 1770 unsigned int i;
1768 struct LocalAddressList *lal; 1771 struct LocalAddressList *lal;
1769 struct MiniList *ml; 1772 struct MiniList *ml;
1770 1773 struct StunServerList *ssl;
1774
1771 LOG (GNUNET_ERROR_TYPE_DEBUG, 1775 LOG (GNUNET_ERROR_TYPE_DEBUG,
1772 "NAT unregister called\n"); 1776 "NAT unregister called\n");
1777 while (NULL != (ssl = h->stun_servers_head))
1778 {
1779 GNUNET_CONTAINER_DLL_remove (h->stun_servers_head,
1780 h->stun_servers_tail,
1781 ssl);
1782 GNUNET_free (ssl->address);
1783 GNUNET_free (ssl);
1784 }
1785 while (NULL != (lal = h->lal_head))
1786 {
1787 GNUNET_CONTAINER_DLL_remove (h->lal_head,
1788 h->lal_tail,
1789 lal);
1790 if (NULL != h->address_callback)
1791 h->address_callback (h->callback_cls,
1792 GNUNET_NO,
1793 (const struct sockaddr *) &lal[1],
1794 lal->addrlen);
1795 GNUNET_free (lal);
1796 }
1773 while (NULL != (ml = h->mini_head)) 1797 while (NULL != (ml = h->mini_head))
1774 { 1798 {
1775 GNUNET_CONTAINER_DLL_remove (h->mini_head, 1799 GNUNET_CONTAINER_DLL_remove (h->mini_head,
@@ -1839,18 +1863,6 @@ GNUNET_NAT_unregister (struct GNUNET_NAT_Handle *h)
1839 h->server_stdout = NULL; 1863 h->server_stdout = NULL;
1840 h->server_stdout_handle = NULL; 1864 h->server_stdout_handle = NULL;
1841 } 1865 }
1842 while (NULL != (lal = h->lal_head))
1843 {
1844 GNUNET_CONTAINER_DLL_remove (h->lal_head,
1845 h->lal_tail,
1846 lal);
1847 if (NULL != h->address_callback)
1848 h->address_callback (h->callback_cls,
1849 GNUNET_NO,
1850 (const struct sockaddr *) &lal[1],
1851 lal->addrlen);
1852 GNUNET_free (lal);
1853 }
1854 for (i = 0; i < h->num_local_addrs; i++) 1866 for (i = 0; i < h->num_local_addrs; i++)
1855 GNUNET_free (h->local_addrs[i]); 1867 GNUNET_free (h->local_addrs[i]);
1856 GNUNET_free_non_null (h->local_addrs); 1868 GNUNET_free_non_null (h->local_addrs);
diff --git a/src/nat/nat_stun.c b/src/nat/nat_stun.c
index 4aa9094ea..b914abb2e 100644
--- a/src/nat/nat_stun.c
+++ b/src/nat/nat_stun.c
@@ -461,9 +461,9 @@ stun_dns_callback (void *cls,
461 int reqlen; 461 int reqlen;
462 struct sockaddr_in server; 462 struct sockaddr_in server;
463 463
464 rh->dns_active = NULL;
465 if (NULL == addr) 464 if (NULL == addr)
466 { 465 {
466 rh->dns_active = NULL;
467 if (GNUNET_NO == rh->dns_success) 467 if (GNUNET_NO == rh->dns_success)
468 { 468 {
469 LOG (GNUNET_ERROR_TYPE_INFO, 469 LOG (GNUNET_ERROR_TYPE_INFO,
@@ -471,8 +471,18 @@ stun_dns_callback (void *cls,
471 rh->stun_server); 471 rh->stun_server);
472 rh->cb (rh->cb_cls, 472 rh->cb (rh->cb_cls,
473 GNUNET_NAT_ERROR_NOT_ONLINE); 473 GNUNET_NAT_ERROR_NOT_ONLINE);
474 GNUNET_NAT_stun_make_request_cancel (rh);
475 } 474 }
475 else if (GNUNET_SYSERR == rh->dns_success)
476 {
477 rh->cb (rh->cb_cls,
478 GNUNET_NAT_ERROR_INTERNAL_NETWORK_ERROR);
479 }
480 else
481 {
482 rh->cb (rh->cb_cls,
483 GNUNET_NAT_ERROR_SUCCESS);
484 }
485 GNUNET_NAT_stun_make_request_cancel (rh);
476 return; 486 return;
477 } 487 }
478 488
@@ -487,31 +497,27 @@ stun_dns_callback (void *cls,
487 497
488 /*Craft the simplest possible STUN packet. A request binding*/ 498 /*Craft the simplest possible STUN packet. A request binding*/
489 req = (struct stun_header *)reqdata; 499 req = (struct stun_header *)reqdata;
490 generate_request_id(req); 500 generate_request_id (req);
491 reqlen = 0; 501 reqlen = 0;
492 req->msgtype = 0; 502 req->msgtype = 0;
493 req->msglen = 0; 503 req->msglen = 0;
494 req->msglen = htons(reqlen); 504 req->msglen = htons (reqlen);
495 req->msgtype = htons(encode_message(STUN_REQUEST, STUN_BINDING)); 505 req->msgtype = htons (encode_message (STUN_REQUEST,
506 STUN_BINDING));
496 507
497 /* Send the packet */ 508 /* Send the packet */
498 if (-1 == GNUNET_NETWORK_socket_sendto (rh->sock, 509 if (-1 ==
499 req, 510 GNUNET_NETWORK_socket_sendto (rh->sock,
500 ntohs(req->msglen) + sizeof(*req), 511 req,
501 (const struct sockaddr *) &server, 512 ntohs(req->msglen) + sizeof(*req),
502 sizeof (server))) 513 (const struct sockaddr *) &server,
514 sizeof (server)))
503 { 515 {
504 GNUNET_log_strerror (GNUNET_ERROR_TYPE_ERROR, 516 GNUNET_log_strerror (GNUNET_ERROR_TYPE_ERROR,
505 "Fail to sendto"); 517 "sendto");
506 rh->cb (rh->cb_cls, 518 rh->dns_success = GNUNET_SYSERR;
507 GNUNET_NAT_ERROR_INTERNAL_NETWORK_ERROR);
508 GNUNET_NAT_stun_make_request_cancel (rh);
509 return; 519 return;
510 } 520 }
511 /* sending STUN request done, let's wait for replies... */
512 rh->cb (rh->cb_cls,
513 GNUNET_NAT_ERROR_SUCCESS);
514 GNUNET_NAT_stun_make_request_cancel (rh);
515} 521}
516 522
517 523
@@ -550,8 +556,6 @@ GNUNET_NAT_stun_make_request (const char *server,
550 &stun_dns_callback, rh); 556 &stun_dns_callback, rh);
551 if (NULL == rh->dns_active) 557 if (NULL == rh->dns_active)
552 { 558 {
553 GNUNET_log_strerror (GNUNET_ERROR_TYPE_ERROR,
554 "Failed DNS");
555 GNUNET_NAT_stun_make_request_cancel (rh); 559 GNUNET_NAT_stun_make_request_cancel (rh);
556 return NULL; 560 return NULL;
557 } 561 }
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