diff options
author | Samuel Thibault <samuel.thibault@ens-lyon.org> | 2017-08-25 01:35:53 +0200 |
---|---|---|
committer | Peter Maydell <peter.maydell@linaro.org> | 2017-08-30 23:14:34 +0100 |
commit | 0b5a6fec4ed11326bcdc07c1ef5702df39f1bb45 (patch) | |
tree | ea0f3d6548990ca181519415eefe2e5419a7d984 | |
parent | 27731580d379716f2a0b4ea7d27486dd9c29198a (diff) | |
download | slirp-0b5a6fec4ed11326bcdc07c1ef5702df39f1bb45.zip slirp-0b5a6fec4ed11326bcdc07c1ef5702df39f1bb45.tar.gz slirp-0b5a6fec4ed11326bcdc07c1ef5702df39f1bb45.tar.bz2 |
slirp: fix clearing ifq_so from pending packets
The if_fastq and if_batchq contain not only packets, but queues of packets
for the same socket. When sofree frees a socket, it thus has to clear ifq_so
from all the packets from the queues, not only the first.
Signed-off-by: Samuel Thibault <samuel.thibault@ens-lyon.org>
Reviewed-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
Cc: qemu-stable@nongnu.org
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
-rw-r--r-- | socket.c | 35 |
1 files changed, 21 insertions, 14 deletions
@@ -60,26 +60,33 @@ struct socket *socreate(Slirp *slirp) } /* + * Remove references to so from the given message queue. + */ +static void soqfree(struct socket *so, struct quehead *qh) +{ + struct mbuf *ifq; + + for (ifq = (struct mbuf *)qh->qh_link; (struct quehead *)ifq != qh; + ifq = ifq->ifq_next) { + if (ifq->ifq_so == so) { + struct mbuf *ifm; + ifq->ifq_so = NULL; + for (ifm = ifq->ifs_next; ifm != ifq; ifm = ifm->ifs_next) { + ifm->ifq_so = NULL; + } + } + } +} + +/* * remque and free a socket, clobber cache */ void sofree(struct socket *so) { Slirp *slirp = so->slirp; - struct mbuf *ifm; - - for (ifm = (struct mbuf *)slirp->if_fastq.qh_link; - (struct quehead *)ifm != &slirp->if_fastq; ifm = ifm->ifq_next) { - if (ifm->ifq_so == so) { - ifm->ifq_so = NULL; - } - } - for (ifm = (struct mbuf *)slirp->if_batchq.qh_link; - (struct quehead *)ifm != &slirp->if_batchq; ifm = ifm->ifq_next) { - if (ifm->ifq_so == so) { - ifm->ifq_so = NULL; - } - } + soqfree(so, &slirp->if_fastq); + soqfree(so, &slirp->if_batchq); if (so->so_emu == EMU_RSH && so->extra) { sofree(so->extra); |