aboutsummaryrefslogtreecommitdiff
path: root/src/transport/plugin_transport_http.c
diff options
context:
space:
mode:
authorMatthias Wachs <wachs@net.in.tum.de>2011-10-06 15:11:22 +0000
committerMatthias Wachs <wachs@net.in.tum.de>2011-10-06 15:11:22 +0000
commitfee3601ae573e7a98419036775b30b53faeec157 (patch)
tree511e3dac59211b245311bb98a8c550b865460836 /src/transport/plugin_transport_http.c
parent09aa75cc9decb90576828b4e2b7507301e4c5eb2 (diff)
downloadgnunet-fee3601ae573e7a98419036775b30b53faeec157.tar.gz
gnunet-fee3601ae573e7a98419036775b30b53faeec157.zip
changed get addresses functionality and added IPv6 test
Diffstat (limited to 'src/transport/plugin_transport_http.c')
-rw-r--r--src/transport/plugin_transport_http.c208
1 files changed, 202 insertions, 6 deletions
diff --git a/src/transport/plugin_transport_http.c b/src/transport/plugin_transport_http.c
index 857f5c83b..60eefd419 100644
--- a/src/transport/plugin_transport_http.c
+++ b/src/transport/plugin_transport_http.c
@@ -764,7 +764,7 @@ nat_port_map_callback (void *cls, int add_remove, const struct sockaddr *addr,
764 struct Plugin *plugin = cls; 764 struct Plugin *plugin = cls;
765#endif 765#endif
766#if DEBUG_HTTP 766#if DEBUG_HTTP
767 GNUNET_log_from (GNUNET_ERROR_TYPE_ERROR, plugin->name, 767 GNUNET_log_from (GNUNET_ERROR_TYPE_DEBUG, plugin->name,
768 "NPMC called %s to address `%s'\n", 768 "NPMC called %s to address `%s'\n",
769 (add_remove == GNUNET_NO) ? "remove" : "add", 769 (add_remove == GNUNET_NO) ? "remove" : "add",
770 GNUNET_a2s (addr, addrlen)); 770 GNUNET_a2s (addr, addrlen));
@@ -780,6 +780,204 @@ nat_port_map_callback (void *cls, int add_remove, const struct sockaddr *addr,
780 } 780 }
781} 781}
782 782
783int
784http_get_addresses (struct Plugin *plugin,
785 const char *serviceName,
786 const struct GNUNET_CONFIGURATION_Handle
787 *cfg, struct sockaddr ***addrs,
788 socklen_t ** addr_lens)
789{
790 int disablev6;
791 struct GNUNET_NETWORK_Handle *desc;
792 unsigned long long port;
793 struct addrinfo hints;
794 struct addrinfo *res;
795 struct addrinfo *pos;
796 struct addrinfo *next;
797 unsigned int i;
798 int resi;
799 int ret;
800 struct sockaddr **saddrs;
801 socklen_t *saddrlens;
802 char *hostname;
803
804 *addrs = NULL;
805 *addr_lens = NULL;
806 desc = NULL;
807
808 disablev6 = !plugin->ipv6;
809
810 if (!disablev6)
811 {
812 /* probe IPv6 support */
813 desc = GNUNET_NETWORK_socket_create (PF_INET6, SOCK_STREAM, 0);
814 if (NULL == desc)
815 {
816 if ((errno == ENOBUFS) || (errno == ENOMEM) || (errno == ENFILE) ||
817 (errno == EACCES))
818 {
819 GNUNET_log_strerror (GNUNET_ERROR_TYPE_ERROR, "socket");
820 return GNUNET_SYSERR;
821 }
822 GNUNET_log (GNUNET_ERROR_TYPE_INFO,
823 _
824 ("Disabling IPv6 since it is not supported on this system\n"),
825 serviceName, STRERROR (errno));
826 disablev6 = GNUNET_YES;
827 plugin->ipv6 = GNUNET_NO;
828 }
829 else
830 {
831 GNUNET_break (GNUNET_OK == GNUNET_NETWORK_socket_close (desc));
832 desc = NULL;
833 }
834 }
835
836 port = 0;
837 if (GNUNET_CONFIGURATION_have_value (cfg, serviceName, "PORT"))
838 {
839 GNUNET_break (GNUNET_OK ==
840 GNUNET_CONFIGURATION_get_value_number (cfg, serviceName,
841 "PORT", &port));
842 if (port > 65535)
843 {
844 GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
845 _
846 ("Require valid port number for service in configuration!\n"));
847 return GNUNET_SYSERR;
848 }
849 }
850
851 if (GNUNET_CONFIGURATION_have_value (cfg, serviceName, "BINDTO"))
852 {
853 GNUNET_break (GNUNET_OK ==
854 GNUNET_CONFIGURATION_get_value_string (cfg, serviceName,
855 "BINDTO", &hostname));
856 }
857 else
858 hostname = NULL;
859
860 if (hostname != NULL)
861 {
862 GNUNET_log_from (GNUNET_ERROR_TYPE_DEBUG, plugin->name,
863 "Resolving `%s' since that is where `%s' will bind to.\n",
864 hostname, serviceName);
865 memset (&hints, 0, sizeof (struct addrinfo));
866 if (disablev6)
867 hints.ai_family = AF_INET;
868 if ((0 != (ret = getaddrinfo (hostname, NULL, &hints, &res))) ||
869 (res == NULL))
870 {
871 GNUNET_log (GNUNET_ERROR_TYPE_ERROR, _("Failed to resolve `%s': %s\n"),
872 hostname, gai_strerror (ret));
873 GNUNET_free (hostname);
874 return GNUNET_SYSERR;
875 }
876 next = res;
877 i = 0;
878 while (NULL != (pos = next))
879 {
880 next = pos->ai_next;
881 if ((disablev6) && (pos->ai_family == AF_INET6))
882 continue;
883 i++;
884 }
885 if (0 == i)
886 {
887 GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
888 _("Failed to find %saddress for `%s'.\n"),
889 disablev6 ? "IPv4 " : "", hostname);
890 freeaddrinfo (res);
891 GNUNET_free (hostname);
892 return GNUNET_SYSERR;
893 }
894 resi = i;
895 saddrs = GNUNET_malloc ((resi + 1) * sizeof (struct sockaddr *));
896 saddrlens = GNUNET_malloc ((resi + 1) * sizeof (socklen_t));
897 i = 0;
898 next = res;
899 while (NULL != (pos = next))
900 {
901 next = pos->ai_next;
902 if ((disablev6) && (pos->ai_family == AF_INET6))
903 continue;
904 if ((pos->ai_protocol != IPPROTO_TCP) && (pos->ai_protocol != 0))
905 continue; /* not TCP */
906 if ((pos->ai_socktype != SOCK_STREAM) && (pos->ai_socktype != 0))
907 continue; /* huh? */
908 GNUNET_log_from (GNUNET_ERROR_TYPE_DEBUG, plugin->name,
909 "Service will bind to `%s'\n",
910 GNUNET_a2s (pos->ai_addr, pos->ai_addrlen));
911 if (pos->ai_family == AF_INET)
912 {
913 GNUNET_assert (pos->ai_addrlen == sizeof (struct sockaddr_in));
914 saddrlens[i] = pos->ai_addrlen;
915 saddrs[i] = GNUNET_malloc (saddrlens[i]);
916 memcpy (saddrs[i], pos->ai_addr, saddrlens[i]);
917 ((struct sockaddr_in *) saddrs[i])->sin_port = htons (port);
918 }
919 else
920 {
921 GNUNET_assert (pos->ai_family == AF_INET6);
922 GNUNET_assert (pos->ai_addrlen == sizeof (struct sockaddr_in6));
923 saddrlens[i] = pos->ai_addrlen;
924 saddrs[i] = GNUNET_malloc (saddrlens[i]);
925 memcpy (saddrs[i], pos->ai_addr, saddrlens[i]);
926 ((struct sockaddr_in6 *) saddrs[i])->sin6_port = htons (port);
927 }
928 i++;
929 }
930 GNUNET_free (hostname);
931 freeaddrinfo (res);
932 resi = i;
933 }
934 else
935 {
936 /* will bind against everything, just set port */
937 if (disablev6)
938 {
939 /* V4-only */
940 resi = 1;
941 i = 0;
942 saddrs = GNUNET_malloc ((resi + 1) * sizeof (struct sockaddr *));
943 saddrlens = GNUNET_malloc ((resi + 1) * sizeof (socklen_t));
944
945 saddrlens[i] = sizeof (struct sockaddr_in);
946 saddrs[i] = GNUNET_malloc (saddrlens[i]);
947#if HAVE_SOCKADDR_IN_SIN_LEN
948 ((struct sockaddr_in *) saddrs[i])->sin_len = saddrlens[i];
949#endif
950 ((struct sockaddr_in *) saddrs[i])->sin_family = AF_INET;
951 ((struct sockaddr_in *) saddrs[i])->sin_port = htons (port);
952 }
953 else
954 {
955 /* dual stack */
956 resi = 2;
957 saddrs = GNUNET_malloc ((resi + 1) * sizeof (struct sockaddr *));
958 saddrlens = GNUNET_malloc ((resi + 1) * sizeof (socklen_t));
959 i = 0;
960 saddrlens[i] = sizeof (struct sockaddr_in6);
961 saddrs[i] = GNUNET_malloc (saddrlens[i]);
962#if HAVE_SOCKADDR_IN_SIN_LEN
963 ((struct sockaddr_in6 *) saddrs[i])->sin6_len = saddrlens[0];
964#endif
965 ((struct sockaddr_in6 *) saddrs[i])->sin6_family = AF_INET6;
966 ((struct sockaddr_in6 *) saddrs[i])->sin6_port = htons (port);
967 i++;
968 saddrlens[i] = sizeof (struct sockaddr_in);
969 saddrs[i] = GNUNET_malloc (saddrlens[i]);
970#if HAVE_SOCKADDR_IN_SIN_LEN
971 ((struct sockaddr_in *) saddrs[i])->sin_len = saddrlens[1];
972#endif
973 ((struct sockaddr_in *) saddrs[i])->sin_family = AF_INET;
974 ((struct sockaddr_in *) saddrs[i])->sin_port = htons (port);
975 }
976 }
977 *addrs = saddrs;
978 *addr_lens = saddrlens;
979 return resi;
980}
783 981
784static void 982static void
785start_report_addresses (struct Plugin *plugin) 983start_report_addresses (struct Plugin *plugin)
@@ -789,12 +987,10 @@ start_report_addresses (struct Plugin *plugin)
789 socklen_t *addrlens; 987 socklen_t *addrlens;
790 988
791 res = 989 res =
792 GNUNET_SERVICE_get_server_addresses (plugin->name, plugin->env->cfg, 990 http_get_addresses (plugin, plugin->name, plugin->env->cfg,
793 &addrs, &addrlens); 991 &addrs, &addrlens);
794#if 0
795 GNUNET_log_from (GNUNET_ERROR_TYPE_DEBUG, plugin->name, 992 GNUNET_log_from (GNUNET_ERROR_TYPE_DEBUG, plugin->name,
796 _("FOUND %u addresses\n"),res); 993 _("Found %u addresses to report to NAT service\n"),res);
797#endif
798 994
799 if (res != GNUNET_SYSERR) 995 if (res != GNUNET_SYSERR)
800 { 996 {
@@ -907,7 +1103,7 @@ configure_plugin (struct Plugin *plugin)
907 plugin->client_only = GNUNET_NO; 1103 plugin->client_only = GNUNET_NO;
908 if (plugin->port == 0) 1104 if (plugin->port == 0)
909 { 1105 {
910 GNUNET_log_from (GNUNET_ERROR_TYPE_ERROR, plugin->name, 1106 GNUNET_log_from (GNUNET_ERROR_TYPE_DEBUG, plugin->name,
911 _("Port 0, client only mode\n")); 1107 _("Port 0, client only mode\n"));
912 plugin->client_only = GNUNET_YES; 1108 plugin->client_only = GNUNET_YES;
913 } 1109 }