Module: sip-router
Branch: master
Commit: 203b2678a7115f2ba744eeda5279108fdd5b139d
URL:
http://git.sip-router.org/cgi-bin/gitweb.cgi/sip-router/?a=commit;h=203b267…
Author: Daniel-Constantin Mierla <miconda(a)gmail.com>
Committer: Daniel-Constantin Mierla <miconda(a)gmail.com>
Date: Mon Aug 1 14:36:39 2011 +0200
tm: backup/restore lists of avps for usage t_uac
- when sending a self-generated request while processing other sip
message, backup the list of avps and restore afterwards
- reported by Sebastian Damm
- added helper function to backup/restore the lists of avps from msg
context to static var and use transaction lists
---
modules/tm/h_table.c | 37 +++++++++++++++++++++++++++++++++++++
modules/tm/h_table.h | 26 +++++++++++++++++++++++++-
modules/tm/uac.c | 11 ++---------
3 files changed, 64 insertions(+), 10 deletions(-)
diff --git a/modules/tm/h_table.c b/modules/tm/h_table.c
index 743fa94..4870920 100644
--- a/modules/tm/h_table.c
+++ b/modules/tm/h_table.c
@@ -487,4 +487,41 @@ error0:
}
+/**
+ * backup xdata from/to msg context to local var and use T lists
+ * - mode = 0 - from msg context to _txdata and use T lists
+ * - mode = 1 - restore to msg context from _txdata
+ */
+void tm_xdata_swap(tm_cell_t *t, int mode)
+{
+ static tm_xdata_t _txdata;
+ tm_xdata_t *x;
+
+ x = &_txdata;
+
+ if(mode==0) {
+ if(t==NULL)
+ return;
+ x->uri_avps_from = set_avp_list(AVP_TRACK_FROM | AVP_CLASS_URI,
&t->uri_avps_from );
+ x->uri_avps_to = set_avp_list(AVP_TRACK_TO | AVP_CLASS_URI, &t->uri_avps_to
);
+ x->user_avps_from = set_avp_list(AVP_TRACK_FROM | AVP_CLASS_USER,
&t->user_avps_from );
+ x->user_avps_to = set_avp_list(AVP_TRACK_TO | AVP_CLASS_USER,
&t->user_avps_to );
+ x->domain_avps_from = set_avp_list(AVP_TRACK_FROM | AVP_CLASS_DOMAIN,
&t->domain_avps_from );
+ x->domain_avps_to = set_avp_list(AVP_TRACK_TO | AVP_CLASS_DOMAIN,
&t->domain_avps_to );
+#ifdef WITH_XAVP
+ x->xavps_list = xavp_set_list(&t->xavps_list);
+#endif
+ } else if(mode==1) {
+ /* restore original avp list */
+ set_avp_list( AVP_TRACK_FROM | AVP_CLASS_URI, x->uri_avps_from );
+ set_avp_list( AVP_TRACK_TO | AVP_CLASS_URI, x->uri_avps_to );
+ set_avp_list( AVP_TRACK_FROM | AVP_CLASS_USER, x->user_avps_from );
+ set_avp_list( AVP_TRACK_TO | AVP_CLASS_USER, x->user_avps_to );
+ set_avp_list( AVP_TRACK_FROM | AVP_CLASS_DOMAIN, x->domain_avps_from );
+ set_avp_list( AVP_TRACK_TO | AVP_CLASS_DOMAIN, x->domain_avps_to );
+#ifdef WITH_XAVP
+ xavp_set_list(x->xavps_list);
+#endif
+ }
+}
diff --git a/modules/tm/h_table.h b/modules/tm/h_table.h
index 30a60e1..2ad42ce 100644
--- a/modules/tm/h_table.h
+++ b/modules/tm/h_table.h
@@ -300,6 +300,25 @@ struct totag_elem {
* saves us 2*2 bytes */
typedef unsigned short retr_timeout_t;
+
+/**
+ * extra data from SIP message context to transaction storage
+ */
+typedef struct tm_xdata
+{
+ /* lists with avps */
+ struct usr_avp **uri_avps_from;
+ struct usr_avp **uri_avps_to;
+ struct usr_avp **user_avps_from;
+ struct usr_avp **user_avps_to;
+ struct usr_avp **domain_avps_from;
+ struct usr_avp **domain_avps_to;
+#ifdef WITH_XAVP
+ sr_xavp_t **xavps_list;
+#endif
+} tm_xdata_t;
+
+
/* transaction context */
typedef struct cell
@@ -370,7 +389,7 @@ typedef struct cell
* many due to downstream forking; */
struct totag_elem *fwded_totags;
- /* list with avp */
+ /* lists with avps */
struct usr_avp *uri_avps_from;
struct usr_avp *uri_avps_to;
struct usr_avp *user_avps_from;
@@ -543,6 +562,11 @@ inline static void remove_from_hash_table_unsafe( struct cell *
p_cell)
t_stats_deleted( is_local(p_cell) );
}
+/**
+ * backup xdata from/to msg context to local var and use T lists
+ */
+void tm_xdata_swap(tm_cell_t *t, int mode);
+
#endif
diff --git a/modules/tm/uac.c b/modules/tm/uac.c
index 1a70e38..0f36a4c 100644
--- a/modules/tm/uac.c
+++ b/modules/tm/uac.c
@@ -352,9 +352,8 @@ static inline int t_uac_prepare(uac_req_t *uac_r,
#ifdef USE_COMP
lreq.rcv.comp=dst.comp;
#endif /* USE_COMP */
- /* AVPs are reset anyway afterwards, so no need to
- backup/restore them*/
sflag_bk = getsflags();
+ tm_xdata_swap(new_cell, 0);
/* run the route */
backup_route_type = get_route_type();
@@ -373,6 +372,7 @@ static inline int t_uac_prepare(uac_req_t *uac_r,
set_route_type( backup_route_type );
/* restore original environment */
+ tm_xdata_swap(new_cell, 1);
setsflagsval(sflag_bk);
if (unlikely(lreq.new_uri.s))
@@ -408,13 +408,6 @@ static inline int t_uac_prepare(uac_req_t *uac_r,
}
#endif
- /* better reset avp list now - anyhow, it's useless from
- * this point (bogdan) */
- reset_avps();
-#ifdef WITH_XAVP
- xavp_reset_list();
-#endif
-
new_cell->method.s = buf;
new_cell->method.len = uac_r->method->len;