diff --git a/net/slirp.c b/net/slirp.c index 6f756a4dcc..78ba96b63f 100644 --- a/net/slirp.c +++ b/net/slirp.c @@ -191,6 +191,11 @@ static void net_slirp_register_poll_fd(int fd) qemu_fd_register(fd); } +static void net_slirp_unregister_poll_fd(int fd) +{ + /* no qemu_fd_unregister */ +} + static const SlirpCb slirp_cb = { .output = net_slirp_output, .guest_error = net_slirp_guest_error, @@ -199,6 +204,7 @@ static const SlirpCb slirp_cb = { .timer_free = net_slirp_timer_free, .timer_mod = net_slirp_timer_mod, .register_poll_fd = net_slirp_register_poll_fd, + .unregister_poll_fd = net_slirp_unregister_poll_fd, }; static int net_slirp_init(NetClientState *peer, const char *model, diff --git a/slirp/ip_icmp.c b/slirp/ip_icmp.c index b59daa801d..19e247f773 100644 --- a/slirp/ip_icmp.c +++ b/slirp/ip_icmp.c @@ -114,6 +114,7 @@ static int icmp_send(struct socket *so, struct mbuf *m, int hlen) void icmp_detach(struct socket *so) { + so->slirp->cb->unregister_poll_fd(so->s); slirp_closesocket(so->s); sofree(so); } diff --git a/slirp/libslirp.h b/slirp/libslirp.h index 70e99139bf..8ce69f0be3 100644 --- a/slirp/libslirp.h +++ b/slirp/libslirp.h @@ -29,6 +29,8 @@ typedef struct SlirpCb { void (*timer_mod)(void *timer, int64_t expire_time); /* Register a fd for future polling */ void (*register_poll_fd)(int fd); + /* Unregister a fd */ + void (*unregister_poll_fd)(int fd); } SlirpCb; diff --git a/slirp/slirp.c b/slirp/slirp.c index 12677e5da7..f0bd59fd6f 100644 --- a/slirp/slirp.c +++ b/slirp/slirp.c @@ -1015,7 +1015,8 @@ int slirp_remove_hostfwd(Slirp *slirp, int is_udp, struct in_addr host_addr, getsockname(so->s, (struct sockaddr *)&addr, &addr_len) == 0 && addr.sin_addr.s_addr == host_addr.s_addr && addr.sin_port == port) { - close(so->s); + so->slirp->cb->unregister_poll_fd(so->s); + slirp_closesocket(so->s); sofree(so); return 0; } diff --git a/slirp/tcp_subr.c b/slirp/tcp_subr.c index 8087ffc047..d8846a33b0 100644 --- a/slirp/tcp_subr.c +++ b/slirp/tcp_subr.c @@ -337,6 +337,7 @@ tcp_close(struct tcpcb *tp) /* clobber input socket cache if we're closing the cached connection */ if (so == slirp->tcp_last_so) slirp->tcp_last_so = &slirp->tcb; + so->slirp->cb->unregister_poll_fd(so->s); slirp_closesocket(so->s); sbfree(&so->so_rcv); sbfree(&so->so_snd); @@ -498,6 +499,7 @@ void tcp_connect(struct socket *inso) /* Close the accept() socket, set right state */ if (inso->so_state & SS_FACCEPTONCE) { /* If we only accept once, close the accept() socket */ + so->slirp->cb->unregister_poll_fd(so->s); slirp_closesocket(so->s); /* Don't select it yet, even though we have an FD */ diff --git a/slirp/udp.c b/slirp/udp.c index 6c3fb9a29f..3915971b50 100644 --- a/slirp/udp.c +++ b/slirp/udp.c @@ -292,6 +292,7 @@ udp_attach(struct socket *so, unsigned short af) void udp_detach(struct socket *so) { + so->slirp->cb->unregister_poll_fd(so->s); slirp_closesocket(so->s); sofree(so); }