X-Git-Url: https://git.librecmc.org/?a=blobdiff_plain;f=src%2Fnat%2Fgnunet-nat.c;h=72f34362733fd5a65db13ceabcb3b8cddf7979bc;hb=800cb255ea7ae4e6b55095949bc84eb864c08b2e;hp=10921150d8a1a9d250b762f96df80b32c7efa0c3;hpb=73a127e962c5ecbfc002b1b0c9ea9cf441591c6d;p=oweals%2Fgnunet.git diff --git a/src/nat/gnunet-nat.c b/src/nat/gnunet-nat.c index 10921150d..72f343627 100644 --- a/src/nat/gnunet-nat.c +++ b/src/nat/gnunet-nat.c @@ -34,14 +34,10 @@ static int global_ret; /** - * Handle to ongoing autoconfiguration. + * Name of section in configuration file to use for + * additional options. */ -static struct GNUNET_NAT_AutoHandle *ah; - -/** - * Port we advertise. - */ -static unsigned int adv_port; +static char *section_name; /** * Flag set to 1 if we use IPPROTO_UDP. @@ -63,18 +59,6 @@ static int use_tcp; */ static uint8_t proto; -/** - * Address we are bound to (in test), or should bind to - * (if #do_stun is set). - */ -static char *bind_addr; - -/** - * External IP address and port to use for the test. - * If not set, use #bind_addr. - */ -static char *extern_addr; - /** * Local address to use for connection reversal request. */ @@ -88,17 +72,7 @@ static char *remote_addr; /** * Should we actually bind to #bind_addr and receive and process STUN requests? */ -static unsigned int do_stun; - -/** - * Should we run autoconfiguration? - */ -static unsigned int do_auto; - -/** - * Handle to a NAT test operation. - */ -static struct GNUNET_NAT_Test *nt; +static int do_stun; /** * Handle to NAT operation. @@ -107,7 +81,7 @@ static struct GNUNET_NAT_Handle *nh; /** * Listen socket for STUN processing. - */ + */ static struct GNUNET_NETWORK_Handle *ls; /** @@ -123,10 +97,6 @@ static struct GNUNET_SCHEDULER_Task *rtask; static void test_finished () { - if (NULL != ah) - return; - if (NULL != nt) - return; if (NULL != nh) return; if (NULL != rtask) @@ -135,108 +105,12 @@ test_finished () } -/** - * Function to iterate over sugested changes options - * - * @param cls closure - * @param section name of the section - * @param option name of the option - * @param value value of the option - */ -static void -auto_conf_iter (void *cls, - const char *section, - const char *option, - const char *value) -{ - PRINTF ("%s: %s\n", - option, - value); -} - - -/** - * Function called with the result from the autoconfiguration. - * - * @param cls closure - * @param diff minimal suggested changes to the original configuration - * to make it work (as best as we can) - * @param result #GNUNET_NAT_ERROR_SUCCESS on success, otherwise the specific error code - * @param type what the situation of the NAT - */ -static void -auto_config_cb (void *cls, - const struct GNUNET_CONFIGURATION_Handle *diff, - enum GNUNET_NAT_StatusCode result, - enum GNUNET_NAT_Type type) -{ - const char *nat_type; - char unknown_type[64]; - - ah = NULL; - switch (type) - { - case GNUNET_NAT_TYPE_NO_NAT: - nat_type = "NO NAT"; - break; - case GNUNET_NAT_TYPE_UNREACHABLE_NAT: - nat_type = "NAT but we can traverse"; - break; - case GNUNET_NAT_TYPE_STUN_PUNCHED_NAT: - nat_type = "NAT but STUN is able to identify the correct information"; - break; - case GNUNET_NAT_TYPE_UPNP_NAT: - nat_type = "NAT but UPNP opened the ports"; - break; - default: - SPRINTF (unknown_type, - "NAT unknown, type %u", - type); - nat_type = unknown_type; - break; - } - - PRINTF ("NAT status: %s/%s\n", - GNUNET_NAT_status2string (result), - nat_type); - - if (NULL != diff) - { - PRINTF ("SUGGESTED CHANGES:\n"); - GNUNET_CONFIGURATION_iterate_section_values (diff, - "nat", - &auto_conf_iter, - NULL); - } - // FIXME: have option to save config - test_finished (); -} - - -/** - * Function called to report success or failure for - * NAT configuration test. - * - * @param cls closure - * @param result #GNUNET_NAT_ERROR_SUCCESS on success, otherwise the specific error code - */ -static void -test_report_cb (void *cls, - enum GNUNET_NAT_StatusCode result) -{ - nt = NULL; - PRINTF ("NAT test result: %s\n", - GNUNET_NAT_status2string (result)); - test_finished (); -} - - /** * Signature of the callback passed to #GNUNET_NAT_register() for * a function to call whenever our set of 'valid' addresses changes. * * @param cls closure, NULL - * @param add_remove #GNUNET_YES to add a new public IP address, + * @param add_remove #GNUNET_YES to add a new public IP address, * #GNUNET_NO to remove a previous (now invalid) one * @param ac address class the address belongs to * @param addr either the previous or the new public IP address @@ -249,12 +123,12 @@ address_cb (void *cls, const struct sockaddr *addr, socklen_t addrlen) { - GNUNET_log (GNUNET_ERROR_TYPE_MESSAGE, - "%s %s (%d)\n", - add_remove ? "+" : "-", - GNUNET_a2s (addr, - addrlen), - (int) ac); + fprintf (stdout, + "%s %s (%d)\n", + add_remove ? "+" : "-", + GNUNET_a2s (addr, + addrlen), + (int) ac); } @@ -264,15 +138,11 @@ address_cb (void *cls, * reversal. * * @param cls closure, NULL - * @param local_addr address where we received the request - * @param local_addrlen actual length of the @a local_addr * @param remote_addr public IP address of the other peer * @param remote_addrlen actual length of the @a remote_addr */ static void reversal_cb (void *cls, - const struct sockaddr *local_addr, - socklen_t local_addrlen, const struct sockaddr *remote_addr, socklen_t remote_addrlen) { @@ -291,16 +161,6 @@ reversal_cb (void *cls, static void do_shutdown (void *cls) { - if (NULL != ah) - { - GNUNET_NAT_autoconfig_cancel (ah); - ah = NULL; - } - if (NULL != nt) - { - GNUNET_NAT_test_stop (nt); - nt = NULL; - } if (NULL != nh) { GNUNET_NAT_unregister (nh); @@ -326,7 +186,7 @@ static void stun_read_task (void *cls) { ssize_t size; - + rtask = GNUNET_SCHEDULER_add_read_net (GNUNET_TIME_UNIT_FOREVER_REL, ls, &stun_read_task, @@ -344,7 +204,7 @@ stun_read_task (void *cls) struct sockaddr_storage sa; socklen_t salen = sizeof (sa); ssize_t ret; - + ret = GNUNET_NETWORK_socket_recvfrom (ls, buf, size + 1, @@ -381,13 +241,11 @@ run (void *cls, const struct GNUNET_CONFIGURATION_Handle *c) { uint8_t af; - struct sockaddr_in bind_sa; - struct sockaddr_in extern_sa; struct sockaddr *local_sa; struct sockaddr *remote_sa; - size_t local_len; + socklen_t local_len; size_t remote_len; - + if (use_tcp && use_udp) { GNUNET_log (GNUNET_ERROR_TYPE_MESSAGE, @@ -404,64 +262,31 @@ run (void *cls, GNUNET_SCHEDULER_add_shutdown (&do_shutdown, NULL); - if (do_auto) - { - ah = GNUNET_NAT_autoconfig_start (c, - &auto_config_cb, - NULL); - } - if (0 == proto) { - if (do_auto) - return; /* all good, we just run auto config */ GNUNET_log (GNUNET_ERROR_TYPE_MESSAGE, "Must specify either TCP or UDP\n"); global_ret = 1; return; } - if (NULL != bind_addr) - { - if (GNUNET_OK != - GNUNET_STRINGS_to_address_ipv4 (bind_addr, - strlen (bind_addr), - &bind_sa)) - { - GNUNET_log (GNUNET_ERROR_TYPE_MESSAGE, - "Invalid socket address `%s'\n", - bind_addr); - global_ret = 1; - return; - } - } - if (NULL != extern_addr) - { - if (GNUNET_OK != - GNUNET_STRINGS_to_address_ipv4 (extern_addr, - strlen (extern_addr), - &extern_sa)) - { - GNUNET_log (GNUNET_ERROR_TYPE_MESSAGE, - "Invalid socket address `%s'\n", - extern_addr); - global_ret = 1; - return; - } - } + local_len = 0; + local_sa = NULL; + remote_len = 0; + remote_sa = NULL; if (NULL != local_addr) { - local_len = GNUNET_STRINGS_parse_socket_addr (local_addr, - &af, - &local_sa); + local_len = (socklen_t) GNUNET_STRINGS_parse_socket_addr (local_addr, + &af, + &local_sa); if (0 == local_len) { GNUNET_log (GNUNET_ERROR_TYPE_MESSAGE, "Invalid socket address `%s'\n", local_addr); - global_ret = 1; - return; + goto fail_and_shutdown; } } + if (NULL != remote_addr) { remote_len = GNUNET_STRINGS_parse_socket_addr (remote_addr, @@ -472,30 +297,17 @@ run (void *cls, GNUNET_log (GNUNET_ERROR_TYPE_MESSAGE, "Invalid socket address `%s'\n", remote_addr); - global_ret = 1; - return; + goto fail_and_shutdown; } } - if (NULL != bind_addr) - { - if (NULL == extern_addr) - extern_sa = bind_sa; - nt = GNUNET_NAT_test_start (c, - proto, - bind_sa.sin_addr, - ntohs (bind_sa.sin_port), - extern_sa.sin_addr, - ntohs (extern_sa.sin_port), - &test_report_cb, - NULL); - } - if (NULL != local_addr) { + if (NULL == section_name) + section_name = GNUNET_strdup ("undefined"); nh = GNUNET_NAT_register (c, + section_name, proto, - (uint16_t) adv_port, 1, (const struct sockaddr **) &local_sa, &local_len, @@ -503,31 +315,35 @@ run (void *cls, (listen_reversal) ? &reversal_cb : NULL, NULL); } + else if (listen_reversal) + { + GNUNET_log (GNUNET_ERROR_TYPE_MESSAGE, + "Use of `-W` only effective in combination with `-i`\n"); + goto fail_and_shutdown; + } if (NULL != remote_addr) { int ret; - + if ( (NULL == nh) || (sizeof (struct sockaddr_in) != local_len) ) { GNUNET_log (GNUNET_ERROR_TYPE_MESSAGE, "Require IPv4 local address to initiate connection reversal\n"); - global_ret = 1; - GNUNET_SCHEDULER_shutdown (); - return; + goto fail_and_shutdown; } if (sizeof (struct sockaddr_in) != remote_len) { GNUNET_log (GNUNET_ERROR_TYPE_MESSAGE, "Require IPv4 reversal target address\n"); - global_ret = 1; - GNUNET_SCHEDULER_shutdown (); - return; + goto fail_and_shutdown; } + GNUNET_assert (AF_INET == local_sa->sa_family); + GNUNET_assert (AF_INET == remote_sa->sa_family); ret = GNUNET_NAT_request_reversal (nh, - (const struct sockaddr_in *) &local_sa, - (const struct sockaddr_in *) &remote_sa); + (const struct sockaddr_in *) local_sa, + (const struct sockaddr_in *) remote_sa); switch (ret) { case GNUNET_SYSERR: @@ -543,49 +359,56 @@ run (void *cls, break; } } - + if (do_stun) { if (NULL == local_addr) { GNUNET_log (GNUNET_ERROR_TYPE_MESSAGE, "Require local address to support STUN requests\n"); - global_ret = 1; - GNUNET_SCHEDULER_shutdown (); - return; + goto fail_and_shutdown; } if (IPPROTO_UDP != proto) { GNUNET_log (GNUNET_ERROR_TYPE_MESSAGE, "STUN only supported over UDP\n"); - global_ret = 1; - GNUNET_SCHEDULER_shutdown (); - return; + goto fail_and_shutdown; } ls = GNUNET_NETWORK_socket_create (af, SOCK_DGRAM, IPPROTO_UDP); + if (NULL == ls) + { + GNUNET_log (GNUNET_ERROR_TYPE_MESSAGE, + "Failed to create socket\n"); + goto fail_and_shutdown; + } if (GNUNET_OK != - GNUNET_NETWORK_socket_bind (ls, - local_sa, - local_len)) + GNUNET_NETWORK_socket_bind (ls, + local_sa, + local_len)) { GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "Failed to bind to %s: %s\n", GNUNET_a2s (local_sa, local_len), STRERROR (errno)); - global_ret = 1; - GNUNET_SCHEDULER_shutdown (); - return; + goto fail_and_shutdown; } rtask = GNUNET_SCHEDULER_add_read_net (GNUNET_TIME_UNIT_FOREVER_REL, ls, &stun_read_task, NULL); } - + GNUNET_free_non_null (remote_sa); + GNUNET_free_non_null (local_sa); test_finished (); + return; + fail_and_shutdown: + global_ret = 1; + GNUNET_SCHEDULER_shutdown (); + GNUNET_free_non_null (remote_sa); + GNUNET_free_non_null (local_sa); } @@ -600,38 +423,46 @@ int main (int argc, char *const argv[]) { - static const struct GNUNET_GETOPT_CommandLineOption options[] = { - {'a', "auto", NULL, - gettext_noop ("run autoconfiguration"), - GNUNET_NO, &GNUNET_GETOPT_set_one, &do_auto }, - {'b', "bind", "ADDRESS", - gettext_noop ("which IP and port are we bound to"), - GNUNET_YES, &GNUNET_GETOPT_set_string, &bind_addr }, - {'e', "external", "ADDRESS", - gettext_noop ("which external IP and port should be used to test"), - GNUNET_YES, &GNUNET_GETOPT_set_string, &extern_addr }, - {'i', "in", "ADDRESS", - gettext_noop ("which IP and port are we locally using to listen to for connection reversals"), - GNUNET_YES, &GNUNET_GETOPT_set_string, &local_addr }, - {'r', "remote", "ADDRESS", - gettext_noop ("which remote IP and port should be asked for connection reversal"), - GNUNET_YES, &GNUNET_GETOPT_set_string, &remote_addr }, - {'L', "listen", NULL, - gettext_noop ("listen for connection reversal requests"), - GNUNET_NO, &GNUNET_GETOPT_set_one, &listen_reversal }, - {'p', "port", NULL, - gettext_noop ("port to use to advertise"), - GNUNET_YES, &GNUNET_GETOPT_set_uint, &adv_port }, - {'s', "stun", NULL, - gettext_noop ("enable STUN processing"), - GNUNET_NO, &GNUNET_GETOPT_set_one, &do_stun }, - {'t', "tcp", NULL, - gettext_noop ("use TCP"), - GNUNET_NO, &GNUNET_GETOPT_set_one, &use_tcp }, - {'u', "udp", NULL, - gettext_noop ("use UDP"), - GNUNET_NO, &GNUNET_GETOPT_set_one, &use_udp }, - GNUNET_GETOPT_OPTION_END + struct GNUNET_GETOPT_CommandLineOption options[] = { + + GNUNET_GETOPT_option_string ('i', + "in", + "ADDRESS", + gettext_noop ("which IP and port are we locally using to bind/listen to"), + &local_addr), + + GNUNET_GETOPT_option_string ('r', + "remote", + "ADDRESS", + gettext_noop ("which remote IP and port should be asked for connection reversal"), + &remote_addr), + + GNUNET_GETOPT_option_string ('S', + "section", + NULL, + gettext_noop ("name of configuration section to find additional options, such as manual host punching data"), + §ion_name), + + GNUNET_GETOPT_option_flag ('s', + "stun", + gettext_noop ("enable STUN processing"), + &do_stun), + + GNUNET_GETOPT_option_flag ('t', + "tcp", + gettext_noop ("use TCP"), + &use_tcp), + + GNUNET_GETOPT_option_flag ('u', + "udp", + gettext_noop ("use UDP"), + &use_udp), + + GNUNET_GETOPT_option_flag ('W', + "watch", + gettext_noop ("watch for connection reversal requests"), + &listen_reversal), + GNUNET_GETOPT_OPTION_END }; if (GNUNET_OK !=