aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorSamuel Thibault <samuel.thibault@ens-lyon.org>2017-08-25 01:35:53 +0200
committerPeter Maydell <peter.maydell@linaro.org>2017-08-30 23:14:34 +0100
commit0b5a6fec4ed11326bcdc07c1ef5702df39f1bb45 (patch)
treeea0f3d6548990ca181519415eefe2e5419a7d984
parent27731580d379716f2a0b4ea7d27486dd9c29198a (diff)
downloadslirp-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.c35
1 files changed, 21 insertions, 14 deletions
diff --git a/socket.c b/socket.c
index b346e1c..245f619 100644
--- a/socket.c
+++ b/socket.c
@@ -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);