[sr-dev] git:3.1: tm: backup X/AVP lists when building new T in t_uac()

Daniel-Constantin Mierla miconda at gmail.com
Wed Sep 14 18:48:44 CEST 2011


Module: sip-router
Branch: 3.1
Commit: 53ee5d0e7e387cdf0f39a371b356ff44f3d36fa9
URL:    http://git.sip-router.org/cgi-bin/gitweb.cgi/sip-router/?a=commit;h=53ee5d0e7e387cdf0f39a371b356ff44f3d36fa9

Author: Daniel-Constantin Mierla <miconda at gmail.com>
Committer: Daniel-Constantin Mierla <miconda at gmail.com>
Date:   Wed Sep 14 18:39:37 2011 +0200

tm: backup X/AVP lists when building new T in t_uac()

- build_cell() is setting core X/AVP lists to new T structure, losing
  the lists that existed in case another T was set already. This is in
  t_uac() which is used for local generated requests, such as
  uac_req_send(), presence notifications, msilo...
- a revious patch was backing up only X/AVPs lists for
  execution of event_route[tm:local-request]
- reported by Vitaliy Aleksandrov
(cherry picked from commit 1e83919bcb3f1a2fb2890a6766a007b8f50cb986)

---

 modules/tm/h_table.c |   44 +++++++++++++++++++++++++++++++++++++++++---
 modules/tm/h_table.h |   25 ++++++++++++++++++++++---
 modules/tm/uac.c     |    9 ++++++++-
 3 files changed, 71 insertions(+), 7 deletions(-)

diff --git a/modules/tm/h_table.c b/modules/tm/h_table.c
index b472787..b18e2d0 100644
--- a/modules/tm/h_table.c
+++ b/modules/tm/h_table.c
@@ -499,10 +499,10 @@ error0:
  * - 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, tm_xdata_t *xd, int mode)
+void tm_xdata_swap(tm_cell_t *t, tm_xlinks_t *xd, int mode)
 {
-	static tm_xdata_t _txdata;
-	tm_xdata_t *x;
+	static tm_xlinks_t _txdata;
+	tm_xlinks_t *x;
 
 	if(xd==NULL)
 		x = &_txdata;
@@ -535,3 +535,41 @@ void tm_xdata_swap(tm_cell_t *t, tm_xdata_t *xd, int mode)
 	}
 
 }
+
+/**
+ * replace existing lists with newxd and backup in bakxd or restore from bakxd
+ */
+void tm_xdata_replace(tm_xdata_t *newxd, tm_xlinks_t *bakxd)
+{
+	if(newxd==NULL && bakxd!=NULL) {
+		set_avp_list(AVP_TRACK_FROM | AVP_CLASS_URI, bakxd->uri_avps_from);
+		set_avp_list(AVP_TRACK_TO | AVP_CLASS_URI, bakxd->uri_avps_to);
+		set_avp_list(AVP_TRACK_FROM | AVP_CLASS_USER, bakxd->user_avps_from);
+		set_avp_list(AVP_TRACK_TO | AVP_CLASS_USER, bakxd->user_avps_to);
+		set_avp_list(AVP_TRACK_FROM | AVP_CLASS_DOMAIN, bakxd->domain_avps_from);
+		set_avp_list(AVP_TRACK_TO | AVP_CLASS_DOMAIN, bakxd->domain_avps_to);
+#ifdef WITH_XAVP
+		xavp_set_list(bakxd->xavps_list);
+#endif
+		return;
+	}
+
+	if(newxd!=NULL && bakxd!=NULL) {
+		bakxd->uri_avps_from = set_avp_list(AVP_TRACK_FROM | AVP_CLASS_URI,
+				&newxd->uri_avps_from);
+		bakxd->uri_avps_to = set_avp_list(AVP_TRACK_TO | AVP_CLASS_URI,
+				&newxd->uri_avps_to);
+		bakxd->user_avps_from = set_avp_list(AVP_TRACK_FROM | AVP_CLASS_USER,
+				&newxd->user_avps_from);
+		bakxd->user_avps_to = set_avp_list(AVP_TRACK_TO | AVP_CLASS_USER,
+				&newxd->user_avps_to);
+		bakxd->domain_avps_from = set_avp_list(AVP_TRACK_FROM | AVP_CLASS_DOMAIN,
+				&newxd->domain_avps_from);
+		bakxd->domain_avps_to = set_avp_list(AVP_TRACK_TO | AVP_CLASS_DOMAIN,
+				&newxd->domain_avps_to);
+#ifdef WITH_XAVP
+		bakxd->xavps_list = xavp_set_list(&newxd->xavps_list);
+#endif
+		return;
+	}
+}
diff --git a/modules/tm/h_table.h b/modules/tm/h_table.h
index 5f74ba3..ea8acd4 100644
--- a/modules/tm/h_table.h
+++ b/modules/tm/h_table.h
@@ -300,13 +300,30 @@ 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;
+
+
+/**
+ * links to extra data from SIP message context to transaction storage
+ */
+typedef struct tm_xlinks
+{
+	/* links to lists with avps */
 	struct usr_avp **uri_avps_from;
 	struct usr_avp **uri_avps_to;
 	struct usr_avp **user_avps_from;
@@ -316,7 +333,7 @@ typedef struct tm_xdata
 #ifdef WITH_XAVP
 	sr_xavp_t **xavps_list;
 #endif
-} tm_xdata_t;
+} tm_xlinks_t;
 
 
 /* transaction context */
@@ -565,7 +582,9 @@ inline static void remove_from_hash_table_unsafe( struct cell * p_cell)
 /**
  * backup xdata from/to msg context to local var and use T lists
  */
-void tm_xdata_swap(tm_cell_t *t, tm_xdata_t *xd, int mode);
+void tm_xdata_swap(tm_cell_t *t, tm_xlinks_t *xd, int mode);
+
+void tm_xdata_replace(tm_xdata_t *newxd, tm_xlinks_t *bakxd);
 
 #endif
 
diff --git a/modules/tm/uac.c b/modules/tm/uac.c
index c552f5a..6ba1e91 100644
--- a/modules/tm/uac.c
+++ b/modules/tm/uac.c
@@ -216,7 +216,8 @@ static inline int t_uac_prepare(uac_req_t *uac_r,
 	int backup_route_type;
 #endif
 	snd_flags_t snd_flags;
-	tm_xdata_t backup_xd;
+	tm_xlinks_t backup_xd;
+	tm_xdata_t local_xd;
 
 	ret=-1;
 	hi=0; /* make gcc happy */
@@ -276,7 +277,13 @@ static inline int t_uac_prepare(uac_req_t *uac_r,
 	}
 #endif /* USE_DNS_FAILOVER */
 
+	/* build cell sets X/AVP lists to new transaction structure
+	 * => bakup in a tmp struct and restore afterwards */
+	memset(&local_xd, 0, sizeof(tm_xdata_t));
+	tm_xdata_replace(&local_xd, &backup_xd);
 	new_cell = build_cell(0); 
+	tm_xdata_replace(0, &backup_xd);
+
 	if (!new_cell) {
 		ret=E_OUT_OF_MEM;
 		LOG(L_ERR, "t_uac: short of cell shmem\n");




More information about the sr-dev mailing list