diff options
author | grothoff <grothoff@140774ce-b5e7-0310-ab8b-a85725594a96> | 2012-01-09 22:38:49 +0000 |
---|---|---|
committer | grothoff <grothoff@140774ce-b5e7-0310-ab8b-a85725594a96> | 2012-01-09 22:38:49 +0000 |
commit | 0b01c77daeb1b2a0b89444cba83dc1ab8513bb16 (patch) | |
tree | 9062233053a29b0689e039c1619b4d3c77f5b679 /src/exit | |
parent | 24d3f6ce8a79aba33dfdf8654e7d1c6c93992ab9 (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.am | 2 | ||||
-rw-r--r-- | src/exit/exit.h | 195 | ||||
-rw-r--r-- | src/exit/gnunet-daemon-exit.c | 129 |
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); } |