diff --git a/src/sip/dialog.c b/src/sip/dialog.c index 4585e22b6..f1cb6cadf 100644 --- a/src/sip/dialog.c +++ b/src/sip/dialog.c @@ -35,6 +35,7 @@ struct sip_dialog { uint32_t lseq; uint32_t rseq; size_t cpos; + size_t rpos; enum sip_transp tp; uint32_t srcport; }; @@ -118,6 +119,7 @@ int sip_dialog_alloc(struct sip_dialog **dlgp, if (i == 0) rend = dlg->mb->pos - 2; } + dlg->rpos = dlg->mb->pos; err |= mbuf_printf(dlg->mb, "To: <%s>\r\n", to_uri); dlg->cpos = dlg->mb->pos; err |= mbuf_printf(dlg->mb, "From: %s%s%s<%s>;tag=%016llx\r\n", @@ -231,7 +233,9 @@ int sip_dialog_accept(struct sip_dialog **dlgp, const struct sip_msg *msg) err |= sip_msg_hdr_apply(msg, true, SIP_HDR_RECORD_ROUTE, record_route_handler, &renc) ? ENOMEM : 0; + dlg->rpos = dlg->mb->pos; err |= mbuf_printf(dlg->mb, "To: %r\r\n", &msg->from.val); + dlg->cpos = dlg->mb->pos; err |= mbuf_printf(dlg->mb, "From: %r;tag=%016llx\r\n", &msg->to.val, msg->tag); if (err) @@ -304,10 +308,12 @@ int sip_dialog_create(struct sip_dialog *dlg, const struct sip_msg *msg) err |= sip_msg_hdr_apply(msg, msg->req, SIP_HDR_RECORD_ROUTE, record_route_handler, &renc) ? ENOMEM : 0; + dlg->rpos = renc.mb->pos; err |= mbuf_printf(renc.mb, "To: %r\r\n", msg->req ? &msg->from.val : &msg->to.val); dlg->mb->pos = dlg->cpos; + dlg->cpos = renc.mb->pos; err |= mbuf_write_mem(renc.mb, mbuf_buf(dlg->mb), mbuf_get_left(dlg->mb)); dlg->mb->pos = 0; @@ -344,7 +350,6 @@ int sip_dialog_create(struct sip_dialog *dlg, const struct sip_msg *msg) dlg->rtag = mem_ref(rtag); dlg->uri = mem_ref(uri); dlg->rseq = msg->req ? msg->cseq.num : 0; - dlg->cpos = 0; dlg->tp = msg->tp; out: @@ -462,6 +467,8 @@ int sip_dialog_update(struct sip_dialog *dlg, const struct sip_msg *msg) { const struct sip_hdr *contact; struct sip_addr addr; + struct mbuf *mb; + size_t cpos; char *uri; int err; @@ -479,6 +486,28 @@ int sip_dialog_update(struct sip_dialog *dlg, const struct sip_msg *msg) if (err) return err; + mb = mbuf_alloc(512); + if (!mb) + return ENOMEM; + + err = mbuf_write_mem(mb, mbuf_buf(dlg->mb), dlg->rpos); + err |= mbuf_printf(mb, "To: %r\r\n", + msg->req ? &msg->from.val : &msg->to.val); + cpos = mb->pos; + err |= mbuf_write_mem(mb, mbuf_buf(dlg->mb) + dlg->cpos, + mbuf_get_left(dlg->mb) - dlg->cpos); + + if (err) + goto out; + + dlg->cpos = cpos; + mb->pos = 0; + + mem_deref(dlg->rtag); + err = pl_strdup(&dlg->rtag, msg->req ? &msg->from.tag : &msg->to.tag); + if (err) + return err; + if (dlg->route.scheme.p == dlg->uri) { struct uri tmp; @@ -492,10 +521,14 @@ int sip_dialog_update(struct sip_dialog *dlg, const struct sip_msg *msg) dlg->route = tmp; } + mem_deref(dlg->mb); mem_deref(dlg->uri); + + dlg->mb = mem_ref(mb); dlg->uri = mem_ref(uri); out: + mem_deref(mb); mem_deref(uri); return err;