diff options
author | Christian Grothoff <christian@grothoff.org> | 2010-11-29 22:32:59 +0000 |
---|---|---|
committer | Christian Grothoff <christian@grothoff.org> | 2010-11-29 22:32:59 +0000 |
commit | c188e8a0cae8ede61e4f8924e8b52558d0ac1861 (patch) | |
tree | ef82bb2e123af423334939466daa0fffc4476bd5 | |
parent | 0942d0e8b1f95d69f550aac7b8abe5e64b2fb6b8 (diff) | |
download | gnunet-c188e8a0cae8ede61e4f8924e8b52558d0ac1861.tar.gz gnunet-c188e8a0cae8ede61e4f8924e8b52558d0ac1861.zip |
allowing DynDNS for external IP specification, option clean up
-rw-r--r-- | contrib/defaults.conf | 7 | ||||
-rw-r--r-- | src/transport/plugin_transport_tcp.c | 178 |
2 files changed, 135 insertions, 50 deletions
diff --git a/contrib/defaults.conf b/contrib/defaults.conf index af9b8f818..d1f83a3aa 100644 --- a/contrib/defaults.conf +++ b/contrib/defaults.conf | |||
@@ -24,7 +24,7 @@ ADVERTISED_PORT = 2086 | |||
24 | BEHIND_NAT = YES | 24 | BEHIND_NAT = YES |
25 | 25 | ||
26 | # Is the NAT hole-punched? | 26 | # Is the NAT hole-punched? |
27 | #NEW: PUNCHED_NAT = NO | 27 | PUNCHED_NAT = NO |
28 | 28 | ||
29 | # External IP address of the NAT box (if known); IPv4 dotted-decimal ONLY at this time (should allow DynDNS!) | 29 | # External IP address of the NAT box (if known); IPv4 dotted-decimal ONLY at this time (should allow DynDNS!) |
30 | # normal interface IP address for non-NATed peers; | 30 | # normal interface IP address for non-NATed peers; |
@@ -33,9 +33,8 @@ BEHIND_NAT = YES | |||
33 | 33 | ||
34 | # Should we use ICMP-based NAT traversal to try connect to NATed peers | 34 | # Should we use ICMP-based NAT traversal to try connect to NATed peers |
35 | # or, if we are behind NAT, to allow connections to us? | 35 | # or, if we are behind NAT, to allow connections to us? |
36 | ALLOW_NAT = YES | 36 | ENABLE_ICMP_CLIENT = YES |
37 | #NEW: ENABLE_ICMP_CLIENT = YES | 37 | ENABLE_ICMP_SERVER = YES |
38 | #NEW: ENABLE_ICMP_SERVER = YES | ||
39 | 38 | ||
40 | # Are we allowed to try UPnP/PMP? | 39 | # Are we allowed to try UPnP/PMP? |
41 | ENABLE_UPNP = YES | 40 | ENABLE_UPNP = YES |
diff --git a/src/transport/plugin_transport_tcp.c b/src/transport/plugin_transport_tcp.c index 18aad989c..627cb6b9b 100644 --- a/src/transport/plugin_transport_tcp.c +++ b/src/transport/plugin_transport_tcp.c | |||
@@ -454,6 +454,11 @@ struct Plugin | |||
454 | struct TCPProbeContext *probe_tail; | 454 | struct TCPProbeContext *probe_tail; |
455 | 455 | ||
456 | /** | 456 | /** |
457 | * Handle for (DYN)DNS lookup of our external IP. | ||
458 | */ | ||
459 | struct GNUNET_RESOLVER_RequestHandle *ext_dns; | ||
460 | |||
461 | /** | ||
457 | * ID of task used to update our addresses when one expires. | 462 | * ID of task used to update our addresses when one expires. |
458 | */ | 463 | */ |
459 | GNUNET_SCHEDULER_TaskIdentifier address_update_task; | 464 | GNUNET_SCHEDULER_TaskIdentifier address_update_task; |
@@ -475,14 +480,24 @@ struct Plugin | |||
475 | int behind_nat; | 480 | int behind_nat; |
476 | 481 | ||
477 | /** | 482 | /** |
483 | * Has the NAT been punched? | ||
484 | */ | ||
485 | int nat_punched; | ||
486 | |||
487 | /** | ||
478 | * Is this transport configured to allow connections to NAT'd peers? | 488 | * Is this transport configured to allow connections to NAT'd peers? |
479 | */ | 489 | */ |
480 | int allow_nat; | 490 | int enable_nat_client; |
491 | |||
492 | /** | ||
493 | * Should we run the gnunet-nat-server? | ||
494 | */ | ||
495 | int enable_nat_server; | ||
481 | 496 | ||
482 | /** | 497 | /** |
483 | * Are we allowed to try UPnP/PMP for NAT traversal? | 498 | * Are we allowed to try UPnP/PMP for NAT traversal? |
484 | */ | 499 | */ |
485 | int allow_upnp; | 500 | int enable_upnp; |
486 | 501 | ||
487 | }; | 502 | }; |
488 | 503 | ||
@@ -619,7 +634,8 @@ add_to_address_list (struct Plugin *plugin, | |||
619 | GNUNET_break (0); | 634 | GNUNET_break (0); |
620 | return; | 635 | return; |
621 | } | 636 | } |
622 | if (plugin->allow_upnp) | 637 | if ( (plugin->behind_nat == GNUNET_YES) && |
638 | (plugin->enable_upnp == GNUNET_YES) ) | ||
623 | lal->nat = GNUNET_NAT_register (sa, salen, | 639 | lal->nat = GNUNET_NAT_register (sa, salen, |
624 | &nat_port_map_callback, | 640 | &nat_port_map_callback, |
625 | lal); | 641 | lal); |
@@ -1362,8 +1378,10 @@ tcp_plugin_send (void *cls, | |||
1362 | return -1; /* NAT client only works with IPv4 addresses */ | 1378 | return -1; /* NAT client only works with IPv4 addresses */ |
1363 | 1379 | ||
1364 | 1380 | ||
1365 | if ((plugin->allow_nat == GNUNET_YES) && (is_natd == GNUNET_YES) && | 1381 | if ( (plugin->enable_nat_client == GNUNET_YES) && |
1366 | (GNUNET_NO == GNUNET_CONTAINER_multihashmap_contains(plugin->nat_wait_conns, &target->hashPubKey))) | 1382 | (is_natd == GNUNET_YES) && |
1383 | (GNUNET_NO == GNUNET_CONTAINER_multihashmap_contains(plugin->nat_wait_conns, | ||
1384 | &target->hashPubKey)) ) | ||
1367 | { | 1385 | { |
1368 | #if DEBUG_TCP_NAT | 1386 | #if DEBUG_TCP_NAT |
1369 | GNUNET_log_from (GNUNET_ERROR_TYPE_DEBUG, | 1387 | GNUNET_log_from (GNUNET_ERROR_TYPE_DEBUG, |
@@ -1407,9 +1425,10 @@ tcp_plugin_send (void *cls, | |||
1407 | run_gnunet_nat_client (plugin, &a4); | 1425 | run_gnunet_nat_client (plugin, &a4); |
1408 | return 0; | 1426 | return 0; |
1409 | } | 1427 | } |
1410 | if ( (plugin->allow_nat == GNUNET_YES) && | 1428 | if ( (plugin->enable_nat_client == GNUNET_YES) && |
1411 | (is_natd == GNUNET_YES) && | 1429 | (is_natd == GNUNET_YES) && |
1412 | (GNUNET_YES == GNUNET_CONTAINER_multihashmap_contains(plugin->nat_wait_conns, &target->hashPubKey)) ) | 1430 | (GNUNET_YES == GNUNET_CONTAINER_multihashmap_contains(plugin->nat_wait_conns, |
1431 | &target->hashPubKey)) ) | ||
1413 | { | 1432 | { |
1414 | /* Only do one NAT punch attempt per peer identity */ | 1433 | /* Only do one NAT punch attempt per peer identity */ |
1415 | return -1; | 1434 | return -1; |
@@ -2593,6 +2612,58 @@ check_gnunet_nat_binary (const char *binary) | |||
2593 | 2612 | ||
2594 | 2613 | ||
2595 | /** | 2614 | /** |
2615 | * Our (external) hostname was resolved. | ||
2616 | * | ||
2617 | * @param cls the 'struct Plugin' | ||
2618 | * @param addr NULL on error, otherwise result of DNS lookup | ||
2619 | * @param addrlen number of bytes in addr | ||
2620 | */ | ||
2621 | static void | ||
2622 | process_external_ip (void *cls, | ||
2623 | const struct sockaddr *addr, | ||
2624 | socklen_t addrlen) | ||
2625 | { | ||
2626 | struct Plugin *plugin = cls; | ||
2627 | const struct sockaddr_in *s; | ||
2628 | struct IPv4TcpAddress t4; | ||
2629 | |||
2630 | |||
2631 | plugin->ext_dns = NULL; | ||
2632 | if (addr == NULL) | ||
2633 | return; | ||
2634 | GNUNET_assert (addrlen == sizeof (struct sockaddr_in)); | ||
2635 | s = (const struct sockaddr_in *) addr; | ||
2636 | t4.ipv4_addr = s->sin_addr.s_addr; | ||
2637 | if ( (plugin->behind_nat == GNUNET_YES) && | ||
2638 | (plugin->enable_nat_server == GNUNET_YES) ) | ||
2639 | { | ||
2640 | t4.t_port = htons(0); | ||
2641 | GNUNET_log_from (GNUNET_ERROR_TYPE_DEBUG, | ||
2642 | "tcp", | ||
2643 | "Notifying transport of address %s:%d\n", | ||
2644 | plugin->external_address, | ||
2645 | 0); | ||
2646 | } | ||
2647 | else | ||
2648 | { | ||
2649 | t4.t_port = htons(plugin->adv_port); | ||
2650 | GNUNET_log_from (GNUNET_ERROR_TYPE_DEBUG, | ||
2651 | "tcp", | ||
2652 | "Notifying transport of address %s:%d\n", | ||
2653 | plugin->external_address, | ||
2654 | (int) plugin->adv_port); | ||
2655 | } | ||
2656 | add_to_address_list (plugin, | ||
2657 | &t4.ipv4_addr, | ||
2658 | sizeof (struct in_addr)); | ||
2659 | plugin->env->notify_address (plugin->env->cls, | ||
2660 | "tcp", | ||
2661 | &t4, sizeof(t4), | ||
2662 | GNUNET_TIME_UNIT_FOREVER_REL); | ||
2663 | } | ||
2664 | |||
2665 | |||
2666 | /** | ||
2596 | * Entry point for the plugin. | 2667 | * Entry point for the plugin. |
2597 | * | 2668 | * |
2598 | * @param cls closure, the 'struct GNUNET_TRANSPORT_PluginEnvironment*' | 2669 | * @param cls closure, the 'struct GNUNET_TRANSPORT_PluginEnvironment*' |
@@ -2616,32 +2687,44 @@ libgnunet_plugin_transport_tcp_init (void *cls) | |||
2616 | unsigned long long bport; | 2687 | unsigned long long bport; |
2617 | unsigned int i; | 2688 | unsigned int i; |
2618 | int behind_nat; | 2689 | int behind_nat; |
2619 | int allow_nat; | 2690 | int nat_punched; |
2691 | int enable_nat_client; | ||
2692 | int enable_nat_server; | ||
2693 | int enable_upnp; | ||
2620 | char *internal_address; | 2694 | char *internal_address; |
2621 | char *external_address; | 2695 | char *external_address; |
2622 | struct sockaddr_in in_addr; | 2696 | struct sockaddr_in in_addr; |
2623 | struct IPv4TcpAddress t4; | ||
2624 | struct GNUNET_TIME_Relative idle_timeout; | 2697 | struct GNUNET_TIME_Relative idle_timeout; |
2625 | 2698 | ||
2626 | behind_nat = GNUNET_CONFIGURATION_get_value_yesno (env->cfg, | 2699 | behind_nat = GNUNET_CONFIGURATION_get_value_yesno (env->cfg, |
2627 | "transport-tcp", | 2700 | "transport-tcp", |
2628 | "BEHIND_NAT"); | 2701 | "BEHIND_NAT"); |
2629 | if ( (GNUNET_YES == behind_nat) && | 2702 | nat_punched = GNUNET_CONFIGURATION_get_value_yesno (env->cfg, |
2703 | "transport-tcp", | ||
2704 | "NAT_PUNCHED"); | ||
2705 | enable_nat_client = GNUNET_CONFIGURATION_get_value_yesno (env->cfg, | ||
2706 | "transport-tcp", | ||
2707 | "ENABLE_NAT_CLIENT"); | ||
2708 | enable_nat_server = GNUNET_CONFIGURATION_get_value_yesno (env->cfg, | ||
2709 | "transport-tcp", | ||
2710 | "ENABLE_NAT_SERVER"); | ||
2711 | enable_upnp = GNUNET_CONFIGURATION_get_value_yesno (env->cfg, | ||
2712 | "transport-tcp", | ||
2713 | "ENABLE_UPNP"); | ||
2714 | |||
2715 | if ( (GNUNET_YES == enable_nat_server) && | ||
2630 | (GNUNET_YES != check_gnunet_nat_binary("gnunet-nat-server")) ) | 2716 | (GNUNET_YES != check_gnunet_nat_binary("gnunet-nat-server")) ) |
2631 | { | 2717 | { |
2632 | behind_nat = GNUNET_NO; | 2718 | enable_nat_server = GNUNET_NO; |
2633 | GNUNET_log (GNUNET_ERROR_TYPE_WARNING, | 2719 | GNUNET_log (GNUNET_ERROR_TYPE_WARNING, |
2634 | _("Configuration requires `%s', but binary is not installed properly (SUID bit not set). Option disabled.\n"), | 2720 | _("Configuration requires `%s', but binary is not installed properly (SUID bit not set). Option disabled.\n"), |
2635 | "gnunet-nat-server"); | 2721 | "gnunet-nat-server"); |
2636 | } | 2722 | } |
2637 | 2723 | ||
2638 | allow_nat = GNUNET_CONFIGURATION_get_value_yesno (env->cfg, | 2724 | if ( (GNUNET_YES == enable_nat_client) && |
2639 | "transport-tcp", | ||
2640 | "ALLOW_NAT"); | ||
2641 | if ( (GNUNET_YES == allow_nat) && | ||
2642 | (GNUNET_YES != check_gnunet_nat_binary("gnunet-nat-client")) ) | 2725 | (GNUNET_YES != check_gnunet_nat_binary("gnunet-nat-client")) ) |
2643 | { | 2726 | { |
2644 | allow_nat = GNUNET_NO; | 2727 | enable_nat_client = GNUNET_NO; |
2645 | GNUNET_log (GNUNET_ERROR_TYPE_WARNING, | 2728 | GNUNET_log (GNUNET_ERROR_TYPE_WARNING, |
2646 | _("Configuration requires `%s', but binary is not installed properly (SUID bit not set). Option disabled.\n"), | 2729 | _("Configuration requires `%s', but binary is not installed properly (SUID bit not set). Option disabled.\n"), |
2647 | "gnunet-nat-client"); | 2730 | "gnunet-nat-client"); |
@@ -2662,6 +2745,7 @@ libgnunet_plugin_transport_tcp_init (void *cls) | |||
2662 | if ( (external_address != NULL) && | 2745 | if ( (external_address != NULL) && |
2663 | (inet_pton(AF_INET, external_address, &in_addr.sin_addr) != 1) ) | 2746 | (inet_pton(AF_INET, external_address, &in_addr.sin_addr) != 1) ) |
2664 | { | 2747 | { |
2748 | |||
2665 | GNUNET_log_from (GNUNET_ERROR_TYPE_WARNING, | 2749 | GNUNET_log_from (GNUNET_ERROR_TYPE_WARNING, |
2666 | "tcp", | 2750 | "tcp", |
2667 | _("Malformed %s `%s' given in configuration!\n"), | 2751 | _("Malformed %s `%s' given in configuration!\n"), |
@@ -2669,6 +2753,20 @@ libgnunet_plugin_transport_tcp_init (void *cls) | |||
2669 | external_address); | 2753 | external_address); |
2670 | return NULL; | 2754 | return NULL; |
2671 | } | 2755 | } |
2756 | if ( (external_address == NULL) && | ||
2757 | (nat_punched == GNUNET_YES) ) | ||
2758 | { | ||
2759 | nat_punched = GNUNET_NO; | ||
2760 | GNUNET_log (GNUNET_ERROR_TYPE_WARNING, | ||
2761 | _("Configuration says NAT was punched, but `%s' is not given. Option ignored.\n"), | ||
2762 | "EXTERNAL_ADDRESS"); | ||
2763 | } | ||
2764 | |||
2765 | if (GNUNET_YES == nat_punched) | ||
2766 | { | ||
2767 | enable_nat_server = GNUNET_NO; | ||
2768 | enable_upnp = GNUNET_NO; | ||
2769 | } | ||
2672 | 2770 | ||
2673 | internal_address = NULL; | 2771 | internal_address = NULL; |
2674 | if (GNUNET_OK == | 2772 | if (GNUNET_OK == |
@@ -2743,10 +2841,10 @@ libgnunet_plugin_transport_tcp_init (void *cls) | |||
2743 | plugin->external_address = external_address; | 2841 | plugin->external_address = external_address; |
2744 | plugin->internal_address = internal_address; | 2842 | plugin->internal_address = internal_address; |
2745 | plugin->behind_nat = behind_nat; | 2843 | plugin->behind_nat = behind_nat; |
2746 | plugin->allow_nat = allow_nat; | 2844 | plugin->nat_punched = nat_punched; |
2747 | plugin->allow_upnp = GNUNET_CONFIGURATION_get_value_yesno (env->cfg, | 2845 | plugin->enable_nat_client = enable_nat_client; |
2748 | "transport-tcp", | 2846 | plugin->enable_nat_server = enable_nat_server; |
2749 | "ENABLE_UPNP"); | 2847 | plugin->enable_upnp = enable_upnp; |
2750 | plugin->env = env; | 2848 | plugin->env = env; |
2751 | plugin->lsock = NULL; | 2849 | plugin->lsock = NULL; |
2752 | api = GNUNET_malloc (sizeof (struct GNUNET_TRANSPORT_PluginFunctions)); | 2850 | api = GNUNET_malloc (sizeof (struct GNUNET_TRANSPORT_PluginFunctions)); |
@@ -2795,6 +2893,7 @@ libgnunet_plugin_transport_tcp_init (void *cls) | |||
2795 | GNUNET_OS_network_interfaces_list (&process_interfaces, plugin); | 2893 | GNUNET_OS_network_interfaces_list (&process_interfaces, plugin); |
2796 | 2894 | ||
2797 | if ( (plugin->behind_nat == GNUNET_YES) && | 2895 | if ( (plugin->behind_nat == GNUNET_YES) && |
2896 | (plugin->enable_nat_server == GNUNET_YES) && | ||
2798 | (GNUNET_YES != tcp_transport_start_nat_server(plugin)) ) | 2897 | (GNUNET_YES != tcp_transport_start_nat_server(plugin)) ) |
2799 | { | 2898 | { |
2800 | GNUNET_log_from (GNUNET_ERROR_TYPE_ERROR, | 2899 | GNUNET_log_from (GNUNET_ERROR_TYPE_ERROR, |
@@ -2812,7 +2911,7 @@ libgnunet_plugin_transport_tcp_init (void *cls) | |||
2812 | return NULL; | 2911 | return NULL; |
2813 | } | 2912 | } |
2814 | 2913 | ||
2815 | if (allow_nat == GNUNET_YES) | 2914 | if (enable_nat_client == GNUNET_YES) |
2816 | { | 2915 | { |
2817 | plugin->nat_wait_conns = GNUNET_CONTAINER_multihashmap_create(16); | 2916 | plugin->nat_wait_conns = GNUNET_CONTAINER_multihashmap_create(16); |
2818 | GNUNET_assert (plugin->nat_wait_conns != NULL); | 2917 | GNUNET_assert (plugin->nat_wait_conns != NULL); |
@@ -2850,32 +2949,14 @@ libgnunet_plugin_transport_tcp_init (void *cls) | |||
2850 | &process_hostname_ips, | 2949 | &process_hostname_ips, |
2851 | plugin); | 2950 | plugin); |
2852 | 2951 | ||
2853 | if ( (plugin->external_address != NULL) && | 2952 | if (plugin->external_address != NULL) |
2854 | (inet_pton(AF_INET, | ||
2855 | plugin->external_address, | ||
2856 | &t4.ipv4_addr) == 1) ) | ||
2857 | { | 2953 | { |
2858 | if (plugin->behind_nat == GNUNET_YES) | 2954 | plugin->ext_dns = GNUNET_RESOLVER_ip_get (env->cfg, |
2859 | { | 2955 | plugin->external_address, |
2860 | GNUNET_log_from (GNUNET_ERROR_TYPE_DEBUG, | 2956 | AF_INET, |
2861 | "tcp", | 2957 | GNUNET_TIME_UNIT_MINUTES, |
2862 | "Notifying transport of address %s:0\n", | 2958 | &process_external_ip, |
2863 | plugin->external_address); | 2959 | plugin); |
2864 | t4.t_port = htons(0); | ||
2865 | } | ||
2866 | else | ||
2867 | { | ||
2868 | t4.t_port = htons(plugin->adv_port); | ||
2869 | GNUNET_log_from (GNUNET_ERROR_TYPE_DEBUG, | ||
2870 | "tcp", | ||
2871 | "Notifying transport of address %s:%d\n", | ||
2872 | plugin->external_address, | ||
2873 | plugin->adv_port); | ||
2874 | } | ||
2875 | add_to_address_list (plugin, &t4.ipv4_addr, sizeof (struct in_addr)); | ||
2876 | plugin->env->notify_address (plugin->env->cls, | ||
2877 | "tcp", | ||
2878 | &t4, sizeof(t4), GNUNET_TIME_UNIT_FOREVER_REL); | ||
2879 | } | 2960 | } |
2880 | return api; | 2961 | return api; |
2881 | } | 2962 | } |
@@ -2893,6 +2974,11 @@ libgnunet_plugin_transport_tcp_done (void *cls) | |||
2893 | struct LocalAddrList *lal; | 2974 | struct LocalAddrList *lal; |
2894 | struct TCPProbeContext *tcp_probe; | 2975 | struct TCPProbeContext *tcp_probe; |
2895 | 2976 | ||
2977 | if (plugin->ext_dns != NULL) | ||
2978 | { | ||
2979 | GNUNET_RESOLVER_request_cancel (plugin->ext_dns); | ||
2980 | plugin->ext_dns = NULL; | ||
2981 | } | ||
2896 | while (NULL != (session = plugin->sessions)) | 2982 | while (NULL != (session = plugin->sessions)) |
2897 | disconnect_session (session); | 2983 | disconnect_session (session); |
2898 | if (NULL != plugin->hostname_dns) | 2984 | if (NULL != plugin->hostname_dns) |