Module: sip-router
Branch: master
Commit: b6d3dc61a78e549c9a75ddfa2fbb86aa2a1682c5
URL:
http://git.sip-router.org/cgi-bin/gitweb.cgi/sip-router/?a=commit;h=b6d3dc6…
Author: Daniel-Constantin Mierla <miconda(a)gmail.com>
Committer: Daniel-Constantin Mierla <miconda(a)gmail.com>
Date: Fri Oct 31 12:33:38 2014 +0100
tm: update headers shortcuts if buffer rebuilt after event_route[tm:local-requests]
- affecting transactions for local generated requests
- bulding local ACK uses the shortcuts and they ended up being broken
- reported by Kristian F. Høgh
---
modules/tm/uac.c | 47 +++++++++++++++++++++++++++++++++++++++++++++++
1 files changed, 47 insertions(+), 0 deletions(-)
diff --git a/modules/tm/uac.c b/modules/tm/uac.c
index 0398118..10e7a59 100644
--- a/modules/tm/uac.c
+++ b/modules/tm/uac.c
@@ -70,6 +70,7 @@
#include "../../dset.h"
#include "../../socket_info.h"
#include "../../compiler_opt.h"
+#include "../../parser/parse_cseq.h"
#include "config.h"
#include "ut.h"
#include "h_table.h"
@@ -185,6 +186,43 @@ static inline unsigned int dlg2hash( dlg_t* dlg )
return hashid;
}
+/**
+ * refresh hdr shortcuts inside new buffer
+ */
+int uac_refresh_hdr_shortcuts(tm_cell_t *tcell, char *buf, int buf_len)
+{
+ sip_msg_t lreq;
+ struct cseq_body *cs;
+
+ if(likely(build_sip_msg_from_buf(&lreq, buf, buf_len, inc_msg_no())<0)) {
+ LM_ERR("failed to parse msg buffer\n");
+ return -1;
+ }
+ if(parse_headers(&lreq,HDR_CSEQ_F|HDR_CALLID_F|HDR_FROM_F|HDR_TO_F,0)<0) {
+ LM_ERR("failed to parse headers in new message\n");
+ goto error;
+ }
+ tcell->from.s = lreq.from->name.s;
+ tcell->from.len = lreq.from->len;
+ tcell->to.s = lreq.to->name.s;
+ tcell->to.len = lreq.to->len;
+ tcell->callid.s = lreq.callid->name.s;
+ tcell->callid.len = lreq.callid->len;
+
+ cs = get_cseq(&lreq);
+ tcell->cseq_n.s = lreq.cseq->name.s;
+ tcell->cseq_n.len = (int)(cs->number.s + cs->number.len -
lreq.cseq->name.s);
+
+ LM_DBG("=========== cseq: [%.*s]\n", tcell->cseq_n.len,
tcell->cseq_n.s);
+ lreq.buf=0; /* covers the obsolete DYN_BUF */
+ free_sip_msg(&lreq);
+ return 0;
+
+error:
+ lreq.buf=0; /* covers the obsolete DYN_BUF */
+ free_sip_msg(&lreq);
+ return -1;
+}
/* WARNING: - dst_cell contains the created cell, but it is un-referenced
* (before using it make sure you REF() it first)
@@ -221,6 +259,7 @@ static inline int t_uac_prepare(uac_req_t *uac_r,
snd_flags_t snd_flags;
tm_xlinks_t backup_xd;
tm_xdata_t local_xd;
+ int refresh_shortcuts = 0;
ret=-1;
hi=0; /* make gcc happy */
@@ -428,6 +467,7 @@ static inline int t_uac_prepare(uac_req_t *uac_r,
buf = buf1;
buf_len = buf_len1;
/* a possible change of the method is not handled! */
+ refresh_shortcuts = 1;
}
} else {
@@ -444,6 +484,7 @@ normal_update:
buf = buf1;
buf_len = buf_len1;
/* a possible change of the method is not handled! */
+ refresh_shortcuts = 1;
}
}
}
@@ -476,6 +517,12 @@ normal_update:
request->buffer = buf;
request->buffer_len = buf_len;
+ if(unlikely(refresh_shortcuts==1)) {
+ if(uac_refresh_hdr_shortcuts(new_cell, buf, buf_len)<0) {
+ LM_ERR("failed to refresh header shortcuts\n");
+ goto error1;
+ }
+ }
new_cell->nr_of_outgoings++;
/* Register the callbacks after everything is successful and nothing can fail.