From b67e9a0415daa0ec7125a831fc8ac58e2c120002 Mon Sep 17 00:00:00 2001 From: Eelco Dolstra Date: Fri, 21 Aug 2009 15:40:32 +0000 Subject: [PATCH] * qemu-kvm unix domain patch: when accepting a connection, initialise the remote address / port to something sensible. Otherwise simultaneous connections to the same guest port don't work properly. svn path=/nixpkgs/trunk/; revision=16805 --- .../linux/qemu-kvm/unix-domain.patch | 110 ++++++++++++++++-- 1 file changed, 101 insertions(+), 9 deletions(-) diff --git a/pkgs/os-specific/linux/qemu-kvm/unix-domain.patch b/pkgs/os-specific/linux/qemu-kvm/unix-domain.patch index 78687da121d5..270b8a0a47f4 100644 --- a/pkgs/os-specific/linux/qemu-kvm/unix-domain.patch +++ b/pkgs/os-specific/linux/qemu-kvm/unix-domain.patch @@ -1,6 +1,6 @@ -diff -rc qemu-kvm-0.11.0-rc1-orig/slirp/socket.c qemu-kvm-0.11.0-rc1/slirp/socket.c +diff -rc --exclude '*~' qemu-kvm-0.11.0-rc1-orig/slirp/socket.c qemu-kvm-0.11.0-rc1/slirp/socket.c *** qemu-kvm-0.11.0-rc1-orig/slirp/socket.c 2009-08-02 15:38:42.000000000 +0200 ---- qemu-kvm-0.11.0-rc1/slirp/socket.c 2009-08-05 18:09:20.000000000 +0200 +--- qemu-kvm-0.11.0-rc1/slirp/socket.c 2009-08-21 17:11:21.000000000 +0200 *************** *** 587,592 **** --- 587,593 ---- @@ -30,9 +30,9 @@ diff -rc qemu-kvm-0.11.0-rc1-orig/slirp/socket.c qemu-kvm-0.11.0-rc1/slirp/socke so->so_lport = lport; /* Kept in network format */ so->so_laddr.s_addr = laddr; /* Ditto */ -! int unix_socket = ntohs(hport) >= 0xff00; +! so->so_uds = ntohs(hport) >= 0xff00; -! if (unix_socket) { +! if (so->so_uds) { ! addr_un.sun_family = AF_UNIX; ! sprintf(addr_un.sun_path, "./%d.socket", ntohs(hport)); ! unlink(addr_un.sun_path); @@ -42,10 +42,10 @@ diff -rc qemu-kvm-0.11.0-rc1-orig/slirp/socket.c qemu-kvm-0.11.0-rc1/slirp/socke ! addr.sin_port = hport; ! } ! -! if (((s = socket(unix_socket ? PF_UNIX : AF_INET, SOCK_STREAM, 0)) < 0) || +! if (((s = socket(so->so_uds ? PF_UNIX : AF_INET, SOCK_STREAM, 0)) < 0) || (setsockopt(s,SOL_SOCKET,SO_REUSEADDR,(char *)&opt,sizeof(int)) < 0) || -! (bind(s, unix_socket ? (struct sockaddr *) &addr_un : (struct sockaddr *) &addr, -! unix_socket ? sizeof(addr_un) : sizeof(addr)) < 0) || +! (bind(s, so->so_uds ? (struct sockaddr *) &addr_un : (struct sockaddr *) &addr, +! so->so_uds ? sizeof(addr_un) : sizeof(addr)) < 0) || (listen(s,1) < 0)) { int tmperrno = errno; /* Don't clobber the real reason we failed */ @@ -63,11 +63,11 @@ diff -rc qemu-kvm-0.11.0-rc1-orig/slirp/socket.c qemu-kvm-0.11.0-rc1/slirp/socke so->s = s; return so; ---- 652,668 ---- +--- 653,669 ---- } setsockopt(s,SOL_SOCKET,SO_OOBINLINE,(char *)&opt,sizeof(int)); -! if (unix_socket) { +! if (so->so_uds) { ! so->so_fport = hport; ! so->so_faddr = slirp->vhost_addr; ! } else { @@ -81,3 +81,95 @@ diff -rc qemu-kvm-0.11.0-rc1-orig/slirp/socket.c qemu-kvm-0.11.0-rc1/slirp/socke so->s = s; return so; +diff -rc --exclude '*~' qemu-kvm-0.11.0-rc1-orig/slirp/socket.h qemu-kvm-0.11.0-rc1/slirp/socket.h +*** qemu-kvm-0.11.0-rc1-orig/slirp/socket.h 2009-08-02 15:38:42.000000000 +0200 +--- qemu-kvm-0.11.0-rc1/slirp/socket.h 2009-08-21 17:02:36.000000000 +0200 +*************** +*** 33,39 **** + struct in_addr so_laddr; /* local host table entry */ + u_int16_t so_fport; /* foreign port */ + u_int16_t so_lport; /* local port */ +! + u_int8_t so_iptos; /* Type of service */ + u_int8_t so_emu; /* Is the socket emulated? */ + +--- 33,40 ---- + struct in_addr so_laddr; /* local host table entry */ + u_int16_t so_fport; /* foreign port */ + u_int16_t so_lport; /* local port */ +! int so_uds; /* foreign "port" is a unix domain socket */ +! + u_int8_t so_iptos; /* Type of service */ + u_int8_t so_emu; /* Is the socket emulated? */ + +diff -rc --exclude '*~' qemu-kvm-0.11.0-rc1-orig/slirp/tcp_subr.c qemu-kvm-0.11.0-rc1/slirp/tcp_subr.c +*** qemu-kvm-0.11.0-rc1-orig/slirp/tcp_subr.c 2009-08-02 15:38:42.000000000 +0200 +--- qemu-kvm-0.11.0-rc1/slirp/tcp_subr.c 2009-08-21 17:21:37.000000000 +0200 +*************** +*** 382,388 **** + Slirp *slirp = inso->slirp; + struct socket *so; + struct sockaddr_in addr; +! socklen_t addrlen = sizeof(struct sockaddr_in); + struct tcpcb *tp; + int s, opt; + +--- 382,389 ---- + Slirp *slirp = inso->slirp; + struct socket *so; + struct sockaddr_in addr; +! struct sockaddr_un addr_un; +! socklen_t addrlen; + struct tcpcb *tp; + int s, opt; + +*************** +*** 412,418 **** + + (void) tcp_mss(sototcpcb(so), 0); + +! if ((s = accept(inso->s,(struct sockaddr *)&addr,&addrlen)) < 0) { + tcp_close(sototcpcb(so)); /* This will sofree() as well */ + return; + } +--- 413,422 ---- + + (void) tcp_mss(sototcpcb(so), 0); + +! addrlen = inso->so_uds ? sizeof(struct sockaddr_un) : sizeof(struct sockaddr_in); +! +! if ((inso->so_uds && (s = accept(inso->s, (struct sockaddr *) &addr_un, &addrlen)) < 0) || +! (!inso->so_uds && (s = accept(inso->s, (struct sockaddr *) &addr, &addrlen)) < 0)) { + tcp_close(sototcpcb(so)); /* This will sofree() as well */ + return; + } +*************** +*** 424,434 **** + opt = 1; + setsockopt(s,IPPROTO_TCP,TCP_NODELAY,(char *)&opt,sizeof(int)); + +! so->so_fport = addr.sin_port; +! so->so_faddr = addr.sin_addr; +! /* Translate connections from localhost to the real hostname */ +! if (so->so_faddr.s_addr == 0 || so->so_faddr.s_addr == loopback_addr.s_addr) +! so->so_faddr = slirp->vhost_addr; + + /* Close the accept() socket, set right state */ + if (inso->so_state & SS_FACCEPTONCE) { +--- 428,443 ---- + opt = 1; + setsockopt(s,IPPROTO_TCP,TCP_NODELAY,(char *)&opt,sizeof(int)); + +! if (inso->so_uds) { +! so->so_fport = htons(s); /* use the fd number as the foreign port */ +! so->so_faddr = slirp->vhost_addr; +! } else { +! so->so_fport = addr.sin_port; +! so->so_faddr = addr.sin_addr; +! /* Translate connections from localhost to the real hostname */ +! if (so->so_faddr.s_addr == 0 || so->so_faddr.s_addr == loopback_addr.s_addr) +! so->so_faddr = slirp->vhost_addr; +! } + + /* Close the accept() socket, set right state */ + if (inso->so_state & SS_FACCEPTONCE) {