Merge remote-tracking branch 'sweil/mingw' into staging
# By Sebastian Ottlik # Via Stefan Weil * sweil/mingw: util: call socket_set_fast_reuse instead of setting SO_REUSEADDR slirp: call socket_set_fast_reuse instead of setting SO_REUSEADDR net: call socket_set_fast_reuse instead of setting SO_REUSEADDR gdbstub: call socket_set_fast_reuse instead of setting SO_REUSEADDR util: add socket_set_fast_reuse function which will replace setting SO_REUSEADDR Message-id: 1380735690-24009-1-git-send-email-sw@weilnetz.de Signed-off-by: Anthony Liguori <anthony@codemonkey.ws>
This commit is contained in:
commit
9e8f8b1cd8
|
@ -1553,7 +1553,7 @@ static void gdb_accept(void)
|
||||||
static int gdbserver_open(int port)
|
static int gdbserver_open(int port)
|
||||||
{
|
{
|
||||||
struct sockaddr_in sockaddr;
|
struct sockaddr_in sockaddr;
|
||||||
int fd, val, ret;
|
int fd, ret;
|
||||||
|
|
||||||
fd = socket(PF_INET, SOCK_STREAM, 0);
|
fd = socket(PF_INET, SOCK_STREAM, 0);
|
||||||
if (fd < 0) {
|
if (fd < 0) {
|
||||||
|
@ -1564,9 +1564,7 @@ static int gdbserver_open(int port)
|
||||||
fcntl(fd, F_SETFD, FD_CLOEXEC);
|
fcntl(fd, F_SETFD, FD_CLOEXEC);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/* allow fast reuse */
|
socket_set_fast_reuse(fd);
|
||||||
val = 1;
|
|
||||||
qemu_setsockopt(fd, SOL_SOCKET, SO_REUSEADDR, &val, sizeof(val));
|
|
||||||
|
|
||||||
sockaddr.sin_family = AF_INET;
|
sockaddr.sin_family = AF_INET;
|
||||||
sockaddr.sin_port = htons(port);
|
sockaddr.sin_port = htons(port);
|
||||||
|
|
|
@ -39,6 +39,7 @@ int socket_set_cork(int fd, int v);
|
||||||
int socket_set_nodelay(int fd);
|
int socket_set_nodelay(int fd);
|
||||||
void qemu_set_block(int fd);
|
void qemu_set_block(int fd);
|
||||||
void qemu_set_nonblock(int fd);
|
void qemu_set_nonblock(int fd);
|
||||||
|
int socket_set_fast_reuse(int fd);
|
||||||
int send_all(int fd, const void *buf, int len1);
|
int send_all(int fd, const void *buf, int len1);
|
||||||
int recv_all(int fd, void *buf, int len1, bool single_read);
|
int recv_all(int fd, void *buf, int len1, bool single_read);
|
||||||
|
|
||||||
|
|
19
net/socket.c
19
net/socket.c
|
@ -262,6 +262,11 @@ static int net_socket_mcast_create(struct sockaddr_in *mcastaddr, struct in_addr
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Allow multiple sockets to bind the same multicast ip and port by setting
|
||||||
|
* SO_REUSEADDR. This is the only situation where SO_REUSEADDR should be set
|
||||||
|
* on windows. Use socket_set_fast_reuse otherwise as it sets SO_REUSEADDR
|
||||||
|
* only on posix systems.
|
||||||
|
*/
|
||||||
val = 1;
|
val = 1;
|
||||||
ret = qemu_setsockopt(fd, SOL_SOCKET, SO_REUSEADDR, &val, sizeof(val));
|
ret = qemu_setsockopt(fd, SOL_SOCKET, SO_REUSEADDR, &val, sizeof(val));
|
||||||
if (ret < 0) {
|
if (ret < 0) {
|
||||||
|
@ -510,7 +515,7 @@ static int net_socket_listen_init(NetClientState *peer,
|
||||||
NetClientState *nc;
|
NetClientState *nc;
|
||||||
NetSocketState *s;
|
NetSocketState *s;
|
||||||
struct sockaddr_in saddr;
|
struct sockaddr_in saddr;
|
||||||
int fd, val, ret;
|
int fd, ret;
|
||||||
|
|
||||||
if (parse_host_port(&saddr, host_str) < 0)
|
if (parse_host_port(&saddr, host_str) < 0)
|
||||||
return -1;
|
return -1;
|
||||||
|
@ -522,9 +527,7 @@ static int net_socket_listen_init(NetClientState *peer,
|
||||||
}
|
}
|
||||||
qemu_set_nonblock(fd);
|
qemu_set_nonblock(fd);
|
||||||
|
|
||||||
/* allow fast reuse */
|
socket_set_fast_reuse(fd);
|
||||||
val = 1;
|
|
||||||
qemu_setsockopt(fd, SOL_SOCKET, SO_REUSEADDR, &val, sizeof(val));
|
|
||||||
|
|
||||||
ret = bind(fd, (struct sockaddr *)&saddr, sizeof(saddr));
|
ret = bind(fd, (struct sockaddr *)&saddr, sizeof(saddr));
|
||||||
if (ret < 0) {
|
if (ret < 0) {
|
||||||
|
@ -645,7 +648,7 @@ static int net_socket_udp_init(NetClientState *peer,
|
||||||
const char *lhost)
|
const char *lhost)
|
||||||
{
|
{
|
||||||
NetSocketState *s;
|
NetSocketState *s;
|
||||||
int fd, val, ret;
|
int fd, ret;
|
||||||
struct sockaddr_in laddr, raddr;
|
struct sockaddr_in laddr, raddr;
|
||||||
|
|
||||||
if (parse_host_port(&laddr, lhost) < 0) {
|
if (parse_host_port(&laddr, lhost) < 0) {
|
||||||
|
@ -661,11 +664,9 @@ static int net_socket_udp_init(NetClientState *peer,
|
||||||
perror("socket(PF_INET, SOCK_DGRAM)");
|
perror("socket(PF_INET, SOCK_DGRAM)");
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
val = 1;
|
|
||||||
ret = qemu_setsockopt(fd, SOL_SOCKET, SO_REUSEADDR,
|
ret = socket_set_fast_reuse(fd);
|
||||||
&val, sizeof(val));
|
|
||||||
if (ret < 0) {
|
if (ret < 0) {
|
||||||
perror("setsockopt(SOL_SOCKET, SO_REUSEADDR)");
|
|
||||||
closesocket(fd);
|
closesocket(fd);
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
|
@ -212,8 +212,7 @@ fork_exec(struct socket *so, const char *ex, int do_pty)
|
||||||
so->s = accept(s, (struct sockaddr *)&addr, &addrlen);
|
so->s = accept(s, (struct sockaddr *)&addr, &addrlen);
|
||||||
} while (so->s < 0 && errno == EINTR);
|
} while (so->s < 0 && errno == EINTR);
|
||||||
closesocket(s);
|
closesocket(s);
|
||||||
opt = 1;
|
socket_set_fast_reuse(so->s);
|
||||||
qemu_setsockopt(so->s, SOL_SOCKET, SO_REUSEADDR, &opt, sizeof(int));
|
|
||||||
opt = 1;
|
opt = 1;
|
||||||
qemu_setsockopt(so->s, SOL_SOCKET, SO_OOBINLINE, &opt, sizeof(int));
|
qemu_setsockopt(so->s, SOL_SOCKET, SO_OOBINLINE, &opt, sizeof(int));
|
||||||
qemu_set_nonblock(so->s);
|
qemu_set_nonblock(so->s);
|
||||||
|
|
|
@ -627,9 +627,7 @@ tcp_listen(Slirp *slirp, uint32_t haddr, u_int hport, uint32_t laddr,
|
||||||
addr.sin_port = hport;
|
addr.sin_port = hport;
|
||||||
|
|
||||||
if (((s = qemu_socket(AF_INET,SOCK_STREAM,0)) < 0) ||
|
if (((s = qemu_socket(AF_INET,SOCK_STREAM,0)) < 0) ||
|
||||||
#ifndef _WIN32
|
(socket_set_fast_reuse(s) < 0) ||
|
||||||
(qemu_setsockopt(s, SOL_SOCKET, SO_REUSEADDR, &opt, sizeof(int)) < 0) ||
|
|
||||||
#endif
|
|
||||||
(bind(s,(struct sockaddr *)&addr, sizeof(addr)) < 0) ||
|
(bind(s,(struct sockaddr *)&addr, sizeof(addr)) < 0) ||
|
||||||
(listen(s,1) < 0)) {
|
(listen(s,1) < 0)) {
|
||||||
int tmperrno = errno; /* Don't clobber the real reason we failed */
|
int tmperrno = errno; /* Don't clobber the real reason we failed */
|
||||||
|
|
|
@ -337,8 +337,7 @@ int tcp_fconnect(struct socket *so)
|
||||||
struct sockaddr_in addr;
|
struct sockaddr_in addr;
|
||||||
|
|
||||||
qemu_set_nonblock(s);
|
qemu_set_nonblock(s);
|
||||||
opt = 1;
|
socket_set_fast_reuse(s);
|
||||||
qemu_setsockopt(s, SOL_SOCKET, SO_REUSEADDR, &opt, sizeof(opt));
|
|
||||||
opt = 1;
|
opt = 1;
|
||||||
qemu_setsockopt(s, SOL_SOCKET, SO_OOBINLINE, &opt, sizeof(opt));
|
qemu_setsockopt(s, SOL_SOCKET, SO_OOBINLINE, &opt, sizeof(opt));
|
||||||
|
|
||||||
|
@ -426,8 +425,7 @@ void tcp_connect(struct socket *inso)
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
qemu_set_nonblock(s);
|
qemu_set_nonblock(s);
|
||||||
opt = 1;
|
socket_set_fast_reuse(s);
|
||||||
qemu_setsockopt(s, SOL_SOCKET, SO_REUSEADDR, &opt, sizeof(int));
|
|
||||||
opt = 1;
|
opt = 1;
|
||||||
qemu_setsockopt(s, SOL_SOCKET, SO_OOBINLINE, &opt, sizeof(int));
|
qemu_setsockopt(s, SOL_SOCKET, SO_OOBINLINE, &opt, sizeof(int));
|
||||||
socket_set_nodelay(s);
|
socket_set_nodelay(s);
|
||||||
|
|
|
@ -354,7 +354,7 @@ udp_listen(Slirp *slirp, uint32_t haddr, u_int hport, uint32_t laddr,
|
||||||
{
|
{
|
||||||
struct sockaddr_in addr;
|
struct sockaddr_in addr;
|
||||||
struct socket *so;
|
struct socket *so;
|
||||||
socklen_t addrlen = sizeof(struct sockaddr_in), opt = 1;
|
socklen_t addrlen = sizeof(struct sockaddr_in);
|
||||||
|
|
||||||
so = socreate(slirp);
|
so = socreate(slirp);
|
||||||
if (!so) {
|
if (!so) {
|
||||||
|
@ -372,7 +372,7 @@ udp_listen(Slirp *slirp, uint32_t haddr, u_int hport, uint32_t laddr,
|
||||||
udp_detach(so);
|
udp_detach(so);
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
qemu_setsockopt(so->s, SOL_SOCKET, SO_REUSEADDR, &opt, sizeof(int));
|
socket_set_fast_reuse(so->s);
|
||||||
|
|
||||||
getsockname(so->s,(struct sockaddr *)&addr,&addrlen);
|
getsockname(so->s,(struct sockaddr *)&addr,&addrlen);
|
||||||
so->so_fport = addr.sin_port;
|
so->so_fport = addr.sin_port;
|
||||||
|
|
|
@ -157,6 +157,18 @@ void qemu_set_nonblock(int fd)
|
||||||
fcntl(fd, F_SETFL, f | O_NONBLOCK);
|
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)
|
void qemu_set_cloexec(int fd)
|
||||||
{
|
{
|
||||||
int f;
|
int f;
|
||||||
|
|
|
@ -124,6 +124,16 @@ void qemu_set_nonblock(int fd)
|
||||||
qemu_fd_register(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)
|
int inet_aton(const char *cp, struct in_addr *ia)
|
||||||
{
|
{
|
||||||
uint32_t addr = inet_addr(cp);
|
uint32_t addr = inet_addr(cp);
|
||||||
|
|
|
@ -155,7 +155,7 @@ int inet_listen_opts(QemuOpts *opts, int port_offset, Error **errp)
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
qemu_setsockopt(slisten, SOL_SOCKET, SO_REUSEADDR, &on, sizeof(on));
|
socket_set_fast_reuse(slisten);
|
||||||
#ifdef IPV6_V6ONLY
|
#ifdef IPV6_V6ONLY
|
||||||
if (e->ai_family == PF_INET6) {
|
if (e->ai_family == PF_INET6) {
|
||||||
/* listen on both ipv4 and ipv6 */
|
/* 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);
|
error_set_errno(errp, errno, QERR_SOCKET_CREATE_FAILED);
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
qemu_setsockopt(sock, SOL_SOCKET, SO_REUSEADDR, &on, sizeof(on));
|
socket_set_fast_reuse(sock);
|
||||||
if (connect_state != NULL) {
|
if (connect_state != NULL) {
|
||||||
qemu_set_nonblock(sock);
|
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);
|
error_set_errno(errp, errno, QERR_SOCKET_CREATE_FAILED);
|
||||||
goto err;
|
goto err;
|
||||||
}
|
}
|
||||||
qemu_setsockopt(sock, SOL_SOCKET, SO_REUSEADDR, &on, sizeof(on));
|
socket_set_fast_reuse(sock);
|
||||||
|
|
||||||
/* bind socket */
|
/* bind socket */
|
||||||
if (bind(sock, local->ai_addr, local->ai_addrlen) < 0) {
|
if (bind(sock, local->ai_addr, local->ai_addrlen) < 0) {
|
||||||
|
|
Loading…
Reference in New Issue