summaryrefslogtreecommitdiff
path: root/lib
diff options
context:
space:
mode:
authorGravatar Karl Ramm <kcr@1ts.org>2010-12-04 03:20:11 +0000
committerGravatar Karl Ramm <kcr@1ts.org>2010-12-04 03:20:11 +0000
commitfb2b001104b02d15b4abe72020b8d763eb7f28da (patch)
tree0cc9e70f526274e6d97431e1339cf3175649b154 /lib
parenta5df0ea3980b67712a29d9866666816e54954b1a (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.c20
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;
}