GNUnet  0.11.x
gnunet-vpn.c
Go to the documentation of this file.
1 /*
2  This file is part of GNUnet.
3  Copyright (C) 2012 GNUnet e.V.
4 
5  GNUnet is free software: you can redistribute it and/or modify it
6  under the terms of the GNU Affero General Public License as published
7  by the Free Software Foundation, either version 3 of the License,
8  or (at your option) any later version.
9 
10  GNUnet is distributed in the hope that it will be useful, but
11  WITHOUT ANY WARRANTY; without even the implied warranty of
12  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13  Affero General Public License for more details.
14 
15  You should have received a copy of the GNU Affero General Public License
16  along with this program. If not, see <http://www.gnu.org/licenses/>.
17 
18  SPDX-License-Identifier: AGPL3.0-or-later
19  */
20 
27 #include "platform.h"
28 #include "gnunet_util_lib.h"
29 #include "gnunet_tun_lib.h"
30 #include "gnunet_vpn_service.h"
31 
32 
36 static struct GNUNET_VPN_Handle *handle;
37 
42 
46 static char *peer_id;
47 
51 static char *service_name;
52 
56 static char *target_ip;
57 
61 static int ipv4;
62 
66 static int ipv6;
67 
71 static int tcp;
72 
76 static int udp;
77 
81 static unsigned int verbosity;
82 
86 static int ret;
87 
91 static struct GNUNET_TIME_Relative duration = { 5 * 60 * 1000 };
92 
93 
97 static void
98 do_disconnect (void *cls)
99 {
100  if (NULL != request)
101  {
102  GNUNET_VPN_cancel_request (request);
103  request = NULL;
104  }
105  if (NULL != handle)
106  {
107  GNUNET_VPN_disconnect (handle);
108  handle = NULL;
109  }
113 }
114 
115 
129 static void
130 allocation_cb (void *cls, int af, const void *address)
131 {
132  char buf[INET6_ADDRSTRLEN];
133 
134  request = NULL;
135  switch (af)
136  {
137  case AF_INET6:
138  case AF_INET:
139  fprintf (stdout, "%s\n", inet_ntop (af, address, buf, sizeof(buf)));
140  break;
141 
142  case AF_UNSPEC:
143  GNUNET_log (GNUNET_ERROR_TYPE_ERROR, _ ("Error creating tunnel\n"));
144  ret = 1;
145  break;
146 
147  default:
148  break;
149  }
151 }
152 
153 
162 static void
163 run (void *cls,
164  char *const *args,
165  const char *cfgfile,
166  const struct GNUNET_CONFIGURATION_Handle *cfg)
167 {
168  int dst_af;
169  int req_af;
170  struct GNUNET_PeerIdentity peer;
171  struct GNUNET_HashCode sd;
172  const void *addr;
173  struct in_addr v4;
174  struct in6_addr v6;
175  uint8_t protocol;
176  struct GNUNET_TIME_Absolute etime;
177 
178  etime = GNUNET_TIME_relative_to_absolute (duration);
180  handle = GNUNET_VPN_connect (cfg);
181  if (NULL == handle)
182  goto error;
183  req_af = AF_UNSPEC;
184  if (ipv4)
185  {
186  if (ipv6)
187  {
188  fprintf (stderr,
189  _ ("Option `%s' makes no sense with option `%s'.\n"),
190  "-4",
191  "-6");
192  goto error;
193  }
194  req_af = AF_INET;
195  }
196  if (ipv6)
197  req_af = AF_INET6;
198 
199  if (NULL == target_ip)
200  {
201  if (NULL == service_name)
202  {
203  fprintf (stderr, _ ("Option `%s' or `%s' is required.\n"), "-i", "-s");
204  goto error;
205  }
206  if (NULL == peer_id)
207  {
208  fprintf (stderr,
209  _ ("Option `%s' is required when using option `%s'.\n"),
210  "-p",
211  "-s");
212  goto error;
213  }
214  if (! (tcp | udp))
215  {
216  fprintf (stderr,
217  _ ("Option `%s' or `%s' is required when using option `%s'.\n"),
218  "-t",
219  "-u",
220  "-s");
221  goto error;
222  }
223  if (tcp & udp)
224  {
225  fprintf (stderr,
226  _ ("Option `%s' makes no sense with option `%s'.\n"),
227  "-t",
228  "-u");
229  goto error;
230  }
231  if (tcp)
232  protocol = IPPROTO_TCP;
233  if (udp)
234  protocol = IPPROTO_UDP;
235  if (GNUNET_OK !=
237  strlen (peer_id),
238  &peer.public_key))
239  {
240  fprintf (stderr, _ ("`%s' is not a valid peer identifier.\n"), peer_id);
241  goto error;
242  }
244  request = GNUNET_VPN_redirect_to_peer (handle,
245  req_af,
246  protocol,
247  &peer,
248  &sd,
249  etime,
250  &allocation_cb,
251  NULL);
252  }
253  else
254  {
255  if (1 != inet_pton (AF_INET6, target_ip, &v6))
256  {
257  if (1 != inet_pton (AF_INET, target_ip, &v4))
258  {
259  fprintf (stderr, _ ("`%s' is not a valid IP address.\n"), target_ip);
260  goto error;
261  }
262  else
263  {
264  dst_af = AF_INET;
265  addr = &v4;
266  }
267  }
268  else
269  {
270  dst_af = AF_INET6;
271  addr = &v6;
272  }
273  request = GNUNET_VPN_redirect_to_ip (handle,
274  req_af,
275  dst_af,
276  addr,
277  etime,
278  &allocation_cb,
279  NULL);
280  }
281  return;
282 
283 error:
285  ret = 1;
286 }
287 
288 
289 int
290 main (int argc, char *const *argv)
291 {
292  struct GNUNET_GETOPT_CommandLineOption options[] =
294  "ipv4",
295  gettext_noop (
296  "request that result should be an IPv4 address"),
297  &ipv4),
298 
300  "ipv6",
301  gettext_noop (
302  "request that result should be an IPv6 address"),
303  &ipv6),
304 
306  'd',
307  "duration",
308  "TIME",
309  gettext_noop ("how long should the mapping be valid for new tunnels?"),
310  &duration),
311 
313  "ip",
314  "IP",
315  gettext_noop (
316  "destination IP for the tunnel"),
317  &target_ip),
318 
320  'p',
321  "peer",
322  "PEERID",
323  gettext_noop ("peer offering the service we would like to access"),
324  &peer_id),
325 
327  "service",
328  "NAME",
329  gettext_noop (
330  "name of the service we would like to access"),
331  &service_name),
332 
334  "tcp",
335  gettext_noop ("service is offered via TCP"),
336  &tcp),
337 
339  "udp",
340  gettext_noop ("service is offered via UDP"),
341  &udp),
342 
344 
346 
347  if (GNUNET_OK != GNUNET_STRINGS_get_utf8_args (argc, argv, &argc, &argv))
348  return 2;
349 
350  ret =
351  (GNUNET_OK == GNUNET_PROGRAM_run (argc,
352  argv,
353  "gnunet-vpn",
354  gettext_noop ("Setup tunnels via VPN."),
355  options,
356  &run,
357  NULL))
358  ? ret
359  : 1;
360  GNUNET_free ((void *) argv);
361  return ret;
362 }
363 
364 
365 /* end of gnunet-vpn.c */
struct GNUNET_GETOPT_CommandLineOption GNUNET_GETOPT_option_relative_time(char shortName, const char *name, const char *argumentHelp, const char *description, struct GNUNET_TIME_Relative *val)
Allow user to specify a struct GNUNET_TIME_Relative (using human-readable "fancy" time)...
static char * target_ip
Option -i: target IP.
Definition: gnunet-vpn.c:56
int main(int argc, char *const *argv)
Definition: gnunet-vpn.c:290
static int udp
Option -u: UDP requested.
Definition: gnunet-vpn.c:76
static struct GNUNET_VPN_RedirectionRequest * request
Opaque redirection request handle.
Definition: gnunet-vpn.c:41
static const struct GNUNET_CONFIGURATION_Handle * cfg
Configuration we are using.
Definition: gnunet-abd.c:36
struct GNUNET_SCHEDULER_Task * GNUNET_SCHEDULER_add_shutdown(GNUNET_SCHEDULER_TaskCallback task, void *task_cls)
Schedule a new task to be run on shutdown, that is when a CTRL-C signal is received, or when GNUNET_SCHEDULER_shutdown() is being invoked.
Definition: scheduler.c:1300
static void run(void *cls, char *const *args, const char *cfgfile, const struct GNUNET_CONFIGURATION_Handle *cfg)
Main function that will be run by the scheduler.
Definition: gnunet-vpn.c:163
struct GNUNET_GETOPT_CommandLineOption GNUNET_GETOPT_option_verbose(unsigned int *level)
Define the &#39;-V&#39; verbosity option.
int GNUNET_STRINGS_get_utf8_args(int argc, char *const *argv, int *u8argc, char *const **u8argv)
Returns utf-8 encoded arguments.
Definition: strings.c:1438
static int ipv4
Option -4: IPv4 requested.
Definition: gnunet-vpn.c:61
struct GNUNET_TIME_Absolute GNUNET_TIME_relative_to_absolute(struct GNUNET_TIME_Relative rel)
Convert relative time to an absolute time in the future.
Definition: time.c:246
static void allocation_cb(void *cls, int af, const void *address)
Callback invoked from the VPN service once a redirection is available.
Definition: gnunet-vpn.c:130
#define GNUNET_OK
Named constants for return values.
Definition: gnunet_common.h:75
#define GNUNET_free_non_null(ptr)
Free the memory pointed to by ptr if ptr is not NULL.
Definition of a command line option.
static unsigned int verbosity
Selected level of verbosity.
Definition: gnunet-vpn.c:81
void GNUNET_SCHEDULER_shutdown(void)
Request the shutdown of a scheduler.
Definition: scheduler.c:526
struct GNUNET_GETOPT_CommandLineOption GNUNET_GETOPT_OPTION_END
Definition: 002.c:13
struct GNUNET_GETOPT_CommandLineOption GNUNET_GETOPT_option_string(char shortName, const char *name, const char *argumentHelp, const char *description, char **str)
Allow user to specify a string.
Opaque VPN handle.
Definition: vpn_api.c:34
#define _(String)
GNU gettext support macro.
Definition: platform.h:181
static struct GNUNET_TIME_Relative duration
Option &#39;-d&#39;: duration of the mapping.
Definition: gnunet-vpn.c:91
void GNUNET_VPN_disconnect(struct GNUNET_VPN_Handle *vh)
Disconnect from the VPN service.
Definition: vpn_api.c:534
static char * service_name
Option -s: service name (hash to get service descriptor)
Definition: gnunet-vpn.c:51
static char buf[2048]
void GNUNET_TUN_service_name_to_hash(const char *service_name, struct GNUNET_HashCode *hc)
Hash the service name of a hosted service to the hash code that is used to identify the service on th...
Definition: regex.c:814
static int ret
Global return value.
Definition: gnunet-vpn.c:86
A 512-bit hashcode.
void GNUNET_VPN_cancel_request(struct GNUNET_VPN_RedirectionRequest *rr)
Cancel redirection request with the service.
Definition: vpn_api.c:375
struct GNUNET_VPN_RedirectionRequest * GNUNET_VPN_redirect_to_peer(struct GNUNET_VPN_Handle *vh, int result_af, uint8_t protocol, const struct GNUNET_PeerIdentity *peer, const struct GNUNET_HashCode *serv, struct GNUNET_TIME_Absolute expiration_time, GNUNET_VPN_AllocationCallback cb, void *cb_cls)
Tell the VPN that a forwarding to a particular peer offering a particular service is requested...
Definition: vpn_api.c:410
Opaque redirection request handle.
Definition: vpn_api.c:76
static int tcp
Option -t: TCP requested.
Definition: gnunet-vpn.c:71
int GNUNET_CRYPTO_eddsa_public_key_from_string(const char *enc, size_t enclen, struct GNUNET_CRYPTO_EddsaPublicKey *pub)
Convert a string representing a public key to a public key.
Definition: crypto_ecc.c:499
struct GNUNET_VPN_Handle * GNUNET_VPN_connect(const struct GNUNET_CONFIGURATION_Handle *cfg)
Connect to the VPN service.
Definition: vpn_api.c:512
The identity of the host (wraps the signing key of the peer).
static void do_disconnect(void *cls)
Shutdown.
Definition: gnunet-vpn.c:98
configuration data
Definition: configuration.c:85
static struct GNUNET_VPN_Handle * handle
Handle to vpn service.
Definition: gnunet-vpn.c:36
struct GNUNET_GETOPT_CommandLineOption GNUNET_GETOPT_option_flag(char shortName, const char *name, const char *description, int *val)
Allow user to specify a flag (which internally means setting an integer to 1/GNUNET_YES/GNUNET_OK.
#define GNUNET_log(kind,...)
int GNUNET_PROGRAM_run(int argc, char *const *argv, const char *binaryName, const char *binaryHelp, const struct GNUNET_GETOPT_CommandLineOption *options, GNUNET_PROGRAM_Main task, void *task_cls)
Run a standard GNUnet command startup sequence (initialize loggers and configuration, parse options).
Definition: program.c:367
static char * peer_id
Option -p: destination peer identity for service.
Definition: gnunet-vpn.c:46
Time for absolute times used by GNUnet, in microseconds.
static char * address
GNS address for this phone.
#define GNUNET_free(ptr)
Wrapper around free.
Time for relative time used by GNUnet, in microseconds.
struct GNUNET_CRYPTO_EddsaPublicKey public_key
#define gettext_noop(String)
Definition: gettext.h:69
static int ipv6
Option -6: IPv6 requested.
Definition: gnunet-vpn.c:66
struct GNUNET_VPN_RedirectionRequest * GNUNET_VPN_redirect_to_ip(struct GNUNET_VPN_Handle *vh, int result_af, int addr_af, const void *addr, struct GNUNET_TIME_Absolute expiration_time, GNUNET_VPN_AllocationCallback cb, void *cb_cls)
Tell the VPN that forwarding to the Internet via some exit node is requested.
Definition: vpn_api.c:461