X-Git-Url: https://www.chiark.greenend.org.uk/ucgi/~mdw/git/preload-hacks/blobdiff_plain/8ce11853751d12c81fdd71a67af21e7c176c15e0..72d85cdbe2c457efb39bfe1a9c73ce2f75d7f36f:/noip.c diff --git a/noip.c b/noip.c index 173d43f..bcba77f 100644 --- a/noip.c +++ b/noip.c @@ -98,7 +98,7 @@ static aclnode *connect_real, **connect_tail = &connect_real; _(sendto, ssize_t, (int, const void *buf, size_t, int, \ const struct sockaddr *to, socklen_t tolen)) \ _(recvfrom, ssize_t, (int, void *buf, size_t, int, \ - struct sockaddr *from, socklen_t *fromlen)) \ + struct sockaddr *from, socklen_t *fromlen)) \ _(sendmsg, ssize_t, (int, const struct msghdr *, int)) \ _(recvmsg, ssize_t, (int, struct msghdr *, int)) \ _(close, int, (int)) @@ -266,7 +266,7 @@ static int unix_socket_status(struct sockaddr_un *sun, int quickp) rc = USED; if ((fp = fopen("/proc/net/unix", "r")) == 0) goto done; - fgets(buf, sizeof(buf), fp); /* skip header */ + if (!fgets(buf, sizeof(buf), fp)) goto done; /* skip header */ len = strlen(sun->sun_path); while (fgets(buf, sizeof(buf), fp)) { n = strlen(buf); @@ -340,11 +340,15 @@ static int encode_inet_addr(struct sockaddr_un *sun, 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; @@ -359,7 +363,7 @@ static int decode_inet_addr(struct sockaddr_in *sin, 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 @@ 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 @@ static void return_fake_name(struct sockaddr *sa, socklen_t len, 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); } @@ -877,17 +882,22 @@ int connect(int sk, const struct sockaddr *sa, socklen_t len) 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 +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", @@ -1080,7 +1090,7 @@ static void get_local_ipaddrs(void) return; for (i = n_local_ipaddrs = 0; n_local_ipaddrs < MAX_LOCAL_IPADDRS && - ifn[i].if_name && *ifn[i].if_name; + ifn[i].if_name && *ifn[i].if_name; i++) { strcpy(ifr.ifr_name, ifn[i].if_name); if (ioctl(sk, SIOCGIFADDR, &ifr) || ifr.ifr_addr.sa_family != AF_INET) @@ -1094,7 +1104,8 @@ static void get_local_ipaddrs(void) } /* Print the given message to standard error. Avoids stdio. */ -static void printerr(const char *p) { write(STDERR_FILENO, p, strlen(p)); } +static void printerr(const char *p) + { int hunoz; hunoz = write(STDERR_FILENO, p, strlen(p)); } /* Create the socket directory, being careful about permissions. */ static void create_sockdir(void)