From fb2b001104b02d15b4abe72020b8d763eb7f28da Mon Sep 17 00:00:00 2001 From: Karl Ramm Date: Sat, 4 Dec 2010 03:20:11 +0000 Subject: Apparently, on Linux at least, if you have an open UDP listening socket with SO_REUSADDR set on a given port, other people can also open listening sockets with SO_REUSEADDR set, so turn SO_REUSADDR back off after we've bound our port. --- lib/ZOpenPort.c | 20 +++++++++++++------- 1 file changed, 13 insertions(+), 7 deletions(-) (limited to 'lib') diff --git a/lib/ZOpenPort.c b/lib/ZOpenPort.c index cf9a66e..b15ee28 100644 --- a/lib/ZOpenPort.c +++ b/lib/ZOpenPort.c @@ -28,16 +28,15 @@ ZOpenPort(u_short *port) if ((__Zephyr_fd = socket(AF_INET, SOCK_DGRAM, 0)) < 0) { __Zephyr_fd = -1; - return (errno); + return errno; } bindin.sin_family = AF_INET; if (port && *port) { bindin.sin_port = *port; - if (setsockopt(__Zephyr_fd, SOL_SOCKET, SO_REUSEADDR, &val, sizeof val) < 0) { + if (setsockopt(__Zephyr_fd, SOL_SOCKET, SO_REUSEADDR, &val, sizeof val) < 0) return errno; - } } else { bindin.sin_port = 0; } @@ -46,15 +45,22 @@ ZOpenPort(u_short *port) if (bind(__Zephyr_fd, (struct sockaddr *)&bindin, sizeof(bindin)) < 0) { if (errno == EADDRINUSE && port && *port) - return (ZERR_PORTINUSE); + return ZERR_PORTINUSE; else - return (errno); + return errno; } + if (port && *port) { + /* turn SO_REUSEADDR back off so no one else can steal it */ + val = 0; + if (setsockopt(__Zephyr_fd, SOL_SOCKET, SO_REUSEADDR, &val, sizeof val) < 0) + return errno; + } + if (!bindin.sin_port) { len = sizeof(bindin); if (getsockname(__Zephyr_fd, (struct sockaddr *)&bindin, &len)) - return (errno); + return errno; } __Zephyr_port = bindin.sin_port; @@ -63,5 +69,5 @@ ZOpenPort(u_short *port) if (port) *port = bindin.sin_port; - return (ZERR_NONE); + return ZERR_NONE; } -- cgit v1.2.3