diff --git a/slirp/slirp.c b/slirp/slirp.c index ab0a8548aa..08c10f2b36 100644 --- a/slirp/slirp.c +++ b/slirp/slirp.c @@ -495,7 +495,8 @@ void slirp_select_poll(fd_set *readfds, fd_set *writefds, fd_set *xfds) continue; /* else failed */ - so->so_state = SS_NOFDREF; + so->so_state &= SS_PERSISTENT_MASK; + so->so_state |= SS_NOFDREF; } /* else so->so_state &= ~SS_ISFCONNECTING; */ @@ -529,7 +530,8 @@ void slirp_select_poll(fd_set *readfds, fd_set *writefds, fd_set *xfds) continue; /* Still connecting, continue */ /* else failed */ - so->so_state = SS_NOFDREF; + so->so_state &= SS_PERSISTENT_MASK; + so->so_state |= SS_NOFDREF; /* tcp_input will take care of it */ } else { @@ -540,7 +542,8 @@ void slirp_select_poll(fd_set *readfds, fd_set *writefds, fd_set *xfds) errno == EINPROGRESS || errno == ENOTCONN) continue; /* else failed */ - so->so_state = SS_NOFDREF; + so->so_state &= SS_PERSISTENT_MASK; + so->so_state |= SS_NOFDREF; } else so->so_state &= ~SS_ISFCONNECTING; diff --git a/slirp/socket.c b/slirp/socket.c index 936021e84d..6b3da0a112 100644 --- a/slirp/socket.c +++ b/slirp/socket.c @@ -581,7 +581,8 @@ sosendto(struct socket *so, struct mbuf *m) */ if (so->so_expire) so->so_expire = curtime + SO_EXPIRE; - so->so_state = SS_ISFCONNECTED; /* So that it gets select()ed */ + so->so_state &= SS_PERSISTENT_MASK; + so->so_state |= SS_ISFCONNECTED; /* So that it gets select()ed */ return 0; } @@ -620,7 +621,8 @@ tcp_listen(u_int32_t haddr, u_int hport, u_int32_t laddr, u_int lport, int flags if (flags & SS_FACCEPTONCE) so->so_tcpcb->t_timer[TCPT_KEEP] = TCPTV_KEEP_INIT*2; - so->so_state = (SS_FACCEPTCONN|flags); + so->so_state &= SS_PERSISTENT_MASK; + so->so_state |= (SS_FACCEPTCONN | flags); so->so_lport = lport; /* Kept in network format */ so->so_laddr.s_addr = laddr; /* Ditto */ @@ -715,10 +717,12 @@ sofcantrcvmore(struct socket *so) } } so->so_state &= ~(SS_ISFCONNECTING); - if (so->so_state & SS_FCANTSENDMORE) - so->so_state = SS_NOFDREF; /* Don't select it */ /* XXX close() here as well? */ - else + if (so->so_state & SS_FCANTSENDMORE) { + so->so_state &= SS_PERSISTENT_MASK; + so->so_state |= SS_NOFDREF; /* Don't select it */ + } else { so->so_state |= SS_FCANTRCVMORE; + } } static void @@ -734,10 +738,12 @@ sofcantsendmore(struct socket *so) } } so->so_state &= ~(SS_ISFCONNECTING); - if (so->so_state & SS_FCANTRCVMORE) - so->so_state = SS_NOFDREF; /* as above */ - else + if (so->so_state & SS_FCANTRCVMORE) { + so->so_state &= SS_PERSISTENT_MASK; + so->so_state |= SS_NOFDREF; /* as above */ + } else { so->so_state |= SS_FCANTSENDMORE; + } } void diff --git a/slirp/socket.h b/slirp/socket.h index ac36aaa4b5..2cf476cb91 100644 --- a/slirp/socket.h +++ b/slirp/socket.h @@ -71,6 +71,8 @@ struct socket { #define SS_FACCEPTCONN 0x100 /* Socket is accepting connections from a host on the internet */ #define SS_FACCEPTONCE 0x200 /* If set, the SS_FACCEPTCONN socket will die after one accept */ +#define SS_PERSISTENT_MASK 0xf000 /* Unremovable state bits */ + extern struct socket tcb; struct socket * solookup _P((struct socket *, struct in_addr, u_int, struct in_addr, u_int)); diff --git a/slirp/tcp_input.c b/slirp/tcp_input.c index ab0840d8dd..8789303c8b 100644 --- a/slirp/tcp_input.c +++ b/slirp/tcp_input.c @@ -1038,7 +1038,8 @@ trimthenstep6: soisfconnected(so); so->so_state &= ~SS_CTL; /* success XXX */ } else if (ret == 2) { - so->so_state = SS_NOFDREF; /* CTL_CMD */ + so->so_state &= SS_PERSISTENT_MASK; + so->so_state |= SS_NOFDREF; /* CTL_CMD */ } else { needoutput = 1; tp->t_state = TCPS_FIN_WAIT_1; diff --git a/slirp/udp.c b/slirp/udp.c index d675ad3e66..3722845cde 100644 --- a/slirp/udp.c +++ b/slirp/udp.c @@ -666,7 +666,8 @@ udp_listen(u_int32_t haddr, u_int hport, u_int32_t laddr, u_int lport, if (flags != SS_FACCEPTONCE) so->so_expire = 0; - so->so_state = SS_ISFCONNECTED; + so->so_state &= SS_PERSISTENT_MASK; + so->so_state |= SS_ISFCONNECTED; return so; }