diff options
author | Karl Ramm <kcr@1ts.org> | 2010-12-04 03:20:11 +0000 |
---|---|---|
committer | Karl Ramm <kcr@1ts.org> | 2010-12-04 03:20:11 +0000 |
commit | fb2b001104b02d15b4abe72020b8d763eb7f28da (patch) | |
tree | 0cc9e70f526274e6d97431e1339cf3175649b154 /lib | |
parent | a5df0ea3980b67712a29d9866666816e54954b1a (diff) |
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.
Diffstat (limited to 'lib')
-rw-r--r-- | lib/ZOpenPort.c | 20 |
1 files changed, 13 insertions, 7 deletions
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; } |