summaryrefslogtreecommitdiff
path: root/util
diff options
context:
space:
mode:
Diffstat (limited to 'util')
-rw-r--r--util/oslib-posix.c12
-rw-r--r--util/oslib-win32.c10
-rw-r--r--util/qemu-sockets.c6
3 files changed, 25 insertions, 3 deletions
diff --git a/util/oslib-posix.c b/util/oslib-posix.c
index 253bc3df2e..e00a44c86f 100644
--- a/util/oslib-posix.c
+++ b/util/oslib-posix.c
@@ -157,6 +157,18 @@ void qemu_set_nonblock(int fd)
fcntl(fd, F_SETFL, f | O_NONBLOCK);
}
+int socket_set_fast_reuse(int fd)
+{
+ int val = 1, ret;
+
+ ret = setsockopt(fd, SOL_SOCKET, SO_REUSEADDR,
+ (const char *)&val, sizeof(val));
+
+ assert(ret == 0);
+
+ return ret;
+}
+
void qemu_set_cloexec(int fd)
{
int f;
diff --git a/util/oslib-win32.c b/util/oslib-win32.c
index 983b7a2375..776ccfaaf0 100644
--- a/util/oslib-win32.c
+++ b/util/oslib-win32.c
@@ -124,6 +124,16 @@ void qemu_set_nonblock(int fd)
qemu_fd_register(fd);
}
+int socket_set_fast_reuse(int fd)
+{
+ /* Enabling the reuse of an endpoint that was used by a socket still in
+ * TIME_WAIT state is usually performed by setting SO_REUSEADDR. On Windows
+ * fast reuse is the default and SO_REUSEADDR does strange things. So we
+ * don't have to do anything here. More info can be found at:
+ * http://msdn.microsoft.com/en-us/library/windows/desktop/ms740621.aspx */
+ return 0;
+}
+
int inet_aton(const char *cp, struct in_addr *ia)
{
uint32_t addr = inet_addr(cp);
diff --git a/util/qemu-sockets.c b/util/qemu-sockets.c
index 095716ecdb..6b97dc11f9 100644
--- a/util/qemu-sockets.c
+++ b/util/qemu-sockets.c
@@ -155,7 +155,7 @@ int inet_listen_opts(QemuOpts *opts, int port_offset, Error **errp)
continue;
}
- qemu_setsockopt(slisten, SOL_SOCKET, SO_REUSEADDR, &on, sizeof(on));
+ socket_set_fast_reuse(slisten);
#ifdef IPV6_V6ONLY
if (e->ai_family == PF_INET6) {
/* listen on both ipv4 and ipv6 */
@@ -274,7 +274,7 @@ static int inet_connect_addr(struct addrinfo *addr, bool *in_progress,
error_set_errno(errp, errno, QERR_SOCKET_CREATE_FAILED);
return -1;
}
- qemu_setsockopt(sock, SOL_SOCKET, SO_REUSEADDR, &on, sizeof(on));
+ socket_set_fast_reuse(sock);
if (connect_state != NULL) {
qemu_set_nonblock(sock);
}
@@ -455,7 +455,7 @@ int inet_dgram_opts(QemuOpts *opts, Error **errp)
error_set_errno(errp, errno, QERR_SOCKET_CREATE_FAILED);
goto err;
}
- qemu_setsockopt(sock, SOL_SOCKET, SO_REUSEADDR, &on, sizeof(on));
+ socket_set_fast_reuse(sock);
/* bind socket */
if (bind(sock, local->ai_addr, local->ai_addrlen) < 0) {