GNUnet  0.20.0
gnunet-helper-exit.c File Reference

the helper for exit nodes. More...

#include "platform.h"
#include "gnunet_util_lib.h"
#include "gnunet_common.h"
#include "gnunet_protocols.h"
Include dependency graph for gnunet-helper-exit.c:

Go to the source code of this file.

Macros

#define DEBUG   GNUNET_NO
 Need 'struct GNUNET_MessageHeader'. More...
 
#define MAX_SIZE   65536
 Maximum size of a GNUnet message (GNUNET_MAX_MESSAGE_SIZE) More...
 
#define init_tun(dev)   open (dev, O_RDWR)
 Creates a tun-interface called dev;. More...
 

Functions

static void open_dev_null (int target_fd, int flags)
 Open '/dev/null' and make the result the given file descriptor. More...
 
static int fork_and_exec (const char *file, char *const cmd[])
 Run the given command and wait for it to complete. More...
 
static void set_address6 (const char *dev, const char *address, unsigned long prefix_len)
 Sets the IPv6-Address given in address on the interface dev. More...
 
static void set_address4 (const char *dev, const char *address, const char *mask)
 Sets the IPv4-Address given in address on the interface dev. More...
 
static void run (int fd_tun)
 Start forwarding to and from the tunnel. More...
 
int main (int argc, char **argv)
 Open VPN tunnel interface. More...
 

Variables

static const char * sbin_sysctl
 Path to 'sysctl' binary. More...
 
static const char * sbin_iptables
 Path to 'iptables' binary. More...
 

Detailed Description

the helper for exit nodes.

Opens a virtual network-interface, sends data received on the if to stdout, sends data received on stdin to the interface. The code also enables IPv4/IPv6 forwarding and NAT on the current system (the latter on an interface specified on the command-line); these changes to the network configuration are NOT automatically undone when the program is stopped (this is because we cannot be sure that some other application didn't enable them before or after us; also, these changes should be mostly harmless as it simply turns the system into a router).

Author
Philipp Tölke
Christian Grothoff

The following list of people have reviewed this code and considered it safe since the last modification (if you reviewed it, please have your name added to the list):

  • Philipp Tölke

Definition in file gnunet-helper-exit.c.

Macro Definition Documentation

◆ DEBUG

#define DEBUG   GNUNET_NO

Need 'struct GNUNET_MessageHeader'.

Need VPN message types. Should we print (interesting|debug) messages that can happen during normal operation?

Definition at line 70 of file gnunet-helper-exit.c.

◆ MAX_SIZE

#define MAX_SIZE   65536

Maximum size of a GNUnet message (GNUNET_MAX_MESSAGE_SIZE)

Definition at line 75 of file gnunet-helper-exit.c.

◆ init_tun

#define init_tun (   dev)    open (dev, O_RDWR)

Creates a tun-interface called dev;.

Parameters
devis assumed to point to a char[IFNAMSIZ] if *dev == '\0', uses the name supplied by the kernel;
Returns
the fd to the tun or -1 on error

Definition at line 268 of file gnunet-helper-exit.c.

Function Documentation

◆ open_dev_null()

static void open_dev_null ( int  target_fd,
int  flags 
)
static

Open '/dev/null' and make the result the given file descriptor.

Parameters
target_fddesired FD to point to /dev/null
flagsopen flags (O_RDONLY, O_WRONLY)

Definition at line 111 of file gnunet-helper-exit.c.

113 {
114  int fd;
115 
116  fd = open ("/dev/null", flags);
117  if (-1 == fd)
118  abort ();
119  if (fd == target_fd)
120  return;
121  if (-1 == dup2 (fd, target_fd))
122  {
123  (void) close (fd);
124  abort ();
125  }
126  (void) close (fd);
127 }

Referenced by fork_and_exec().

Here is the caller graph for this function:

◆ fork_and_exec()

static int fork_and_exec ( const char *  file,
char *const  cmd[] 
)
static

Run the given command and wait for it to complete.

Parameters
filename of the binary to run
cmdcommand line arguments (as given to 'execv')
Returns
0 on success, 1 on any error

Definition at line 138 of file gnunet-helper-exit.c.

140 {
141  int status;
142  pid_t pid;
143  pid_t ret;
144 
145  pid = fork ();
146  if (-1 == pid)
147  {
148  fprintf (stderr,
149  "fork failed: %s\n",
150  strerror (errno));
151  return 1;
152  }
153  if (0 == pid)
154  {
155  /* we are the child process */
156  /* close stdin/stdout to not cause interference
157  with the helper's main protocol! */
158  (void) close (0);
159  open_dev_null (0, O_RDONLY);
160  (void) close (1);
161  open_dev_null (1, O_WRONLY);
162  (void) execv (file, cmd);
163  /* can only get here on error */
164  fprintf (stderr,
165  "exec `%s' failed: %s\n",
166  file,
167  strerror (errno));
168  _exit (1);
169  }
170  /* keep running waitpid as long as the only error we get is 'EINTR' */
171  while ((-1 == (ret = waitpid (pid, &status, 0))) &&
172  (errno == EINTR))
173  ;
174  if (-1 == ret)
175  {
176  fprintf (stderr,
177  "waitpid failed: %s\n",
178  strerror (errno));
179  return 1;
180  }
181  if (! (WIFEXITED (status) && (0 == WEXITSTATUS (status))))
182  return 1;
183  /* child process completed and returned success, we're happy */
184  return 0;
185 }
static int ret
Return value of the commandline.
Definition: gnunet-abd.c:81
static void open_dev_null(int target_fd, int flags)
Open '/dev/null' and make the result the given file descriptor.
uint16_t status
See PRISM_STATUS_*-constants.
static struct GNUNET_PeerIdentity pid
Identity of the peer we transmit to / connect to.

References open_dev_null(), pid, ret, and status.

Referenced by main().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ set_address6()

static void set_address6 ( const char *  dev,
const char *  address,
unsigned long  prefix_len 
)
static

Sets the IPv6-Address given in address on the interface dev.

Parameters
devthe interface to configure
addressthe IPv6-Address
prefix_lenthe length of the network-prefix

Definition at line 280 of file gnunet-helper-exit.c.

281 {
282  struct ifreq ifr;
283  struct sockaddr_in6 sa6;
284  int fd;
285  struct in6_ifreq ifr6;
286 
287  /*
288  * parse the new address
289  */
290  memset (&sa6, 0, sizeof(struct sockaddr_in6));
291  sa6.sin6_family = AF_INET6;
292  if (1 != inet_pton (AF_INET6, address, &sa6.sin6_addr))
293  {
294  fprintf (stderr, "Failed to parse address `%s': %s\n", address,
295  strerror (errno));
296  exit (1);
297  }
298 
299  if (-1 == (fd = socket (PF_INET6, SOCK_DGRAM, 0)))
300  {
301  fprintf (stderr, "Error creating socket: %s\n", strerror (errno));
302  exit (1);
303  }
304 
305  memset (&ifr, 0, sizeof(struct ifreq));
306  /*
307  * Get the index of the if
308  */
309  strncpy (ifr.ifr_name, dev, IFNAMSIZ);
310  if (-1 == ioctl (fd, SIOGIFINDEX, &ifr))
311  {
312  fprintf (stderr, "ioctl failed at %d: %s\n", __LINE__, strerror (errno));
313  (void) close (fd);
314  exit (1);
315  }
316 
317  memset (&ifr6, 0, sizeof(struct in6_ifreq));
318  ifr6.ifr6_addr = sa6.sin6_addr;
319  ifr6.ifr6_ifindex = ifr.ifr_ifindex;
320  ifr6.ifr6_prefixlen = prefix_len;
321 
322  /*
323  * Set the address
324  */
325  if (-1 == ioctl (fd, SIOCSIFADDR, &ifr6))
326  {
327  fprintf (stderr, "ioctl failed at line %d: %s\n", __LINE__,
328  strerror (errno));
329  (void) close (fd);
330  exit (1);
331  }
332 
333  /*
334  * Get the flags
335  */
336  if (-1 == ioctl (fd, SIOCGIFFLAGS, &ifr))
337  {
338  fprintf (stderr, "ioctl failed at line %d: %s\n", __LINE__,
339  strerror (errno));
340  (void) close (fd);
341  exit (1);
342  }
343 
344  /*
345  * Add the UP and RUNNING flags
346  */
347  ifr.ifr_flags |= IFF_UP | IFF_RUNNING;
348  if (-1 == ioctl (fd, SIOCSIFFLAGS, &ifr))
349  {
350  fprintf (stderr, "ioctl failed at line %d: %s\n", __LINE__,
351  strerror (errno));
352  (void) close (fd);
353  exit (1);
354  }
355 
356  if (0 != close (fd))
357  {
358  fprintf (stderr, "close failed: %s\n", strerror (errno));
359  exit (1);
360  }
361 }
static char * address
GNS address for this phone.
This is in linux/include/net/ipv6.h, but not always exported...

References address, in6_ifreq::ifr6_addr, in6_ifreq::ifr6_ifindex, and in6_ifreq::ifr6_prefixlen.

Referenced by main().

Here is the caller graph for this function:

◆ set_address4()

static void set_address4 ( const char *  dev,
const char *  address,
const char *  mask 
)
static

Sets the IPv4-Address given in address on the interface dev.

Parameters
devthe interface to configure
addressthe IPv4-Address
maskthe netmask

Definition at line 372 of file gnunet-helper-exit.c.

373 {
374  int fd;
375  struct sockaddr_in *addr;
376  struct ifreq ifr;
377 
378  memset (&ifr, 0, sizeof(struct ifreq));
379  addr = (struct sockaddr_in *) &(ifr.ifr_addr);
380  addr->sin_family = AF_INET;
381 
382  /*
383  * Parse the address
384  */
385  if (1 != inet_pton (AF_INET, address, &addr->sin_addr.s_addr))
386  {
387  fprintf (stderr, "Failed to parse address `%s': %s\n", address,
388  strerror (errno));
389  exit (1);
390  }
391 
392  if (-1 == (fd = socket (PF_INET, SOCK_DGRAM, 0)))
393  {
394  fprintf (stderr, "Error creating socket: %s\n", strerror (errno));
395  exit (1);
396  }
397 
398  strncpy (ifr.ifr_name, dev, IFNAMSIZ);
399 
400  /*
401  * Set the address
402  */
403  if (-1 == ioctl (fd, SIOCSIFADDR, &ifr))
404  {
405  fprintf (stderr, "ioctl failed at %d: %s\n", __LINE__, strerror (errno));
406  (void) close (fd);
407  exit (1);
408  }
409 
410  /*
411  * Parse the netmask
412  */
413  addr = (struct sockaddr_in *) &(ifr.ifr_netmask);
414  if (1 != inet_pton (AF_INET, mask, &addr->sin_addr.s_addr))
415  {
416  fprintf (stderr, "Failed to parse address `%s': %s\n", mask,
417  strerror (errno));
418  (void) close (fd);
419  exit (1);
420  }
421 
422  /*
423  * Set the netmask
424  */
425  if (-1 == ioctl (fd, SIOCSIFNETMASK, &ifr))
426  {
427  fprintf (stderr, "ioctl failed at line %d: %s\n", __LINE__,
428  strerror (errno));
429  (void) close (fd);
430  exit (1);
431  }
432 
433  /*
434  * Get the flags
435  */
436  if (-1 == ioctl (fd, SIOCGIFFLAGS, &ifr))
437  {
438  fprintf (stderr, "ioctl failed at line %d: %s\n", __LINE__,
439  strerror (errno));
440  (void) close (fd);
441  exit (1);
442  }
443 
444  /*
445  * Add the UP and RUNNING flags
446  */
447  ifr.ifr_flags |= IFF_UP | IFF_RUNNING;
448  if (-1 == ioctl (fd, SIOCSIFFLAGS, &ifr))
449  {
450  fprintf (stderr, "ioctl failed at line %d: %s\n", __LINE__,
451  strerror (errno));
452  (void) close (fd);
453  exit (1);
454  }
455 
456  if (0 != close (fd))
457  {
458  fprintf (stderr, "close failed: %s\n", strerror (errno));
459  (void) close (fd);
460  exit (1);
461  }
462 }

References address.

Referenced by main().

Here is the caller graph for this function:

◆ run()

static void run ( int  fd_tun)
static

Start forwarding to and from the tunnel.

Parameters
fd_tuntunnel FD

Definition at line 471 of file gnunet-helper-exit.c.

472 {
473  /*
474  * The buffer filled by reading from fd_tun
475  */
476  unsigned char buftun[MAX_SIZE];
477  ssize_t buftun_size = 0;
478  unsigned char *buftun_read = NULL;
479 
480  /*
481  * The buffer filled by reading from stdin
482  */
483  unsigned char bufin[MAX_SIZE];
484  ssize_t bufin_size = 0;
485  size_t bufin_rpos = 0;
486  unsigned char *bufin_read = NULL;
487 
488  fd_set fds_w;
489  fd_set fds_r;
490 
491  /* read refers to reading from fd_tun, writing to stdout */
492  int read_open = 1;
493 
494  /* write refers to reading from stdin, writing to fd_tun */
495  int write_open = 1;
496 
497  while ((1 == read_open) && (1 == write_open))
498  {
499  FD_ZERO (&fds_w);
500  FD_ZERO (&fds_r);
501 
502  /*
503  * We are supposed to read and the buffer is empty
504  * -> select on read from tun
505  */
506  if (read_open && (0 == buftun_size))
507  FD_SET (fd_tun, &fds_r);
508 
509  /*
510  * We are supposed to read and the buffer is not empty
511  * -> select on write to stdout
512  */
513  if (read_open && (0 != buftun_size))
514  FD_SET (1, &fds_w);
515 
516  /*
517  * We are supposed to write and the buffer is empty
518  * -> select on read from stdin
519  */
520  if (write_open && (NULL == bufin_read))
521  FD_SET (0, &fds_r);
522 
523  /*
524  * We are supposed to write and the buffer is not empty
525  * -> select on write to tun
526  */
527  if (write_open && (NULL != bufin_read))
528  FD_SET (fd_tun, &fds_w);
529 
530  int r = select (fd_tun + 1, &fds_r, &fds_w, NULL, NULL);
531 
532  if (-1 == r)
533  {
534  if (EINTR == errno)
535  continue;
536  fprintf (stderr, "select failed: %s\n", strerror (errno));
537  exit (1);
538  }
539 
540  if (r > 0)
541  {
542  if (FD_ISSET (fd_tun, &fds_r))
543  {
544  buftun_size =
545  read (fd_tun, buftun + sizeof(struct GNUNET_MessageHeader),
546  MAX_SIZE - sizeof(struct GNUNET_MessageHeader));
547  if (-1 == buftun_size)
548  {
549  fprintf (stderr,
550  "read-error: %s\n",
551  strerror (errno));
552  shutdown (fd_tun, SHUT_RD);
553  shutdown (1, SHUT_WR);
554  read_open = 0;
555  buftun_size = 0;
556  }
557  else if (0 == buftun_size)
558  {
559 #if DEBUG
560  fprintf (stderr, "EOF on tun\n");
561 #endif
562  shutdown (fd_tun, SHUT_RD);
563  shutdown (1, SHUT_WR);
564  read_open = 0;
565  buftun_size = 0;
566  }
567  else
568  {
569  buftun_read = buftun;
570  struct GNUNET_MessageHeader *hdr =
571  (struct GNUNET_MessageHeader *) buftun;
572  buftun_size += sizeof(struct GNUNET_MessageHeader);
573  hdr->type = htons (GNUNET_MESSAGE_TYPE_VPN_HELPER);
574  hdr->size = htons (buftun_size);
575  }
576  }
577  else if (FD_ISSET (1, &fds_w))
578  {
579  ssize_t written = write (1, buftun_read, buftun_size);
580 
581  if (-1 == written)
582  {
583 #if ! DEBUG
584  if (errno != EPIPE)
585 #endif
586  fprintf (stderr,
587  "write-error to stdout: %s\n",
588  strerror (errno));
589  shutdown (fd_tun, SHUT_RD);
590  shutdown (1, SHUT_WR);
591  read_open = 0;
592  buftun_size = 0;
593  }
594  else if (0 == written)
595  {
596  fprintf (stderr, "write returned 0!?\n");
597  exit (1);
598  }
599  else
600  {
601  buftun_size -= written;
602  buftun_read += written;
603  }
604  }
605 
606  if (FD_ISSET (0, &fds_r))
607  {
608  bufin_size = read (0, bufin + bufin_rpos, MAX_SIZE - bufin_rpos);
609  if (-1 == bufin_size)
610  {
611  fprintf (stderr, "read-error: %s\n", strerror (errno));
612  shutdown (0, SHUT_RD);
613  shutdown (fd_tun, SHUT_WR);
614  write_open = 0;
615  bufin_size = 0;
616  }
617  else if (0 == bufin_size)
618  {
619 #if DEBUG
620  fprintf (stderr, "EOF on stdin\n");
621 #endif
622  shutdown (0, SHUT_RD);
623  shutdown (fd_tun, SHUT_WR);
624  write_open = 0;
625  bufin_size = 0;
626  }
627  else
628  {
629  struct GNUNET_MessageHeader *hdr;
630 
631 PROCESS_BUFFER:
632  bufin_rpos += bufin_size;
633  if (bufin_rpos < sizeof(struct GNUNET_MessageHeader))
634  continue;
635  hdr = (struct GNUNET_MessageHeader *) bufin;
636  if (ntohs (hdr->type) != GNUNET_MESSAGE_TYPE_VPN_HELPER)
637  {
638  fprintf (stderr, "protocol violation!\n");
639  exit (1);
640  }
641  if (ntohs (hdr->size) > bufin_rpos)
642  continue;
643  bufin_read = bufin + sizeof(struct GNUNET_MessageHeader);
644  bufin_size = ntohs (hdr->size) - sizeof(struct GNUNET_MessageHeader);
645  bufin_rpos -= bufin_size + sizeof(struct GNUNET_MessageHeader);
646  }
647  }
648  else if (FD_ISSET (fd_tun, &fds_w))
649  {
650  ssize_t written = write (fd_tun, bufin_read, bufin_size);
651 
652  if (-1 == written)
653  {
654  fprintf (stderr, "write-error to tun: %s\n", strerror (errno));
655  shutdown (0, SHUT_RD);
656  shutdown (fd_tun, SHUT_WR);
657  write_open = 0;
658  bufin_size = 0;
659  }
660  else if (0 == written)
661  {
662  fprintf (stderr, "write returned 0!?\n");
663  exit (1);
664  }
665  else
666  {
667  bufin_size -= written;
668  bufin_read += written;
669  if (0 == bufin_size)
670  {
671  memmove (bufin, bufin_read, bufin_rpos);
672  bufin_read = NULL; /* start reading again */
673  bufin_size = 0;
674  goto PROCESS_BUFFER;
675  }
676  }
677  }
678  }
679  }
680 }
#define MAX_SIZE
Maximum size of a GNUnet message (GNUNET_MAX_MESSAGE_SIZE)
#define GNUNET_MESSAGE_TYPE_VPN_HELPER
Type of messages between the gnunet-vpn-helper and the daemon.
Header for all communications.
uint16_t type
The type of the message (GNUNET_MESSAGE_TYPE_XXXX), in big-endian format.
uint16_t size
The length of the struct (in bytes, including the length field itself), in big-endian format.

References GNUNET_MESSAGE_TYPE_VPN_HELPER, MAX_SIZE, GNUNET_MessageHeader::size, and GNUNET_MessageHeader::type.

Referenced by main().

Here is the caller graph for this function:

◆ main()

int main ( int  argc,
char **  argv 
)

Open VPN tunnel interface.

Parameters
argcmust be 6
argv0: binary name ("gnunet-helper-exit") 1: tunnel interface name ("gnunet-exit") 2: "physical" interface name ("eth0"), or "-" to not setup NAT and routing 3: IPv6 address ("::1"), or "-" to skip IPv6 4: IPv6 netmask length in bits ("64") [ignored if #4 is "-"] 5: IPv4 address ("1.2.3.4"), or "-" to skip IPv4 6: IPv4 netmask ("255.255.0.0") [ignored if #4 is "-"]

Definition at line 697 of file gnunet-helper-exit.c.

698 {
699  char dev[IFNAMSIZ];
700  int fd_tun;
701  int global_ret;
702 
703  if (7 != argc)
704  {
705  fprintf (stderr, "Fatal: must supply 6 arguments!\n");
706  return 1;
707  }
708  if ((0 == strcmp (argv[3], "-")) &&
709  (0 == strcmp (argv[5], "-")))
710  {
711  fprintf (stderr, "Fatal: disabling both IPv4 and IPv6 makes no sense.\n");
712  return 1;
713  }
714  if (0 != strcmp (argv[2], "-"))
715  {
716 #ifdef IPTABLES
717  if (0 == access (IPTABLES, X_OK))
718  sbin_iptables = IPTABLES;
719  else
720 #endif
721  if (0 == access ("/sbin/iptables", X_OK))
722  sbin_iptables = "/sbin/iptables";
723  else if (0 == access ("/usr/sbin/iptables", X_OK))
724  sbin_iptables = "/usr/sbin/iptables";
725  else
726  {
727  fprintf (stderr,
728  "Fatal: executable iptables not found in approved directories: %s\n",
729  strerror (errno));
730  return 1;
731  }
732 #ifdef SYSCTL
733  if (0 == access (SYSCTL, X_OK))
734  sbin_sysctl = SYSCTL;
735  else
736 #endif
737  if (0 == access ("/sbin/sysctl", X_OK))
738  sbin_sysctl = "/sbin/sysctl";
739  else if (0 == access ("/usr/sbin/sysctl", X_OK))
740  sbin_sysctl = "/usr/sbin/sysctl";
741  else
742  {
743  fprintf (stderr,
744  "Fatal: executable sysctl not found in approved directories: %s\n",
745  strerror (errno));
746  return 1;
747  }
748  }
749 
750  strncpy (dev, argv[1], IFNAMSIZ);
751  dev[IFNAMSIZ - 1] = '\0';
752 
753  if (-1 == (fd_tun = init_tun (dev)))
754  {
755  fprintf (stderr,
756  "Fatal: could not initialize tun-interface `%s' with IPv6 %s/%s and IPv4 %s/%s\n",
757  dev,
758  argv[3],
759  argv[4],
760  argv[5],
761  argv[6]);
762  return 1;
763  }
764 
765  if (0 != strcmp (argv[3], "-"))
766  {
767  {
768  const char *address = argv[3];
769  long prefix_len = atol (argv[4]);
770 
771  if ((prefix_len < 1) || (prefix_len > 127))
772  {
773  fprintf (stderr, "Fatal: prefix_len out of range\n");
774  return 1;
775  }
776  set_address6 (dev, address, prefix_len);
777  }
778  if (0 != strcmp (argv[2], "-"))
779  {
780  char *const sysctl_args[] = {
781  "sysctl", "-w", "net.ipv6.conf.all.forwarding=1", NULL
782  };
783  if (0 != fork_and_exec (sbin_sysctl,
784  sysctl_args))
785  {
786  fprintf (stderr,
787  "Failed to enable IPv6 forwarding. Will continue anyway.\n");
788  }
789  }
790  }
791 
792  if (0 != strcmp (argv[5], "-"))
793  {
794  {
795  const char *address = argv[5];
796  const char *mask = argv[6];
797 
798  set_address4 (dev, address, mask);
799  }
800  if (0 != strcmp (argv[2], "-"))
801  {
802  {
803  char *const sysctl_args[] = {
804  "sysctl", "-w", "net.ipv4.ip_forward=1", NULL
805  };
806  if (0 != fork_and_exec (sbin_sysctl,
807  sysctl_args))
808  {
809  fprintf (stderr,
810  "Failed to enable IPv4 forwarding. Will continue anyway.\n");
811  }
812  }
813  {
814  char *const iptables_args[] = {
815  "iptables", "-t", "nat", "-A", "POSTROUTING", "-o", argv[2], "-j",
816  "MASQUERADE", NULL
817  };
818  if (0 != fork_and_exec (sbin_iptables,
819  iptables_args))
820  {
821  fprintf (stderr,
822  "Failed to enable IPv4 masquerading (NAT). Will continue anyway.\n");
823  }
824  }
825  }
826  }
827 
828  uid_t uid = getuid ();
829 #ifdef HAVE_SETRESUID
830  if (0 != setresuid (uid, uid, uid))
831  {
832  fprintf (stderr, "Failed to setresuid: %s\n", strerror (errno));
833  global_ret = 2;
834  goto cleanup;
835  }
836 #else
837  if (0 != (setuid (uid) | seteuid (uid)))
838  {
839  fprintf (stderr, "Failed to setuid: %s\n", strerror (errno));
840  global_ret = 2;
841  goto cleanup;
842  }
843 #endif
844 
845  if (SIG_ERR == signal (SIGPIPE, SIG_IGN))
846  {
847  fprintf (stderr, "Failed to protect against SIGPIPE: %s\n",
848  strerror (errno));
849  /* no exit, we might as well die with SIGPIPE should it ever happen */
850  }
851  run (fd_tun);
852  global_ret = 0;
853 cleanup:
854  (void) close (fd_tun);
855  return global_ret;
856 }
static void cleanup(void *cls)
Function scheduled as very last function, cleans up after us.
static const char * sbin_sysctl
Path to 'sysctl' binary.
static void run(int fd_tun)
Start forwarding to and from the tunnel.
static int fork_and_exec(const char *file, char *const cmd[])
Run the given command and wait for it to complete.
static const char * sbin_iptables
Path to 'iptables' binary.
static void set_address4(const char *dev, const char *address, const char *mask)
Sets the IPv4-Address given in address on the interface dev.
static void set_address6(const char *dev, const char *address, unsigned long prefix_len)
Sets the IPv6-Address given in address on the interface dev.
#define init_tun(dev)
Creates a tun-interface called dev;.
static int global_ret
Return value from main.

References address, cleanup(), fork_and_exec(), global_ret, init_tun, run(), sbin_iptables, sbin_sysctl, set_address4(), and set_address6().

Here is the call graph for this function:

Variable Documentation

◆ sbin_sysctl

const char* sbin_sysctl
static

Path to 'sysctl' binary.

Definition at line 80 of file gnunet-helper-exit.c.

Referenced by main().

◆ sbin_iptables

const char* sbin_iptables
static

Path to 'iptables' binary.

Definition at line 85 of file gnunet-helper-exit.c.

Referenced by main().