slirp updates
-----BEGIN PGP SIGNATURE----- Version: GnuPG v1 iQIcBAABCgAGBQJXBj4/AAoJEOPlHOj7ay8dVTEP/0IilPRZ1Iop61PvIRJd6R9S H4NEz6jkuhk6jHxZgg5ynarzp7aC2eitBS5M029+3oI0s/sa7ag+TDe7Mj/z2CBZ lJh2QO8lNH9MV/MWT3yA5vqUvjc13NdfsgSytzVbbsGasuMt92gU3/7K6jb8Ucyc CfBRtCrBFAGF1cdIRrzeoC3Y0BkNuajTBKVt1dn7RxOToaUtVcwZVoRMO60VWgn/ mRgjTQD/Ib+4bTRiN5J6GSMaqd7NznJmhN629zFx9SOygu2vq9kHeJgEG66SrjBu 8RiNFq6o6zgAITM7lyF+c7JlsbdDjm9rPUVIOJ9L146bXE8vdrezQDPPTTdhrA+9 Bw0dAowKfgdimWeVOu/gpzolE2eaiqPS2EvxoihOXYNkK0iMbG9qo41BopzA1mti jQUueLBMCJn2tiBM2oMKWJdwt7PxPlyzCq8c2rOD/s1lQLWpUV0eWd72tj67cIhH 6mcHyYhALqXVKvtzcKXFByrpJ+QGoQQnfvEUrgdNay57ZmYrj9vUsiihYtq03tFZ rW0JPinFD2+1V9LjEXOll0bNb3rdl/nBhWqJb/DsThWvCaXttaf5GbDHvPFLRV+u e8X90FJvvCffznW/OCwFHfBu9LAqa/pgeGo/wH/3mCdzhddhZOrTDJFR4rGP1nkd UDJzmSf8JLFFYkZtUYEM =Qlkw -----END PGP SIGNATURE----- Merge remote-tracking branch 'remotes/thibault/tags/samuel-thibault' into staging slirp updates # gpg: Signature made Thu 07 Apr 2016 12:02:23 BST using RSA key ID FB6B2F1D # gpg: Good signature from "Samuel Thibault <samuel.thibault@gnu.org>" # gpg: aka "Samuel Thibault <sthibault@debian.org>" # gpg: aka "Samuel Thibault <samuel.thibault@inria.fr>" # gpg: aka "Samuel Thibault <samuel.thibault@labri.fr>" # gpg: aka "Samuel Thibault <samuel.thibault@ens-lyon.org>" # gpg: WARNING: This key is not certified with sufficiently trusted signatures! # gpg: It is not certain that the signature belongs to the owner. # Primary key fingerprint: 900C B024 B679 31D4 0F82 304B D017 8C76 7D06 9EE6 # Subkey fingerprint: F632 74CD C630 0873 CB3D 29D9 E3E5 1CE8 FB6B 2F1D * remotes/thibault/tags/samuel-thibault: slirp: handle deferred ECONNREFUSED on non-blocking TCP sockets slirp: Propagate host TCP RST to the guest. slirp: avoid use-after-free in slirp_pollfds_poll() if soread() returns an error slirp: don't crash when tcp_sockclosed() is called with a NULL tp Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
This commit is contained in:
commit
e380023898
|
@ -534,7 +534,12 @@ void slirp_pollfds_poll(GArray *pollfds, int select_error)
|
|||
* test for G_IO_IN below if this succeeds
|
||||
*/
|
||||
if (revents & G_IO_PRI) {
|
||||
sorecvoob(so);
|
||||
ret = sorecvoob(so);
|
||||
if (ret < 0) {
|
||||
/* Socket error might have resulted in the socket being
|
||||
* removed, do not try to do anything more with it. */
|
||||
continue;
|
||||
}
|
||||
}
|
||||
/*
|
||||
* Check sockets for reading
|
||||
|
@ -553,6 +558,11 @@ void slirp_pollfds_poll(GArray *pollfds, int select_error)
|
|||
if (ret > 0) {
|
||||
tcp_output(sototcpcb(so));
|
||||
}
|
||||
if (ret < 0) {
|
||||
/* Socket error might have resulted in the socket being
|
||||
* removed, do not try to do anything more with it. */
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
|
|
|
@ -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 == ECONNREFUSED
|
||||
|| err == ENOTCONN || err == EPIPE) {
|
||||
tcp_drop(sototcpcb(so), err);
|
||||
} else {
|
||||
tcp_sockclosed(sototcpcb(so));
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
|
@ -260,10 +275,11 @@ err:
|
|||
* so when OOB data arrives, we soread() it and everything
|
||||
* in the send buffer is sent as urgent data
|
||||
*/
|
||||
void
|
||||
int
|
||||
sorecvoob(struct socket *so)
|
||||
{
|
||||
struct tcpcb *tp = sototcpcb(so);
|
||||
int ret;
|
||||
|
||||
DEBUG_CALL("sorecvoob");
|
||||
DEBUG_ARG("so = %p", so);
|
||||
|
@ -276,11 +292,15 @@ sorecvoob(struct socket *so)
|
|||
* urgent data, or the read() doesn't return all the
|
||||
* urgent data.
|
||||
*/
|
||||
soread(so);
|
||||
tp->snd_up = tp->snd_una + so->so_snd.sb_cc;
|
||||
tp->t_force = 1;
|
||||
tcp_output(tp);
|
||||
tp->t_force = 0;
|
||||
ret = soread(so);
|
||||
if (ret > 0) {
|
||||
tp->snd_up = tp->snd_una + so->so_snd.sb_cc;
|
||||
tp->t_force = 1;
|
||||
tcp_output(tp);
|
||||
tp->t_force = 0;
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
/*
|
||||
|
|
|
@ -127,7 +127,7 @@ struct socket *solookup(struct socket **, struct socket *,
|
|||
struct socket *socreate(Slirp *);
|
||||
void sofree(struct socket *);
|
||||
int soread(struct socket *);
|
||||
void sorecvoob(struct socket *);
|
||||
int sorecvoob(struct socket *);
|
||||
int sosendoob(struct socket *);
|
||||
int sowrite(struct socket *);
|
||||
void sorecvfrom(struct socket *);
|
||||
|
|
|
@ -725,6 +725,12 @@ findso:
|
|||
so->so_ti = ti;
|
||||
tp->t_timer[TCPT_KEEP] = TCPTV_KEEP_INIT;
|
||||
tp->t_state = TCPS_SYN_RECEIVED;
|
||||
/*
|
||||
* Initialize receive sequence numbers now so that we can send a
|
||||
* valid RST if the remote end rejects our connection.
|
||||
*/
|
||||
tp->irs = ti->ti_seq;
|
||||
tcp_rcvseqinit(tp);
|
||||
tcp_template(tp);
|
||||
}
|
||||
return;
|
||||
|
|
|
@ -356,6 +356,10 @@ tcp_sockclosed(struct tcpcb *tp)
|
|||
DEBUG_CALL("tcp_sockclosed");
|
||||
DEBUG_ARG("tp = %p", tp);
|
||||
|
||||
if (!tp) {
|
||||
return;
|
||||
}
|
||||
|
||||
switch (tp->t_state) {
|
||||
|
||||
case TCPS_CLOSED:
|
||||
|
@ -374,8 +378,7 @@ tcp_sockclosed(struct tcpcb *tp)
|
|||
tp->t_state = TCPS_LAST_ACK;
|
||||
break;
|
||||
}
|
||||
if (tp)
|
||||
tcp_output(tp);
|
||||
tcp_output(tp);
|
||||
}
|
||||
|
||||
/*
|
||||
|
|
Loading…
Reference in a new issue