diff --git a/src/sipsess/connect.c b/src/sipsess/connect.c index eec8297af..15fb6ae4d 100644 --- a/src/sipsess/connect.c +++ b/src/sipsess/connect.c @@ -88,7 +88,21 @@ static void invite_resp_handler(int err, const struct sip_msg *msg, void *arg) if (sip_msg_hdr_has_value(msg, SIP_HDR_REQUIRE, "100rel") && sess->rel100_supported) { - err = sip_dialog_established(sess->dlg) ? + if (msg && mbuf_get_left(msg->mb)) { + if (sess->sent_offer) { + sess->awaiting_answer = false; + err = sess->answerh(msg, sess->arg); + if (err) + goto out; + } + else { + sess->modify_pending = false; + err = sess->offerh(&desc, msg, + sess->arg); + } + } + + err |= sip_dialog_established(sess->dlg) ? sip_dialog_update(sess->dlg, msg) : sip_dialog_create(sess->dlg, msg); err |= sipsess_prack(sess, msg->cseq.num, msg->rel_seq, diff --git a/src/sipsess/listen.c b/src/sipsess/listen.c index 6aa3b1a58..5dc6aa3d0 100644 --- a/src/sipsess/listen.c +++ b/src/sipsess/listen.c @@ -190,12 +190,12 @@ static void ack_handler(struct sipsess_sock *sock, const struct sip_msg *msg) static void prack_handler(struct sipsess_sock *sock, const struct sip_msg *msg) { struct sipsess *sess; - bool awaiting_answer; - int err = 0; + struct mbuf *desc = NULL; + bool awaiting_answer = false; sess = sipsess_find(sock, msg); - if (!sess || sipsess_reply_prack(sess, msg, &awaiting_answer)) { + if (!sess || sipsess_reply_ack(sess, msg, &awaiting_answer)) { (void)sip_reply(sock->sip, msg, 481, "Transaction Does Not Exist"); return; @@ -212,11 +212,15 @@ static void prack_handler(struct sipsess_sock *sock, const struct sip_msg *msg) if (awaiting_answer) { sess->awaiting_answer = false; - err = sess->answerh(msg, sess->arg); + (void)sess->answerh(msg, sess->arg); + } + else if (msg && mbuf_get_left(msg->mb)) { + (void)sess->offerh(&desc, msg, sess->arg); } - if (err) - sipsess_terminate(sess, err, NULL); + (void)sipsess_reply_2xx(sess, msg, 200, "OK", desc, NULL, NULL); + + mem_deref(desc); } diff --git a/src/sipsess/reply.c b/src/sipsess/reply.c index 4f03145d6..f6ffdc8b6 100644 --- a/src/sipsess/reply.c +++ b/src/sipsess/reply.c @@ -87,25 +87,28 @@ int sipsess_reply_2xx(struct sipsess *sess, const struct sip_msg *msg, uint16_t scode, const char *reason, struct mbuf *desc, const char *fmt, va_list *ap) { - struct sipsess_reply *reply; + struct sipsess_reply *reply = NULL; struct sip_contact contact; - bool is_prack = false; int err = ENOMEM; + bool is_prack = !pl_strcmp(&msg->met, "PRACK"); - reply = mem_zalloc(sizeof(*reply), destructor); - if (!reply) - goto out; + if (!is_prack) { + reply = mem_zalloc(sizeof(*reply), destructor); + if (!reply) + goto out; - list_append(&sess->replyl, &reply->le, reply); - reply->rel_seq = 0; - reply->seq = msg->cseq.num; - reply->msg = mem_ref((void *)msg); - reply->sess = sess; + list_append(&sess->replyl, &reply->le, reply); + + reply->rel_seq = 0; + reply->seq = msg->cseq.num; + 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(is_prack ? NULL : &sess->st, &reply->mb, sess->sip, + err = sip_treplyf(is_prack ? NULL : &sess->st, + reply ? &reply->mb : NULL, sess->sip, msg, true, scode, reason, "%H" "%v" @@ -125,17 +128,14 @@ int sipsess_reply_2xx(struct sipsess *sess, const struct sip_msg *msg, if (err) goto out; - if (!is_prack) { + if (reply) { tmr_start(&reply->tmr, 64 * SIP_T1, tmr_handler, reply); tmr_start(&reply->tmrg, SIP_T1, retransmit_handler, reply); - } - else { - mem_deref(reply); - } - if (!mbuf_get_left(msg->mb) && desc) { - reply->awaiting_answer = true; - sess->awaiting_answer = true; + if (!mbuf_get_left(msg->mb) && desc) { + reply->awaiting_answer = true; + sess->awaiting_answer = true; + } } out: @@ -283,23 +283,3 @@ int sipsess_reply_ack(struct sipsess *sess, const struct sip_msg *msg, return 0; } - - -int sipsess_reply_prack(struct sipsess *sess, const struct sip_msg *msg, - bool *awaiting_answer) -{ - struct sipsess_reply *reply; - int err; - - reply = list_ledata(list_apply(&sess->replyl, false, cmp_handler, - (void *)msg)); - if (!reply) - return ENOENT; - - *awaiting_answer = reply->awaiting_answer; - err = sipsess_reply_2xx(sess, msg, 200, "OK", NULL, NULL, NULL); - - mem_deref(reply); - - return err; -} diff --git a/src/sipsess/sipsess.h b/src/sipsess/sipsess.h index febd1bca7..8eceb483c 100644 --- a/src/sipsess/sipsess.h +++ b/src/sipsess/sipsess.h @@ -94,8 +94,6 @@ int sipsess_reply_1xx(struct sipsess *sess, const struct sip_msg *msg, const char *fmt, va_list *ap); int sipsess_reply_ack(struct sipsess *sess, const struct sip_msg *msg, bool *awaiting_answer); -int sipsess_reply_prack(struct sipsess *sess, const struct sip_msg *msg, - bool *awaiting_answer); int sipsess_reinvite(struct sipsess *sess, bool reset_ls); int sipsess_bye(struct sipsess *sess, bool reset_ls); int sipsess_request_alloc(struct sipsess_request **reqp, struct sipsess *sess,