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  {
103  request = NULL;
104  }
105  if (NULL != handle)
106  {
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;
177 
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  }
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  }
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 {
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_nz ((void *) argv);
361  return ret;
362 }
363 
364 
365 /* end of gnunet-vpn.c */
struct GNUNET_GETOPT_CommandLineOption GNUNET_GETOPT_OPTION_END
Definition: 002.c:13
struct GNUNET_GETOPT_CommandLineOption options[]
Definition: 002.c:5
#define gettext_noop(String)
Definition: gettext.h:69
static const struct GNUNET_CONFIGURATION_Handle * cfg
Configuration we are using.
Definition: gnunet-abd.c:36
static uint64_t etime
Expiration string converted to numeric value.
Definition: gnunet-abd.c:201
static char * address
GNS address for this phone.
static char buf[2048]
static void do_disconnect(void *cls)
Shutdown.
Definition: gnunet-vpn.c:98
static unsigned int verbosity
Selected level of verbosity.
Definition: gnunet-vpn.c:81
static char * target_ip
Option -i: target IP.
Definition: gnunet-vpn.c:56
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
static char * peer_id
Option -p: destination peer identity for service.
Definition: gnunet-vpn.c:46
static int ret
Global return value.
Definition: gnunet-vpn.c:86
static char * service_name
Option -s: service name (hash to get service descriptor)
Definition: gnunet-vpn.c:51
static struct GNUNET_TIME_Relative duration
Option '-d': duration of the mapping.
Definition: gnunet-vpn.c:91
static int ipv4
Option -4: IPv4 requested.
Definition: gnunet-vpn.c:61
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
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 int ipv6
Option -6: IPv6 requested.
Definition: gnunet-vpn.c:66
static struct GNUNET_VPN_RedirectionRequest * request
Opaque redirection request handle.
Definition: gnunet-vpn.c:41
static struct GNUNET_VPN_Handle * handle
Handle to vpn service.
Definition: gnunet-vpn.c:36
static int tcp
Option -t: TCP requested.
Definition: gnunet-vpn.c:71
#define GNUNET_log(kind,...)
@ GNUNET_OK
Definition: gnunet_common.h:95
enum GNUNET_GenericReturnValue 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:357
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).
struct GNUNET_GETOPT_CommandLineOption GNUNET_GETOPT_option_verbose(unsigned int *level)
Define the '-V' verbosity option.
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.
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.
@ GNUNET_ERROR_TYPE_ERROR
#define GNUNET_free(ptr)
Wrapper around free.
#define GNUNET_free_nz(ptr)
Wrapper around free.
enum GNUNET_GenericReturnValue 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,...
Definition: program.c:364
void GNUNET_SCHEDULER_shutdown(void)
Request the shutdown of a scheduler.
Definition: scheduler.c:531
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,...
Definition: scheduler.c:1331
enum GNUNET_GenericReturnValue GNUNET_STRINGS_get_utf8_args(int argc, char *const *argv, int *u8argc, char *const **u8argv)
Returns utf-8 encoded arguments.
Definition: strings.c:1209
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:181
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
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
void GNUNET_VPN_cancel_request(struct GNUNET_VPN_RedirectionRequest *rr)
Cancel redirection request with the service.
Definition: vpn_api.c:375
struct GNUNET_VPN_Handle * GNUNET_VPN_connect(const struct GNUNET_CONFIGURATION_Handle *cfg)
Connect to the VPN service.
Definition: vpn_api.c:512
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
void GNUNET_VPN_disconnect(struct GNUNET_VPN_Handle *vh)
Disconnect from the VPN service.
Definition: vpn_api.c:534
#define _(String)
GNU gettext support macro.
Definition: platform.h:177
Definition of a command line option.
A 512-bit hashcode.
The identity of the host (wraps the signing key of the peer).
Time for absolute times used by GNUnet, in microseconds.
Time for relative time used by GNUnet, in microseconds.
Opaque VPN handle.
Definition: vpn_api.c:35
Opaque redirection request handle.
Definition: vpn_api.c:77
struct GNUNET_TESTBED_Peer * peer
The peer associated with this model.