aboutsummaryrefslogtreecommitdiff
path: root/src/transport
diff options
context:
space:
mode:
Diffstat (limited to 'src/transport')
-rw-r--r--src/transport/plugin_transport_udp.c175
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))