diff options
author | Matthias Wachs <wachs@net.in.tum.de> | 2011-10-06 15:11:22 +0000 |
---|---|---|
committer | Matthias Wachs <wachs@net.in.tum.de> | 2011-10-06 15:11:22 +0000 |
commit | fee3601ae573e7a98419036775b30b53faeec157 (patch) | |
tree | 511e3dac59211b245311bb98a8c550b865460836 /src/transport/plugin_transport_http.c | |
parent | 09aa75cc9decb90576828b4e2b7507301e4c5eb2 (diff) | |
download | gnunet-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.c | 208 |
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 | ||
783 | int | ||
784 | http_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 | ||
784 | static void | 982 | static void |
785 | start_report_addresses (struct Plugin *plugin) | 983 | start_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 | } |