Merge branch 'master' of metalzone:public-git/preload-hacks
authorMark Wooding <mdw@distorted.org.uk>
Sat, 26 Dec 2009 12:16:09 +0000 (12:16 +0000)
committerMark Wooding <mdw@distorted.org.uk>
Sat, 26 Dec 2009 12:16:09 +0000 (12:16 +0000)
* 'master' of metalzone:public-git/preload-hacks:
  Version 1.0.4.
  noip (decode_inet_addr): Be more careful when converting addresses.
  noip: Don't try to support families other than AF_UNIX and AF_INET.

1  2 
noip.c

diff --combined noip.c
--- 1/noip.c
--- 2/noip.c
+++ b/noip.c
@@@ -340,11 -340,15 +340,15 @@@ static int encode_inet_addr(struct sock
    return (0);
  }
  
- /* Decode the Unix address SUN to an Internet address SIN.  Returns zero on
-  * success; -1 on failure (e.g., it wasn't one of our addresses). */
+ /* Decode the Unix address SUN to an Internet address SIN.  If
+  * DECODE_UNBOUND_P is nonzero, an empty address (indicative of an unbound
+  * Unix-domain socket) is translated to a wildcard Internet address.  Returns
+  * zero on success; -1 on failure (e.g., it wasn't one of our addresses).
+  */
  static int decode_inet_addr(struct sockaddr_in *sin,
                            const struct sockaddr_un *sun,
-                           socklen_t len)
+                           socklen_t len,
+                           int decode_unbound_p)
  {
    char buf[INET_ADDRSTRLEN + 16];
    char *p;
    if (len < sizeof(sun)) ((char *)sun)[len] = 0;
    D( fprintf(stderr, "noip: decode (%d) `%s'",
             *sun->sun_path, sun->sun_path); )
-   if (!sun->sun_path[0]) {
+   if (decode_unbound_p && !sun->sun_path[0]) {
      sin->sin_family = AF_INET;
      sin->sin_addr.s_addr = INADDR_ANY;
      sin->sin_port = 0;
@@@ -425,7 -429,7 +429,7 @@@ static int fixup_real_ip_socket(int sk
    len = sizeof(sun);
    if (real_getsockname(sk, SA(&sun), &len))
      return (-1);
-   if (decode_inet_addr(&sin, &sun, len))
+   if (decode_inet_addr(&sin, &sun, len, 1))
      return (0); /* Not one of ours */
    len = sizeof(type);
    if (real_getsockopt(sk, SOL_SOCKET, SO_TYPE, &type, &len) < 0 ||
@@@ -502,7 -506,8 +506,8 @@@ static void return_fake_name(struct soc
    struct sockaddr_in sin;
    socklen_t alen;
  
-   if (sa->sa_family == AF_UNIX && !decode_inet_addr(&sin, SUN(sa), len)) {
+   if (sa->sa_family == AF_UNIX &&
+       !decode_inet_addr(&sin, SUN(sa), len, 0)) {
      sa = SA(&sin);
      len = sizeof(sin);
    }
@@@ -831,11 -836,16 +836,16 @@@ done
  
  int socket(int pf, int ty, int proto)
  {
-   if (pf == PF_INET) {
-     pf = PF_UNIX;
-     proto = 0;
+   switch (pf) {
+     case PF_INET:
+       pf = PF_UNIX;
+       proto = 0;
+     case PF_UNIX:
+       return real_socket(pf, ty, proto);
+     default:
+       errno = EAFNOSUPPORT;
+       return -1;
    }
-   return real_socket(pf, ty, proto);
  }
  
  int socketpair(int pf, int ty, int proto, int *sk)
@@@ -872,22 -882,17 +882,22 @@@ int connect(int sk, const struct sockad
    int fixup_p = 0;
    int rc;
  
 -  if (sa->sa_family == AF_INET) {
 -    PRESERVING_ERRNO({
 -      do_implicit_bind(sk, &sa, &len, &sun);
 -      fixup_p = 1;
 -    });
 -  }
 -  rc = real_connect(sk, sa, len);
 -  if (rc < 0) {
 -    switch (errno) {
 -      case ENOENT:    errno = ECONNREFUSED;   break;
 -    }
 +  switch (sa->sa_family) {
 +    case AF_INET:
 +      PRESERVING_ERRNO({
 +      do_implicit_bind(sk, &sa, &len, &sun);
 +      fixup_p = 1;
 +      });
 +      rc = real_connect(sk, sa, len);
 +      if (rc < 0) {
 +      switch (errno) {
 +        case ENOENT:  errno = ECONNREFUSED;   break;
 +      }
 +      }
 +      break;
 +    default:
 +      rc = real_connect(sk, sa, len);
 +      break;
    }
    return rc;
  }
@@@ -1049,7 -1054,7 +1059,7 @@@ static void cleanup_sockdir(void
      if (d->d_name[0] == '.') continue;
      snprintf(sun.sun_path, sizeof(sun.sun_path),
             "%s/%s", sockdir, d->d_name);
-     if (decode_inet_addr(&sin, &sun, SUN_LEN(&sun)) ||
+     if (decode_inet_addr(&sin, &sun, SUN_LEN(&sun), 0) ||
        stat(sun.sun_path, &st) ||
        !S_ISSOCK(st.st_mode)) {
        D( fprintf(stderr, "noip: ignoring unknown socketdir entry `%s'\n",