From b22dde05f04b31fc6323ff52b07c813b78e42f8b Mon Sep 17 00:00:00 2001 From: Richard Fuchs Date: Wed, 4 Feb 2015 12:10:23 -0500 Subject: [PATCH] MT#11357 fix race condition during call teardown Streams are removed from kernel forwarding at the "Final packet stats" stage, which also stops the packet handler. But if a packet has already been received at this point, with the packet handler already running, only waiting to acquire the mutex, then the handler will run after the streams have been removed from kernel and will promptly push them back into kernel, where they will remain forever after. --- daemon/call.c | 4 ++++ daemon/call.h | 1 + 2 files changed, 5 insertions(+) diff --git a/daemon/call.c b/daemon/call.c index 8407a57..f9bbe2f 100644 --- a/daemon/call.c +++ b/daemon/call.c @@ -566,6 +566,9 @@ static int stream_packet(struct streamrelay *sr_incoming, str *s, struct sockadd m = c->callmaster; smart_ntop_port(addr, fsin, sizeof(addr)); + if (p_incoming->shutdown || p_outgoing->shutdown) + return 0; + if (sr_incoming->stun && is_stun(s)) { stun_ret = stun(s, sr_incoming, fsin); if (!stun_ret) @@ -1800,6 +1803,7 @@ static void kill_callstream(struct callstream *s) { for (i = 0; i < 2; i++) { p = &s->peers[i]; + p->shutdown = 1; unkernelize(p); for (j = 0; j < 2; j++) { diff --git a/daemon/call.h b/daemon/call.h index 88e0e2a..fc14267 100644 --- a/daemon/call.h +++ b/daemon/call.h @@ -132,6 +132,7 @@ struct peer { int kernelized:1; int filled:1; int confirmed:1; + int shutdown:1; }; struct callstream { struct obj obj;