aboutsummaryrefslogtreecommitdiff
path: root/src/exit
diff options
context:
space:
mode:
authorgrothoff <grothoff@140774ce-b5e7-0310-ab8b-a85725594a96>2012-01-09 22:38:49 +0000
committergrothoff <grothoff@140774ce-b5e7-0310-ab8b-a85725594a96>2012-01-09 22:38:49 +0000
commit0b01c77daeb1b2a0b89444cba83dc1ab8513bb16 (patch)
tree9062233053a29b0689e039c1619b4d3c77f5b679 /src/exit
parent24d3f6ce8a79aba33dfdf8654e7d1c6c93992ab9 (diff)
-defining proper structs for vpn-exit mesh communication
git-svn-id: https://gnunet.org/svn/gnunet@19074 140774ce-b5e7-0310-ab8b-a85725594a96
Diffstat (limited to 'src/exit')
-rw-r--r--src/exit/Makefile.am2
-rw-r--r--src/exit/exit.h195
-rw-r--r--src/exit/gnunet-daemon-exit.c129
3 files changed, 283 insertions, 43 deletions
diff --git a/src/exit/Makefile.am b/src/exit/Makefile.am
index 9d1e8b4136..736bb5fd31 100644
--- a/src/exit/Makefile.am
+++ b/src/exit/Makefile.am
@@ -33,7 +33,7 @@ gnunet_helper_exit_SOURCES = \
gnunet-helper-exit.c
gnunet_daemon_exit_SOURCES = \
- gnunet-daemon-exit.c
+ gnunet-daemon-exit.c exit.h
gnunet_daemon_exit_LDADD = \
$(top_builddir)/src/core/libgnunetcore.la \
$(top_builddir)/src/statistics/libgnunetstatistics.la \
diff --git a/src/exit/exit.h b/src/exit/exit.h
new file mode 100644
index 0000000000..1e92cc5011
--- /dev/null
+++ b/src/exit/exit.h
@@ -0,0 +1,195 @@
+/*
+ This file is part of GNUnet.
+ (C) 2012 Christian Grothoff
+
+ GNUnet is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published
+ by the Free Software Foundation; either version 3, or (at your
+ option) any later version.
+
+ GNUnet is distributed in the hope that it will be useful, but
+ WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with GNUnet; see the file COPYING. If not, write to the
+ Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ Boston, MA 02111-1307, USA.
+*/
+
+/**
+ * @file exit/exit.h
+ * @brief format for mesh messages exchanged between VPN service and exit daemon
+ * @author Christian Grothoff
+ */
+#ifndef EXIT_H
+#define EXIT_H
+
+#include "gnunet_util_lib.h"
+
+/**
+ * Message send via mesh to an exit daemon to initiate forwarding of
+ * TCP data to a local service.
+ */
+struct GNUNET_EXIT_TcpServiceStartMessage
+{
+ /**
+ * Type is GNUNET_MESSAGE_TYPE_VPN_TCP_TO_SERVICE_START
+ */
+ struct GNUNET_MessageHeader header;
+
+ /**
+ * Always 0.
+ */
+ uint32_t reserved;
+
+ /**
+ * Identification for the desired service.
+ */
+ GNUNET_HashCode service_descriptor;
+
+ /**
+ * Skeleton of the TCP header to send. Port numbers are to
+ * be replaced and the checksum may be updated as necessary.
+ */
+ struct tcp_packet tcp_header;
+
+ /* followed by TCP payload */
+};
+
+
+/**
+ * Message send via mesh to an exit daemon to initiate forwarding of
+ * TCP data to the Internet.
+ */
+struct GNUNET_EXIT_TcpInternetStartMessage
+{
+ /**
+ * Type is GNUNET_MESSAGE_TYPE_VPN_TCP_TO_INTERNET_START
+ */
+ struct GNUNET_MessageHeader header;
+
+ /**
+ * Address family, AF_INET or AF_INET6, in network byte order.
+ */
+ int32_t af;
+
+ /**
+ * Skeleton of the TCP header to send. Port numbers are to
+ * be replaced and the checksum may be updated as necessary.
+ */
+ struct tcp_packet tcp_header;
+
+ /* followed by IP address of the destination; either
+ 'struct in_addr' or 'struct in6_addr', depending on af */
+
+ /* followed by TCP payload */
+};
+
+
+/**
+ * Message send via mesh between VPN and entry and an exit daemon to
+ * transmit TCP data between the VPN entry and an exit session. This
+ * format is used for both Internet-exits and service-exits and
+ * in both directions (VPN to exit and exit to VPN).
+ */
+struct GNUNET_EXIT_TcpDataMessage
+{
+ /**
+ * Type is GNUNET_MESSAGE_TYPE_VPN_TCP_DATA
+ */
+ struct GNUNET_MessageHeader header;
+
+ /**
+ * Always 0.
+ */
+ uint32_t reserved;
+
+ /**
+ * Skeleton of the TCP header to send. Port numbers are to
+ * be replaced and the checksum may be updated as necessary.
+ */
+ struct tcp_packet tcp_header;
+
+ /* followed by TCP payload */
+};
+
+
+/**
+ * Message send via mesh to an exit daemon to send
+ * UDP data to a local service.
+ */
+struct GNUNET_EXIT_UdpServiceMessage
+{
+ /**
+ * Type is GNUNET_MESSAGE_TYPE_VPN_UDP_TO_SERVICE
+ */
+ struct GNUNET_MessageHeader header;
+
+ /**
+ * Always 0.
+ */
+ uint32_t reserved;
+
+ /**
+ * Identification for the desired service.
+ */
+ GNUNET_HashCode service_descriptor;
+
+ /* followed by UDP payload */
+};
+
+
+/**
+ * Message send via mesh to an exit daemon to forward
+ * UDP data to the Internet.
+ */
+struct GNUNET_EXIT_UdpInternetMessage
+{
+ /**
+ * Type is GNUNET_MESSAGE_TYPE_VPN_UDP_TO_INTERNET
+ */
+ struct GNUNET_MessageHeader header;
+
+ /**
+ * Address family, AF_INET or AF_INET6, in network byte order.
+ */
+ int32_t af;
+
+
+ /* followed by IP address of the destination; either
+ 'struct in_addr' or 'struct in6_addr', depending on af */
+
+ /* followed by UDP payload */
+};
+
+
+/**
+ * Message send from exit daemon back to the UDP entry point
+ * (used for both Internet and Service exit replies).
+ */
+struct GNUNET_EXIT_UdpReplyMessage
+{
+ /**
+ * Type is GNUNET_MESSAGE_TYPE_VPN_UDP_REPLY
+ */
+ struct GNUNET_MessageHeader header;
+
+ /**
+ * Source port to use for the UDP reply (0 to use the same
+ * port as for the original request). In NBO.
+ */
+ uint16_t source_port;
+
+ /**
+ * Destination port to use for the UDP reply (0 to use the same
+ * port as for the original request). In NBO.
+ */
+ uint16_t destination_port;
+
+ /* followed by UDP payload */
+};
+
+
+#endif
diff --git a/src/exit/gnunet-daemon-exit.c b/src/exit/gnunet-daemon-exit.c
index 4ce0f634f6..eecc26aeb6 100644
--- a/src/exit/gnunet-daemon-exit.c
+++ b/src/exit/gnunet-daemon-exit.c
@@ -25,8 +25,8 @@
* @author Christian Grothoff
*
* TODO:
- * - need proper message headers for mesh P2P messages
- * - factor out crc computations from DNS/EXIT into shared library?
+ * - use new proper message headers for mesh P2P messages
+ * - factor out crc computations from DNS/EXIT/VPN into shared library?
* - which code should advertise services? the service model is right
* now a bit odd, especially as this code DOES the exit and knows
* the DNS "name", but OTOH this is clearly NOT the place to advertise
@@ -40,6 +40,7 @@
#include "gnunet_mesh_service.h"
#include "gnunet_constants.h"
#include "tcpip_tun.h"
+#include "exit.h"
/**
* Information about an address.
@@ -267,6 +268,15 @@ static struct GNUNET_CONTAINER_MultiHashMap *udp_services;
*/
static struct GNUNET_CONTAINER_MultiHashMap *tcp_services;
+/**
+ * Are we an IPv4-exit?
+ */
+static int ipv4_exit;
+
+/**
+ * Are we an IPv6-exit?
+ */
+static int ipv6_exit;
/**
* Given IP information about a connection, calculate the respective
@@ -1265,7 +1275,7 @@ receive_tcp_service (void *unused GNUNET_UNUSED, struct GNUNET_MESH_Tunnel *tunn
if (pkt_len < sizeof (struct GNUNET_MessageHeader) + sizeof (GNUNET_HashCode) + sizeof (struct tcp_packet))
{
GNUNET_break_op (0);
- return GNUNET_YES;
+ return GNUNET_SYSERR;
}
pkt_len -= (sizeof (struct GNUNET_MessageHeader) + sizeof (GNUNET_HashCode));
@@ -1279,8 +1289,7 @@ receive_tcp_service (void *unused GNUNET_UNUSED, struct GNUNET_MESH_Tunnel *tunn
_("No service found for %s on port %d!\n"),
"TCP",
ntohs (pkt->dpt));
- GNUNET_MESH_tunnel_destroy (state->tunnel);
- return GNUNET_YES;
+ return GNUNET_SYSERR;
}
state->ri.remote_address = state->serv->address;
setup_state_record (state);
@@ -1321,7 +1330,7 @@ receive_tcp_remote (void *cls GNUNET_UNUSED, struct GNUNET_MESH_Tunnel *tunnel,
if (pkt_len < sizeof (struct GNUNET_MessageHeader) + sizeof (GNUNET_HashCode) + sizeof (struct tcp_packet))
{
GNUNET_break_op (0);
- return GNUNET_YES;
+ return GNUNET_SYSERR;
}
pkt_len -= (sizeof (struct GNUNET_MessageHeader) + sizeof (GNUNET_HashCode));
@@ -1340,6 +1349,54 @@ receive_tcp_remote (void *cls GNUNET_UNUSED, struct GNUNET_MESH_Tunnel *tunnel,
/**
+ * Process a request to forward TCP data on an established
+ * connection via this peer.
+ *
+ * @param cls closure, NULL
+ * @param tunnel connection to the other end
+ * @param tunnel_ctx pointer to our 'struct TunnelState *'
+ * @param sender who sent the message
+ * @param message the actual message
+ * @param atsi performance data for the connection
+ * @return GNUNET_OK to keep the connection open,
+ * GNUNET_SYSERR to close it (signal serious error)
+ */
+static int
+receive_tcp_data (void *cls GNUNET_UNUSED, struct GNUNET_MESH_Tunnel *tunnel,
+ void **tunnel_ctx GNUNET_UNUSED,
+ const struct GNUNET_PeerIdentity *sender GNUNET_UNUSED,
+ const struct GNUNET_MessageHeader *message,
+ const struct GNUNET_ATS_Information *atsi GNUNET_UNUSED)
+{
+ struct TunnelState *state = *tunnel_ctx;
+ // FIXME: write proper request struct (!)
+ const GNUNET_HashCode *desc = (const GNUNET_HashCode *) &message[1];
+ const struct tcp_packet *pkt = (const struct tcp_packet *) &desc[1];
+ uint16_t pkt_len = ntohs (message->size);
+
+ if (NULL == state)
+ {
+ /* connection should have been up! */
+ /* FIXME: call statistics */
+ return GNUNET_SYSERR;
+ }
+
+ if (pkt_len < sizeof (struct GNUNET_MessageHeader) + sizeof (GNUNET_HashCode) + sizeof (struct tcp_packet))
+ {
+ GNUNET_break_op (0);
+ return GNUNET_SYSERR;
+ }
+ pkt_len -= (sizeof (struct GNUNET_MessageHeader) + sizeof (GNUNET_HashCode));
+
+
+ send_tcp_packet_via_tun (&state->ri.remote_address,
+ &state->ri.local_address,
+ pkt, pkt_len);
+ return GNUNET_YES;
+}
+
+
+/**
* Send a UDP packet via the TUN interface.
*
* @param destination_address IP and port to use for the UDP packet's destination
@@ -1449,7 +1506,7 @@ receive_udp_remote (void *cls GNUNET_UNUSED, struct GNUNET_MESH_Tunnel *tunnel,
if (pkt_len < sizeof (struct GNUNET_MessageHeader) + sizeof (GNUNET_HashCode) + sizeof (struct udp_packet))
{
GNUNET_break_op (0);
- return GNUNET_YES;
+ return GNUNET_SYSERR;
}
pkt_len -= (sizeof (struct GNUNET_MessageHeader) + sizeof (GNUNET_HashCode));
@@ -1498,7 +1555,7 @@ receive_udp_service (void *cls GNUNET_UNUSED, struct GNUNET_MESH_Tunnel *tunnel,
if (pkt_len < sizeof (struct GNUNET_MessageHeader) + sizeof (GNUNET_HashCode) + sizeof (struct udp_packet))
{
GNUNET_break_op (0);
- return GNUNET_YES;
+ return GNUNET_SYSERR;
}
pkt_len -= (sizeof (struct GNUNET_MessageHeader) + sizeof (GNUNET_HashCode));
@@ -1517,7 +1574,7 @@ receive_udp_service (void *cls GNUNET_UNUSED, struct GNUNET_MESH_Tunnel *tunnel,
"UDP",
ntohs (pkt->dpt));
GNUNET_MESH_tunnel_destroy (state->tunnel);
- return GNUNET_YES;
+ return GNUNET_SYSERR;
}
state->ri.remote_address = state->serv->address;
setup_state_record (state);
@@ -1819,10 +1876,11 @@ run (void *cls, char *const *args GNUNET_UNUSED,
const struct GNUNET_CONFIGURATION_Handle *cfg_)
{
static struct GNUNET_MESH_MessageHandler handlers[] = {
- {&receive_udp_service, GNUNET_MESSAGE_TYPE_VPN_SERVICE_UDP, 0},
- {&receive_tcp_service, GNUNET_MESSAGE_TYPE_VPN_SERVICE_TCP, 0},
- {NULL, 0, 0},
- {NULL, 0, 0},
+ {&receive_udp_service, GNUNET_MESSAGE_TYPE_VPN_UDP_TO_SERVICE, 0},
+ {&receive_udp_remote, GNUNET_MESSAGE_TYPE_VPN_UDP_TO_INTERNET, 0},
+ {&receive_tcp_service, GNUNET_MESSAGE_TYPE_VPN_TCP_TO_SERVICE_START, 0},
+ {&receive_tcp_remote, GNUNET_MESSAGE_TYPE_VPN_TCP_TO_INTERNET_START, 0},
+ {&receive_tcp_data, GNUNET_MESSAGE_TYPE_VPN_TCP_DATA, 0},
{NULL, 0, 0}
};
@@ -1831,10 +1889,7 @@ run (void *cls, char *const *args GNUNET_UNUSED,
GNUNET_APPLICATION_TYPE_END,
GNUNET_APPLICATION_TYPE_END
};
- unsigned int handler_idx;
unsigned int app_idx;
- int udp;
- int tcp;
char *ifname;
char *ipv6addr;
char *ipv6prefix_s;
@@ -1844,7 +1899,22 @@ run (void *cls, char *const *args GNUNET_UNUSED,
struct in6_addr v6;
cfg = cfg_;
+ ipv4_exit = GNUNET_CONFIGURATION_get_value_yesno (cfg, "exit", "ENABLE_IPV4");
+ ipv6_exit = GNUNET_CONFIGURATION_get_value_yesno (cfg, "exit", "ENABLE_IPV6");
+ app_idx = 0;
+ if (GNUNET_YES == ipv4_exit)
+ {
+ apptypes[app_idx] = GNUNET_APPLICATION_TYPE_IPV4_GATEWAY;
+ app_idx++;
+ }
+ if (GNUNET_YES == ipv6_exit)
+ {
+ apptypes[app_idx] = GNUNET_APPLICATION_TYPE_IPV6_GATEWAY;
+ app_idx++;
+ }
+
GNUNET_SCHEDULER_add_delayed (GNUNET_TIME_UNIT_FOREVER_REL, &cleanup, cls);
+
if (GNUNET_OK !=
GNUNET_CONFIGURATION_get_value_number (cfg, "exit", "MAX_CONNECTIONS",
&max_connections))
@@ -1914,31 +1984,6 @@ run (void *cls, char *const *args GNUNET_UNUSED,
exit_argv[5] = ipv4mask;
exit_argv[6] = NULL;
- app_idx = 0;
- handler_idx = 2;
- // FIXME: new 'vpn' has other apptypes (IPv4/IPv6, no longer TCP vs. UDP)!
- // The new 'exit' should reflect that!
- udp = GNUNET_CONFIGURATION_get_value_yesno (cfg, "exit", "ENABLE_UDP");
- tcp = GNUNET_CONFIGURATION_get_value_yesno (cfg, "exit", "ENABLE_TCP");
- if (GNUNET_YES == udp)
- {
- handlers[handler_idx].callback = &receive_udp_remote;
- handlers[handler_idx].expected_size = 0;
- handlers[handler_idx].type = GNUNET_MESSAGE_TYPE_VPN_REMOTE_UDP;
- apptypes[app_idx] = GNUNET_APPLICATION_TYPE_INTERNET_UDP_GATEWAY;
- handler_idx++;
- app_idx++;
- }
-
- if (GNUNET_YES == tcp)
- {
- handlers[handler_idx].callback = &receive_tcp_remote;
- handlers[handler_idx].expected_size = 0;
- handlers[handler_idx].type = GNUNET_MESSAGE_TYPE_VPN_REMOTE_TCP;
- apptypes[app_idx] = GNUNET_APPLICATION_TYPE_INTERNET_TCP_GATEWAY;
- handler_idx++;
- app_idx++;
- }
udp_services = GNUNET_CONTAINER_multihashmap_create (65536);
tcp_services = GNUNET_CONTAINER_multihashmap_create (65536);
GNUNET_CONFIGURATION_iterate_sections (cfg, &read_service_conf, NULL);
@@ -1955,7 +2000,7 @@ run (void *cls, char *const *args GNUNET_UNUSED,
GNUNET_SCHEDULER_shutdown ();
return;
}
- helper_handle = GNUNET_HELPER_start ("gnunet-helper-vpn",
+ helper_handle = GNUNET_HELPER_start ("gnunet-helper-exit",
exit_argv,
&message_token, NULL);
}