When the host aborts (RST) it's side of a TCP connection we need to propagate that RST to the guest. The current code can leave such guest connections dangling forever. Spotted by Jason Wessel.
[ste...@steven676.net: coding style adjustments] Signed-off-by: Steven Luo <steven+q...@steven676.net> --- Edgar proposed this patch many years ago: https://lists.gnu.org/archive/html/qemu-devel/2008-06/msg00383.html It doesn't appear that it was ever merged. (It's the top Google result for "QEMU slirp RST".) I've been unable to test the specific case it addresses (an established connection interrupted by RST), but the discussion from 2008 seems to imply it worked for the person reporting the problem then, and my next patch builds on this one. As this patch isn't my work and did not come with a Signed-off-by line, I'm not entirely clear on how I should handle that. slirp/socket.c | 17 ++++++++++++++++- 1 file changed, 16 insertions(+), 1 deletion(-) diff --git a/slirp/socket.c b/slirp/socket.c index b836c42..4372ec2 100644 --- a/slirp/socket.c +++ b/slirp/socket.c @@ -176,9 +176,24 @@ soread(struct socket *so) if (nn < 0 && (errno == EINTR || errno == EAGAIN)) return 0; else { + int err; + socklen_t slen = sizeof err; + + err = errno; + if (nn == 0) { + getsockopt(so->s, SOL_SOCKET, SO_ERROR, + &err, &slen); + } + DEBUG_MISC((dfd, " --- soread() disconnected, nn = %d, errno = %d-%s\n", nn, errno,strerror(errno))); sofcantrcvmore(so); - tcp_sockclosed(sototcpcb(so)); + + if (err == ECONNRESET + || err == ENOTCONN || err == EPIPE) { + tcp_drop(sototcpcb(so), err); + } else { + tcp_sockclosed(sototcpcb(so)); + } return -1; } } -- 2.1.4