From a39ce9d2591b7e0f12066c70cb0aab8f7e7dc747 Mon Sep 17 00:00:00 2001 From: Maximilian Fridrich Date: Fri, 8 Jul 2022 09:12:49 +0200 Subject: [PATCH] strans/accept: fix cancel/rejection (#423) In sipsess_reply_2xx, the reply is sent using a server transaction which sets the st to NULL when replying with scode >=200. This is problematic when sending 2xx responses to PRACKs after which sess->st was NULL. Now, st is not passed to sip_treplyf if the request was PRACK, so st is not set to NULL. --- src/sipsess/accept.c | 4 +--- src/sipsess/reply.c | 10 +++++++--- 2 files changed, 8 insertions(+), 6 deletions(-) diff --git a/src/sipsess/accept.c b/src/sipsess/accept.c index 4a68a2831..9fb7cdddf 100644 --- a/src/sipsess/accept.c +++ b/src/sipsess/accept.c @@ -197,9 +197,7 @@ int sipsess_answer(struct sipsess *sess, uint16_t scode, const char *reason, va_list ap; int err; - if (!sess || (!sess->st - && (sess->established || sess->awaiting_answer)) - || !sess->msg || scode < 200 || scode > 299) + if (!sess || !sess->st || !sess->msg || scode < 200 || scode > 299) return EINVAL; va_start(ap, fmt); diff --git a/src/sipsess/reply.c b/src/sipsess/reply.c index b4a388490..4f03145d6 100644 --- a/src/sipsess/reply.c +++ b/src/sipsess/reply.c @@ -89,6 +89,7 @@ int sipsess_reply_2xx(struct sipsess *sess, const struct sip_msg *msg, { struct sipsess_reply *reply; struct sip_contact contact; + bool is_prack = false; int err = ENOMEM; reply = mem_zalloc(sizeof(*reply), destructor); @@ -101,9 +102,10 @@ int sipsess_reply_2xx(struct sipsess *sess, const struct sip_msg *msg, reply->msg = mem_ref((void *)msg); reply->sess = sess; + is_prack = !pl_strcmp(&msg->met, "PRACK"); sip_contact_set(&contact, sess->cuser, &msg->dst, msg->tp); - err = sip_treplyf(&sess->st, &reply->mb, sess->sip, + err = sip_treplyf(is_prack ? NULL : &sess->st, &reply->mb, sess->sip, msg, true, scode, reason, "%H" "%v" @@ -123,7 +125,7 @@ int sipsess_reply_2xx(struct sipsess *sess, const struct sip_msg *msg, if (err) goto out; - if (pl_strcmp(&msg->met, "PRACK")) { + if (!is_prack) { tmr_start(&reply->tmr, 64 * SIP_T1, tmr_handler, reply); tmr_start(&reply->tmrg, SIP_T1, retransmit_handler, reply); } @@ -138,7 +140,9 @@ int sipsess_reply_2xx(struct sipsess *sess, const struct sip_msg *msg, out: if (err) { - sess->st = mem_deref(sess->st); + if (!is_prack) + sess->st = mem_deref(sess->st); + mem_deref(reply); }