diff options
Diffstat (limited to 'src/transport/plugin_transport_udp.c')
-rw-r--r-- | src/transport/plugin_transport_udp.c | 175 |
1 files changed, 114 insertions, 61 deletions
diff --git a/src/transport/plugin_transport_udp.c b/src/transport/plugin_transport_udp.c index 36a3650cf..228eaeb6c 100644 --- a/src/transport/plugin_transport_udp.c +++ b/src/transport/plugin_transport_udp.c | |||
@@ -2687,6 +2687,7 @@ setup_sockets (struct Plugin *plugin, struct sockaddr_in6 *bind_v6, struct socka | |||
2687 | } | 2687 | } |
2688 | else | 2688 | else |
2689 | { | 2689 | { |
2690 | memset (&serverAddrv6, '\0', sizeof (struct sockaddr_in6)); | ||
2690 | #if HAVE_SOCKADDR_IN_SIN_LEN | 2691 | #if HAVE_SOCKADDR_IN_SIN_LEN |
2691 | serverAddrv6.sin6_len = sizeof (struct sockaddr_in6); | 2692 | serverAddrv6.sin6_len = sizeof (struct sockaddr_in6); |
2692 | #endif | 2693 | #endif |
@@ -2695,84 +2696,134 @@ setup_sockets (struct Plugin *plugin, struct sockaddr_in6 *bind_v6, struct socka | |||
2695 | serverAddrv6.sin6_addr = bind_v6->sin6_addr; | 2696 | serverAddrv6.sin6_addr = bind_v6->sin6_addr; |
2696 | else | 2697 | else |
2697 | serverAddrv6.sin6_addr = in6addr_any; | 2698 | serverAddrv6.sin6_addr = in6addr_any; |
2698 | serverAddrv6.sin6_port = htons (plugin->port); | 2699 | |
2700 | if (0 == plugin->port) | ||
2701 | /* autodetect */ | ||
2702 | serverAddrv6.sin6_port = htons (GNUNET_CRYPTO_random_u32 (GNUNET_CRYPTO_QUALITY_STRONG, 33537) + 32000); | ||
2703 | else | ||
2704 | serverAddrv6.sin6_port = htons (plugin->port); | ||
2705 | |||
2706 | |||
2699 | addrlen = sizeof (struct sockaddr_in6); | 2707 | addrlen = sizeof (struct sockaddr_in6); |
2700 | serverAddr = (struct sockaddr *) &serverAddrv6; | 2708 | serverAddr = (struct sockaddr *) &serverAddrv6; |
2701 | LOG (GNUNET_ERROR_TYPE_INFO, "Binding to IPv6 `%s'\n", | 2709 | |
2702 | GNUNET_a2s (serverAddr, addrlen)); | ||
2703 | tries = 0; | 2710 | tries = 0; |
2704 | while (GNUNET_OK != GNUNET_NETWORK_socket_bind (plugin->sockv6, | 2711 | while (tries < 10) |
2705 | (struct sockaddr *) &serverAddrv6, | ||
2706 | addrlen)) | ||
2707 | { | 2712 | { |
2708 | serverAddrv6.sin6_port = htons (GNUNET_CRYPTO_random_u32 (GNUNET_CRYPTO_QUALITY_STRONG, 33537) + 32000); /* Find a good, non-root port */ | 2713 | LOG (GNUNET_ERROR_TYPE_DEBUG, "Binding to IPv6 `%s'\n", |
2709 | LOG (GNUNET_ERROR_TYPE_DEBUG, | 2714 | GNUNET_a2s (serverAddr, addrlen)); |
2710 | "IPv6 Binding failed, trying new port %d\n", | 2715 | |
2711 | ntohs (serverAddrv6.sin6_port)); | 2716 | /* binding */ |
2712 | tries++; | 2717 | if (GNUNET_OK == GNUNET_NETWORK_socket_bind (plugin->sockv6, serverAddr, addrlen)) |
2713 | if (tries > 10) | 2718 | break; |
2714 | { | 2719 | |
2715 | GNUNET_NETWORK_socket_close (plugin->sockv6); | 2720 | if (0 != plugin->port) |
2716 | plugin->sockv6 = NULL; | 2721 | { |
2717 | break; | 2722 | tries = 10; /* fail */ |
2718 | } | 2723 | break; /* bind failed on specific port */ |
2724 | } | ||
2725 | |||
2726 | /* autodetect */ | ||
2727 | serverAddrv6.sin6_port = htons (GNUNET_CRYPTO_random_u32 (GNUNET_CRYPTO_QUALITY_STRONG, 33537) + 32000); | ||
2728 | tries ++; | ||
2719 | } | 2729 | } |
2730 | |||
2731 | if (tries >= 10) | ||
2732 | { | ||
2733 | GNUNET_NETWORK_socket_close (plugin->sockv6); | ||
2734 | plugin->sockv6 = NULL; | ||
2735 | } | ||
2736 | |||
2720 | if (plugin->sockv6 != NULL) | 2737 | if (plugin->sockv6 != NULL) |
2721 | { | 2738 | { |
2722 | LOG (GNUNET_ERROR_TYPE_DEBUG, | 2739 | LOG (GNUNET_ERROR_TYPE_DEBUG, |
2723 | "IPv6 socket created on port %d\n", | 2740 | "IPv6 socket created on port %s\n", |
2724 | ntohs (serverAddrv6.sin6_port)); | 2741 | GNUNET_a2s (serverAddr, addrlen)); |
2725 | addrs[sockets_created] = (struct sockaddr *) &serverAddrv6; | 2742 | addrs[sockets_created] = (struct sockaddr *) &serverAddrv6; |
2726 | addrlens[sockets_created] = sizeof (struct sockaddr_in6); | 2743 | addrlens[sockets_created] = sizeof (struct sockaddr_in6); |
2727 | sockets_created++; | 2744 | sockets_created++; |
2728 | } | 2745 | } |
2746 | else | ||
2747 | { | ||
2748 | LOG (GNUNET_ERROR_TYPE_ERROR, | ||
2749 | "Failed to create IPv6 socket created on %s\n", | ||
2750 | GNUNET_a2s (serverAddr, addrlen)); | ||
2751 | } | ||
2729 | } | 2752 | } |
2730 | } | 2753 | } |
2731 | 2754 | ||
2732 | /* Create IPv4 socket */ | 2755 | /* Create IPv4 socket */ |
2733 | plugin->sockv4 = GNUNET_NETWORK_socket_create (PF_INET, SOCK_DGRAM, 0); | 2756 | plugin->sockv4 = GNUNET_NETWORK_socket_create (PF_INET, SOCK_DGRAM, 0); |
2734 | if (NULL == plugin->sockv4) | 2757 | if (NULL == plugin->sockv4) |
2735 | { | 2758 | { |
2736 | GNUNET_log_strerror (GNUNET_ERROR_TYPE_WARNING, "socket"); | 2759 | LOG (GNUNET_ERROR_TYPE_WARNING, "Failed to create IPv4 socket!\n"); |
2737 | } | 2760 | return sockets_created; |
2738 | else | 2761 | } |
2739 | { | 2762 | else |
2763 | { | ||
2764 | memset (&serverAddrv4, '\0', sizeof (struct sockaddr_in)); | ||
2740 | #if HAVE_SOCKADDR_IN_SIN_LEN | 2765 | #if HAVE_SOCKADDR_IN_SIN_LEN |
2741 | serverAddrv4.sin_len = sizeof (struct sockaddr_in); | 2766 | serverAddrv4.sin_len = sizeof (struct sockaddr_in); |
2742 | #endif | 2767 | #endif |
2743 | serverAddrv4.sin_family = AF_INET; | 2768 | serverAddrv4.sin_family = AF_INET; |
2744 | if (NULL != bind_v4) | 2769 | if (NULL != bind_v4) |
2745 | serverAddrv4.sin_addr = bind_v4->sin_addr; | 2770 | serverAddrv4.sin_addr = bind_v4->sin_addr; |
2746 | else | 2771 | else |
2747 | serverAddrv4.sin_addr.s_addr = INADDR_ANY; | 2772 | serverAddrv4.sin_addr.s_addr = INADDR_ANY; |
2748 | serverAddrv4.sin_port = htons (plugin->port); | 2773 | |
2749 | addrlen = sizeof (struct sockaddr_in); | 2774 | if (0 == plugin->port) |
2750 | serverAddr = (struct sockaddr *) &serverAddrv4; | 2775 | /* autodetect */ |
2751 | 2776 | serverAddrv4.sin_port = htons (GNUNET_CRYPTO_random_u32 (GNUNET_CRYPTO_QUALITY_STRONG, 33537) + 32000); | |
2752 | LOG (GNUNET_ERROR_TYPE_INFO, "Binding to IPv4 %s\n", | 2777 | else |
2753 | GNUNET_a2s (serverAddr, addrlen)); | 2778 | serverAddrv4.sin_port = htons (plugin->port); |
2754 | tries = 0; | 2779 | |
2755 | while (GNUNET_NETWORK_socket_bind (plugin->sockv4, serverAddr, addrlen) != | 2780 | |
2756 | GNUNET_OK) | 2781 | addrlen = sizeof (struct sockaddr_in); |
2757 | { | 2782 | serverAddr = (struct sockaddr *) &serverAddrv4; |
2758 | serverAddrv4.sin_port = htons (GNUNET_CRYPTO_random_u32 (GNUNET_CRYPTO_QUALITY_STRONG, 33537) + 32000); /* Find a good, non-root port */ | 2783 | |
2759 | LOG (GNUNET_ERROR_TYPE_DEBUG, "IPv4 Binding failed, trying new port %d\n", | 2784 | tries = 0; |
2760 | ntohs (serverAddrv4.sin_port)); | 2785 | while (tries < 10) |
2761 | tries++; | 2786 | { |
2762 | if (tries > 10) | 2787 | LOG (GNUNET_ERROR_TYPE_DEBUG, "Binding to IPv4 `%s'\n", |
2763 | { | 2788 | GNUNET_a2s (serverAddr, addrlen)); |
2764 | GNUNET_NETWORK_socket_close (plugin->sockv4); | 2789 | |
2765 | plugin->sockv4 = NULL; | 2790 | /* binding */ |
2766 | break; | 2791 | if (GNUNET_OK == GNUNET_NETWORK_socket_bind (plugin->sockv4, serverAddr, addrlen)) |
2767 | } | 2792 | break; |
2768 | } | 2793 | |
2769 | if (plugin->sockv4 != NULL) | 2794 | if (0 != plugin->port) |
2770 | { | 2795 | { |
2771 | addrs[sockets_created] = (struct sockaddr *) &serverAddrv4; | 2796 | tries = 10; /* fail */ |
2772 | addrlens[sockets_created] = sizeof (struct sockaddr_in); | 2797 | break; /* bind failed on specific port */ |
2773 | sockets_created++; | 2798 | } |
2774 | } | 2799 | |
2775 | } | 2800 | /* autodetect */ |
2801 | serverAddrv4.sin_port = htons (GNUNET_CRYPTO_random_u32 (GNUNET_CRYPTO_QUALITY_STRONG, 33537) + 32000); | ||
2802 | tries ++; | ||
2803 | } | ||
2804 | |||
2805 | if (tries >= 10) | ||
2806 | { | ||
2807 | GNUNET_NETWORK_socket_close (plugin->sockv4); | ||
2808 | plugin->sockv4 = NULL; | ||
2809 | } | ||
2810 | |||
2811 | if (plugin->sockv4 != NULL) | ||
2812 | { | ||
2813 | LOG (GNUNET_ERROR_TYPE_DEBUG, | ||
2814 | "IPv4 socket created on port %s\n", | ||
2815 | GNUNET_a2s (serverAddr, addrlen)); | ||
2816 | addrs[sockets_created] = (struct sockaddr *) &serverAddrv4; | ||
2817 | addrlens[sockets_created] = sizeof (struct sockaddr_in); | ||
2818 | sockets_created++; | ||
2819 | } | ||
2820 | else | ||
2821 | { | ||
2822 | LOG (GNUNET_ERROR_TYPE_ERROR, | ||
2823 | "Failed to create IPv4 socket created on %s\n", | ||
2824 | GNUNET_a2s (serverAddr, addrlen)); | ||
2825 | } | ||
2826 | } | ||
2776 | 2827 | ||
2777 | /* Create file descriptors */ | 2828 | /* Create file descriptors */ |
2778 | plugin->rs_v4 = GNUNET_NETWORK_fdset_create (); | 2829 | plugin->rs_v4 = GNUNET_NETWORK_fdset_create (); |
@@ -2852,7 +2903,9 @@ libgnunet_plugin_transport_udp_init (void *cls) | |||
2852 | 2903 | ||
2853 | GNUNET_assert( NULL != env->stats); | 2904 | GNUNET_assert( NULL != env->stats); |
2854 | 2905 | ||
2855 | /* Get port number */ | 2906 | /* Get port number: port == 0 : autodetect a port, |
2907 | * > 0 : use this port, | ||
2908 | * not given : 2086 default */ | ||
2856 | if (GNUNET_OK != | 2909 | if (GNUNET_OK != |
2857 | GNUNET_CONFIGURATION_get_value_number (env->cfg, "transport-udp", "PORT", | 2910 | GNUNET_CONFIGURATION_get_value_number (env->cfg, "transport-udp", "PORT", |
2858 | &port)) | 2911 | &port)) |