noip.c: Add debugging to most of the syscall wrappers.
authorMark Wooding <mdw@distorted.org.uk>
Mon, 2 May 2016 21:28:36 +0000 (22:28 +0100)
committerMark Wooding <mdw@distorted.org.uk>
Mon, 2 May 2016 23:14:25 +0000 (00:14 +0100)
noip.c

diff --git a/noip.c b/noip.c
index e7f13cd..ee86680 100644 (file)
--- a/noip.c
+++ b/noip.c
@@ -1173,38 +1173,90 @@ done:
 
 /*----- Overridden system calls -------------------------------------------*/
 
+static void dump_syserr(long rc)
+  { fprintf(stderr, " => %ld (E%d)\n", rc, errno); }
+
+static void dump_sysresult(long rc)
+{
+  if (rc < 0) dump_syserr(rc);
+  else fprintf(stderr, " => %ld\n", rc);
+}
+
+static void dump_addrresult(long rc, const struct sockaddr *sa,
+                           socklen_t len)
+{
+  char addrbuf[ADDRBUFSZ];
+
+  if (rc < 0) dump_syserr(rc);
+  else {
+    fprintf(stderr, " => %ld [%s]\n", rc,
+           present_sockaddr(sa, len, addrbuf, sizeof(addrbuf)));
+  }
+}
+
 int socket(int pf, int ty, int proto)
 {
+  int sk;
+
+  D( fprintf(stderr, "noip(%d): SOCKET pf=%d, type=%d, proto=%d",
+            getpid(), pf, ty, proto); )
+
   switch (pf) {
     default:
       if (!family_known_p(pf)) {
+       D( fprintf(stderr, " -> unknown; refuse\n"); )
        errno = EAFNOSUPPORT;
-       return (-1);
+       sk = -1;
       }
+      D( fprintf(stderr, " -> inet; substitute"); )
       pf = PF_UNIX;
       proto = 0;
+      break;
     case PF_UNIX:
 #ifdef PF_NETLINK
     case PF_NETLINK:
 #endif
-      return (real_socket(pf, ty, proto));
+      D( fprintf(stderr, " -> safe; permit"); )
+      break;
   }
+  sk = real_socket(pf, ty, proto);
+  D( dump_sysresult(sk); )
+  return (sk);
 }
 
 int socketpair(int pf, int ty, int proto, int *sk)
 {
-  if (family_known_p(pf)) {
+  int rc;
+
+  D( fprintf(stderr, "noip(%d): SOCKETPAIR pf=%d, type=%d, proto=%d",
+            getpid(), pf, ty, proto); )
+  if (!family_known_p(pf))
+    D( fprintf(stderr, " -> unknown; permit"); )
+  else {
+    D( fprintf(stderr, " -> inet; substitute"); )
     pf = PF_UNIX;
     proto = 0;
   }
-  return (real_socketpair(pf, ty, proto, sk));
+  rc = real_socketpair(pf, ty, proto, sk);
+  D( if (rc < 0) dump_syserr(rc);
+     else fprintf(stderr, " => %d (%d, %d)\n", rc, sk[0], sk[1]); )
+  return (rc);
 }
 
 int bind(int sk, const struct sockaddr *sa, socklen_t len)
 {
   struct sockaddr_un sun;
+  int rc;
+  Dpid;
+
+  D({ char buf[ADDRBUFSZ];
+      fprintf(stderr, "noip(%d): BIND sk=%d, sa[%d]=%s", pid,
+             sk, len, present_sockaddr(sa, len, buf, sizeof(buf))); })
 
-  if (family_known_p(sa->sa_family)) {
+  if (!family_known_p(sa->sa_family))
+    D( fprintf(stderr, " -> unknown af; pass through"); )
+  else {
+    D( fprintf(stderr, " -> checking...\n"); )
     PRESERVING_ERRNO({
       if (acl_allows_p(bind_real, sa)) {
        if (fixup_real_ip_socket(sk, sa->sa_family, 0))
@@ -1215,21 +1267,32 @@ int bind(int sk, const struct sockaddr *sa, socklen_t len)
        len = SUN_LEN(&sun);
       }
     });
+    D( fprintf(stderr, "noip(%d): BIND ...", pid); )
   }
-  return (real_bind(sk, sa, len));
+  rc = real_bind(sk, sa, len);
+  D( dump_sysresult(rc); )
+  return (rc);
 }
 
 int connect(int sk, const struct sockaddr *sa, socklen_t len)
 {
   struct sockaddr_un sun;
   int rc;
+  Dpid;
 
-  if (!family_known_p(sa->sa_family))
+  D({ char buf[ADDRBUFSZ];
+      fprintf(stderr, "noip(%d): CONNECT sk=%d, sa[%d]=%s", pid,
+             sk, len, present_sockaddr(sa, len, buf, sizeof(buf))); })
+
+  if (!family_known_p(sa->sa_family)) {
+    D( fprintf(stderr, " -> unknown af; pass through"); )
     rc = real_connect(sk, sa, len);
-  else {
+  } else {
+    D( fprintf(stderr, " -> checking...\n"); )
     PRESERVING_ERRNO({
       do_implicit_bind(sk, &sa, &len, &sun);
     });
+    D( fprintf(stderr, "noip(%d): CONNECT ...", pid); )
     rc = real_connect(sk, sa, len);
     if (rc < 0) {
       switch (errno) {
@@ -1237,6 +1300,7 @@ int connect(int sk, const struct sockaddr *sa, socklen_t len)
       }
     }
   }
+  D( dump_sysresult(rc); )
   return (rc);
 }
 
@@ -1244,13 +1308,28 @@ ssize_t sendto(int sk, const void *buf, size_t len, int flags,
               const struct sockaddr *to, socklen_t tolen)
 {
   struct sockaddr_un sun;
+  ssize_t n;
+  Dpid;
 
-  if (to && family_known_p(to->sa_family)) {
+  D({ char addrbuf[ADDRBUFSZ];
+      fprintf(stderr, "noip(%d): SENDTO sk=%d, len=%lu, flags=%d, to[%d]=%s",
+             pid, sk, (unsigned long)len, flags, tolen,
+             present_sockaddr(to, tolen, addrbuf, sizeof(addrbuf))); })
+
+  if (!to)
+    D( fprintf(stderr, " -> null address; leaving"); )
+  else if (!family_known_p(to->sa_family))
+    D( fprintf(stderr, " -> unknown af; pass through"); )
+  else {
+    D( fprintf(stderr, " -> checking...\n"); )
     PRESERVING_ERRNO({
       do_implicit_bind(sk, &to, &tolen, &sun);
     });
+    D( fprintf(stderr, "noip(%d): SENDTO ...", pid); )
   }
-  return (real_sendto(sk, buf, len, flags, to, tolen));
+  n = real_sendto(sk, buf, len, flags, to, tolen);
+  D( dump_sysresult(n); )
+  return (n);
 }
 
 ssize_t recvfrom(int sk, void *buf, size_t len, int flags,
@@ -1259,57 +1338,91 @@ ssize_t recvfrom(int sk, void *buf, size_t len, int flags,
   char sabuf[1024];
   socklen_t mylen = sizeof(sabuf);
   ssize_t n;
+  Dpid;
 
-  if (!from)
-    return real_recvfrom(sk, buf, len, flags, 0, 0);
-  PRESERVING_ERRNO({
-    n = real_recvfrom(sk, buf, len, flags, SA(sabuf), &mylen);
-    if (n < 0)
-      return (-1);
-    return_fake_name(SA(sabuf), mylen, from, fromlen);
-  });
+  D( fprintf(stderr, "noip(%d): RECVFROM sk=%d, len=%lu, flags=%d",
+            pid, sk, (unsigned long)len, flags); )
+
+  if (!from) {
+    D( fprintf(stderr, " -> null addr; pass through"); )
+    n = real_recvfrom(sk, buf, len, flags, 0, 0);
+  } else {
+    PRESERVING_ERRNO({
+      n = real_recvfrom(sk, buf, len, flags, SA(sabuf), &mylen);
+      if (n >= 0) {
+       D( fprintf(stderr, " -> converting...\n"); )
+       return_fake_name(SA(sabuf), mylen, from, fromlen);
+       D( fprintf(stderr, "noip(%d): ... RECVFROM", pid); )
+      }
+    });
+  }
+  D( dump_addrresult(n, from, fromlen ? *fromlen : 0); )
   return (n);
 }
 
 ssize_t sendmsg(int sk, const struct msghdr *msg, int flags)
 {
   struct sockaddr_un sun;
-  const struct sockaddr *sa;
+  const struct sockaddr *sa = SA(msg->msg_name);
   struct msghdr mymsg;
+  ssize_t n;
+  Dpid;
 
-  if (msg->msg_name && family_known_p(SA(msg->msg_name)->sa_family)) {
+  D({ char addrbuf[ADDRBUFSZ];
+      fprintf(stderr, "noip(%d): SENDMSG sk=%d, "
+                     "msg_flags=%d, msg_name[%d]=%s, ...",
+             pid, sk, msg->msg_flags, msg->msg_namelen,
+             present_sockaddr(sa, msg->msg_namelen,
+                              addrbuf, sizeof(addrbuf))); })
+
+  if (!sa)
+    D( fprintf(stderr, " -> null address; leaving"); )
+  else if (!family_known_p(sa->sa_family))
+    D( fprintf(stderr, " -> unknown af; pass through"); )
+  else {
+    D( fprintf(stderr, " -> checking...\n"); )
     PRESERVING_ERRNO({
-      sa = SA(msg->msg_name);
       mymsg = *msg;
       do_implicit_bind(sk, &sa, &mymsg.msg_namelen, &sun);
       mymsg.msg_name = SA(sa);
       msg = &mymsg;
     });
+    D( fprintf(stderr, "noip(%d): SENDMSG ...", pid); )
   }
-  return (real_sendmsg(sk, msg, flags));
+  n = real_sendmsg(sk, msg, flags);
+  D( dump_sysresult(n); )
+  return (n);
 }
 
 ssize_t recvmsg(int sk, struct msghdr *msg, int flags)
 {
   char sabuf[1024];
-  struct sockaddr *sa;
-  socklen_t len;
+  struct sockaddr *sa = SA(msg->msg_name);
+  socklen_t len = msg->msg_namelen;
   ssize_t n;
+  Dpid;
+
+  D( fprintf(stderr, "noip(%d): RECVMSG sk=%d msg_flags=%d, ...",
+            pid, sk, msg->msg_flags); )
 
-  if (!msg->msg_name)
+  if (!msg->msg_name) {
+    D( fprintf(stderr, " -> null addr; pass through"); )
     return (real_recvmsg(sk, msg, flags));
-  PRESERVING_ERRNO({
-    sa = SA(msg->msg_name);
-    len = msg->msg_namelen;
-    msg->msg_name = sabuf;
-    msg->msg_namelen = sizeof(sabuf);
-    n = real_recvmsg(sk, msg, flags);
-    if (n < 0)
-      return (-1);
-    return_fake_name(SA(sabuf), msg->msg_namelen, sa, &len);
-    msg->msg_name = sa;
-    msg->msg_namelen = len;
-  });
+  } else {
+    PRESERVING_ERRNO({
+      msg->msg_name = sabuf;
+      msg->msg_namelen = sizeof(sabuf);
+      n = real_recvmsg(sk, msg, flags);
+      if (n >= 0) {
+       D( fprintf(stderr, " -> converting...\n"); )
+       return_fake_name(SA(sabuf), msg->msg_namelen, sa, &len);
+       D( fprintf(stderr, "noip(%d): ... RECVMSG", pid); )
+      }
+      msg->msg_name = sa;
+      msg->msg_namelen = len;
+    });
+  }
+  D( dump_addrresult(n, sa, len); )
   return (n);
 }
 
@@ -1317,35 +1430,60 @@ int accept(int sk, struct sockaddr *sa, socklen_t *len)
 {
   char sabuf[1024];
   socklen_t mylen = sizeof(sabuf);
-  int nsk = real_accept(sk, SA(sabuf), &mylen);
+  int nsk;
+  Dpid;
 
-  if (nsk < 0)
-    return (-1);
-  return_fake_name(SA(sabuf), mylen, sa, len);
+  D( fprintf(stderr, "noip(%d): ACCEPT sk=%d", pid, sk); )
+
+  nsk = real_accept(sk, SA(sabuf), &mylen);
+  if (nsk < 0) /* failed */;
+  else if (!sa) D( fprintf(stderr, " -> address not wanted"); )
+  else {
+    D( fprintf(stderr, " -> converting...\n"); )
+    return_fake_name(SA(sabuf), mylen, sa, len);
+    D( fprintf(stderr, "noip(%d): ... ACCEPT", pid); )
+  }
+  D( dump_addrresult(nsk, sa, len ? *len : 0); )
   return (nsk);
 }
 
 int getsockname(int sk, struct sockaddr *sa, socklen_t *len)
 {
+  int rc;
+  Dpid;
+
+  D( fprintf(stderr, "noip(%d): GETSOCKNAME sk=%d", pid, sk); )
   PRESERVING_ERRNO({
     char sabuf[1024];
     socklen_t mylen = sizeof(sabuf);
-    if (real_getsockname(sk, SA(sabuf), &mylen))
-      return (-1);
-    return_fake_name(SA(sabuf), mylen, sa, len);
+    rc = real_getsockname(sk, SA(sabuf), &mylen);
+    if (rc >= 0) {
+      D( fprintf(stderr, " -> converting...\n"); )
+      return_fake_name(SA(sabuf), mylen, sa, len);
+      D( fprintf(stderr, "noip(%d): ... GETSOCKNAME", pid); )
+    }
   });
-  return (0);
+  D( dump_addrresult(rc, sa, *len); )
+  return (rc);
 }
 
 int getpeername(int sk, struct sockaddr *sa, socklen_t *len)
 {
+  int rc;
+  Dpid;
+
+  D( fprintf(stderr, "noip(%d): GETPEERNAME sk=%d", pid, sk); )
   PRESERVING_ERRNO({
     char sabuf[1024];
     socklen_t mylen = sizeof(sabuf);
-    if (real_getpeername(sk, SA(sabuf), &mylen))
-      return (-1);
-    return_fake_name(SA(sabuf), mylen, sa, len);
+    rc = real_getpeername(sk, SA(sabuf), &mylen);
+    if (rc >= 0) {
+      D( fprintf(stderr, " -> converting...\n"); )
+      return_fake_name(SA(sabuf), mylen, sa, len);
+      D( fprintf(stderr, "noip(%d): ... GETPEERNAME", pid); )
+    }
   });
+  D( dump_addrresult(rc, sa, *len); )
   return (0);
 }