X-Git-Url: https://www.chiark.greenend.org.uk/ucgi/~mdw/git/preload-hacks/blobdiff_plain/dc3956b3f2f9b13bbf93df2ed7295407cc90ab86..f6e0ea86fb3c3acddcbeddf625953aa1526daf35:/noip.c?ds=inline diff --git a/noip.c b/noip.c index ee86680..de7cf89 100644 --- a/noip.c +++ b/noip.c @@ -624,6 +624,34 @@ done: return (rc); } +/* Convert the IP address SA to a Unix-domain address SUN. Fail if the + * address seems already taken. If DESPARATEP then try cleaning up stale old + * sockets. + */ +static int encode_unused_inet_addr(struct sockaddr *sa, + struct sockaddr_un *sun, + int desperatep) +{ + address waddr; + struct sockaddr_un wsun; + int rc; + char buf[ADDRBUFSZ]; + + snprintf(sun->sun_path, sizeof(sun->sun_path), "%s/%s", sockdir, + present_sockaddr(sa, 0, buf, sizeof(buf))); + if ((rc = unix_socket_status(sun, !desperatep)) == USED) return (-1); + else if (rc == STALE) unlink(sun->sun_path); + + wildcard_address(sa->sa_family, &waddr.sa); + port_to_sockaddr(&waddr.sa, port_from_sockaddr(sa)); + snprintf(wsun.sun_path, sizeof(wsun.sun_path), "%s/%s", sockdir, + present_sockaddr(&waddr.sa, 0, buf, sizeof(buf))); + if ((rc = unix_socket_status(&wsun, !desperatep)) == USED) return (-1); + else if (rc == STALE) unlink(wsun.sun_path); + + return (0); +} + /* Encode the Internet address SA as a Unix-domain address SUN. If WANT is * WANT_FRESH, and SA's port number is zero, then we pick an arbitrary local * port. Otherwise we pick the port given. There's an unpleasant hack to @@ -660,20 +688,12 @@ static int encode_inet_addr(struct sockaddr_un *sun, copy_sockaddr(&addr.sa, sa); for (i = 0; i < 10; i++) { port_to_sockaddr(&addr.sa, randrange(minautoport, maxautoport)); - snprintf(sun->sun_path, sizeof(sun->sun_path), "%s/%s", sockdir, - present_sockaddr(&addr.sa, 0, buf, sizeof(buf))); - if (unix_socket_status(sun, 1) == UNUSED) goto found; + if (!encode_unused_inet_addr(&addr.sa, sun, 0)) goto found; } for (desperatep = 0; desperatep < 2; desperatep++) { for (i = minautoport; i <= maxautoport; i++) { port_to_sockaddr(&addr.sa, i); - snprintf(sun->sun_path, sizeof(sun->sun_path), "%s/%s", sockdir, - present_sockaddr(&addr.sa, 0, buf, sizeof(buf))); - rc = unix_socket_status(sun, !desperatep); - switch (rc) { - case STALE: unlink(sun->sun_path); - case UNUSED: goto found; - } + if (!encode_unused_inet_addr(&addr.sa, sun, 0)) goto found; } } errno = EADDRINUSE;