server/tripe.c: Establish the stdio admin client early.
[tripe] / server / tripe.c
index d8a6cc1..aa225da 100644 (file)
@@ -91,6 +91,8 @@ Options:\n\
 -u, --usage            Display pointless usage message.\n\
     --tunnels          Display IP tunnel drivers and exit.\n\
 \n\
+-4, --ipv4             Transport over IPv4 only.\n\
+-6, --ipv6             Transport over IPv6 only.\n\
 -D, --daemon           Run in the background.\n\
 -F, --foreground       Quit when stdin reports end-of-file.\n\
 -d, --directory=DIR    Switch to directory DIR [default " CONFIGDIR "].\n\
@@ -141,7 +143,7 @@ int main(int argc, char *argv[])
   if ((p = getenv("TRIPESOCK")) != 0)
     csock = p;
   tun_default = tunnels[0];
-  aihint.ai_family = AF_INET;
+  aihint.ai_family = AF_UNSPEC;
 
   for (;;) {
     static const struct option opts[] = {
@@ -150,6 +152,8 @@ int main(int argc, char *argv[])
       { "usage",       0,              0,      'u' },
       { "tunnels",     0,              0,      '0' },
 
+      { "ipv4",                0,              0,      '4' },
+      { "ipv6",                0,              0,      '6' },
       { "daemon",      0,              0,      'D' },
       { "foreground",  0,              0,      'F' },
       { "uid",         OPTF_ARGREQ,    0,      'U' },
@@ -172,7 +176,7 @@ int main(int argc, char *argv[])
       { 0,             0,              0,      0 }
     };
 
-    i = mdwopt(argc, argv, "hvuDFU:G:b:n:p:d:k:K:t:a:m:" T("T:"),
+    i = mdwopt(argc, argv, "hvu46DFU:G:b:n:p:d:k:K:t:a:m:" T("T:"),
               opts, 0, 0, 0);
     if (i < 0)
       break;
@@ -187,6 +191,12 @@ int main(int argc, char *argv[])
        usage(stdout);
        exit(0);
 
+      case '4':
+       aihint.ai_family = AF_INET;
+       break;
+      case '6':
+       aihint.ai_family = AF_INET6;
+       break;
       case 'D':
        f |= f_daemon;
        break;
@@ -282,9 +292,7 @@ int main(int argc, char *argv[])
   rand_noisesrc(RAND_GLOBAL, &noise_source);
   rand_seed(RAND_GLOBAL, MAXHASHSZ);
   signal(SIGPIPE, SIG_IGN);
-  for (i = 0; tunnels[i]; i++)
-    tunnels[i]->init();
-  p_init(ailist); freeaddrinfo(ailist);
+
   if (!(f & f_daemon)) {
     af = AF_WARN;
 #ifndef NTRACE
@@ -293,15 +301,32 @@ int main(int argc, char *argv[])
     if (f & f_foreground)
       af |= AF_FOREGROUND;
     a_create(STDIN_FILENO, STDOUT_FILENO, af);
+    a_switcherr();
   }
-  ps_split(f & f_daemon);
-  a_init(csock, u, g, csockmode);
+
+  p_init();
+  for (i = 0; tunnels[i]; i++)
+    tunnels[i]->init();
+  p_bind(ailist); freeaddrinfo(ailist);
+
+  for (i = 0; tunnels[i]; i++) {
+    if (tunnels[i]->flags&TUNF_PRIVOPEN) {
+      ps_split(f & f_daemon);
+      break;
+    }
+  }
+
+  a_init();
+  a_signals();
+  a_listen(csock, u, g, csockmode);
   u_setugid(u, g);
   km_init(kr_priv, kr_pub, tag_priv);
+  kx_init();
   if (f & f_daemon) {
     if (daemonize())
       die(EXIT_FAILURE, "couldn't become a daemon: %s", strerror(errno));
     a_daemon();
+    a_switcherr();
   }
 
   tv.tv_sec = time(0) + T_INTERVAL;