diff options
author | Christian Grothoff <christian@grothoff.org> | 2013-06-05 21:33:37 +0000 |
---|---|---|
committer | Christian Grothoff <christian@grothoff.org> | 2013-06-05 21:33:37 +0000 |
commit | 4ce2d673d41ad8a8b9e5389b5b97ecb5e77f190d (patch) | |
tree | 4121ea931c40568a7624413cf2b19c707572876f /src/vpn | |
parent | 8411c737ab7cf78a37d841f75cf1a0298c3cd26d (diff) | |
download | gnunet-4ce2d673d41ad8a8b9e5389b5b97ecb5e77f190d.tar.gz gnunet-4ce2d673d41ad8a8b9e5389b5b97ecb5e77f190d.zip |
-moving to regex
Diffstat (limited to 'src/vpn')
-rw-r--r-- | src/vpn/Makefile.am | 2 | ||||
-rw-r--r-- | src/vpn/gnunet-service-vpn.c | 219 |
2 files changed, 196 insertions, 25 deletions
diff --git a/src/vpn/Makefile.am b/src/vpn/Makefile.am index 8b67a3373..d4c985116 100644 --- a/src/vpn/Makefile.am +++ b/src/vpn/Makefile.am | |||
@@ -59,7 +59,7 @@ gnunet_service_vpn_LDADD = \ | |||
59 | $(top_builddir)/src/tun/libgnunettun.la \ | 59 | $(top_builddir)/src/tun/libgnunettun.la \ |
60 | $(top_builddir)/src/util/libgnunetutil.la \ | 60 | $(top_builddir)/src/util/libgnunetutil.la \ |
61 | $(top_builddir)/src/mesh/libgnunetmesh.la \ | 61 | $(top_builddir)/src/mesh/libgnunetmesh.la \ |
62 | $(top_builddir)/src/regex/libgnunetregex.la \ | 62 | $(top_builddir)/src/regex/libgnunetregexnew.la \ |
63 | $(GN_LIBINTL) | 63 | $(GN_LIBINTL) |
64 | gnunet_service_vpn_CFLAGS = \ | 64 | gnunet_service_vpn_CFLAGS = \ |
65 | -I$(top_srcdir)/src/exit $(CFLAGS) | 65 | -I$(top_srcdir)/src/exit $(CFLAGS) |
diff --git a/src/vpn/gnunet-service-vpn.c b/src/vpn/gnunet-service-vpn.c index a56aff52a..a223e746e 100644 --- a/src/vpn/gnunet-service-vpn.c +++ b/src/vpn/gnunet-service-vpn.c | |||
@@ -25,6 +25,10 @@ | |||
25 | * IP traffic received on those IPs via the GNUnet mesh | 25 | * IP traffic received on those IPs via the GNUnet mesh |
26 | * @author Philipp Toelke | 26 | * @author Philipp Toelke |
27 | * @author Christian Grothoff | 27 | * @author Christian Grothoff |
28 | * | ||
29 | * TODO: | ||
30 | * - keep multiple peers/mesh tunnels ready as alternative exits / | ||
31 | * recover from tunnel-to-exit failure gracefully | ||
28 | */ | 32 | */ |
29 | #include "platform.h" | 33 | #include "platform.h" |
30 | #include "gnunet_util_lib.h" | 34 | #include "gnunet_util_lib.h" |
@@ -35,7 +39,7 @@ | |||
35 | #include "gnunet_statistics_service.h" | 39 | #include "gnunet_statistics_service.h" |
36 | #include "gnunet_constants.h" | 40 | #include "gnunet_constants.h" |
37 | #include "gnunet_tun_lib.h" | 41 | #include "gnunet_tun_lib.h" |
38 | #include "gnunet_regex_lib.h" | 42 | #include "gnunet_regex_service.h" |
39 | #include "vpn.h" | 43 | #include "vpn.h" |
40 | #include "exit.h" | 44 | #include "exit.h" |
41 | 45 | ||
@@ -45,6 +49,16 @@ | |||
45 | */ | 49 | */ |
46 | #define MAX_MESSAGE_QUEUE_SIZE 4 | 50 | #define MAX_MESSAGE_QUEUE_SIZE 4 |
47 | 51 | ||
52 | /** | ||
53 | * Maximum regex string length for use with GNUNET_REGEX_ipv4toregex | ||
54 | */ | ||
55 | #define GNUNET_REGEX_IPV4_REGEXLEN 32 + 6 | ||
56 | |||
57 | /** | ||
58 | * Maximum regex string length for use with GNUNET_REGEX_ipv6toregex | ||
59 | */ | ||
60 | #define GNUNET_REGEX_IPV6_REGEXLEN 128 + 6 | ||
61 | |||
48 | 62 | ||
49 | /** | 63 | /** |
50 | * State we keep for each of our tunnels. | 64 | * State we keep for each of our tunnels. |
@@ -172,6 +186,11 @@ struct TunnelState | |||
172 | struct GNUNET_MESH_Tunnel *tunnel; | 186 | struct GNUNET_MESH_Tunnel *tunnel; |
173 | 187 | ||
174 | /** | 188 | /** |
189 | * Active query with REGEX to locate exit. | ||
190 | */ | ||
191 | struct GNUNET_REGEX_Search *search; | ||
192 | |||
193 | /** | ||
175 | * Active transmission handle, NULL for none. | 194 | * Active transmission handle, NULL for none. |
176 | */ | 195 | */ |
177 | struct GNUNET_MESH_TransmitHandle *th; | 196 | struct GNUNET_MESH_TransmitHandle *th; |
@@ -536,6 +555,11 @@ free_tunnel_state (struct TunnelState *ts) | |||
536 | ts->tunnel = NULL; | 555 | ts->tunnel = NULL; |
537 | GNUNET_MESH_tunnel_destroy (tunnel); | 556 | GNUNET_MESH_tunnel_destroy (tunnel); |
538 | } | 557 | } |
558 | if (NULL != ts->search) | ||
559 | { | ||
560 | GNUNET_REGEX_search_cancel (ts->search); | ||
561 | ts->search = NULL; | ||
562 | } | ||
539 | if (GNUNET_SCHEDULER_NO_TASK != ts->destroy_task) | 563 | if (GNUNET_SCHEDULER_NO_TASK != ts->destroy_task) |
540 | { | 564 | { |
541 | GNUNET_SCHEDULER_cancel (ts->destroy_task); | 565 | GNUNET_SCHEDULER_cancel (ts->destroy_task); |
@@ -751,6 +775,150 @@ send_to_tunnel (struct TunnelMessageQueueEntry *tnq, | |||
751 | 775 | ||
752 | 776 | ||
753 | /** | 777 | /** |
778 | * Create a string with binary IP notation for the given 'addr' in 'str'. | ||
779 | * | ||
780 | * @param af address family of the given 'addr'. | ||
781 | * @param addr address that should be converted to a string. | ||
782 | * struct in_addr * for IPv4 and struct in6_addr * for IPv6. | ||
783 | * @param str string that will contain binary notation of 'addr'. Expected | ||
784 | * to be at least 33 bytes long for IPv4 and 129 bytes long for IPv6. | ||
785 | */ | ||
786 | static void | ||
787 | iptobinstr (const int af, const void *addr, char *str) | ||
788 | { | ||
789 | int i; | ||
790 | |||
791 | switch (af) | ||
792 | { | ||
793 | case AF_INET: | ||
794 | { | ||
795 | uint32_t b = htonl (((struct in_addr *) addr)->s_addr); | ||
796 | |||
797 | str[32] = '\0'; | ||
798 | str += 31; | ||
799 | for (i = 31; i >= 0; i--) | ||
800 | { | ||
801 | *str = (b & 1) + '0'; | ||
802 | str--; | ||
803 | b >>= 1; | ||
804 | } | ||
805 | break; | ||
806 | } | ||
807 | case AF_INET6: | ||
808 | { | ||
809 | struct in6_addr b = *(const struct in6_addr *) addr; | ||
810 | |||
811 | str[128] = '\0'; | ||
812 | str += 127; | ||
813 | for (i = 127; i >= 0; i--) | ||
814 | { | ||
815 | *str = (b.s6_addr[i / 8] & 1) + '0'; | ||
816 | str--; | ||
817 | b.s6_addr[i / 8] >>= 1; | ||
818 | } | ||
819 | break; | ||
820 | } | ||
821 | } | ||
822 | } | ||
823 | |||
824 | |||
825 | /** | ||
826 | * Get the ipv4 network prefix from the given 'netmask'. | ||
827 | * | ||
828 | * @param netmask netmask for which to get the prefix len. | ||
829 | * | ||
830 | * @return length of ipv4 prefix for 'netmask'. | ||
831 | */ | ||
832 | static unsigned int | ||
833 | ipv4netmasktoprefixlen (const char *netmask) | ||
834 | { | ||
835 | struct in_addr a; | ||
836 | unsigned int len; | ||
837 | uint32_t t; | ||
838 | |||
839 | if (1 != inet_pton (AF_INET, netmask, &a)) | ||
840 | return 0; | ||
841 | len = 32; | ||
842 | for (t = htonl (~a.s_addr); 0 != t; t >>= 1) | ||
843 | len--; | ||
844 | return len; | ||
845 | } | ||
846 | |||
847 | |||
848 | /** | ||
849 | * Create a regex in 'rxstr' from the given 'ip' and 'netmask'. | ||
850 | * | ||
851 | * @param ip IPv4 representation. | ||
852 | * @param netmask netmask for the ip. | ||
853 | * @param rxstr generated regex, must be at least GNUNET_REGEX_IPV4_REGEXLEN | ||
854 | * bytes long. | ||
855 | */ | ||
856 | static void | ||
857 | ipv4toregex (const struct in_addr *ip, const char *netmask, | ||
858 | char *rxstr) | ||
859 | { | ||
860 | unsigned int pfxlen; | ||
861 | |||
862 | pfxlen = ipv4netmasktoprefixlen (netmask); | ||
863 | iptobinstr (AF_INET, ip, rxstr); | ||
864 | rxstr[pfxlen] = '\0'; | ||
865 | if (pfxlen < 32) | ||
866 | strcat (rxstr, "(0|1)+"); | ||
867 | } | ||
868 | |||
869 | |||
870 | /** | ||
871 | * Create a regex in 'rxstr' from the given 'ipv6' and 'prefixlen'. | ||
872 | * | ||
873 | * @param ipv6 IPv6 representation. | ||
874 | * @param prefixlen length of the ipv6 prefix. | ||
875 | * @param rxstr generated regex, must be at least GNUNET_REGEX_IPV6_REGEXLEN | ||
876 | * bytes long. | ||
877 | */ | ||
878 | static void | ||
879 | ipv6toregex (const struct in6_addr *ipv6, unsigned int prefixlen, | ||
880 | char *rxstr) | ||
881 | { | ||
882 | iptobinstr (AF_INET6, ipv6, rxstr); | ||
883 | rxstr[prefixlen] = '\0'; | ||
884 | if (prefixlen < 128) | ||
885 | strcat (rxstr, "(0|1)+"); | ||
886 | } | ||
887 | |||
888 | |||
889 | /** | ||
890 | * Regex has found a potential exit peer for us; consider using it. | ||
891 | * | ||
892 | * @param cls the 'struct TunnelState' | ||
893 | * @param id Peer providing a regex that matches the string. | ||
894 | * @param get_path Path of the get request. | ||
895 | * @param get_path_length Lenght of get_path. | ||
896 | * @param put_path Path of the put request. | ||
897 | * @param put_path_length Length of the put_path. | ||
898 | */ | ||
899 | static void | ||
900 | handle_regex_result (void *cls, | ||
901 | const struct GNUNET_PeerIdentity *id, | ||
902 | const struct GNUNET_PeerIdentity *get_path, | ||
903 | unsigned int get_path_length, | ||
904 | const struct GNUNET_PeerIdentity *put_path, | ||
905 | unsigned int put_path_length) | ||
906 | { | ||
907 | struct TunnelState *ts = cls; | ||
908 | |||
909 | GNUNET_REGEX_search_cancel (ts->search); | ||
910 | ts->search = NULL; | ||
911 | ts->tunnel = GNUNET_MESH_tunnel_create (mesh_handle, | ||
912 | ts, | ||
913 | &tunnel_peer_connect_handler, | ||
914 | &tunnel_peer_disconnect_handler, | ||
915 | ts); | ||
916 | GNUNET_MESH_peer_request_connect_add (ts->tunnel, | ||
917 | id); | ||
918 | } | ||
919 | |||
920 | |||
921 | /** | ||
754 | * Initialize the given destination entry's mesh tunnel. | 922 | * Initialize the given destination entry's mesh tunnel. |
755 | * | 923 | * |
756 | * @param de destination entry for which we need to setup a tunnel | 924 | * @param de destination entry for which we need to setup a tunnel |
@@ -783,22 +951,22 @@ create_tunnel_to_destination (struct DestinationEntry *de, | |||
783 | ts->destination.heap_node = NULL; /* copy is NOT in destination heap */ | 951 | ts->destination.heap_node = NULL; /* copy is NOT in destination heap */ |
784 | de->ts = ts; | 952 | de->ts = ts; |
785 | ts->destination_container = de; /* we are referenced from de */ | 953 | ts->destination_container = de; /* we are referenced from de */ |
786 | ts->tunnel = GNUNET_MESH_tunnel_create (mesh_handle, | ||
787 | ts, | ||
788 | &tunnel_peer_connect_handler, | ||
789 | &tunnel_peer_disconnect_handler, | ||
790 | ts); | ||
791 | if (NULL == ts->tunnel) | ||
792 | { | ||
793 | GNUNET_log (GNUNET_ERROR_TYPE_ERROR, | ||
794 | _("Failed to setup mesh tunnel!\n")); | ||
795 | if (NULL != client) | ||
796 | GNUNET_SERVER_client_drop (client); | ||
797 | GNUNET_free (ts); | ||
798 | return NULL; | ||
799 | } | ||
800 | if (de->is_service) | 954 | if (de->is_service) |
801 | { | 955 | { |
956 | ts->tunnel = GNUNET_MESH_tunnel_create (mesh_handle, | ||
957 | ts, | ||
958 | &tunnel_peer_connect_handler, | ||
959 | &tunnel_peer_disconnect_handler, | ||
960 | ts); | ||
961 | if (NULL == ts->tunnel) | ||
962 | { | ||
963 | GNUNET_log (GNUNET_ERROR_TYPE_ERROR, | ||
964 | _("Failed to setup mesh tunnel!\n")); | ||
965 | if (NULL != client) | ||
966 | GNUNET_SERVER_client_drop (client); | ||
967 | GNUNET_free (ts); | ||
968 | return NULL; | ||
969 | } | ||
802 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, | 970 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, |
803 | "Creating tunnel to peer %s offering service %s\n", | 971 | "Creating tunnel to peer %s offering service %s\n", |
804 | GNUNET_i2s (&de->details.service_destination.target), | 972 | GNUNET_i2s (&de->details.service_destination.target), |
@@ -815,8 +983,9 @@ create_tunnel_to_destination (struct DestinationEntry *de, | |||
815 | case AF_INET: | 983 | case AF_INET: |
816 | { | 984 | { |
817 | char address[GNUNET_REGEX_IPV4_REGEXLEN]; | 985 | char address[GNUNET_REGEX_IPV4_REGEXLEN]; |
818 | GNUNET_REGEX_ipv4toregex (&de->details.exit_destination.ip.v4, | 986 | |
819 | "255.255.255.255", address); | 987 | ipv4toregex (&de->details.exit_destination.ip.v4, |
988 | "255.255.255.255", address); | ||
820 | GNUNET_asprintf (&policy, "%s%s%s", | 989 | GNUNET_asprintf (&policy, "%s%s%s", |
821 | GNUNET_APPLICATION_TYPE_EXIT_REGEX_PREFIX, | 990 | GNUNET_APPLICATION_TYPE_EXIT_REGEX_PREFIX, |
822 | "4", | 991 | "4", |
@@ -826,8 +995,9 @@ create_tunnel_to_destination (struct DestinationEntry *de, | |||
826 | case AF_INET6: | 995 | case AF_INET6: |
827 | { | 996 | { |
828 | char address[GNUNET_REGEX_IPV6_REGEXLEN]; | 997 | char address[GNUNET_REGEX_IPV6_REGEXLEN]; |
829 | GNUNET_REGEX_ipv6toregex (&de->details.exit_destination.ip.v6, | 998 | |
830 | 128, address); | 999 | ipv6toregex (&de->details.exit_destination.ip.v6, |
1000 | 128, address); | ||
831 | GNUNET_asprintf (&policy, "%s%s%s", | 1001 | GNUNET_asprintf (&policy, "%s%s%s", |
832 | GNUNET_APPLICATION_TYPE_EXIT_REGEX_PREFIX, | 1002 | GNUNET_APPLICATION_TYPE_EXIT_REGEX_PREFIX, |
833 | "6", | 1003 | "6", |
@@ -839,12 +1009,13 @@ create_tunnel_to_destination (struct DestinationEntry *de, | |||
839 | break; | 1009 | break; |
840 | } | 1010 | } |
841 | 1011 | ||
842 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Requesting connect by string: %s\n", policy); | ||
843 | |||
844 | GNUNET_MESH_peer_request_connect_by_string (ts->tunnel, policy); | ||
845 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, | 1012 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, |
846 | "Creating tunnel to exit peer for policy `%s'\n", | 1013 | "Requesting connect by string: %s\n", |
847 | policy); | 1014 | policy); |
1015 | ts->search = GNUNET_REGEX_search (cfg, | ||
1016 | policy, | ||
1017 | &handle_regex_result, | ||
1018 | ts); | ||
848 | GNUNET_free (policy); | 1019 | GNUNET_free (policy); |
849 | } | 1020 | } |
850 | return ts; | 1021 | return ts; |