Module: sip-router Branch: master Commit: 1e83919bcb3f1a2fb2890a6766a007b8f50cb986 URL: http://git.sip-router.org/cgi-bin/gitweb.cgi/sip-router/?a=commit;h=1e83919b...
Author: Daniel-Constantin Mierla miconda@gmail.com Committer: Daniel-Constantin Mierla miconda@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");