From a59a964f9c53aa41b1c3ccb0273c3a1b6886a4ed Mon Sep 17 00:00:00 2001 From: Mark Wooding Date: Sat, 9 Jun 2018 15:56:33 +0100 Subject: [PATCH 1/1] noip.c: Support `SO_REUSEADDR', rather sketchily. If the caller tries to bind, and has previously set the `SO_REUSEADDR' flag, then unlink any existing socket unless there's an active listener already. --- noip.c | 11 ++++++++++- 1 file changed, 10 insertions(+), 1 deletion(-) diff --git a/noip.c b/noip.c index 45ed9a5..f60788e 100644 --- a/noip.c +++ b/noip.c @@ -800,6 +800,7 @@ static int encode_unused_inet_addr(struct sockaddr *sa, * Returns zero on success; -1 on failure. */ #define ENCF_FRESH 1u +#define ENCF_REUSEADDR 2u static int encode_inet_addr(struct sockaddr_un *sun, const struct sockaddr *sa, unsigned f) @@ -825,6 +826,7 @@ static int encode_inet_addr(struct sockaddr_un *sun, * want an existing socket, then we're done. */ rc = encode_single_inet_addr(sa, sun, 0); + if ((f&ENCF_REUSEADDR) && !(rc&LISTEN)) unlink(sun->sun_path); if ((rc&USED) || (f&ENCF_FRESH)) goto found; /* We're looking for a socket which already exists. This is @@ -1723,6 +1725,9 @@ int bind(int sk, const struct sockaddr *sa, socklen_t len) { struct sockaddr_un sun; int rc; + unsigned f; + int reusep; + socklen_t n; Dpid; D({ char buf[ADDRBUFSZ]; @@ -1738,7 +1743,11 @@ int bind(int sk, const struct sockaddr *sa, socklen_t len) if (fixup_real_ip_socket(sk, sa->sa_family, 0)) return (-1); } else { - encode_inet_addr(&sun, sa, ENCF_FRESH); + f = ENCF_FRESH; + n = sizeof(reusep); + if (!getsockopt(sk, SOL_SOCKET, SO_REUSEADDR, &reusep, &n) && reusep) + f |= ENCF_REUSEADDR; + encode_inet_addr(&sun, sa, f); sa = SA(&sun); len = SUN_LEN(&sun); } -- 2.11.0