aboutsummaryrefslogtreecommitdiff
path: root/src/vpn
diff options
context:
space:
mode:
authorChristian Grothoff <christian@grothoff.org>2013-06-05 21:33:37 +0000
committerChristian Grothoff <christian@grothoff.org>2013-06-05 21:33:37 +0000
commit4ce2d673d41ad8a8b9e5389b5b97ecb5e77f190d (patch)
tree4121ea931c40568a7624413cf2b19c707572876f /src/vpn
parent8411c737ab7cf78a37d841f75cf1a0298c3cd26d (diff)
downloadgnunet-4ce2d673d41ad8a8b9e5389b5b97ecb5e77f190d.tar.gz
gnunet-4ce2d673d41ad8a8b9e5389b5b97ecb5e77f190d.zip
-moving to regex
Diffstat (limited to 'src/vpn')
-rw-r--r--src/vpn/Makefile.am2
-rw-r--r--src/vpn/gnunet-service-vpn.c219
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)
64gnunet_service_vpn_CFLAGS = \ 64gnunet_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 */
786static void
787iptobinstr (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 */
832static unsigned int
833ipv4netmasktoprefixlen (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 */
856static void
857ipv4toregex (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 */
878static void
879ipv6toregex (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 */
899static void
900handle_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;