GNUnet  0.11.x
Macros | Functions | Variables
gnunet-helper-exit.c File Reference

the helper for exit nodes. More...

#include "platform.h"
#include "gnunet_crypto_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):

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.

Referenced by run().

◆ init_tun

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

Creates a tun-interface called dev;.

Parameters
devis asumed 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 266 of file gnunet-helper-exit.c.

Referenced by fork_and_exec(), and main().

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 109 of file gnunet-helper-exit.c.

Referenced by fork_and_exec().

111 {
112  int fd;
113 
114  fd = open ("/dev/null", flags);
115  if (-1 == fd)
116  abort ();
117  if (fd == target_fd)
118  return;
119  if (-1 == dup2 (fd, target_fd))
120  {
121  (void) close (fd);
122  abort ();
123  }
124  (void) close (fd);
125 }
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 136 of file gnunet-helper-exit.c.

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

Referenced by main().

138 {
139  int status;
140  pid_t pid;
141  pid_t ret;
142 
143  pid = fork ();
144  if (-1 == pid)
145  {
146  fprintf (stderr,
147  "fork failed: %s\n",
148  strerror (errno));
149  return 1;
150  }
151  if (0 == pid)
152  {
153  /* we are the child process */
154  /* close stdin/stdout to not cause interference
155  with the helper's main protocol! */
156  (void) close (0);
157  open_dev_null (0, O_RDONLY);
158  (void) close (1);
159  open_dev_null (1, O_WRONLY);
160  (void) execv (file, cmd);
161  /* can only get here on error */
162  fprintf (stderr,
163  "exec `%s' failed: %s\n",
164  file,
165  strerror (errno));
166  _exit (1);
167  }
168  /* keep running waitpid as long as the only error we get is 'EINTR' */
169  while ((-1 == (ret = waitpid (pid, &status, 0))) &&
170  (errno == EINTR))
171  ;
172  if (-1 == ret)
173  {
174  fprintf (stderr,
175  "waitpid failed: %s\n",
176  strerror (errno));
177  return 1;
178  }
179  if (! (WIFEXITED (status) && (0 == WEXITSTATUS (status))))
180  return 1;
181  /* child process completed and returned success, we're happy */
182  return 0;
183 }
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.
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 278 of file gnunet-helper-exit.c.

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

Referenced by main().

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

Referenced by main().

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

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

Referenced by main().

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

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

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