server/: Issue `WARN' messages for (most) initialization errors.
authorMark Wooding <mdw@distorted.org.uk>
Sun, 13 May 2018 14:26:59 +0000 (15:26 +0100)
committerMark Wooding <mdw@distorted.org.uk>
Fri, 25 Jan 2019 12:10:31 +0000 (12:10 +0000)
Now, most initialization problems which aren't to do with duff arguments
are diagnosed as `WARN' messages rather than human-readable messages on
stderr.

Document the new warnings.

server/admin.c
server/peer.c
server/privsep.c
server/tripe-admin.5.in
server/tripe.c
server/tun-slip.c

index 6ff0dbf..5146fde 100644 (file)
@@ -2514,8 +2514,10 @@ void a_listen(const char *name, uid_t u, gid_t g, mode_t m)
   /* --- Set up the socket address --- */
 
   sz = strlen(name) + 1;
-  if (sz > sizeof(sun.sun_path))
-    die(EXIT_FAILURE, "socket name `%s' too long", name);
+  if (sz > sizeof(sun.sun_path)) {
+    a_warn("ADMIN", "admin-socket", "%s", name, "name-too-long", A_END);
+    exit(EXIT_FAILURE);
+  }
   BURN(sun);
   sun.sun_family = AF_UNIX;
   memcpy(sun.sun_path, name, sz);
@@ -2525,48 +2527,68 @@ void a_listen(const char *name, uid_t u, gid_t g, mode_t m)
 
   omask = umask(0077);
 again:
-  if ((fd = socket(PF_UNIX, SOCK_STREAM, 0)) < 0)
-    die(EXIT_FAILURE, "couldn't create socket: %s", strerror(errno));
+  if ((fd = socket(PF_UNIX, SOCK_STREAM, 0)) < 0) {
+    a_warn("ADMIN", "admin-socket", "%s", sun.sun_path,
+          "create-failed", "?ERRNO", A_END);
+    exit(EXIT_FAILURE);
+  }
   if (bind(fd, (struct sockaddr *)&sun, sz) < 0) {
     struct stat st;
     int e = errno;
     if (errno != EADDRINUSE) {
-      die(EXIT_FAILURE, "couldn't bind to address `%s': %s",
-         sun.sun_path, strerror(e));
+      a_warn("ADMIN", "admin-socket", "%s", sun.sun_path,
+            "bind-failed", "?ERRNO", A_END);
+      exit(EXIT_FAILURE);
+    }
+    if (!n) {
+      a_warn("ADMIN", "admin-socket", "%s", sun.sun_path,
+            "too-many-retries", A_END);
+      exit(EXIT_FAILURE);
     }
-    if (!n)
-      die(EXIT_FAILURE, "too many retries; giving up");
     n--;
     if (!connect(fd, (struct sockaddr *)&sun, sz)) {
-      die(EXIT_FAILURE, "server already listening on admin socket `%s'",
-         sun.sun_path);
+      a_warn("ADMIN", "admin-socket", "%s", sun.sun_path,
+            "already-in-use", A_END);
+      exit(EXIT_FAILURE);
+    }
+    if (errno != ECONNREFUSED) {
+      a_warn("ADMIN", "admin-socket", "%s", sun.sun_path,
+            "bind-failed", "?ERR", e, A_END);
+      exit(EXIT_FAILURE);
     }
-    if (errno != ECONNREFUSED)
-      die(EXIT_FAILURE, "couldn't bind to address: %s", strerror(e));
     if (stat(sun.sun_path, &st)) {
       if (errno == ENOENT) { close(fd); goto again; }
-      die(EXIT_FAILURE, "couldn't stat `%s': %s",
-         sun.sun_path, strerror(errno));
+      a_warn("ADMIN", "admin-socket", "%s", sun.sun_path,
+            "stat-failed", "?ERRNO", A_END);
+      exit(EXIT_FAILURE);
+    }
+    if (!S_ISSOCK(st.st_mode)) {
+      a_warn("ADMIN", "admin-socket", "%s", sun.sun_path,
+            "not-a-socket", A_END);
+      exit(EXIT_FAILURE);
     }
-    if (!S_ISSOCK(st.st_mode))
-      die(EXIT_FAILURE, "object `%s' isn't a socket", sun.sun_path);
     T( trace(T_ADMIN, "admin: stale socket found; removing it"); )
     unlink(sun.sun_path);
     close(fd);
     goto again;
   }
   if (chown(sun.sun_path, u, g)) {
-    die(EXIT_FAILURE, "failed to set socket owner: %s",
-       strerror(errno));
+    a_warn("ADMIN", "admin-socket", "%s", sun.sun_path,
+          "chown-failed", "?ERRNO", A_END);
+    exit(EXIT_FAILURE);
   }
   if (chmod(sun.sun_path, m)) {
-    die(EXIT_FAILURE, "failed to set socket permissions: %s",
-       strerror(errno));
+    a_warn("ADMIN", "admin-socket", "%s", sun.sun_path,
+          "chmod-failed", "?ERRNO", A_END);
+    exit(EXIT_FAILURE);
   }
   umask(omask);
   fdflags(fd, O_NONBLOCK, O_NONBLOCK, FD_CLOEXEC, FD_CLOEXEC);
-  if (listen(fd, 5))
-    die(EXIT_FAILURE, "couldn't listen on socket: %s", strerror(errno));
+  if (listen(fd, 5)) {
+    a_warn("ADMIN", "admin-socket", "%s", sun.sun_path,
+          "listen-failed", "?ERRNO", A_END);
+    exit(EXIT_FAILURE);
+  }
 
   /* --- Listen to the socket --- */
 
@@ -2644,8 +2666,10 @@ void a_init(void)
                       (adns_if_permit_ipv4 | adns_if_permit_ipv6 |
                        adns_if_noserverwarn | adns_if_nosigpipe |
                        adns_if_noautosys),
-                      0)) != 0)
-    die(EXIT_FAILURE, "failed to initialize ADNS: %s", strerror(errno));
+                      0)) != 0) {
+    a_warn("ADMIN", "adns-init-failed", "?ERRNO", A_END);
+    exit(EXIT_FAILURE);
+  }
   sel_addhook(&sel, &hook, before_select, after_select, 0);
 #else
   bres_init(&sel);
index 27ac4a7..246d84e 100644 (file)
@@ -850,22 +850,30 @@ void p_bind(struct addrinfo *ailist)
      * than second-guessing me.
      */
 
-    if ((fd = socket(ai->ai_family, SOCK_DGRAM, 0)) < 0)
-      die(EXIT_FAILURE, "socket creation failed: %s", strerror(errno));
+    if ((fd = socket(ai->ai_family, SOCK_DGRAM, 0)) < 0) {
+      a_warn("PEER", "-", "udp-socket", "%s", aftab[i].name,
+            "create-failed", "?ERRNO", A_END);
+      exit(EXIT_FAILURE);
+    }
     if (i == AFIX_INET6 &&
        setsockopt(fd, IPPROTO_IPV6, IPV6_V6ONLY, &yes, sizeof(yes))) {
-      die(EXIT_FAILURE, "failed to set IPv6-only state: %s",
-         strerror(errno));
+      a_warn("PEER", "-", "udp-socket", "%s", aftab[i].name,
+            "set-v6only-failed", "?ERRNO", A_END);
+      exit(EXIT_FAILURE);
     }
     assert(ai->ai_addrlen <= sizeof(a));
     memcpy(&a, ai->ai_addr, ai->ai_addrlen);
     if ((port = getport(&a)) == 0 && lastport) setport(&a, lastport);
-    if (bind(fd, &a.sa, addrsz(&a)))
-      die(EXIT_FAILURE, "bind failed: %s", strerror(errno));
+    if (bind(fd, &a.sa, addrsz(&a))) {
+      a_warn("PEER", "-", "udp-socket", "%s", aftab[i].name,
+            "bind-failed", "?ERRNO", A_END);
+      exit(EXIT_FAILURE);
+    }
     if (setsockopt(fd, SOL_SOCKET, SO_RCVBUF, &len, sizeof(len)) ||
        setsockopt(fd, SOL_SOCKET, SO_SNDBUF, &len, sizeof(len))) {
-      die(EXIT_FAILURE, "failed to set socket buffer sizes: %s",
-         strerror(errno));
+      a_warn("PEER", "-", "udp-socket", "%s", aftab[i].name,
+            "set-buffers-failed", "?ERRNO", A_END);
+      exit(EXIT_FAILURE);
     }
     fdflags(fd, O_NONBLOCK, O_NONBLOCK, FD_CLOEXEC, FD_CLOEXEC);
     sel_initfile(&sel, &udpsock[i].sf, fd, SEL_READ, p_read, 0);
@@ -876,8 +884,9 @@ void p_bind(struct addrinfo *ailist)
     else {
       sz = sizeof(a);
       if (getsockname(fd, &a.sa, &sz)) {
-       die(EXIT_FAILURE, "failed to read local socket address: %s",
-           strerror(errno));
+       a_warn("PEER", "-", "udp-socket", "%s", aftab[i].name,
+              "read-local-address-failed", "?ERRNO", A_END);
+       exit(EXIT_FAILURE);
       }
       udpsock[i].port = lastport = getport(&a);
     }
index 0b5390e..56b22be 100644 (file)
@@ -177,9 +177,8 @@ void ps_split(int detachp)
   const char *helper;
 
   if (socketpair(PF_UNIX, SOCK_STREAM, 0, fd)) {
-    die(EXIT_FAILURE,
-       "failed to create socket pair for privilege separation: %s",
-       strerror(errno));
+    a_warn("PRIVSEP", "socketpair-create-failed", "?ERRNO", A_END);
+    exit(EXIT_FAILURE);
   }
   helper = getenv("TRIPE_PRIVHELPER");
   if (!helper) helper = PRIVSEP_HELPER;
index 698e2a6..86fe314 100644 (file)
@@ -1369,6 +1369,59 @@ client.
 .BI "ADMIN client-write-error " ecode " " message
 There was an error sending data to a client.  The connection to the
 client has been closed.
+.SP
+.BI "ADMIN admin-socket " path " already-in-use"
+The server failed to create the Unix-domain socket object in the
+filesystem, because there's already a socket there, and some other
+process is actively listening for incoming connections.
+.SP
+.BI "ADMIN admin-socket " path " bind-failed " ecode " " message
+The server failed to create the Unix-domain socket object in the
+filesystem for an unusual reason.  (The usual reason is
+.BR EADDRINUSE ,
+but this is handled specially.)
+.SP
+.BI "ADMIN admin-socket " path " chmod-failed " ecode " " message
+The server failed to set the correct permissions of the Unix-domain
+socket object.
+.SP
+.BI "ADMIN admin-socket " path " chown-failed " ecode " " message
+The server failed to set the correct ownership of the Unix-domain socket
+object.
+.SP
+.BI "ADMIN admin-socket " path " create-failed " ecode " " message
+The server failed to create its administration socket.  This is usually
+because some system resource is unavailable.
+.SP
+.BI "ADMIN admin-socket " path " listen-failed " ecode " " message
+The server failed to arrange to receive incoming connections on its
+Unix-domain socket.
+.SP
+.BI "ADMIN admin-socket " path " name-too-long"
+The server can't create its administration socket, because the chosen
+pathname
+.I path
+is too long.  There is, for historical reasons, a rather tight limit on
+the length of name permitted for Unix-domain sockets, usually around 108
+bytes.
+.SP
+.BI "ADMIN admin-socket " path " stat-failed " ecode " " message
+The server failed to create the Unix-domain socket object in the
+filesystem, because there's already something there, but the server
+couldn't discover what.
+.SP
+.BI "ADMIN admin-socket " path " too-many-retries"
+The server failed to create the Unix-domain socket object in the
+filesystem.  This error indicates that another process is also
+repeatedly trying to create a Unix-domain socket at the same
+.IR path ,
+and then failing to actually listen for connections on it, but the
+server always loses the applicable race for some reason.  This situation
+merits investigation.
+.SP
+.BI "ADMIN adns-init-failed " ecode " " message
+The server failed to initialize the ADNS asynchronous DNS-resolution
+library.
 .SS "CHAL warnings"
 These indicate errors in challenges, either in the
 .B CHECKCHAL
@@ -1652,6 +1705,24 @@ switched off by command-line options.
 An error occurred attempting to send a network packet.  We lost that
 one.
 .SP
+.BI "PEER \- udp-socket " address-family " bind-failed " ecode " " message
+The server failed to associate a UDP socket with a local address.
+.SP
+.BI "PEER \- udp-socket " address-family " create-failed " ecode " " message
+The server failed to create a UDP socket for the
+.IR address-family .
+.SP
+.BI "PEER \- udp-socket " address-family " read-local-address-failed " ecode " " message
+The server failed to discover the local address for one of its own UDP
+sockets.
+.SP
+.BI "PEER \- udp-socket " address-family " set-buffers-failed " ecode " " message
+The server failed to configure appropriate buffer sizes on a UDP socket.
+.SP
+.BI "PEER \- udp-socket INET6 set-v6only-failed " ecode " " message
+The server failed to configure an IPv6 socket not to try to collect IPv4
+traffic too.
+.SP
 .BI "PEER " peer " unexpected-encrypted-ping 0x" id
 The peer sent an encrypted ping response whose id doesn't match any
 outstanding ping.  Maybe it was delayed for longer than the server was
@@ -1711,6 +1782,10 @@ The server failed to send a message to the helper process.
 The helper process sent back a positive response, but didn't include the
 requested tunnel descriptor.
 .SP
+.BI "PRIVSEP socketpair-create-failed " ecode " " message
+The server couldn't create the socketpair it's supposed to use to
+communicate with the helper process.
+.SP
 .BI "PRIVSEP unknown-response-code"
 The helper process sent back an incomprehensible reply.  It's probably
 very confused and may crash.
@@ -1737,6 +1812,9 @@ A client of the administration interface issued a
 .B QUIT
 command.
 .SP
+.BI "SERVER daemon-error " ecode " " message
+The server failed to become a daemon during initialization.
+.SP
 .BI "SERVER quit foreground-eof"
 The server is running in foreground mode (the
 .B \-F
@@ -1792,6 +1870,11 @@ Writing from the tunnel device failed.
 The SLIP driver encountered a escaped byte it wasn't expecting to see.
 The erroneous packet will be ignored.
 .SP
+.BI "TUN \- slip bad-interface-list"
+The interface list, in the
+.B TRIPE_SLIPIF
+environment variable, is malformed.
+.SP
 .BI "TUN " ifname " slip eof"
 The SLIP driver encountered end-of-file on its input descriptor.
 Pending data is discarded, and no attempt is made to read any more data
index aa225da..93d40b9 100644 (file)
@@ -323,8 +323,10 @@ int main(int argc, char *argv[])
   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));
+    if (daemonize()) {
+      a_warn("SERVER", "daemon-error", "?ERRNO", A_END);
+      exit(EXIT_FAILURE);
+    }
     a_daemon();
     a_switcherr();
   }
index 1c45295..d4b35d0 100644 (file)
@@ -243,7 +243,7 @@ static void t_init(void)
   return;
 
 whine:
-  moan("bad slip interface list");
+  a_warn("TUN", "-", "slip", "bad-interface-list", A_END);
 }
 
 /* --- @t_broken@ --- *