Module: sip-router
Branch: master
Commit: 1e83919bcb3f1a2fb2890a6766a007b8f50cb986
URL:
http://git.sip-router.org/cgi-bin/gitweb.cgi/sip-router/?a=commit;h=1e83919…
Author: Daniel-Constantin Mierla <miconda(a)gmail.com>
Committer: Daniel-Constantin Mierla <miconda(a)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
---
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 aff447d..18b0857 100644
--- a/modules/tm/h_table.c
+++ b/modules/tm/h_table.c
@@ -492,10 +492,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;
@@ -528,3 +528,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 df4f979..8b8741b 100644
--- a/modules/tm/h_table.h
+++ b/modules/tm/h_table.h
@@ -299,13 +299,30 @@ struct totag_elem {
* max retr. = 65 s which should be enough and 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;
@@ -315,7 +332,7 @@ typedef struct tm_xdata
#ifdef WITH_XAVP
sr_xavp_t **xavps_list;
#endif
-} tm_xdata_t;
+} tm_xlinks_t;
/* transaction context */
@@ -564,7 +581,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 15add04..e6ba762 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");