From 75bfc02cd9753b664e4799b2f837c1de9ab2e2dc Mon Sep 17 00:00:00 2001 From: Christian Grothoff Date: Sat, 7 Jan 2012 20:41:38 +0000 Subject: [PATCH] -finishing gnunet-vpn tool and man page --- doc/man/gnunet-vpn.1 | 65 +++++++++++ src/dns/gnunet-dns-redirector.c | 2 +- src/vpn/gnunet-vpn.c | 188 +++++++++++++++++++++++++++++++- 3 files changed, 252 insertions(+), 3 deletions(-) create mode 100644 doc/man/gnunet-vpn.1 diff --git a/doc/man/gnunet-vpn.1 b/doc/man/gnunet-vpn.1 new file mode 100644 index 000000000..4d07c5ad9 --- /dev/null +++ b/doc/man/gnunet-vpn.1 @@ -0,0 +1,65 @@ +.TH GNUNET\-VPN 1 "Jan 7, 2012" "GNUnet" + +.SH NAME +gnunet\-vpn \- manually setup a GNUnet VPN tunnel + +.SH SYNOPSIS +.B gnunet\-vpn +.RI [ options ] +.br + +.SH DESCRIPTION +\fBgnunet\-vpn\fP can be used to manually setup a VPN tunnel via the GNUnet network. There are two main types of tunnels. Tunnels to an exit node which routes the traffic to the global Internet, and tunnels to a node that runs a service only within GNUnet. Depending on the type of tunnel, gnunet\-vpn takes different options. The "\-i" option is required for tunnels to an exit node, whereas the "\-p" and "\-s" options in conjuction with either "\-u" or "\-t" are required for tunnels to services. For exit tunnels, both UDP and TCP traffic will be redirected. For service tunnels, either UDP ("\-u") or TCP ("\-t") traffic will be redirected. + +The tool will display the IP address for this end of the tunnel. The address can be displayed as soon as it has been allocated, or only after ("\-a") the tunnel has been created. + +.SH OPTIONS +.B +.IP "\-4, \-\-ipv4" +Desired IP address on this end of the tunnel should be an IPv4 address. +.B +.IP "\-6, \-\-ipv6" +Desired IP address on this end of the tunnel should be an IPv6 address. +.B +.IP "\-a, \-\-after\-connect" +Display IP address only after the tunnel is fully connected. +.B +.IP "\-c FILENAME, \-\-config=FILENAME" +Use the configuration file FILENAME. +.B +.IP "\-d SEC, \-\-duration SEC" +The mapping should be established for SEC seconds. Default is 5 minutes. +.B +.IP "\-h, \-\-help" +Print short help on options. +.B +.IP "\-i IP, \-\-ip IP" +Tunnel should be to an exit node and connect to the given IPv4 or IPv6 IP address. Note that you can specify an IPv6 address as the target here, even in combination with "\-4" (4to6) and similarly you can specify an IPv4 address in combination with "\-6" (6to4). +.B +.IP "\-L LOGLEVEL, \-\-loglevel=LOGLEVEL" +Use LOGLEVEL for logging. Valid values are DEBUG, INFO, WARNING and ERROR. +.B +.IP "\-p PEERID, \-\-peer=PEERID" +Name of the peer offering the service to connect to. Cannot be used in conjunction with "\-i", requires "\-s". +.B +.IP "\-s NAME, \-\-service=NAME" +Name of the service running on the target peer. Cannot be used in conjunction with "\-i", requires "\-p". +.B +.IP "\-t, \-\-tcp" +Service runs TCP. Either "\-t" or \"-u" must be specified when using "\-s". +.B +.IP "\-u, \-\-udp" +Service runs UDP. Either "\-t" or \"-u" must be specified when using "\-s". +.B +.IP "\-V, \-\-verbose" +Be verbose. +.B +.IP "\-v, \-\-version" +Print GNUnet version number. + + +.SH BUGS +Report bugs by using Mantis or by sending electronic mail to + +.SH SEE ALSO +gnunet\-service\-arm(1) diff --git a/src/dns/gnunet-dns-redirector.c b/src/dns/gnunet-dns-redirector.c index cc317e5e4..4eabc8c79 100644 --- a/src/dns/gnunet-dns-redirector.c +++ b/src/dns/gnunet-dns-redirector.c @@ -30,7 +30,7 @@ #include "gnunet_dnsparser_lib.h" /** - * Handle to transport service. + * Handle to DNS service. */ static struct GNUNET_DNS_Handle *handle; diff --git a/src/vpn/gnunet-vpn.c b/src/vpn/gnunet-vpn.c index 3be830a6a..74c9956e2 100644 --- a/src/vpn/gnunet-vpn.c +++ b/src/vpn/gnunet-vpn.c @@ -64,16 +64,36 @@ static int ipv4; */ static int ipv6; +/** + * Option -t: TCP requested. + */ +static int tcp; + +/** + * Option -u: UDP requested. + */ +static int udp; + /** * Selected level of verbosity. */ static int verbosity; +/** + * Option '-a': Notify only once the tunnel is connected? + */ +static int nac; + /** * Global return value. */ static int ret; +/** + * Option '-d': duration of the mapping + */ +static unsigned long long duration = 5 * 60; + /** * Shutdown. @@ -97,6 +117,46 @@ do_disconnect (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc) } +/** + * Callback invoked from the VPN service once a redirection is + * available. Provides the IP address that can now be used to + * reach the requested destination. + * + * @param cls closure + * @param af address family, AF_INET or AF_INET6; AF_UNSPEC on error; + * will match 'result_af' from the request + * @param address IP address (struct in_addr or struct in_addr6, depending on 'af') + * that the VPN allocated for the redirection; + * traffic to this IP will now be redirected to the + * specified target peer; NULL on error + */ +static void +allocation_cb (void *cls, + int af, + const void *address) +{ + char buf[INET6_ADDRSTRLEN]; + + switch (af) + { + case AF_INET6: + case AF_INET: + FPRINTF (stdout, + "%s", + inet_ntop (af, address, buf, sizeof (buf))); + break; + case AF_UNSPEC: + GNUNET_log (GNUNET_ERROR_TYPE_ERROR, + _("Error creating tunnel\n")); + ret = 1; + break; + default: + break; + } + GNUNET_SCHEDULER_shutdown (); +} + + /** * Main function that will be run by the scheduler. * @@ -109,10 +169,121 @@ static void run (void *cls, char *const *args, const char *cfgfile, const struct GNUNET_CONFIGURATION_Handle *cfg) { - handle = GNUNET_VPN_connect (cfg); - + int dst_af; + int req_af; + struct GNUNET_PeerIdentity peer; + GNUNET_HashCode sd; + const void *addr; + struct in_addr v4; + struct in6_addr v6; + uint8_t protocol; + struct GNUNET_TIME_Absolute etime; + + etime = GNUNET_TIME_relative_to_absolute (GNUNET_TIME_relative_multiply (GNUNET_TIME_UNIT_SECONDS, + (unsigned int) duration)); GNUNET_SCHEDULER_add_delayed (GNUNET_TIME_UNIT_FOREVER_REL, &do_disconnect, NULL); + handle = GNUNET_VPN_connect (cfg); + if (NULL == handle) + goto error; + req_af = AF_UNSPEC; + if (ipv4) + { + if (ipv6) + { + FPRINTF (stderr, _("Option `%s' makes no sense with option `%s'.\n"), + "-4", "-6"); + goto error; + } + req_af = AF_INET; + } + if (ipv6) + req_af = AF_INET6; + + if (NULL == target_ip) + { + if (NULL == service_name) + { + FPRINTF (stderr, _("Option `%s' or `%s' is required.\n"), + "-i", "-s"); + goto error; + } + if (NULL == peer_id) + { + FPRINTF (stderr, _("Option `%s' is required when using option `%s'.\n"), + "-p", "-s"); + goto error; + } + if (! (tcp | udp) ) + { + FPRINTF (stderr, _("Option `%s' or `%s' is required when using option `%s'.\n"), + "-t", "-u", "-s"); + goto error; + } + if (tcp & udp) + { + FPRINTF (stderr, _("Option `%s' makes no sense with option `%s'.\n"), + "-t", "-u"); + goto error; + } + if (tcp) + protocol = IPPROTO_TCP; + if (udp) + protocol = IPPROTO_UDP; + if (GNUNET_OK != + GNUNET_CRYPTO_hash_from_string (peer_id, + &peer.hashPubKey)) + { + FPRINTF (stderr, _("`%s' is not a valid peer identifier.\n"), + peer_id); + goto error; + } + GNUNET_CRYPTO_hash (service_name, + strlen (service_name), + &sd); + request = GNUNET_VPN_redirect_to_peer (handle, + req_af, + protocol, + &peer, + &sd, + nac, + etime, + &allocation_cb, NULL); + } + else + { + if (1 != inet_pton (AF_INET6, target_ip, &v6)) + { + if (1 != inet_pton (AF_INET, target_ip, &v4)) + { + FPRINTF (stderr, _("`%s' is not a valid IP address.\n"), + target_ip); + goto error; + } + else + { + dst_af = AF_INET; + addr = &v4; + } + } + else + { + dst_af = AF_INET6; + addr = &v6; + } + request = GNUNET_VPN_redirect_to_ip (handle, + req_af, + dst_af, + addr, + nac, + etime, + &allocation_cb, NULL); + } + return; + + error: + GNUNET_SCHEDULER_shutdown (); + ret = 1; } @@ -126,6 +297,12 @@ main (int argc, char *const *argv) {'6', "ipv6", NULL, gettext_noop ("request that result should be an IPv6 address"), 0, &GNUNET_GETOPT_set_one, &ipv6}, + {'a', "after-connect", NULL, + gettext_noop ("print IP address only after mesh tunnel has been created"), + 0, &GNUNET_GETOPT_set_one, &ipv6}, + {'d', "duration", "SECONDS", + gettext_noop ("how long should the mapping be valid for new tunnels?"), + 1, &GNUNET_GETOPT_set_ulong, &duration}, {'i', "ip", "IP", gettext_noop ("destination IP for the tunnel"), 1, &GNUNET_GETOPT_set_string, &target_ip}, @@ -135,6 +312,13 @@ main (int argc, char *const *argv) {'s', "service", "NAME", gettext_noop ("name of the service we would like to access"), 1, &GNUNET_GETOPT_set_string, &peer_id}, + {'t', "tcp", NULL, + gettext_noop ("service is offered via TCP"), + 0, &GNUNET_GETOPT_set_one, &tcp}, + {'u', "udp", NULL, + gettext_noop ("service is offered via UDP"), + 0, &GNUNET_GETOPT_set_one, &udp}, + GNUNET_GETOPT_OPTION_VERBOSE (&verbosity), GNUNET_GETOPT_OPTION_END }; -- 2.25.1