From d11cc80c3a4a2fdeb446837c550517e4f4a511a9 Mon Sep 17 00:00:00 2001 From: Juha Heinanen Date: Wed, 23 Mar 2016 16:32:06 +0200 Subject: [PATCH 01/32] srdb1/schema: removed unique constraint from connection_idx (cherry picked from commit d72ac166b152ca6906248d67e2605d5b283fa01e) --- lib/srdb1/schema/location.xml | 1 - 1 file changed, 1 deletion(-) diff --git a/lib/srdb1/schema/location.xml b/lib/srdb1/schema/location.xml index 07c8d5895f4..c22fcaf9b05 100644 --- a/lib/srdb1/schema/location.xml +++ b/lib/srdb1/schema/location.xml @@ -232,7 +232,6 @@ connection_idx - From e8f230e7989eb0aef2510f52738e8718863b8567 Mon Sep 17 00:00:00 2001 From: Daniel-Constantin Mierla Date: Wed, 23 Mar 2016 16:08:48 +0100 Subject: [PATCH 02/32] kamctl: refreshed definition of location table (cherry picked from commit 2ddf88df7deeebf2966344031eb905811b8e86cb) --- utils/kamctl/db_sqlite/usrloc-create.sql | 4 ++-- utils/kamctl/mysql/usrloc-create.sql | 4 ++-- utils/kamctl/oracle/usrloc-create.sql | 4 ++-- utils/kamctl/postgres/usrloc-create.sql | 4 ++-- 4 files changed, 8 insertions(+), 8 deletions(-) diff --git a/utils/kamctl/db_sqlite/usrloc-create.sql b/utils/kamctl/db_sqlite/usrloc-create.sql index 50f6894b35b..6cbfbdd217d 100644 --- a/utils/kamctl/db_sqlite/usrloc-create.sql +++ b/utils/kamctl/db_sqlite/usrloc-create.sql @@ -22,12 +22,12 @@ CREATE TABLE location ( connection_id INTEGER DEFAULT 0 NOT NULL, keepalive INTEGER DEFAULT 0 NOT NULL, partition INTEGER DEFAULT 0 NOT NULL, - CONSTRAINT location_ruid_idx UNIQUE (ruid), - CONSTRAINT location_connection_idx UNIQUE (server_id, connection_id) + CONSTRAINT location_ruid_idx UNIQUE (ruid) ); CREATE INDEX location_account_contact_idx ON location (username, domain, contact); CREATE INDEX location_expires_idx ON location (expires); +CREATE INDEX location_connection_idx ON location (server_id, connection_id); INSERT INTO version (table_name, table_version) values ('location','8'); diff --git a/utils/kamctl/mysql/usrloc-create.sql b/utils/kamctl/mysql/usrloc-create.sql index f7edfbb3b44..a300661f965 100644 --- a/utils/kamctl/mysql/usrloc-create.sql +++ b/utils/kamctl/mysql/usrloc-create.sql @@ -22,12 +22,12 @@ CREATE TABLE `location` ( `connection_id` INT(11) DEFAULT 0 NOT NULL, `keepalive` INT(11) DEFAULT 0 NOT NULL, `partition` INT(11) DEFAULT 0 NOT NULL, - CONSTRAINT ruid_idx UNIQUE (`ruid`), - CONSTRAINT connection_idx UNIQUE (`server_id`, `connection_id`) + CONSTRAINT ruid_idx UNIQUE (`ruid`) ); CREATE INDEX account_contact_idx ON location (`username`, `domain`, `contact`); CREATE INDEX expires_idx ON location (`expires`); +CREATE INDEX connection_idx ON location (`server_id`, `connection_id`); INSERT INTO version (table_name, table_version) values ('location','8'); diff --git a/utils/kamctl/oracle/usrloc-create.sql b/utils/kamctl/oracle/usrloc-create.sql index 8ab1d98d83a..792322963d7 100644 --- a/utils/kamctl/oracle/usrloc-create.sql +++ b/utils/kamctl/oracle/usrloc-create.sql @@ -22,8 +22,7 @@ CREATE TABLE location ( connection_id NUMBER(10) DEFAULT 0 NOT NULL, keepalive NUMBER(10) DEFAULT 0 NOT NULL, partition NUMBER(10) DEFAULT 0 NOT NULL, - CONSTRAINT location_ruid_idx UNIQUE (ruid), - CONSTRAINT location_connection_idx UNIQUE (server_id, connection_id) + CONSTRAINT location_ruid_idx UNIQUE (ruid) ); CREATE OR REPLACE TRIGGER location_tr @@ -36,6 +35,7 @@ BEGIN map2users('location'); END; / CREATE INDEX location_account_contact_idx ON location (username, domain, contact); CREATE INDEX location_expires_idx ON location (expires); +CREATE INDEX location_connection_idx ON location (server_id, connection_id); INSERT INTO version (table_name, table_version) values ('location','8'); diff --git a/utils/kamctl/postgres/usrloc-create.sql b/utils/kamctl/postgres/usrloc-create.sql index a8102e38b64..9a56326d7fd 100644 --- a/utils/kamctl/postgres/usrloc-create.sql +++ b/utils/kamctl/postgres/usrloc-create.sql @@ -22,12 +22,12 @@ CREATE TABLE location ( connection_id INTEGER DEFAULT 0 NOT NULL, keepalive INTEGER DEFAULT 0 NOT NULL, partition INTEGER DEFAULT 0 NOT NULL, - CONSTRAINT location_ruid_idx UNIQUE (ruid), - CONSTRAINT location_connection_idx UNIQUE (server_id, connection_id) + CONSTRAINT location_ruid_idx UNIQUE (ruid) ); CREATE INDEX location_account_contact_idx ON location (username, domain, contact); CREATE INDEX location_expires_idx ON location (expires); +CREATE INDEX location_connection_idx ON location (server_id, connection_id); INSERT INTO version (table_name, table_version) values ('location','8'); From 7423c33bfb56268bfa9cb3c03966c37c9a2d7d69 Mon Sep 17 00:00:00 2001 From: Daniel-Constantin Mierla Date: Thu, 24 Mar 2016 09:21:00 +0100 Subject: [PATCH 03/32] dispatcher: coherent indentation and whitespacing (cherry picked from commit 1d401e0a9b4c3010c32b0084ec6a218fc46e4f78) --- modules/dispatcher/dispatch.c | 20 ++++++++++---------- modules/dispatcher/dispatcher.c | 4 ++-- 2 files changed, 12 insertions(+), 12 deletions(-) diff --git a/modules/dispatcher/dispatch.c b/modules/dispatcher/dispatch.c index 6921aaed7e4..60c91219c55 100644 --- a/modules/dispatcher/dispatch.c +++ b/modules/dispatcher/dispatch.c @@ -305,7 +305,7 @@ int add_dest2list(int id, str uri, int flags, int priority, str *attrs, /* skip IPv6 references if IPv6 lookups are disabled */ if (default_core_cfg.dns_try_ipv6 == 0 && - puri.host.s[0] == '[' && puri.host.s[puri.host.len-1] == ']') { + puri.host.s[0] == '[' && puri.host.s[puri.host.len-1] == ']') { LM_DBG("skipping IPv6 record %.*s\n", puri.host.len, puri.host.s); return 0; } @@ -496,7 +496,7 @@ int dp_init_relative_weights(ds_set_t *dset) if(dset==NULL || dset->dlist==NULL) return -1; - + int rw_sum = 0; /* find the sum of relative weights*/ for(j=0; jnr; j++){ @@ -514,9 +514,9 @@ int dp_init_relative_weights(ds_set_t *dset) for(j=0; jnr; j++) { if( ds_skip_dst(dset->dlist[j].flags ) ) - continue; + continue; - int current_slice = dset->dlist[j].attrs.rweight*100/rw_sum; //truncate here; + int current_slice = dset->dlist[j].attrs.rweight*100/rw_sum; //truncate here; for(k=0; krwlist[t] = (unsigned int)j; @@ -525,7 +525,7 @@ int dp_init_relative_weights(ds_set_t *dset) } /* if the array was not completely filled (i.e., the sum of rweights is * less than 100 due to truncated), then use last address to fill the rest */ - unsigned int last_insert = t>0? dset->rwlist[t-1] : (unsigned int)(dset->nr-1); + unsigned int last_insert = t>0? dset->rwlist[t-1] : (unsigned int)(dset->nr-1); for(j=t; j<100; j++) dset->rwlist[j] = last_insert; @@ -1765,7 +1765,7 @@ static inline int ds_update_dst(struct sip_msg *msg, str *uri, return -1; } /* dst_uri changes, so it makes sense to re-use the current uri for - forking */ + * forking */ ruri_mark_new(); /* re-use uri for serial forking */ break; } @@ -2487,7 +2487,7 @@ static void ds_run_route(sip_msg_t *msg, str *uri, char *route) /** - recalculate relative states if some destination state was changed + * recalculate relative states if some destination state was changed */ int ds_reinit_rweight_on_state_change(int old_state, int new_state, ds_set_t *dset) { @@ -2495,7 +2495,7 @@ int ds_reinit_rweight_on_state_change(int old_state, int new_state, ds_set_t *ds LM_ERR("destination set is null\n"); return -1; } - if ( (!ds_skip_dst(old_state) && ds_skip_dst(new_state)) || + if ( (!ds_skip_dst(old_state) && ds_skip_dst(new_state)) || (ds_skip_dst(old_state) && !ds_skip_dst(new_state)) ) { dp_init_relative_weights(dset); @@ -2804,8 +2804,8 @@ static void ds_options_callback( struct cell *t, int type, { /* Set the according entry back to "Active" */ state = 0; - if (ds_probing_mode==DS_PROBE_ALL || - ((ds_probing_mode==DS_PROBE_ONLYFLAGGED) + if (ds_probing_mode==DS_PROBE_ALL || + ((ds_probing_mode==DS_PROBE_ONLYFLAGGED) && (ds_get_state(group, &uri) & DS_PROBING_DST))) state |= DS_PROBING_DST; diff --git a/modules/dispatcher/dispatcher.c b/modules/dispatcher/dispatcher.c index 51d1955bc74..2a0ddbc34ca 100644 --- a/modules/dispatcher/dispatcher.c +++ b/modules/dispatcher/dispatcher.c @@ -96,9 +96,9 @@ unsigned short sock_avp_type; pv_elem_t * hash_param_model = NULL; int probing_threshold = 1; /* number of failed requests, before a destination - is taken into probing */ + * is taken into probing */ int inactive_threshold = 1; /* number of replied requests, before a destination - is taken into back in active state */ + * is taken into back in active state */ str ds_ping_method = str_init("OPTIONS"); str ds_ping_from = str_init("sip:dispatcher@localhost"); static int ds_ping_interval = 0; From b53bf975bddf16424d7b6416276371e12cf590f4 Mon Sep 17 00:00:00 2001 From: Daniel-Constantin Mierla Date: Sat, 26 Mar 2016 08:44:16 +0100 Subject: [PATCH 04/32] ndb_redis: use pkg-config for compile flags (cherry picked from commit 57bcad1b336e7aae5c0933a83ac4ab16f6893896) --- modules/ndb_redis/Makefile | 21 +++++++++++++++++++-- 1 file changed, 19 insertions(+), 2 deletions(-) diff --git a/modules/ndb_redis/Makefile b/modules/ndb_redis/Makefile index 6e2d86ba8f2..524647d5dfd 100644 --- a/modules/ndb_redis/Makefile +++ b/modules/ndb_redis/Makefile @@ -5,8 +5,25 @@ include ../../Makefile.defs auto_gen= NAME=ndb_redis.so -DEFS += -I/usr/local/include -LIBS = -lhiredis +ifeq ($(CROSS_COMPILE),) +HIREDIS_BUILDER = $(shell \ + if pkg-config --exists libcre; then \ + echo 'pkg-config hiredis'; \ + else \ + which pcre-config; \ + fi) +endif + +ifeq ($(HIREDIS_BUILDER),) + HIREDISDEFS=-I$(LOCALBASE)/include + HIREDISLIBS=-L$(LOCALBASE)/lib -lhiredis +else + HIREDISDEFS = $(shell $(HIREDIS_BUILDER) --cflags) + HIREDISLIBS = $(shell $(HIREDIS_BUILDER) --libs) +endif + +DEFS+=$(HIREDISDEFS) +LIBS=$(HIREDISLIBS) DEFS+=-DKAMAILIO_MOD_INTERFACE From b04d257acd0dddd87051266493a81b93210de3bc Mon Sep 17 00:00:00 2001 From: Daniel-Constantin Mierla Date: Sat, 26 Mar 2016 11:05:26 +0100 Subject: [PATCH 05/32] ndb_redis: fix for broken output of pkg-config for hiredis (cherry picked from commit 4a40dd39cec713c569dc3480c905d808026aad39) --- modules/ndb_redis/Makefile | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-) diff --git a/modules/ndb_redis/Makefile b/modules/ndb_redis/Makefile index 524647d5dfd..5874c317ce2 100644 --- a/modules/ndb_redis/Makefile +++ b/modules/ndb_redis/Makefile @@ -7,10 +7,8 @@ NAME=ndb_redis.so ifeq ($(CROSS_COMPILE),) HIREDIS_BUILDER = $(shell \ - if pkg-config --exists libcre; then \ + if pkg-config --exists hiredis; then \ echo 'pkg-config hiredis'; \ - else \ - which pcre-config; \ fi) endif @@ -20,6 +18,12 @@ ifeq ($(HIREDIS_BUILDER),) else HIREDISDEFS = $(shell $(HIREDIS_BUILDER) --cflags) HIREDISLIBS = $(shell $(HIREDIS_BUILDER) --libs) + +ifeq ($(HIREDISLIBS),-L -lhiredis) + HIREDISDEFS = $(shell $(HIREDIS_BUILDER) --cflags) /opt/local/include + HIREDISLIBS = -L/opt/local/lib -lhiredis +endif + endif DEFS+=$(HIREDISDEFS) From a45f580174ee5b21746e5e0172c55fccb421d25d Mon Sep 17 00:00:00 2001 From: Daniel-Constantin Mierla Date: Sat, 26 Mar 2016 10:23:02 +0100 Subject: [PATCH 06/32] cnxcc: use pkg-config for hiredis lib compile flags (cherry picked from commit 162ccdaeeb6bff185f49b3dc2e2b9b43687ec0fc) --- modules/cnxcc/Makefile | 23 +++++++++++++++++++++-- 1 file changed, 21 insertions(+), 2 deletions(-) diff --git a/modules/cnxcc/Makefile b/modules/cnxcc/Makefile index e5c69df15c9..af6979e8201 100644 --- a/modules/cnxcc/Makefile +++ b/modules/cnxcc/Makefile @@ -1,14 +1,33 @@ # # cnxcc module makefile # -# +# # WARNING: do not run this directly, it should be run by the master Makefile include ../../Makefile.defs auto_gen= NAME=cnxcc.so -LIBS=-lhiredis -levent +ifeq ($(CROSS_COMPILE),) +HIREDIS_BUILDER = $(shell \ + if pkg-config --exists libcre; then \ + echo 'pkg-config hiredis'; \ + else \ + which pcre-config; \ + fi) +endif + +ifeq ($(HIREDIS_BUILDER),) + HIREDISDEFS=-I$(LOCALBASE)/include + HIREDISLIBS=-L$(LOCALBASE)/lib -lhiredis +else + HIREDISDEFS = $(shell $(HIREDIS_BUILDER) --cflags) + HIREDISLIBS = $(shell $(HIREDIS_BUILDER) --libs) +endif + +DEFS+=$(HIREDISDEFS) +LIBS=$(HIREDISLIBS) -levent + DEFS+=-DOPENSER_MOD_INTERFACE SERLIBPATH=../../lib SER_LIBS+=$(SERLIBPATH)/kmi/kmi From 4080d31080b5ad74504715b404e0829be090c731 Mon Sep 17 00:00:00 2001 From: Daniel-Constantin Mierla Date: Sat, 26 Mar 2016 11:11:25 +0100 Subject: [PATCH 07/32] cnxcc: use pkg-config for libevent compile flags (cherry picked from commit fa0d3267890e77a5184490d11f76fe4cb400e2df) --- modules/cnxcc/Makefile | 29 ++++++++++++++++++++++++----- 1 file changed, 24 insertions(+), 5 deletions(-) diff --git a/modules/cnxcc/Makefile b/modules/cnxcc/Makefile index af6979e8201..7748a3740fb 100644 --- a/modules/cnxcc/Makefile +++ b/modules/cnxcc/Makefile @@ -10,10 +10,8 @@ NAME=cnxcc.so ifeq ($(CROSS_COMPILE),) HIREDIS_BUILDER = $(shell \ - if pkg-config --exists libcre; then \ + if pkg-config --exists hiredis; then \ echo 'pkg-config hiredis'; \ - else \ - which pcre-config; \ fi) endif @@ -23,10 +21,31 @@ ifeq ($(HIREDIS_BUILDER),) else HIREDISDEFS = $(shell $(HIREDIS_BUILDER) --cflags) HIREDISLIBS = $(shell $(HIREDIS_BUILDER) --libs) + +ifeq ($(HIREDISLIBS),-L -lhiredis) + HIREDISDEFS = $(shell $(HIREDIS_BUILDER) --cflags) /opt/local/include + HIREDISLIBS = -L/opt/local/lib -lhiredis +endif + +endif + +ifeq ($(CROSS_COMPILE),) +LEVENT_BUILDER = $(shell \ + if pkg-config --exists libevent; then \ + echo 'pkg-config libevent'; \ + fi) +endif + +ifeq ($(LEVENT_BUILDER),) + LEVENTDEFS= + LEVENTLIBS=-L$(LOCALBASE)/lib -levent +else + LEVENTDEFS = $(shell $(LEVENT_BUILDER) --cflags) + LEVENTLIBS = $(shell $(LEVENT_BUILDER) --libs) endif -DEFS+=$(HIREDISDEFS) -LIBS=$(HIREDISLIBS) -levent +DEFS+=$(HIREDISDEFS) $(LEVENTDEFS) +LIBS=$(HIREDISLIBS) $(LEVENTLIBS) DEFS+=-DOPENSER_MOD_INTERFACE SERLIBPATH=../../lib From 410bdba67ec77e87d2ff53f429bc260c03b10317 Mon Sep 17 00:00:00 2001 From: Daniel-Constantin Mierla Date: Sat, 26 Mar 2016 11:18:36 +0100 Subject: [PATCH 08/32] crypto: safety check for memory allocation and free on error cases (cherry picked from commit 181c3cfa266ec5897cc2fdd889d90928f90fcbb8) --- modules/crypto/crypto_mod.c | 14 ++++++++++++++ 1 file changed, 14 insertions(+) diff --git a/modules/crypto/crypto_mod.c b/modules/crypto/crypto_mod.c index 2517b60a47e..fe16b6daa1d 100644 --- a/modules/crypto/crypto_mod.c +++ b/modules/crypto/crypto_mod.c @@ -360,9 +360,14 @@ unsigned char *crypto_aes_encrypt(EVP_CIPHER_CTX *e, unsigned char *plaintext, int c_len = *len + AES_BLOCK_SIZE - 1, f_len = 0; unsigned char *ciphertext = (unsigned char *)malloc(c_len); + if(ciphertext == NULL) { + LM_ERR("no more system memory\n"); + return NULL; + } /* allows reusing of 'e' for multiple encryption cycles */ if(!EVP_EncryptInit_ex(e, NULL, NULL, NULL, NULL)){ LM_ERR("failure in EVP_EncryptInit_ex \n"); + free(ciphertext); return NULL; } @@ -370,12 +375,14 @@ unsigned char *crypto_aes_encrypt(EVP_CIPHER_CTX *e, unsigned char *plaintext, * generated, *len is the size of plaintext in bytes */ if(!EVP_EncryptUpdate(e, ciphertext, &c_len, plaintext, *len)){ LM_ERR("failure in EVP_EncryptUpdate \n"); + free(ciphertext); return NULL; } /* update ciphertext with the final remaining bytes */ if(!EVP_EncryptFinal_ex(e, ciphertext+c_len, &f_len)){ LM_ERR("failure in EVP_EncryptFinal_ex \n"); + free(ciphertext); return NULL; } @@ -393,18 +400,25 @@ unsigned char *crypto_aes_decrypt(EVP_CIPHER_CTX *e, unsigned char *ciphertext, int p_len = *len, f_len = 0; unsigned char *plaintext = (unsigned char *)malloc(p_len); + if(plaintext==NULL) { + LM_ERR("no more system memory\n"); + return NULL; + } if(!EVP_DecryptInit_ex(e, NULL, NULL, NULL, NULL)){ LM_ERR("failure in EVP_DecryptInit_ex \n"); + free(plaintext); return NULL; } if(!EVP_DecryptUpdate(e, plaintext, &p_len, ciphertext, *len)){ LM_ERR("failure in EVP_DecryptUpdate\n"); + free(plaintext); return NULL; } if(!EVP_DecryptFinal_ex(e, plaintext+p_len, &f_len)){ LM_ERR("failure in EVP_DecryptFinal_ex\n"); + free(plaintext); return NULL; } From 6a65b9ae0432491a1bcf540643f7b90cbc0c3ad1 Mon Sep 17 00:00:00 2001 From: Daniel-Constantin Mierla Date: Sat, 26 Mar 2016 11:22:32 +0100 Subject: [PATCH 09/32] dispatcher: proper check for ds active ping variable (cherry picked from commit cafb1522b2c27aae404d97fe242324423ccdb99b) --- modules/dispatcher/dispatch.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/modules/dispatcher/dispatch.c b/modules/dispatcher/dispatch.c index 60c91219c55..d734e9f57d5 100644 --- a/modules/dispatcher/dispatch.c +++ b/modules/dispatcher/dispatch.c @@ -113,7 +113,7 @@ int ds_ping_active_init(void) */ int ds_ping_active_get(void) { - if(_ds_ping_active!=NULL) + if(_ds_ping_active==NULL) return -1; return *_ds_ping_active; } @@ -123,7 +123,7 @@ int ds_ping_active_get(void) */ int ds_ping_active_set(int v) { - if(_ds_ping_active!=NULL) + if(_ds_ping_active==NULL) return -1; *_ds_ping_active = v; return 0; From b28b3d27597b898add46051f24120f833b035d3d Mon Sep 17 00:00:00 2001 From: Daniel-Constantin Mierla Date: Sat, 26 Mar 2016 11:26:29 +0100 Subject: [PATCH 10/32] ndb_redis: safety check for log message parameters (cherry picked from commit 0a51e8c941b1c916137eb3e57fa7db86ecb9a1f8) --- modules/ndb_redis/redis_client.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/modules/ndb_redis/redis_client.c b/modules/ndb_redis/redis_client.c index 02aa7b866be..903284e5b20 100644 --- a/modules/ndb_redis/redis_client.c +++ b/modules/ndb_redis/redis_client.c @@ -429,7 +429,8 @@ void * redisc_exec_argv(redisc_server_t *rsrv, int argc, const char **argv, cons if(rsrv==NULL || rsrv->ctxRedis==NULL) { LM_ERR("no redis context found for server %.*s\n", - rsrv->sname->len, rsrv->sname->s); + (rsrv)?rsrv->sname->len:0, + (rsrv)?rsrv->sname->s:""); return NULL; } if(argc<=0) From ed9ad742f9e9cd0d6e75dc788923addf9984ce3d Mon Sep 17 00:00:00 2001 From: Daniel-Constantin Mierla Date: Sat, 26 Mar 2016 12:58:33 +0100 Subject: [PATCH 11/32] lib/trie: init variable to get rid of compile warnings (cherry picked from commit 5075cef8230202138bf08c402797d9dffcb8971d) --- lib/trie/dtrie.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/lib/trie/dtrie.c b/lib/trie/dtrie.c index f0b26554930..28e7e7af198 100644 --- a/lib/trie/dtrie.c +++ b/lib/trie/dtrie.c @@ -15,8 +15,8 @@ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ @@ -245,7 +245,7 @@ void **dtrie_longest_match(struct dtrie_node_t *root, const char *number, digit = number[i]; if (digit>127) return ret; } - + if (node->child[digit] == NULL) return ret; node = node->child[digit]; i++; @@ -262,7 +262,7 @@ void **dtrie_longest_match(struct dtrie_node_t *root, const char *number, void **dtrie_contains(struct dtrie_node_t *root, const char *number, const unsigned int numberlen, const unsigned int branches) { - int nmatch; + int nmatch = 0; void **ret; ret = dtrie_longest_match(root, number, numberlen, &nmatch, branches); From fd20bff1e420a93be588b2c0dd4189f6f7e8ea0b Mon Sep 17 00:00:00 2001 From: Daniel-Constantin Mierla Date: Sat, 26 Mar 2016 13:01:01 +0100 Subject: [PATCH 12/32] seas: init variable to get rid of compile warning (cherry picked from commit 3a25e489d0ab8d55d4011ccf62de4f3d8d08b028) --- modules/seas/encode_msg.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/modules/seas/encode_msg.c b/modules/seas/encode_msg.c index e56b5fba893..8f84ca62a84 100644 --- a/modules/seas/encode_msg.c +++ b/modules/seas/encode_msg.c @@ -148,7 +148,7 @@ char get_header_code(struct hdr_field *hf) */ int encode_msg(struct sip_msg *msg,char *payload,int len) { - int i,j,k,u,request; + int i,j=0,k,u,request; unsigned short int h; struct hdr_field* hf; struct msg_start* ms; From b667c768dd87575873cec872abdf3caaf20c9ffc Mon Sep 17 00:00:00 2001 From: Daniel-Constantin Mierla Date: Sat, 26 Mar 2016 13:09:53 +0100 Subject: [PATCH 13/32] usrloc: if no location record loaded from db, then no attrs to look up (cherry picked from commit bedd6f4df9d2b5600bed5e31052bc49f8b18382f) --- modules/usrloc/udomain.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/modules/usrloc/udomain.c b/modules/usrloc/udomain.c index d57f212ca83..58fc9a31d02 100644 --- a/modules/usrloc/udomain.c +++ b/modules/usrloc/udomain.c @@ -697,6 +697,8 @@ urecord_t* db_load_urecord(db1_con_t* _c, udomain_t* _d, str *_aor) goto done; } + if(r==0) goto done; + for (c = r->contacts; c != NULL; c = c->next) { vals[0].val.str_val.s = c->ruid.s; vals[0].val.str_val.len = c->ruid.len; From f229c60396fa8590bbbb2d66cb8006dd31ab6521 Mon Sep 17 00:00:00 2001 From: Daniel-Constantin Mierla Date: Sat, 26 Mar 2016 22:29:27 +0100 Subject: [PATCH 14/32] http_client: check first if pointer is not exceeding limit - then test its value not to be null char (cherry picked from commit 47a776efcd3d5c2ffafdd780fa169edc85e436d2) --- modules/http_client/curlcon.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/modules/http_client/curlcon.c b/modules/http_client/curlcon.c index aa618602d38..b38a352f7a7 100644 --- a/modules/http_client/curlcon.c +++ b/modules/http_client/curlcon.c @@ -575,7 +575,7 @@ int fixup_raw_http_client_conn_list(void) schema.s = raw_cc->url.s; pos = schema.s; end = raw_cc->url.s + raw_cc->url.len; - while (pos != '\0' && (pos < end)) + while ((pos < end) && (*pos != '\0')) { if (*pos == ':') break; pos++; From 745e5dd42d032f0343c88d033e3b924fa79cd5ae Mon Sep 17 00:00:00 2001 From: Daniel-Constantin Mierla Date: Sun, 27 Mar 2016 11:38:17 +0200 Subject: [PATCH 15/32] presence: remove jumping to error from error in update_presentity() - coherent indentation (cherry picked from commit 07dbe3697bcad18f5766fc0d71a7fc48ff8a26d0) --- modules/presence/presentity.c | 137 +++++++++++++++++----------------- 1 file changed, 67 insertions(+), 70 deletions(-) diff --git a/modules/presence/presentity.c b/modules/presence/presentity.c index 1c385b53e0a..71adc362ff6 100644 --- a/modules/presence/presentity.c +++ b/modules/presence/presentity.c @@ -13,8 +13,8 @@ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA * */ @@ -22,7 +22,7 @@ /*! * \file * \brief Kamailio presence module :: Presentity handling - * \ingroup presence + * \ingroup presence */ @@ -39,7 +39,7 @@ #include "../../str.h" #include "../../data_lump_rpl.h" #include "presentity.h" -#include "presence.h" +#include "presence.h" #include "notify.h" #include "publish.h" #include "hash.h" @@ -101,9 +101,9 @@ int publ_send200ok(struct sip_msg *msg, int lexpire, str etag) if (msg == NULL) return 0; - LM_DBG("send 200OK reply\n"); + LM_DBG("send 200OK reply\n"); LM_DBG("etag= %s - len= %d\n", etag.s, etag.len); - + hdr_append.s = buf; hdr_append.s[0]='\0'; hdr_append.len = snprintf(hdr_append.s, buf_len, "Expires: %d\r\n", @@ -119,7 +119,7 @@ int publ_send200ok(struct sip_msg *msg, int lexpire, str etag) goto error; } hdr_append.s[hdr_append.len]= '\0'; - + if (add_lump_rpl( msg, hdr_append.s, hdr_append.len, LUMP_RPL_HDR)==0 ) { LM_ERR("unable to add lump_rl\n"); @@ -192,17 +192,17 @@ unsigned int pres_get_priority(void) /** * create new presentity record */ -presentity_t* new_presentity( str* domain,str* user,int expires, +presentity_t* new_presentity( str* domain,str* user,int expires, pres_ev_t* event, str* etag, str* sender) { presentity_t *presentity= NULL; int size, init_len; - + /* allocating memory for presentity */ size = sizeof(presentity_t)+ domain->len+ user->len+ etag->len +1; if(sender) size+= sizeof(str)+ sender->len* sizeof(char); - + init_len= size; presentity = (presentity_t*)pkg_malloc(size); @@ -216,8 +216,8 @@ presentity_t* new_presentity( str* domain,str* user,int expires, presentity->domain.s = (char*)presentity+ size; strncpy(presentity->domain.s, domain->s, domain->len); presentity->domain.len = domain->len; - size+= domain->len; - + size+= domain->len; + presentity->user.s = (char*)presentity+size; strncpy(presentity->user.s, user->s, user->len); presentity->user.len = user->len; @@ -229,7 +229,7 @@ presentity_t* new_presentity( str* domain,str* user,int expires, presentity->etag.len = etag->len; size+= etag->len+1; - + if(sender) { presentity->sender= (str*)((char*)presentity+ size); @@ -250,7 +250,7 @@ presentity_t* new_presentity( str* domain,str* user,int expires, presentity->received_time= (int)time(NULL); presentity->priority = pres_get_priority(); return presentity; - + error: if(presentity) pkg_free(presentity); @@ -328,7 +328,7 @@ int update_presentity(struct sip_msg* msg, presentity_t* presentity, str* body, goto error; } } - + if(uandd_to_uri(presentity->user, presentity->domain, &pres_uri)< 0) { LM_ERR("constructing uri from user and domain\n"); @@ -342,7 +342,7 @@ int update_presentity(struct sip_msg* msg, presentity_t* presentity, str* body, query_vals[n_query_cols].nul = 0; query_vals[n_query_cols].val.str_val = presentity->domain; n_query_cols++; - + query_cols[n_query_cols] = &str_username_col; query_ops[n_query_cols] = OP_EQ; query_vals[n_query_cols].type = DB1_STR; @@ -367,7 +367,7 @@ int update_presentity(struct sip_msg* msg, presentity_t* presentity, str* body, result_cols[rez_body_col= n_result_cols++] = &str_body_col; result_cols[rez_sender_col= n_result_cols++] = &str_sender_col; - if(new_t) + if(new_t) { /* insert new record in hash_table */ @@ -377,8 +377,8 @@ int update_presentity(struct sip_msg* msg, presentity_t* presentity, str* body, LM_ERR("inserting record in hash table\n"); goto error; } - - /* insert new record into database */ + + /* insert new record into database */ query_cols[n_query_cols] = &str_sender_col; query_vals[n_query_cols].type = DB1_STR; query_vals[n_query_cols].nul = 0; @@ -397,7 +397,7 @@ int update_presentity(struct sip_msg* msg, presentity_t* presentity, str* body, query_vals[n_query_cols].nul = 0; query_vals[n_query_cols].val.str_val = *body; n_query_cols++; - + query_cols[n_query_cols] = &str_received_time_col; query_vals[n_query_cols].type = DB1_INT; query_vals[n_query_cols].nul = 0; @@ -409,7 +409,7 @@ int update_presentity(struct sip_msg* msg, presentity_t* presentity, str* body, query_vals[n_query_cols].nul = 0; query_vals[n_query_cols].val.int_val = presentity->priority; n_query_cols++; - + if (presentity->expires != -1) { /* A real PUBLISH */ @@ -419,8 +419,8 @@ int update_presentity(struct sip_msg* msg, presentity_t* presentity, str* body, query_vals[n_query_cols].val.int_val = presentity->expires+ (int)time(NULL); n_query_cols++; - - if (pa_dbf.use_table(pa_db, &presentity_table) < 0) + + if (pa_dbf.use_table(pa_db, &presentity_table) < 0) { LM_ERR("unsuccessful use_table\n"); goto error; @@ -436,8 +436,8 @@ int update_presentity(struct sip_msg* msg, presentity_t* presentity, str* body, } LM_DBG("inserting %d cols into table\n",n_query_cols); - - if (pa_dbf.insert(pa_db, query_cols, query_vals, n_query_cols) < 0) + + if (pa_dbf.insert(pa_db, query_cols, query_vals, n_query_cols) < 0) { LM_ERR("inserting new record in database\n"); goto error; @@ -451,8 +451,8 @@ int update_presentity(struct sip_msg* msg, presentity_t* presentity, str* body, query_vals[n_query_cols].nul = 0; query_vals[n_query_cols].val.int_val = -1; n_query_cols++; - - if (pa_dbf.use_table(pa_db, &presentity_table) < 0) + + if (pa_dbf.use_table(pa_db, &presentity_table) < 0) { LM_ERR("unsuccessful use_table\n"); goto error; @@ -474,7 +474,7 @@ int update_presentity(struct sip_msg* msg, presentity_t* presentity, str* body, } - if (pa_dbf.replace(pa_db, query_cols, query_vals, n_query_cols, 4, 0) < 0) + if (pa_dbf.replace(pa_db, query_cols, query_vals, n_query_cols, 4, 0) < 0) { LM_ERR("replacing record in database\n"); goto error; @@ -490,9 +490,9 @@ int update_presentity(struct sip_msg* msg, presentity_t* presentity, str* body, goto send_notify; } else - { + { - if (pa_dbf.use_table(pa_db, &presentity_table) < 0) + if (pa_dbf.use_table(pa_db, &presentity_table) < 0) { LM_ERR("unsuccessful sql use table\n"); goto error; @@ -511,7 +511,7 @@ int update_presentity(struct sip_msg* msg, presentity_t* presentity, str* body, { if (pa_dbf.query (pa_db, query_cols, query_ops, query_vals, - result_cols, n_query_cols, n_result_cols, 0, &result) < 0) + result_cols, n_query_cols, n_result_cols, 0, &result) < 0) { LM_ERR("unsuccessful sql query\n"); goto error; @@ -521,7 +521,7 @@ int update_presentity(struct sip_msg* msg, presentity_t* presentity, str* body, if (!(result->n > 0)) goto send_412; - + db_record_exists= 1; /* analize if previous body has a dialog */ row = &result->rows[0]; @@ -553,23 +553,23 @@ int update_presentity(struct sip_msg* msg, presentity_t* presentity, str* body, LM_DBG("old_sender = %.*s\n", sender.len, sender.s ); if(presentity->sender) { - if(!(presentity->sender->len == sender.len && - presence_sip_uri_match(presentity->sender, &sender)== 0)) - bla_update_publish= 0; + if(!(presentity->sender->len == sender.len && + presence_sip_uri_match(presentity->sender, &sender)== 0)) + bla_update_publish= 0; } after_dialog_check: pa_dbf.free_result(pa_db, result); result = NULL; - + } - if(presentity->expires <= 0) + if(presentity->expires <= 0) { if (!db_record_exists) { if (pa_dbf.query (pa_db, query_cols, query_ops, query_vals, - result_cols, n_query_cols, n_result_cols, 0, &result) < 0) + result_cols, n_query_cols, n_result_cols, 0, &result) < 0) { LM_ERR("unsuccessful sql query\n"); goto error; @@ -658,7 +658,7 @@ int update_presentity(struct sip_msg* msg, presentity_t* presentity, str* body, } if(presentity->event->etag_not_new== 0) - { + { /* generate another etag */ unsigned int publ_nr; str str_publ_nr= {0, 0}; @@ -673,7 +673,7 @@ int update_presentity(struct sip_msg* msg, presentity_t* presentity, str* body, { LM_ERR("wrong etag\n"); goto error; - } + } str_publ_nr.s= dot+1; str_publ_nr.len--; @@ -689,7 +689,7 @@ int update_presentity(struct sip_msg* msg, presentity_t* presentity, str* body, goto error; } etag.len=(strlen(etag.s)); - + cur_etag= etag; update_keys[n_update_cols] = &str_etag_col; @@ -701,7 +701,7 @@ int update_presentity(struct sip_msg* msg, presentity_t* presentity, str* body, } else cur_etag= presentity->etag; - + update_keys[n_update_cols] = &str_expires_col; update_vals[n_update_cols].type = DB1_INT; update_vals[n_update_cols].nul = 0; @@ -730,7 +730,7 @@ int update_presentity(struct sip_msg* msg, presentity_t* presentity, str* body, n_update_cols++; /* updated stored sphere */ - if(sphere_enable && + if(sphere_enable && presentity->event->evp->type== EVENT_PRESENCE) { if( publ_cache_enabled && @@ -741,8 +741,7 @@ int update_presentity(struct sip_msg* msg, presentity_t* presentity, str* body, } } } - - + if( presentity->sender) { update_keys[n_update_cols] = &str_sender_col; @@ -756,14 +755,14 @@ int update_presentity(struct sip_msg* msg, presentity_t* presentity, str* body, if (!pa_dbf.affected_rows && !db_record_exists) { if (pa_dbf.query (pa_db, query_cols, query_ops, query_vals, - result_cols, n_query_cols, n_result_cols, 0, &result) < 0) + result_cols, n_query_cols, n_result_cols, 0, &result) < 0) { LM_ERR("unsuccessful sql query\n"); goto error; } if(result== NULL) goto error; - + if (!(result->n > 0)) goto send_412; @@ -773,7 +772,7 @@ int update_presentity(struct sip_msg* msg, presentity_t* presentity, str* body, } if( pa_dbf.update( pa_db,query_cols, query_ops, query_vals, - update_keys, update_vals, n_query_cols, n_update_cols )<0) + update_keys, update_vals, n_query_cols, n_update_cols )<0) { LM_ERR("updating published info in database\n"); goto error; @@ -871,21 +870,19 @@ int update_presentity(struct sip_msg* msg, presentity_t* presentity, str* body, pa_dbf.free_result(pa_db, result); if(etag.s) pkg_free(etag.s); - if(rules_doc) - { + if(rules_doc) { if(rules_doc->s) pkg_free(rules_doc->s); pkg_free(rules_doc); } - if(pres_uri.s) + if(pres_uri.s) { pkg_free(pres_uri.s); + pres_uri.s = NULL; + } - if (pa_dbf.abort_transaction) - { - if (pa_dbf.abort_transaction(pa_db) < 0) - { + if (pa_dbf.abort_transaction) { + if (pa_dbf.abort_transaction(pa_db) < 0) { LM_ERR("in abort_transaction\n"); - goto error; } } @@ -894,7 +891,7 @@ int update_presentity(struct sip_msg* msg, presentity_t* presentity, str* body, int pres_htable_restore(void) { - /* query all records from presentity table and insert records + /* query all records from presentity table and insert records * in presentity table */ db_key_t result_cols[6]; db1_res_t *result= NULL; @@ -946,7 +943,7 @@ int pres_htable_restore(void) if(row_vals[expires_col].val.int_val< (int)time(NULL)) continue; - + sphere= NULL; user.s= (char*)row_vals[user_col].val.string_val; user.len= strlen(user.s); @@ -970,7 +967,7 @@ int pres_htable_restore(void) goto error; } /* insert in hash_table*/ - + if(sphere_enable && event== EVENT_PRESENCE ) { body.s= (char*)row_vals[body_col].val.string_val; @@ -1000,7 +997,7 @@ int pres_htable_restore(void) error: if(result) pa_dbf.free_result(pa_db, result); - return -1; + return -1; } char* extract_sphere(str body) @@ -1010,7 +1007,7 @@ char* extract_sphere(str body) xmlDocPtr doc= NULL; xmlNodePtr node; char* cont, *sphere= NULL; - + doc= xmlParseMemory(body.s, body.len); if(doc== NULL) @@ -1020,7 +1017,7 @@ char* extract_sphere(str body) } node= xmlNodeGetNodeByName(doc->children, "sphere", "rpid"); - + if(node== NULL) node= xmlNodeGetNodeByName(doc->children, "sphere", "r"); @@ -1144,8 +1141,8 @@ char* get_sphere(str* pres_uri) n_query_cols++; result_cols[n_result_cols++] = &str_body_col; - - if (pa_dbf.use_table(pa_db, &presentity_table) < 0) + + if (pa_dbf.use_table(pa_db, &presentity_table) < 0) { LM_ERR("in use_table\n"); return NULL; @@ -1157,14 +1154,14 @@ char* get_sphere(str* pres_uri) query_str = str_received_time_col; } if (pa_dbf.query (pa_db, query_cols, 0, query_vals, - result_cols, n_query_cols, n_result_cols, &query_str , &result) < 0) + result_cols, n_query_cols, n_result_cols, &query_str , &result) < 0) { LM_ERR("failed to query %.*s table\n", presentity_table.len, presentity_table.s); if(result) pa_dbf.free_result(pa_db, result); return NULL; } - + if(result== NULL) return NULL; @@ -1190,7 +1187,7 @@ char* get_sphere(str* pres_uri) LM_ERR("Empty notify body record\n"); goto error; } - + sphere= extract_sphere(body); pa_dbf.free_result(pa_db, result); @@ -1290,7 +1287,7 @@ int mark_presentity_for_delete(presentity_t *pres) if (RES_ROW_N(result) > 1) { /* More that one is prevented by DB constraint - but handle - it anyway */ + * it anyway */ LM_ERR("Found %d presentities - expected 1\n", RES_ROW_N(result)); if (delete_presentity(pres) < 0) @@ -1300,7 +1297,7 @@ int mark_presentity_for_delete(presentity_t *pres) } /* Want the calling function to continue properly so do not - return an error */ + * return an error */ goto done; } @@ -1341,7 +1338,7 @@ int mark_presentity_for_delete(presentity_t *pres) n_update_cols++; if (pa_dbf.update(pa_db, query_cols, 0, query_vals, update_cols, - update_vals, n_query_cols, n_update_cols) < 0) + update_vals, n_query_cols, n_update_cols) < 0) { LM_ERR("unsuccessful sql update operation"); goto error; From dec9de968e5894fba808e01614a29655ce375141 Mon Sep 17 00:00:00 2001 From: Daniel-Constantin Mierla Date: Sun, 27 Mar 2016 11:39:09 +0200 Subject: [PATCH 16/32] core: mem - export pkg api even when using system malloc (cherry picked from commit 33fe5e38d2eefc2244eccb6279c082a789ed0307) --- Makefile.defs | 1 - mem/pkg.h | 16 +++++++++------- 2 files changed, 9 insertions(+), 8 deletions(-) diff --git a/Makefile.defs b/Makefile.defs index 135dd4f850e..65e7665fbed 100644 --- a/Makefile.defs +++ b/Makefile.defs @@ -626,7 +626,6 @@ C_DEFS= $(extra_defs) \ -DSER_VER=$(SER_VER) \ -DCFG_DIR='"$(cfg_target)"'\ -DRUN_DIR='"$(run_target)"'\ - -DPKG_MALLOC \ -DSHM_MEM -DSHM_MMAP \ -DDNS_IP_HACK \ -DUSE_MCAST \ diff --git a/mem/pkg.h b/mem/pkg.h index 82e430a0110..eb07bd2de92 100644 --- a/mem/pkg.h +++ b/mem/pkg.h @@ -20,12 +20,17 @@ #ifndef _sr_pkg_h_ #define _sr_pkg_h_ -#ifdef PKG_MALLOC - #include "memapi.h" extern sr_pkg_api_t _pkg_root; +int pkg_init_api(sr_pkg_api_t *ap); +int pkg_init_manager(char *name); +void pkg_destroy_manager(void); +void pkg_print_manager(void); + +#ifdef PKG_MALLOC + #ifdef DBG_SR_MEMORY # define pkg_malloc(s) _pkg_root.xmalloc(_pkg_root.mem_block, (s), _SRC_LOC_, \ _SRC_FUNCTION_, _SRC_LINE_, _SRC_MODULE_) @@ -46,11 +51,6 @@ extern sr_pkg_api_t _pkg_root; # define pkg_mod_get_stats(x) _pkg_root.xstats(_pkg_root.mem_block, x) # define pkg_mod_free_stats(x) _pkg_root.xfstats(x) -int pkg_init_api(sr_pkg_api_t *ap); -int pkg_init_manager(char *name); -void pkg_destroy_manager(void); -void pkg_print_manager(void); - #else /*PKG_MALLOC*/ /* use system allocator */ # include @@ -74,6 +74,8 @@ void pkg_print_manager(void); # define pkg_info(mi) do{ memset((mi),0, sizeof(*(mi))); } while(0) # define pkg_available() 0 # define pkg_sums() do{}while(0) +# define pkg_mod_get_stats(x) do{}while(0) +# define pkg_mod_free_stats(x) do{}while(0) #endif /*PKG_MALLOC*/ #endif From 1a1f3606bde2a4e45ade6212a440e5289de5af91 Mon Sep 17 00:00:00 2001 From: Daniel-Constantin Mierla Date: Sun, 27 Mar 2016 11:48:33 +0200 Subject: [PATCH 17/32] p_usrloc: free allocated items in case of no more memory during domain add (cherry picked from commit b27384a0a7c6567a9ecebab3f987079ad0ff7366) --- modules/p_usrloc/dlist.c | 15 +++++++++------ 1 file changed, 9 insertions(+), 6 deletions(-) diff --git a/modules/p_usrloc/dlist.c b/modules/p_usrloc/dlist.c index 5c16508f6a1..75914f50d1a 100644 --- a/modules/p_usrloc/dlist.c +++ b/modules/p_usrloc/dlist.c @@ -52,7 +52,7 @@ static inline struct domain_list_item * find_dlist (str *name) { for (item = domain_list; item != NULL; item = item->next) { if (item->name.len == name->len - && memcmp (item->name.s, name->s, name->len) == 0) { + && memcmp (item->name.s, name->s, name->len) == 0) { return item; } } @@ -64,16 +64,17 @@ static inline struct domain_list_item * find_dlist (str *name) { static inline struct domain_list_item * add_to_dlist (str *name, int type) { struct domain_list_item *item; - int i; + int i; item = (struct domain_list_item *) - pkg_malloc (sizeof (struct domain_list_item)); + pkg_malloc (sizeof (struct domain_list_item)); if (item == NULL) { - LM_ERR("Out of shared memory.\n"); + LM_ERR("Out of pkg memory.\n"); return NULL; } item->name.s = (char *) pkg_malloc (name->len + 1); if (item->name.s == NULL) { - LM_ERR("Out of shared memory.\n"); + LM_ERR("Out of pkg memory (1).\n"); + pkg_free(item); return NULL; } memcpy (item->name.s, name->s, name->len); @@ -86,7 +87,9 @@ static inline struct domain_list_item * add_to_dlist (str *name, int type) { item->domain.table = (hslot_t*)pkg_malloc(sizeof(hslot_t) * ul_hash_size); if (!item->domain.table) { - LM_ERR("no memory left 2\n"); + LM_ERR("Out of pkg memory (2)\n"); + pkg_free(item->name.s); + pkg_free(item); return NULL; } From 85a5b41599e9a8a27c10acdc17438b0571e5171d Mon Sep 17 00:00:00 2001 From: Daniel-Constantin Mierla Date: Sun, 27 Mar 2016 12:04:47 +0200 Subject: [PATCH 18/32] tm: coherent indentation - removed historical top comments (cherry picked from commit 5d903fd40a9e89d601be25df282a008ba8ba421e) --- modules/tm/tm.c | 3466 +++++++++++++++++++++++------------------------ 1 file changed, 1707 insertions(+), 1759 deletions(-) diff --git a/modules/tm/tm.c b/modules/tm/tm.c index ecca92e26df..e220458bc0e 100644 --- a/modules/tm/tm.c +++ b/modules/tm/tm.c @@ -1,30 +1,5 @@ /* - * TM module - * - * - * *************************************************** - * * Jiri's Source Memorial * - * * * - * * Welcome, pilgrim ! This is the greatest place * - * * where dramatic changes happend. There are not * - * * many places with a history like this, as there * - * * are not so many people like Jiri, one of the * - * * ser's fathers, who brought everywhere the wind * - * * of change, the flood of clean-up. We all felt * - * * his fatherly eye watching over us day and night.* - * * * - * * Please, preserve this codework heritage, as * - * * it's unlikely for fresh, juicy pieces of code to * - * * arise to give him the again the chance to * - * * demonstrate his clean-up and improvement skills.* - * * * - * * Hereby, we solicit you to adopt this historical * - * * piece of code. For $100, your name will be * - * * be printed in this banner and we will use * - * * collected funds to create and display an ASCII * - * * statue of Jiri . * - * *************************************************** - * + * TM (transaction management) module * * Copyright (C) 2001-2003 FhG Fokus * @@ -46,54 +21,28 @@ */ /** TM :: Module API (core). - * @file + * @file * @ingroup tm */ /** * @defgroup tm TM :: Transaction stateful proxy support * - The TM module enables stateful processing of SIP transactions. The main use - of stateful logic, which is costly in terms of memory and CPU, is some - services that inherently need state. - - For example, transaction-based accounting (module acc) needs to process - transaction state as opposed to individual messages, and any kinds of - forking must be implemented statefully. Other use of stateful processing - is it trading CPU caused by retransmission processing for memory. - That however only makes sense if CPU consumption per request is huge. - For example, if you want to avoid costly DNS resolution for every - retransmission of a request to an unresolvable destination, use stateful - mode. Then, only the initial message burdens server by DNS queries, - subsequent retransmissions will be dropped and will not result in more - processes blocked by DNS resolution. The price is more memory consumption - and higher processing latency. - + * The TM module enables stateful processing of SIP transactions. The main use + * of stateful logic, which is costly in terms of memory and CPU, is some + * services that inherently need state. * -\code - * *************************************************** - * * Jiri's Source Memorial * - * * * - * * Welcome, pilgrim ! This is the greatest place * - * * where dramatic changes happend. There are not * - * * many places with a history like this, as there * - * * are not so many people like Jiri, one of the * - * * ser's fathers, who brought everywhere the wind * - * * of change, the flood of clean-up. We all felt * - * * his fatherly eye watching over us day and night.* - * * * - * * Please, preserve this codework heritage, as * - * * it's unlikely for fresh, juicy pieces of code to * - * * arise to give him the again the chance to * - * * demonstrate his clean-up and improvement skills.* - * * * - * * Hereby, we solicit you to adopt this historical * - * * piece of code. For $100, your name will be * - * * be printed in this banner and we will use * - * * collected funds to create and display an ASCII * - * * statue of Jiri . * - * *************************************************** -\endcode + * For example, transaction-based accounting (module acc) needs to process + * transaction state as opposed to individual messages, and any kinds of + * forking must be implemented statefully. Other use of stateful processing + * is it trading CPU caused by retransmission processing for memory. + * That however only makes sense if CPU consumption per request is huge. + * For example, if you want to avoid costly DNS resolution for every + * retransmission of a request to an unresolvable destination, use stateful + * mode. Then, only the initial message burdens server by DNS queries, + * subsequent retransmissions will be dropped and will not result in more + * processes blocked by DNS resolution. The price is more memory consumption + * and higher processing latency. */ @@ -163,53 +112,53 @@ inline static int w_t_lookup_cancel(struct sip_msg* msg, char* str, char* str2); inline static int w_t_reply(struct sip_msg* msg, char* str, char* str2); inline static int w_t_release(struct sip_msg* msg, char* str, char* str2); inline static int w_t_retransmit_reply(struct sip_msg* p_msg, char* foo, - char* bar ); + char* bar ); inline static int w_t_newtran(struct sip_msg* p_msg, char* foo, char* bar ); inline static int w_t_relay( struct sip_msg *p_msg , char *_foo, char *_bar); inline static int w_t_relay2( struct sip_msg *p_msg , char *proxy, char*); inline static int w_t_relay_to_udp( struct sip_msg *p_msg , char *proxy, - char *); + char *); inline static int w_t_relay_to_udp_uri( struct sip_msg *p_msg , char*, char*); #ifdef USE_TCP inline static int w_t_relay_to_tcp( struct sip_msg *p_msg , char *proxy, - char *); + char *); inline static int w_t_relay_to_tcp_uri( struct sip_msg *p_msg , char*, char*); #endif #ifdef USE_TLS inline static int w_t_relay_to_tls( struct sip_msg *p_msg , char *proxy, - char *); + char *); inline static int w_t_relay_to_tls_uri( struct sip_msg *p_msg , char*, char*); #endif #ifdef USE_SCTP inline static int w_t_relay_to_sctp( struct sip_msg *p_msg , char *proxy, - char *); + char *); inline static int w_t_relay_to_sctp_uri( struct sip_msg*, char*, char*); #endif inline static int w_t_relay_to_avp(struct sip_msg* msg, char* str,char*); inline static int w_t_relay_to(struct sip_msg* msg, char* str,char*); inline static int w_t_replicate_uri( struct sip_msg *p_msg , - char *uri, /* sip uri as string or variable */ - char *_foo /* nothing expected */ ); + char *uri, /* sip uri as string or variable */ + char *_foo /* nothing expected */ ); inline static int w_t_replicate( struct sip_msg *p_msg , - char *proxy, /* struct proxy_l *proxy expected */ - char *_foo /* nothing expected */ ); + char *proxy, /* struct proxy_l *proxy expected */ + char *_foo /* nothing expected */ ); inline static int w_t_replicate_udp( struct sip_msg *p_msg , - char *proxy, /* struct proxy_l *proxy expected */ - char *_foo /* nothing expected */ ); + char *proxy, /* struct proxy_l *proxy expected */ + char *_foo /* nothing expected */ ); #ifdef USE_TCP inline static int w_t_replicate_tcp( struct sip_msg *p_msg , - char *proxy, /* struct proxy_l *proxy expected */ - char *_foo /* nothing expected */ ); + char *proxy, /* struct proxy_l *proxy expected */ + char *_foo /* nothing expected */ ); #endif #ifdef USE_TLS inline static int w_t_replicate_tls( struct sip_msg *p_msg , - char *proxy, /* struct proxy_l *proxy expected */ - char *_foo /* nothing expected */ ); + char *proxy, /* struct proxy_l *proxy expected */ + char *_foo /* nothing expected */ ); #endif #ifdef USE_SCTP inline static int w_t_replicate_sctp( struct sip_msg *p_msg , - char *proxy, /* struct proxy_l *proxy expected */ - char *_foo /* nothing expected */ ); + char *proxy, /* struct proxy_l *proxy expected */ + char *_foo /* nothing expected */ ); #endif inline static int w_t_replicate_to(struct sip_msg* msg, char* str,char*); inline static int w_t_forward_nonack(struct sip_msg* msg, char* str, char* ); @@ -243,7 +192,7 @@ static int t_set_disable_6xx(struct sip_msg* msg, char* on_off, char* foo); static int t_set_disable_failover(struct sip_msg* msg, char* on_off, char* f); #ifdef CANCEL_REASON_SUPPORT static int t_set_no_e2e_cancel_reason(struct sip_msg* msg, char* on_off, - char* f); + char* f); #endif /* CANCEL_REASON_SUPPORT */ static int t_set_disable_internal_reply(struct sip_msg* msg, char* on_off, char* f); static int t_branch_timeout(struct sip_msg* msg, char*, char*); @@ -282,177 +231,177 @@ static int fixup_t_check_status(void** param, int param_no); static cmd_export_t cmds[]={ {"t_newtran", w_t_newtran, 0, 0, - REQUEST_ROUTE}, + REQUEST_ROUTE}, {"t_lookup_request", w_t_check, 0, 0, - REQUEST_ROUTE}, + REQUEST_ROUTE}, {"t_lookup_cancel", w_t_lookup_cancel, 0, 0, - REQUEST_ROUTE}, + REQUEST_ROUTE}, {"t_lookup_cancel", w_t_lookup_cancel, 1, fixup_int_1, - REQUEST_ROUTE}, + REQUEST_ROUTE}, {"t_reply", w_t_reply, 2, fixup_t_reply, - REQUEST_ROUTE | ONREPLY_ROUTE | FAILURE_ROUTE }, + REQUEST_ROUTE | ONREPLY_ROUTE | FAILURE_ROUTE }, {"t_retransmit_reply", w_t_retransmit_reply, 0, 0, - REQUEST_ROUTE}, + REQUEST_ROUTE}, {"t_release", w_t_release, 0, 0, - REQUEST_ROUTE}, + REQUEST_ROUTE}, {"t_relay_to_udp", w_t_relay_to_udp, 2, fixup_hostport2proxy, - REQUEST_ROUTE|FAILURE_ROUTE}, + REQUEST_ROUTE|FAILURE_ROUTE}, {"t_relay_to_udp", w_t_relay_to_udp_uri, 0, 0, - REQUEST_ROUTE|FAILURE_ROUTE}, + REQUEST_ROUTE|FAILURE_ROUTE}, #ifdef USE_TCP {"t_relay_to_tcp", w_t_relay_to_tcp, 2, fixup_hostport2proxy, - REQUEST_ROUTE|FAILURE_ROUTE}, + REQUEST_ROUTE|FAILURE_ROUTE}, {"t_relay_to_tcp", w_t_relay_to_tcp_uri, 0, 0, - REQUEST_ROUTE|FAILURE_ROUTE}, + REQUEST_ROUTE|FAILURE_ROUTE}, #endif #ifdef USE_TLS {"t_relay_to_tls", w_t_relay_to_tls, 2, fixup_hostport2proxy, - REQUEST_ROUTE|FAILURE_ROUTE}, + REQUEST_ROUTE|FAILURE_ROUTE}, {"t_relay_to_tls", w_t_relay_to_tls_uri, 0, 0, - REQUEST_ROUTE|FAILURE_ROUTE}, + REQUEST_ROUTE|FAILURE_ROUTE}, #endif #ifdef USE_SCTP {"t_relay_to_sctp", w_t_relay_to_sctp, 2, fixup_hostport2proxy, - REQUEST_ROUTE|FAILURE_ROUTE}, + REQUEST_ROUTE|FAILURE_ROUTE}, {"t_relay_to_sctp", w_t_relay_to_sctp_uri, 0, 0, - REQUEST_ROUTE|FAILURE_ROUTE}, + REQUEST_ROUTE|FAILURE_ROUTE}, #endif {"t_replicate", w_t_replicate_uri, 0, 0, - REQUEST_ROUTE}, + REQUEST_ROUTE}, {"t_replicate", w_t_replicate_uri, 1, fixup_spve_null, - REQUEST_ROUTE}, + REQUEST_ROUTE}, {"t_replicate", w_t_replicate, 2, fixup_hostport2proxy, - REQUEST_ROUTE}, + REQUEST_ROUTE}, {"t_replicate_udp", w_t_replicate_udp, 2, fixup_hostport2proxy, - REQUEST_ROUTE}, + REQUEST_ROUTE}, #ifdef USE_TCP {"t_replicate_tcp", w_t_replicate_tcp, 2, fixup_hostport2proxy, - REQUEST_ROUTE}, + REQUEST_ROUTE}, #endif #ifdef USE_TLS {"t_replicate_tls", w_t_replicate_tls, 2, fixup_hostport2proxy, - REQUEST_ROUTE}, + REQUEST_ROUTE}, #endif #ifdef USE_SCTP {"t_replicate_sctp", w_t_replicate_sctp, 2, fixup_hostport2proxy, - REQUEST_ROUTE}, + REQUEST_ROUTE}, #endif {"t_replicate_to", w_t_replicate_to, 2, fixup_proto_hostport2proxy, - REQUEST_ROUTE}, + REQUEST_ROUTE}, {"t_relay", w_t_relay, 0, 0, - REQUEST_ROUTE | FAILURE_ROUTE }, + REQUEST_ROUTE | FAILURE_ROUTE }, {"t_relay", w_t_relay2, 2, fixup_hostport2proxy, - REQUEST_ROUTE | FAILURE_ROUTE }, + REQUEST_ROUTE | FAILURE_ROUTE }, {"t_relay_to_avp", w_t_relay_to_avp, 2, fixup_proto_hostport2proxy, - REQUEST_ROUTE}, + REQUEST_ROUTE}, {"t_relay_to", w_t_relay_to, 0, 0, - REQUEST_ROUTE | FAILURE_ROUTE }, + REQUEST_ROUTE | FAILURE_ROUTE }, {"t_relay_to", w_t_relay_to, 1, fixup_t_relay_to, - REQUEST_ROUTE | FAILURE_ROUTE }, + REQUEST_ROUTE | FAILURE_ROUTE }, {"t_relay_to", w_t_relay_to, 2, fixup_t_relay_to, - REQUEST_ROUTE | FAILURE_ROUTE }, + REQUEST_ROUTE | FAILURE_ROUTE }, {"t_forward_nonack", w_t_forward_nonack, 2, fixup_hostport2proxy, - REQUEST_ROUTE}, + REQUEST_ROUTE}, {"t_forward_nonack_uri", w_t_forward_nonack_uri, 0, 0, - REQUEST_ROUTE}, + REQUEST_ROUTE}, {"t_forward_nonack_udp", w_t_forward_nonack_udp, 2, fixup_hostport2proxy, - REQUEST_ROUTE}, + REQUEST_ROUTE}, #ifdef USE_TCP {"t_forward_nonack_tcp", w_t_forward_nonack_tcp, 2, fixup_hostport2proxy, - REQUEST_ROUTE}, + REQUEST_ROUTE}, #endif #ifdef USE_TLS {"t_forward_nonack_tls", w_t_forward_nonack_tls, 2, fixup_hostport2proxy, - REQUEST_ROUTE}, + REQUEST_ROUTE}, #endif #ifdef USE_SCTP {"t_forward_nonack_sctp", w_t_forward_nonack_sctp, 2, fixup_hostport2proxy, - REQUEST_ROUTE}, + REQUEST_ROUTE}, #endif {"t_forward_nonack_to", w_t_forward_nonack_to, 2, fixup_proto_hostport2proxy, - REQUEST_ROUTE}, + REQUEST_ROUTE}, {"t_relay_cancel", w_t_relay_cancel, 0, 0, - REQUEST_ROUTE}, + REQUEST_ROUTE}, {"t_on_failure", w_t_on_failure, 1, fixup_on_failure, - REQUEST_ROUTE | FAILURE_ROUTE | TM_ONREPLY_ROUTE | BRANCH_ROUTE }, + REQUEST_ROUTE | FAILURE_ROUTE | TM_ONREPLY_ROUTE | BRANCH_ROUTE }, {"t_on_branch_failure",w_t_on_branch_failure, 1, fixup_on_branch_failure, - REQUEST_ROUTE | FAILURE_ROUTE | TM_ONREPLY_ROUTE | BRANCH_ROUTE }, + REQUEST_ROUTE | FAILURE_ROUTE | TM_ONREPLY_ROUTE | BRANCH_ROUTE }, {"t_on_reply", w_t_on_reply, 1, fixup_on_reply, - REQUEST_ROUTE | FAILURE_ROUTE | TM_ONREPLY_ROUTE | BRANCH_ROUTE }, + REQUEST_ROUTE | FAILURE_ROUTE | TM_ONREPLY_ROUTE | BRANCH_ROUTE }, {"t_on_branch", w_t_on_branch, 1, fixup_on_branch, - REQUEST_ROUTE | FAILURE_ROUTE }, + REQUEST_ROUTE | FAILURE_ROUTE }, {"t_check_status", t_check_status, 1, fixup_t_check_status, - REQUEST_ROUTE | FAILURE_ROUTE | ONREPLY_ROUTE}, + REQUEST_ROUTE | FAILURE_ROUTE | ONREPLY_ROUTE}, {"t_write_req", t_write_req, 2, fixup_t_write, - REQUEST_ROUTE | FAILURE_ROUTE }, + REQUEST_ROUTE | FAILURE_ROUTE }, {"t_write_unix", t_write_unix, 2, fixup_t_write, - REQUEST_ROUTE | FAILURE_ROUTE }, + REQUEST_ROUTE | FAILURE_ROUTE }, {"t_set_fr", t_set_fr_inv, 1, fixup_var_int_1, - REQUEST_ROUTE|TM_ONREPLY_ROUTE|FAILURE_ROUTE|BRANCH_ROUTE }, + REQUEST_ROUTE|TM_ONREPLY_ROUTE|FAILURE_ROUTE|BRANCH_ROUTE }, {"t_set_fr", t_set_fr_all, 2, fixup_var_int_12, - REQUEST_ROUTE|TM_ONREPLY_ROUTE|FAILURE_ROUTE|BRANCH_ROUTE }, + REQUEST_ROUTE|TM_ONREPLY_ROUTE|FAILURE_ROUTE|BRANCH_ROUTE }, {"t_reset_fr", w_t_reset_fr, 0, 0, - REQUEST_ROUTE|TM_ONREPLY_ROUTE|FAILURE_ROUTE|BRANCH_ROUTE }, + REQUEST_ROUTE|TM_ONREPLY_ROUTE|FAILURE_ROUTE|BRANCH_ROUTE }, {"t_set_retr", w_t_set_retr, 2, fixup_var_int_12, - REQUEST_ROUTE|TM_ONREPLY_ROUTE|FAILURE_ROUTE|BRANCH_ROUTE }, + REQUEST_ROUTE|TM_ONREPLY_ROUTE|FAILURE_ROUTE|BRANCH_ROUTE }, {"t_reset_retr", w_t_reset_retr, 0, 0, - REQUEST_ROUTE|TM_ONREPLY_ROUTE|FAILURE_ROUTE|BRANCH_ROUTE }, + REQUEST_ROUTE|TM_ONREPLY_ROUTE|FAILURE_ROUTE|BRANCH_ROUTE }, {"t_set_max_lifetime", w_t_set_max_lifetime, 2, fixup_var_int_12, - REQUEST_ROUTE|TM_ONREPLY_ROUTE|FAILURE_ROUTE|BRANCH_ROUTE }, + REQUEST_ROUTE|TM_ONREPLY_ROUTE|FAILURE_ROUTE|BRANCH_ROUTE }, {"t_reset_max_lifetime", w_t_reset_max_lifetime, 0, 0, - REQUEST_ROUTE|TM_ONREPLY_ROUTE|FAILURE_ROUTE|BRANCH_ROUTE }, + REQUEST_ROUTE|TM_ONREPLY_ROUTE|FAILURE_ROUTE|BRANCH_ROUTE }, {"t_set_auto_inv_100", t_set_auto_inv_100, 1, fixup_var_int_1, - REQUEST_ROUTE}, + REQUEST_ROUTE}, {"t_set_disable_6xx", t_set_disable_6xx, 1, fixup_var_int_1, - REQUEST_ROUTE|TM_ONREPLY_ROUTE|FAILURE_ROUTE|BRANCH_ROUTE }, + REQUEST_ROUTE|TM_ONREPLY_ROUTE|FAILURE_ROUTE|BRANCH_ROUTE }, {"t_set_disable_failover", t_set_disable_failover, 1, fixup_var_int_1, - REQUEST_ROUTE|TM_ONREPLY_ROUTE|FAILURE_ROUTE|BRANCH_ROUTE }, + REQUEST_ROUTE|TM_ONREPLY_ROUTE|FAILURE_ROUTE|BRANCH_ROUTE }, #ifdef CANCEL_REASON_SUPPORT {"t_set_no_e2e_cancel_reason", t_set_no_e2e_cancel_reason, 1, fixup_var_int_1, - REQUEST_ROUTE|TM_ONREPLY_ROUTE|FAILURE_ROUTE|BRANCH_ROUTE }, + REQUEST_ROUTE|TM_ONREPLY_ROUTE|FAILURE_ROUTE|BRANCH_ROUTE }, /* alias for t_set_no_e2e_cancel_reason */ {"t_disable_e2e_cancel_reason", t_set_no_e2e_cancel_reason, 1, fixup_var_int_1, - REQUEST_ROUTE|TM_ONREPLY_ROUTE|FAILURE_ROUTE|BRANCH_ROUTE }, + REQUEST_ROUTE|TM_ONREPLY_ROUTE|FAILURE_ROUTE|BRANCH_ROUTE }, #endif /* CANCEL_REASON_SUPPORT */ {"t_set_disable_internal_reply", t_set_disable_internal_reply, 1, fixup_var_int_1, - REQUEST_ROUTE|TM_ONREPLY_ROUTE|FAILURE_ROUTE|BRANCH_ROUTE }, + REQUEST_ROUTE|TM_ONREPLY_ROUTE|FAILURE_ROUTE|BRANCH_ROUTE }, {"t_branch_timeout", t_branch_timeout, 0, 0, - FAILURE_ROUTE|EVENT_ROUTE}, + FAILURE_ROUTE|EVENT_ROUTE}, {"t_branch_replied", t_branch_replied, 0, 0, - FAILURE_ROUTE|EVENT_ROUTE}, - {"t_any_timeout", t_any_timeout, 0, 0, - REQUEST_ROUTE|TM_ONREPLY_ROUTE|FAILURE_ROUTE|BRANCH_ROUTE }, - {"t_any_replied", t_any_replied, 0, 0, - REQUEST_ROUTE|TM_ONREPLY_ROUTE|FAILURE_ROUTE|BRANCH_ROUTE }, + FAILURE_ROUTE|EVENT_ROUTE}, + {"t_any_timeout", t_any_timeout, 0, 0, + REQUEST_ROUTE|TM_ONREPLY_ROUTE|FAILURE_ROUTE|BRANCH_ROUTE }, + {"t_any_replied", t_any_replied, 0, 0, + REQUEST_ROUTE|TM_ONREPLY_ROUTE|FAILURE_ROUTE|BRANCH_ROUTE }, {"t_is_canceled", w_t_is_canceled, 0, 0, - REQUEST_ROUTE|TM_ONREPLY_ROUTE|FAILURE_ROUTE|BRANCH_ROUTE }, - {"t_is_retr_async_reply", w_t_is_retr_async_reply, 0, 0, - TM_ONREPLY_ROUTE}, + REQUEST_ROUTE|TM_ONREPLY_ROUTE|FAILURE_ROUTE|BRANCH_ROUTE }, + {"t_is_retr_async_reply", w_t_is_retr_async_reply, 0, 0, + TM_ONREPLY_ROUTE}, {"t_is_expired", t_is_expired, 0, 0, - REQUEST_ROUTE|TM_ONREPLY_ROUTE|FAILURE_ROUTE|BRANCH_ROUTE }, - {"t_grep_status", t_grep_status, 1, fixup_var_int_1, - REQUEST_ROUTE|TM_ONREPLY_ROUTE|FAILURE_ROUTE|BRANCH_ROUTE }, + REQUEST_ROUTE|TM_ONREPLY_ROUTE|FAILURE_ROUTE|BRANCH_ROUTE }, + {"t_grep_status", t_grep_status, 1, fixup_var_int_1, + REQUEST_ROUTE|TM_ONREPLY_ROUTE|FAILURE_ROUTE|BRANCH_ROUTE }, {"t_drop_replies", w_t_drop_replies, 0, 0, - FAILURE_ROUTE}, + FAILURE_ROUTE}, {"t_drop_replies", w_t_drop_replies, 1, 0, - FAILURE_ROUTE}, + FAILURE_ROUTE}, {"t_save_lumps", w_t_save_lumps, 0, 0, - REQUEST_ROUTE}, + REQUEST_ROUTE}, {"t_check_trans", w_t_check_trans, 0, 0, - REQUEST_ROUTE|ONREPLY_ROUTE|BRANCH_ROUTE }, + REQUEST_ROUTE|ONREPLY_ROUTE|BRANCH_ROUTE }, {"t_is_set", w_t_is_set, 1, fixup_t_is_set, - ANY_ROUTE }, + ANY_ROUTE }, {"t_use_uac_headers", w_t_use_uac_headers, 0, 0, - ANY_ROUTE }, + ANY_ROUTE }, {"t_load_contacts", t_load_contacts, 0, 0, - REQUEST_ROUTE | FAILURE_ROUTE}, + REQUEST_ROUTE | FAILURE_ROUTE}, {"t_next_contacts", t_next_contacts, 0, 0, - REQUEST_ROUTE | FAILURE_ROUTE}, + REQUEST_ROUTE | FAILURE_ROUTE}, {"t_next_contact_flow", t_next_contact_flow, 0, 0, - REQUEST_ROUTE }, + REQUEST_ROUTE }, /* not applicable from the script */ {"load_tm", (cmd_function)load_tm, NO_SCRIPT, 0, 0}, @@ -478,13 +427,13 @@ static param_export_t params[]={ {"auto_inv_100_reason", PARAM_STRING, &default_tm_cfg.tm_auto_inv_100_r }, {"unix_tx_timeout", PARAM_INT, &default_tm_cfg.tm_unix_tx_timeout }, {"restart_fr_on_each_reply", PARAM_INT, - &default_tm_cfg.restart_fr_on_each_reply}, + &default_tm_cfg.restart_fr_on_each_reply}, {"fr_timer_avp", PARAM_STRING, &fr_timer_param }, {"fr_inv_timer_avp", PARAM_STRING, &fr_inv_timer_param }, - {"tw_append", PARAM_STRING|PARAM_USE_FUNC, - (void*)parse_tw_append }, - {"pass_provisional_replies", PARAM_INT, - &default_tm_cfg.pass_provisional_replies }, + {"tw_append", PARAM_STRING|PARAM_USE_FUNC, + (void*)parse_tw_append }, + {"pass_provisional_replies", PARAM_INT, + &default_tm_cfg.pass_provisional_replies }, {"aggregate_challenges", PARAM_INT, &default_tm_cfg.tm_aggregate_auth }, {"unmatched_cancel", PARAM_INT, &default_tm_cfg.unmatched_cancel }, {"default_code", PARAM_INT, &default_tm_cfg.default_code }, @@ -520,1693 +469,1729 @@ static param_export_t params[]={ #ifdef STATIC_TM struct module_exports tm_exports = { #else -struct module_exports exports= { + struct module_exports exports= { #endif - "tm", - /* -------- exported functions ----------- */ - cmds, - tm_rpc, /* RPC methods */ - /* ------------ exported variables ---------- */ - params, - - mod_init, /* module initialization function */ - (response_function) reply_received, - (destroy_function) tm_shutdown, - 0, /* w_onbreak, */ - child_init /* per-child init function */ -}; + "tm", + /* -------- exported functions ----------- */ + cmds, + tm_rpc, /* RPC methods */ + /* ------------ exported variables ---------- */ + params, + mod_init, /* module initialization function */ + (response_function) reply_received, + (destroy_function) tm_shutdown, + 0, /* w_onbreak, */ + child_init /* per-child init function */ + }; -/* helper for fixup_on_* */ -static int fixup_routes(char* r_type, struct route_list* rt, void** param) -{ - int i; - - i=route_get(rt, (char*)*param); - if (i==-1){ - LOG(L_ERR, "ERROR: tm: fixup_routes: route_get failed\n"); - return E_UNSPEC; - } - if (r_type && rt->rlist[i]==0){ - LOG(L_WARN, "WARNING: %s(\"%s\"): empty/non existing route\n", - r_type, (char*)*param); - } - *param=(void*)(long)i; - return 0; -} - -static int fixup_t_reply(void** param, int param_no) -{ - if (param_no == 1) { - if (fixup_var_int_12(param, 1) != 0) return -1; - } else if (param_no == 2) { - return fixup_var_str_12(param, 2); - } - return 0; -} - -static int fixup_on_failure(void** param, int param_no) -{ - if (param_no==1){ - if(strlen((char*)*param)<=1 - && (*(char*)(*param)==0 || *(char*)(*param)=='0')) { - *param = (void*)0; - return 0; - } - return fixup_routes("t_on_failure", &failure_rt, param); - } - return 0; -} -#define BRANCH_FAILURE_ROUTE_PREFIX "tm:branch-failure" -static int fixup_on_branch_failure(void** param, int param_no) -{ - char *full_route_name = NULL; - int len; - int ret = 0; - if (param_no==1){ - if((len = strlen((char*)*param))<=1 - && (*(char*)(*param)==0 || *(char*)(*param)=='0')) { - *param = (void*)0; - return 0; + /* helper for fixup_on_* */ + static int fixup_routes(char* r_type, struct route_list* rt, void** param) + { + int i; + + i=route_get(rt, (char*)*param); + if (i==-1){ + LOG(L_ERR, "ERROR: tm: fixup_routes: route_get failed\n"); + return E_UNSPEC; } - len += strlen(BRANCH_FAILURE_ROUTE_PREFIX) + 1; - if ((full_route_name = pkg_malloc(len+1)) == NULL) - { - LM_ERR("No memory left in branch_failure fixup\n"); - return -1; + if (r_type && rt->rlist[i]==0){ + LOG(L_WARN, "WARNING: %s(\"%s\"): empty/non existing route\n", + r_type, (char*)*param); } - sprintf(full_route_name, "%s:%s", BRANCH_FAILURE_ROUTE_PREFIX, (char*)*param); - *param=(void*)full_route_name; - ret = fixup_routes("t_on_branch_failure", &event_rt, param); - pkg_free(full_route_name); + *param=(void*)(long)i; + return 0; } - return ret; -} - -static int fixup_on_reply(void** param, int param_no) -{ - if (param_no==1){ - if(strlen((char*)*param)<=1 - && (*(char*)(*param)==0 || *(char*)(*param)=='0')) { - *param = (void*)0; - return 0; + static int fixup_t_reply(void** param, int param_no) + { + if (param_no == 1) { + if (fixup_var_int_12(param, 1) != 0) return -1; + } else if (param_no == 2) { + return fixup_var_str_12(param, 2); } - return fixup_routes("t_on_reply", &onreply_rt, param); + return 0; } - return 0; -} - - -static int fixup_on_branch(void** param, int param_no) -{ - if (param_no==1){ - if(strlen((char*)*param)<=1 - && (*(char*)(*param)==0 || *(char*)(*param)=='0')) { - *param = (void*)0; - return 0; + static int fixup_on_failure(void** param, int param_no) + { + if (param_no==1){ + if(strlen((char*)*param)<=1 + && (*(char*)(*param)==0 || *(char*)(*param)=='0')) { + *param = (void*)0; + return 0; + } + return fixup_routes("t_on_failure", &failure_rt, param); } - return fixup_routes("t_on_branch", &branch_rt, param); + return 0; } - return 0; -} -static int fixup_on_sl_reply(modparam_t type, void* val) -{ - if ((type & PARAM_STRING) == 0) { - LOG(L_ERR, "ERROR: tm: fixup_on_sl_reply: not a string parameter\n"); - return -1; +#define BRANCH_FAILURE_ROUTE_PREFIX "tm:branch-failure" + static int fixup_on_branch_failure(void** param, int param_no) + { + char *full_route_name = NULL; + int len; + int ret = 0; + if (param_no==1){ + if((len = strlen((char*)*param))<=1 + && (*(char*)(*param)==0 || *(char*)(*param)=='0')) { + *param = (void*)0; + return 0; + } + len += strlen(BRANCH_FAILURE_ROUTE_PREFIX) + 1; + if ((full_route_name = pkg_malloc(len+1)) == NULL) + { + LM_ERR("No memory left in branch_failure fixup\n"); + return -1; + } + sprintf(full_route_name, "%s:%s", BRANCH_FAILURE_ROUTE_PREFIX, (char*)*param); + *param=(void*)full_route_name; + ret = fixup_routes("t_on_branch_failure", &event_rt, param); + pkg_free(full_route_name); + } + return ret; } - if (fixup_routes(0, &onreply_rt, &val)) - return -1; - - goto_on_sl_reply = (int)(long)val; - return 0; -} + static int fixup_on_reply(void** param, int param_no) + { + if (param_no==1){ + if(strlen((char*)*param)<=1 + && (*(char*)(*param)==0 || *(char*)(*param)=='0')) { + *param = (void*)0; + return 0; + } + return fixup_routes("t_on_reply", &onreply_rt, param); + } + return 0; + } -/* (char *hostname, char *port_nr) ==> (struct proxy_l *, -) */ -static int fixup_hostport2proxy(void** param, int param_no) -{ - unsigned int port; - char *host; - int err; - struct proxy_l *proxy; - action_u_t *a; - str s; - DBG("TM module: fixup_hostport2proxy(%s, %d)\n", (char*)*param, param_no); - if (param_no==1){ + static int fixup_on_branch(void** param, int param_no) + { + if (param_no==1){ + if(strlen((char*)*param)<=1 + && (*(char*)(*param)==0 || *(char*)(*param)=='0')) { + *param = (void*)0; + return 0; + } + return fixup_routes("t_on_branch", &branch_rt, param); + } return 0; - } else if (param_no==2) { - a = fixup_get_param(param, param_no, 1); - host= a->u.string; - port=str2s(*param, strlen(*param), &err); - if (err!=0) { - LOG(L_ERR, "TM module:fixup_hostport2proxy: bad port number <%s>\n", - (char*)(*param)); - return E_UNSPEC; - } - s.s = host; - s.len = strlen(host); - proxy=mk_proxy(&s, port, 0); /* FIXME: udp or tcp? */ - if (proxy==0) { - LOG(L_ERR, "ERROR: fixup_hostport2proxy: bad host name in URI <%s>\n", - host ); - return E_BAD_ADDRESS; + } + + static int fixup_on_sl_reply(modparam_t type, void* val) + { + if ((type & PARAM_STRING) == 0) { + LOG(L_ERR, "ERROR: tm: fixup_on_sl_reply: not a string parameter\n"); + return -1; } - /* success -- fix the first parameter to proxy now ! */ - a->u.data=proxy; + if (fixup_routes(0, &onreply_rt, &val)) + return -1; + + goto_on_sl_reply = (int)(long)val; return 0; - } else { - LOG(L_ERR,"ERROR: fixup_hostport2proxy called with parameter #<>{1,2}\n"); - return E_BUG; } -} -/* (char *$proto, char *$host:port) ==> (fparam, fparam) */ -static int fixup_proto_hostport2proxy(void** param, int param_no) { - int ret; - ret = fix_param(FPARAM_AVP, param); - if (ret <= 0) return ret; -/* if (param_no = 1) { FIXME: param_str currently does not offer INT/STR overloading - ret = fix_param(FPARAM_INT, param); - if (ret <= 0) return ret; - } */ - if (fix_param(FPARAM_STRING, param) != 0) return -1; - return 0; -} - - -static int fixup_t_check_status(void** param, int param_no) -{ - int ret; - - ret = fix_param(FPARAM_AVP, param); - if (ret <= 0) return ret; - - ret = fix_param(FPARAM_SELECT, param); - if (ret <= 0) return ret; - - if (fix_param(FPARAM_REGEX, param) != 0) return -1; - return 0; -} - - -/***************************** init functions *****************************/ -static int w_t_unref( struct sip_msg *foo, unsigned int flags, void *bar) -{ - return t_unref(foo); -} - - -static int script_init( struct sip_msg *foo, unsigned int flags, void *bar) -{ - /* we primarily reset all private memory here to make sure - * private values left over from previous message will - * not be used again */ - - /* make sure the new message will not inherit previous - message's t_on_failure value - */ - t_on_failure( 0 ); - t_on_branch_failure(0); - t_on_reply(0); - t_on_branch(0); - /* reset the kr status */ - reset_kr(); - /* set request mode so that multiple-mode actions know - * how to behave */ - set_route_type(REQUEST_ROUTE); - lumps_are_cloned = 0; - return 1; -} - - -static int mod_init(void) -{ - DBG( "TM - (sizeof cell=%ld, sip_msg=%ld) initializing...\n", - (long)sizeof(struct cell), (long)sizeof(struct sip_msg)); - - /* checking if we have sufficient bitmap capacity for given - maximum number of branches */ - if (sr_dst_max_branches+1>31) { - LOG(L_CRIT, "Too many max UACs for UAC branch_bm_t bitmap: %d\n", - sr_dst_max_branches ); - return -1; - } - if (init_callid() < 0) { - LOG(L_CRIT, "Error while initializing Call-ID generator\n"); - return -1; - } + /* (char *hostname, char *port_nr) ==> (struct proxy_l *, -) */ + static int fixup_hostport2proxy(void** param, int param_no) + { + unsigned int port; + char *host; + int err; + struct proxy_l *proxy; + action_u_t *a; + str s; + + DBG("TM module: fixup_hostport2proxy(%s, %d)\n", (char*)*param, param_no); + if (param_no==1){ + return 0; + } else if (param_no==2) { + a = fixup_get_param(param, param_no, 1); + host= a->u.string; + port=str2s(*param, strlen(*param), &err); + if (err!=0) { + LOG(L_ERR, "TM module:fixup_hostport2proxy: bad port number <%s>\n", + (char*)(*param)); + return E_UNSPEC; + } + s.s = host; + s.len = strlen(host); + proxy=mk_proxy(&s, port, 0); /* FIXME: udp or tcp? */ + if (proxy==0) { + LOG(L_ERR, "ERROR: fixup_hostport2proxy: bad host name in URI <%s>\n", + host ); + return E_BAD_ADDRESS; + } + /* success -- fix the first parameter to proxy now ! */ - /* building the hash table*/ - if (!init_hash_table()) { - LOG(L_ERR, "ERROR: mod_init: initializing hash_table failed\n"); - return -1; + a->u.data=proxy; + return 0; + } else { + LOG(L_ERR,"ERROR: fixup_hostport2proxy called with parameter #<>{1,2}\n"); + return E_BUG; + } } - /* init static hidden values */ - init_t(); + /* (char *$proto, char *$host:port) ==> (fparam, fparam) */ + static int fixup_proto_hostport2proxy(void** param, int param_no) { + int ret; - if (tm_init_selects()==-1) { - LOG(L_ERR, "ERROR: mod_init: select init failed\n"); - return -1; + ret = fix_param(FPARAM_AVP, param); + if (ret <= 0) return ret; + /* if (param_no = 1) { FIXME: param_str currently does not offer INT/STR overloading + ret = fix_param(FPARAM_INT, param); + if (ret <= 0) return ret; + } */ + if (fix_param(FPARAM_STRING, param) != 0) return -1; + return 0; } - /* the default timer values must be fixed-up before - * declaring the configuration (Miklos) */ - if (tm_init_timers()==-1) { - LOG(L_ERR, "ERROR: mod_init: timer init failed\n"); - return -1; - } - - /* the cancel branch flags must be fixed before declaring the - * configuration */ - if (cancel_b_flags_get(&default_tm_cfg.cancel_b_flags, - default_tm_cfg.cancel_b_flags)<0){ - LOG(L_ERR, "ERROR: mod_init: bad cancel branch method\n"); - return -1; - } -#ifdef USE_DNS_FAILOVER - if (default_tm_cfg.reparse_on_dns_failover && mhomed) { - LOG(L_WARN, "WARNING: mod_init: " - "reparse_on_dns_failover is enabled on a " - "multihomed host -- check the readme of tm module!\n"); - } -#endif + static int fixup_t_check_status(void** param, int param_no) + { + int ret; - /* declare the configuration */ - if (cfg_declare("tm", tm_cfg_def, &default_tm_cfg, cfg_sizeof(tm), - &tm_cfg)) { - LOG(L_ERR, "ERROR: mod_init: failed to declare the configuration\n"); - return -1; - } + ret = fix_param(FPARAM_AVP, param); + if (ret <= 0) return ret; - /* First tm_stat initialization function only allocates the top level stat - * structure in shared memory, the initialization will complete in child - * init with init_tm_stats_child when the final value of estimated_process_count is - * known - */ - if (init_tm_stats() < 0) { - LOG(L_CRIT, "ERROR: mod_init: failed to init stats\n"); - return -1; - } + ret = fix_param(FPARAM_SELECT, param); + if (ret <= 0) return ret; - if (uac_init()==-1) { - LOG(L_ERR, "ERROR: mod_init: uac_init failed\n"); - return -1; + if (fix_param(FPARAM_REGEX, param) != 0) return -1; + return 0; } - if (init_tmcb_lists()!=1) { - LOG(L_CRIT, "ERROR:tm:mod_init: failed to init tmcb lists\n"); - return -1; - } - - tm_init_tags(); - init_twrite_lines(); - if (init_twrite_sock() < 0) { - LOG(L_ERR, "ERROR:tm:mod_init: Unable to create socket\n"); - return -1; - } - /* register post-script clean-up function */ - if (register_script_cb( w_t_unref, POST_SCRIPT_CB|REQUEST_CB, 0)<0 ) { - LOG(L_ERR,"ERROR:tm:mod_init: failed to register POST request " - "callback\n"); - return -1; - } - if (register_script_cb( script_init, PRE_SCRIPT_CB|REQUEST_CB , 0)<0 ) { - LOG(L_ERR,"ERROR:tm:mod_init: failed to register PRE request " - "callback\n"); - return -1; + /***************************** init functions *****************************/ + static int w_t_unref( struct sip_msg *foo, unsigned int flags, void *bar) + { + return t_unref(foo); } - if (init_avp_params(fr_timer_param, fr_inv_timer_param) < 0) { - LOG(L_ERR,"ERROR:tm:mod_init: failed to process AVP params\n"); - return -1; - } - if ((contacts_avp.len > 0) && (contact_flows_avp.len == 0)) { - LOG(L_ERR,"ERROR:tm:mod_init: contact_flows_avp param has not been defined\n"); - return -1; + + static int script_init( struct sip_msg *foo, unsigned int flags, void *bar) + { + /* we primarily reset all private memory here to make sure + * private values left over from previous message will + * not be used again */ + + /* make sure the new message will not inherit previous + message's t_on_failure value + */ + t_on_failure( 0 ); + t_on_branch_failure(0); + t_on_reply(0); + t_on_branch(0); + /* reset the kr status */ + reset_kr(); + /* set request mode so that multiple-mode actions know + * how to behave */ + set_route_type(REQUEST_ROUTE); + lumps_are_cloned = 0; + return 1; } -#ifdef WITH_EVENT_LOCAL_REQUEST - goto_on_local_req=route_lookup(&event_rt, "tm:local-request"); - if (goto_on_local_req>=0 && event_rt.rlist[goto_on_local_req]==0) - goto_on_local_req=-1; /* disable */ - if (goto_on_local_req>=0) - set_child_rpc_sip_mode(); -#endif /* WITH_EVENT_LOCAL_REQUEST */ - if (goto_on_sl_reply && onreply_rt.rlist[goto_on_sl_reply]==0) - WARN("empty/non existing on_sl_reply route\n"); -#ifdef WITH_TM_CTX - tm_ctx_init(); -#endif - tm_init = 1; - return 0; -} - -static int child_init(int rank) -{ - if (rank == PROC_INIT) { - /* we must init stats when rank==PROC_INIT: after mod_init we know - * the exact number of processes and we must init the shared structure - * before any other process is starting (or else some new process - * might try to use the stats before the stats array is allocated) */ - if (init_tm_stats_child() < 0) { - ERR("Error while initializing tm statistics structures\n"); + static int mod_init(void) + { + DBG( "TM - (sizeof cell=%ld, sip_msg=%ld) initializing...\n", + (long)sizeof(struct cell), (long)sizeof(struct sip_msg)); + + /* checking if we have sufficient bitmap capacity for given + * maximum number of branches */ + if (sr_dst_max_branches+1>31) { + LOG(L_CRIT, "Too many max UACs for UAC branch_bm_t bitmap: %d\n", + sr_dst_max_branches ); return -1; } - }else if (child_init_callid(rank) < 0) { - /* don't init callid for PROC_INIT*/ - LOG(L_ERR, "ERROR: child_init: Error while initializing Call-ID" - " generator\n"); - return -2; - } - return 0; -} - - - -/**************************** wrapper functions ***************************/ -static int t_check_status(struct sip_msg* msg, char *p1, char *foo) -{ - regmatch_t pmatch; - struct cell *t; - char *status, *s = NULL; - char backup; - int lowest_status, n, ret; - fparam_t* fp; - regex_t* re = NULL; - str tmp; - - fp = (fparam_t*)p1; - t = 0; - /* first get the transaction */ - if (t_check(msg, 0 ) == -1) return -1; - if ((t = get_t()) == 0) { - LOG(L_ERR, "ERROR: t_check_status: cannot check status for a reply " - "which has no T-state established\n"); - goto error; - } - backup = 0; - - switch(fp->type) { - case FPARAM_REGEX: - re = fp->v.regex; - break; - - default: - /* AVP or select, get the value and compile the regex */ - if (get_str_fparam(&tmp, msg, fp) < 0) goto error; - s = pkg_malloc(tmp.len + 1); - if (s == NULL) { - ERR("Out of memory\n"); - goto error; - } - memcpy(s, tmp.s, tmp.len); - s[tmp.len] = '\0'; - - if ((re = pkg_malloc(sizeof(regex_t))) == 0) { - ERR("No memory left\n"); - goto error; - } - - if (regcomp(re, s, REG_EXTENDED|REG_ICASE|REG_NEWLINE)) { - ERR("Bad regular expression '%s'\n", s); - pkg_free(re); - re = NULL; - goto error; - } - break; - } - - switch(get_route_type()) { - case REQUEST_ROUTE: - /* use the status of the last sent reply */ - status = int2str( t->uas.status, 0); - break; - - case TM_ONREPLY_ROUTE: - case CORE_ONREPLY_ROUTE: - /* use the status of the current reply */ - status = msg->first_line.u.reply.status.s; - backup = status[msg->first_line.u.reply.status.len]; - status[msg->first_line.u.reply.status.len] = 0; - break; - - case FAILURE_ROUTE: - /* use the status of the winning reply */ - ret = t_pick_branch( -1, 0, t, &lowest_status); - if (ret == -1) { - /* t_pick_branch() retuns error also when there are only - * blind UACs. Let us give it another chance including the - * blind branches. */ - LOG(L_DBG, "DEBUG: t_check_status: t_pick_branch returned error, " - "trying t_pick_branch_blind\n"); - ret = t_pick_branch_blind(t, &lowest_status); - } - if (ret < 0) { - LOG(L_CRIT,"BUG:t_check_status: t_pick_branch failed to get " - " a final response in FAILURE_ROUTE\n"); - goto error; - } - status = int2str( lowest_status , 0); - break; - case BRANCH_FAILURE_ROUTE: - status = int2str(t->uac[get_t_branch()].last_received, 0); - break; - default: - LOG(L_ERR,"ERROR:t_check_status: unsupported route type %d\n", - get_route_type()); - goto error; - } - - DBG("DEBUG:t_check_status: checked status is <%s>\n",status); - /* do the checking */ - n = regexec(re, status, 1, &pmatch, 0); - - if (backup) status[msg->first_line.u.reply.status.len] = backup; - if (s) pkg_free(s); - if ((fp->type != FPARAM_REGEX) && re) { - regfree(re); - pkg_free(re); - } - - if (unlikely(t && is_route_type(CORE_ONREPLY_ROUTE))){ - /* t_check() above has the side effect of setting T and - REFerencing T => we must unref and unset it. */ - UNREF( t ); - set_t(T_UNDEFINED, T_BR_UNDEFINED); - } - if (n!=0) return -1; - return 1; - - error: - if (unlikely(t && is_route_type(CORE_ONREPLY_ROUTE))){ - /* t_check() above has the side effect of setting T and - REFerencing T => we must unref and unset it. */ - UNREF( t ); - set_t(T_UNDEFINED, T_BR_UNDEFINED); - } - if (s) pkg_free(s); - if ((fp->type != FPARAM_REGEX) && re) { - regfree(re); - pkg_free(re); - } - return -1; -} - - -inline static int w_t_check(struct sip_msg* msg, char* str, char* str2) -{ - return (t_check_msg( msg , 0 )==1) ? 1 : -1; -} - -inline static int w_t_lookup_cancel(struct sip_msg* msg, char* str, char* str2) -{ - struct cell *ret; - int i=0; - if (msg->REQ_METHOD==METHOD_CANCEL) { - ret = t_lookupOriginalT( msg ); - DBG("lookup_original: t_lookupOriginalT returned: %p\n", ret); - if (ret != T_NULL_CELL) { - /* If the parameter is set to 1, overwrite the message flags of - * the CANCEL with the flags of the INVITE */ - if (str && (get_int_fparam(&i, msg, (fparam_t*)str)==0) && i) - msg->flags = ret->uas.request->flags; - - /* The cell is reffed by t_lookupOriginalT, but T is not set. - So we must unref it before returning. */ - UNREF(ret); - return 1; - } - } else { - LOG(L_WARN, "WARNING: script error t_lookup_cancel() called for non-CANCEL request\n"); - } - return -1; -} - -inline static int str2proto(char *s, int len) { - if (len == 3 && !strncasecmp(s, "udp", 3)) - return PROTO_UDP; - else if (len == 3 && !strncasecmp(s, "tcp", 3)) /* tcp&tls checks will be passed in getproto() */ - return PROTO_TCP; - else if (len == 3 && !strncasecmp(s, "tls", 3)) - return PROTO_TLS; - else if (len == 4 && !strncasecmp(s, "sctp", 4)) - return PROTO_SCTP; - else if (len == 2 && !strncasecmp(s, "ws", 2)) - return PROTO_WS; - else if (len == 3 && !strncasecmp(s, "wss", 3)) { - LM_WARN("\"wss\" used somewhere...\n"); - return PROTO_WS; - } else - return PROTO_NONE; -} - -inline static struct proxy_l* t_protoaddr2proxy(char *proto_par, char *addr_par) { - struct proxy_l *proxy = 0; - avp_t* avp; - avp_value_t val; - int proto, port, err; - str s; - char *c; - - switch(((fparam_t *)proto_par)->type) { - case FPARAM_AVP: - if (!(avp = search_first_avp(((fparam_t *)proto_par)->v.avp.flags, ((fparam_t *)proto_par)->v.avp.name, &val, 0))) { - proto = PROTO_NONE; - } else { - if (avp->flags & AVP_VAL_STR) { - proto = str2proto(val.s.s, val.s.len); - } - else { - proto = val.n; - } + + if (init_callid() < 0) { + LOG(L_CRIT, "Error while initializing Call-ID generator\n"); + return -1; } - break; - case FPARAM_INT: - proto = ((fparam_t *)proto_par)->v.i; - break; - case FPARAM_STRING: - proto = str2proto( ((fparam_t *)proto_par)->v.asciiz, strlen(((fparam_t *)proto_par)->v.asciiz)); - break; - default: - ERR("BUG: Invalid proto parameter value in t_protoaddr2proxy\n"); - return 0; - } + /* building the hash table*/ + if (!init_hash_table()) { + LOG(L_ERR, "ERROR: mod_init: initializing hash_table failed\n"); + return -1; + } + /* init static hidden values */ + init_t(); - switch(((fparam_t *)addr_par)->type) { - case FPARAM_AVP: - if (!(avp = search_first_avp(((fparam_t *)addr_par)->v.avp.flags, ((fparam_t *)addr_par)->v.avp.name, &val, 0))) { - s.len = 0; - } else { - if ((avp->flags & AVP_VAL_STR) == 0) { - LOG(L_ERR, "tm:t_protoaddr2proxy: avp <%.*s> value is not string\n", - ((fparam_t *)addr_par)->v.avp.name.s.len, ((fparam_t *)addr_par)->v.avp.name.s.s); - return 0; - } - s = val.s; + if (tm_init_selects()==-1) { + LOG(L_ERR, "ERROR: mod_init: select init failed\n"); + return -1; } - break; - case FPARAM_STRING: - s.s = ((fparam_t *) addr_par)->v.asciiz; - s.len = strlen(s.s); - break; + /* the default timer values must be fixed-up before + * declaring the configuration (Miklos) */ + if (tm_init_timers()==-1) { + LOG(L_ERR, "ERROR: mod_init: timer init failed\n"); + return -1; + } - default: - ERR("BUG: Invalid addr parameter value in t_protoaddr2proxy\n"); - return 0; - } + /* the cancel branch flags must be fixed before declaring the + * configuration */ + if (cancel_b_flags_get(&default_tm_cfg.cancel_b_flags, + default_tm_cfg.cancel_b_flags)<0){ + LOG(L_ERR, "ERROR: mod_init: bad cancel branch method\n"); + return -1; + } - port = 5060; - if (s.len) { - c = memchr(s.s, ':', s.len); - if (c) { - port = str2s(c+1, s.len-(c-s.s+1), &err); - if (err!=0) { - LOG(L_ERR, "tm:t_protoaddr2proxy: bad port number <%.*s>\n", - s.len, s.s); - return 0; - } - s.len = c-s.s; +#ifdef USE_DNS_FAILOVER + if (default_tm_cfg.reparse_on_dns_failover && mhomed) { + LOG(L_WARN, "WARNING: mod_init: " + "reparse_on_dns_failover is enabled on a " + "multihomed host -- check the readme of tm module!\n"); } - } - if (!s.len) { - LOG(L_ERR, "tm: protoaddr2proxy: host name is empty\n"); - return 0; - } - proxy=mk_proxy(&s, port, proto); - if (proxy==0) { - LOG(L_ERR, "tm: protoaddr2proxy: bad host name in URI <%.*s>\n", - s.len, s.s ); - return 0; - } - return proxy; -} +#endif -inline static int _w_t_forward_nonack(struct sip_msg* msg, struct proxy_l* proxy, - int proto) -{ - struct cell *t; - if (t_check( msg , 0 )==-1) { - LOG(L_ERR, "ERROR: forward_nonack: " - "can't forward when no transaction was set up\n"); - return -1; - } - t=get_t(); - if ( t && t!=T_UNDEFINED ) { - if (msg->REQ_METHOD==METHOD_ACK) { - LOG(L_WARN,"WARNING: you don't really want to fwd hbh ACK\n"); + /* declare the configuration */ + if (cfg_declare("tm", tm_cfg_def, &default_tm_cfg, cfg_sizeof(tm), + &tm_cfg)) { + LOG(L_ERR, "ERROR: mod_init: failed to declare the configuration\n"); return -1; } - return t_forward_nonack(t, msg, proxy, proto ); - } else { - DBG("DEBUG: forward_nonack: no transaction found\n"); - return -1; - } -} + /* First tm_stat initialization function only allocates the top level stat + * structure in shared memory, the initialization will complete in child + * init with init_tm_stats_child when the final value of estimated_process_count is + * known + */ + if (init_tm_stats() < 0) { + LOG(L_CRIT, "ERROR: mod_init: failed to init stats\n"); + return -1; + } -inline static int w_t_forward_nonack( struct sip_msg* msg, char* proxy, - char* foo) -{ - return _w_t_forward_nonack(msg, ( struct proxy_l *) proxy, PROTO_NONE); -} + if (uac_init()==-1) { + LOG(L_ERR, "ERROR: mod_init: uac_init failed\n"); + return -1; + } + if (init_tmcb_lists()!=1) { + LOG(L_CRIT, "ERROR:tm:mod_init: failed to init tmcb lists\n"); + return -1; + } -inline static int w_t_forward_nonack_uri(struct sip_msg* msg, char *foo, - char *bar) -{ - return _w_t_forward_nonack(msg, 0, PROTO_NONE); -} + tm_init_tags(); + init_twrite_lines(); + if (init_twrite_sock() < 0) { + LOG(L_ERR, "ERROR:tm:mod_init: Unable to create socket\n"); + return -1; + } + /* register post-script clean-up function */ + if (register_script_cb( w_t_unref, POST_SCRIPT_CB|REQUEST_CB, 0)<0 ) { + LOG(L_ERR,"ERROR:tm:mod_init: failed to register POST request " + "callback\n"); + return -1; + } + if (register_script_cb( script_init, PRE_SCRIPT_CB|REQUEST_CB , 0)<0 ) { + LOG(L_ERR,"ERROR:tm:mod_init: failed to register PRE request " + "callback\n"); + return -1; + } -inline static int w_t_forward_nonack_udp( struct sip_msg* msg, char* proxy, - char* foo) -{ - return _w_t_forward_nonack(msg, ( struct proxy_l *) proxy, PROTO_UDP); -} + if (init_avp_params(fr_timer_param, fr_inv_timer_param) < 0) { + LOG(L_ERR,"ERROR:tm:mod_init: failed to process AVP params\n"); + return -1; + } + if ((contacts_avp.len > 0) && (contact_flows_avp.len == 0)) { + LOG(L_ERR,"ERROR:tm:mod_init: contact_flows_avp param has not been defined\n"); + return -1; + } +#ifdef WITH_EVENT_LOCAL_REQUEST + goto_on_local_req=route_lookup(&event_rt, "tm:local-request"); + if (goto_on_local_req>=0 && event_rt.rlist[goto_on_local_req]==0) + goto_on_local_req=-1; /* disable */ + if (goto_on_local_req>=0) + set_child_rpc_sip_mode(); +#endif /* WITH_EVENT_LOCAL_REQUEST */ + if (goto_on_sl_reply && onreply_rt.rlist[goto_on_sl_reply]==0) + WARN("empty/non existing on_sl_reply route\n"); -#ifdef USE_TCP -inline static int w_t_forward_nonack_tcp( struct sip_msg* msg, char* proxy, - char* foo) -{ - return _w_t_forward_nonack(msg, ( struct proxy_l *) proxy, PROTO_TCP); -} +#ifdef WITH_TM_CTX + tm_ctx_init(); #endif + tm_init = 1; + return 0; + } + static int child_init(int rank) + { + if (rank == PROC_INIT) { + /* we must init stats when rank==PROC_INIT: after mod_init we know + * the exact number of processes and we must init the shared structure + * before any other process is starting (or else some new process + * might try to use the stats before the stats array is allocated) */ + if (init_tm_stats_child() < 0) { + ERR("Error while initializing tm statistics structures\n"); + return -1; + } + }else if (child_init_callid(rank) < 0) { + /* don't init callid for PROC_INIT*/ + LOG(L_ERR, "ERROR: child_init: Error while initializing Call-ID" + " generator\n"); + return -2; + } + return 0; + } -#ifdef USE_TLS -inline static int w_t_forward_nonack_tls( struct sip_msg* msg, char* proxy, - char* foo) -{ - return _w_t_forward_nonack(msg, ( struct proxy_l *) proxy, PROTO_TLS); -} -#endif -#ifdef USE_SCTP -inline static int w_t_forward_nonack_sctp( struct sip_msg* msg, char* proxy, - char* foo) -{ - return _w_t_forward_nonack(msg, ( struct proxy_l *) proxy, PROTO_SCTP); -} -#endif + /**************************** wrapper functions ***************************/ + static int t_check_status(struct sip_msg* msg, char *p1, char *foo) + { + regmatch_t pmatch; + struct cell *t; + char *status, *s = NULL; + char backup; + int lowest_status, n, ret; + fparam_t* fp; + regex_t* re = NULL; + str tmp; + + fp = (fparam_t*)p1; + t = 0; + /* first get the transaction */ + if (t_check(msg, 0 ) == -1) return -1; + if ((t = get_t()) == 0) { + LOG(L_ERR, "ERROR: t_check_status: cannot check status for a reply " + "which has no T-state established\n"); + goto error; + } + backup = 0; + + switch(fp->type) { + case FPARAM_REGEX: + re = fp->v.regex; + break; + + default: + /* AVP or select, get the value and compile the regex */ + if (get_str_fparam(&tmp, msg, fp) < 0) goto error; + s = pkg_malloc(tmp.len + 1); + if (s == NULL) { + ERR("Out of memory\n"); + goto error; + } + memcpy(s, tmp.s, tmp.len); + s[tmp.len] = '\0'; + if ((re = pkg_malloc(sizeof(regex_t))) == 0) { + ERR("No memory left\n"); + goto error; + } -inline static int w_t_forward_nonack_to( struct sip_msg *p_msg , - char *proto_par, - char *addr_par ) -{ - struct proxy_l *proxy; - int r = -1; - proxy = t_protoaddr2proxy(proto_par, addr_par); - if (proxy) { - r = _w_t_forward_nonack(p_msg, proxy, proxy->proto); - free_proxy(proxy); - pkg_free(proxy); - } - return r; -} + if (regcomp(re, s, REG_EXTENDED|REG_ICASE|REG_NEWLINE)) { + ERR("Bad regular expression '%s'\n", s); + pkg_free(re); + re = NULL; + goto error; + } + break; + } + switch(get_route_type()) { + case REQUEST_ROUTE: + /* use the status of the last sent reply */ + status = int2str( t->uas.status, 0); + break; + + case TM_ONREPLY_ROUTE: + case CORE_ONREPLY_ROUTE: + /* use the status of the current reply */ + status = msg->first_line.u.reply.status.s; + backup = status[msg->first_line.u.reply.status.len]; + status[msg->first_line.u.reply.status.len] = 0; + break; + + case FAILURE_ROUTE: + /* use the status of the winning reply */ + ret = t_pick_branch( -1, 0, t, &lowest_status); + if (ret == -1) { + /* t_pick_branch() retuns error also when there are only + * blind UACs. Let us give it another chance including the + * blind branches. */ + LOG(L_DBG, "DEBUG: t_check_status: t_pick_branch returned error, " + "trying t_pick_branch_blind\n"); + ret = t_pick_branch_blind(t, &lowest_status); + } + if (ret < 0) { + LOG(L_CRIT,"BUG:t_check_status: t_pick_branch failed to get " + " a final response in FAILURE_ROUTE\n"); + goto error; + } + status = int2str( lowest_status , 0); + break; + case BRANCH_FAILURE_ROUTE: + status = int2str(t->uac[get_t_branch()].last_received, 0); + break; + default: + LOG(L_ERR,"ERROR:t_check_status: unsupported route type %d\n", + get_route_type()); + goto error; + } -inline static int w_t_reply(struct sip_msg* msg, char* p1, char* p2) -{ - struct cell *t; - int code, ret = -1; - str reason; - char* r; + DBG("DEBUG:t_check_status: checked status is <%s>\n",status); + /* do the checking */ + n = regexec(re, status, 1, &pmatch, 0); - if (msg->REQ_METHOD==METHOD_ACK) { - LOG(L_WARN, "WARNING: t_reply: ACKs are not replied\n"); - return -1; - } - if (t_check( msg , 0 )==-1) return -1; - t=get_t(); - if (!t) { - LOG(L_ERR, "ERROR: t_reply: cannot send a t_reply to a message " - "for which no T-state has been established\n"); - return -1; - } + if (backup) status[msg->first_line.u.reply.status.len] = backup; + if (s) pkg_free(s); + if ((fp->type != FPARAM_REGEX) && re) { + regfree(re); + pkg_free(re); + } - if (get_int_fparam(&code, msg, (fparam_t*)p1) < 0) { - code = cfg_get(tm, tm_cfg, default_code); - } - - if (get_str_fparam(&reason, msg, (fparam_t*)p2) < 0) { - r = cfg_get(tm, tm_cfg, default_reason); - } else { - r = as_asciiz(&reason); - if (r == NULL) r = cfg_get(tm, tm_cfg, default_reason); - } - - /* if called from reply_route, make sure that unsafe version - * is called; we are already in a mutex and another mutex in - * the safe version would lead to a deadlock - */ - - t->flags |= T_ADMIN_REPLY; - if (is_route_type(FAILURE_ROUTE)) { - DBG("DEBUG: t_reply_unsafe called from w_t_reply\n"); - ret = t_reply_unsafe(t, msg, code, r); - } else if (is_route_type(REQUEST_ROUTE)) { - ret = t_reply( t, msg, code, r); - } else if (is_route_type(ONREPLY_ROUTE)) { - if (likely(t->uas.request)){ - if (is_route_type(CORE_ONREPLY_ROUTE)) - ret=t_reply(t, t->uas.request, code, r); - else - ret=t_reply_unsafe(t, t->uas.request, code, r); - }else - ret=-1; - /* t_check() above has the side effect of setting T and - REFerencing T => we must unref and unset it. - Note: this is needed only in the CORE_ONREPLY_ROUTE and not also in - the TM_ONREPLY_ROUTE. - */ - if (is_route_type(CORE_ONREPLY_ROUTE)) { + if (unlikely(t && is_route_type(CORE_ONREPLY_ROUTE))){ + /* t_check() above has the side effect of setting T and + * REFerencing T => we must unref and unset it. */ + UNREF( t ); + set_t(T_UNDEFINED, T_BR_UNDEFINED); + } + if (n!=0) return -1; + return 1; + +error: + if (unlikely(t && is_route_type(CORE_ONREPLY_ROUTE))){ + /* t_check() above has the side effect of setting T and + * REFerencing T => we must unref and unset it. */ UNREF( t ); set_t(T_UNDEFINED, T_BR_UNDEFINED); } - } else { - LOG(L_CRIT, "BUG: w_t_reply entered in unsupported mode\n"); - ret = -1; + if (s) pkg_free(s); + if ((fp->type != FPARAM_REGEX) && re) { + regfree(re); + pkg_free(re); + } + return -1; } - if (r && (r != cfg_get(tm, tm_cfg, default_reason))) pkg_free(r); - return ret; -} + inline static int w_t_check(struct sip_msg* msg, char* str, char* str2) + { + return (t_check_msg( msg , 0 )==1) ? 1 : -1; + } -inline static int w_t_release(struct sip_msg* msg, char* str, char* str2) -{ - struct cell *t; - int ret; - - if(get_route_type()!=REQUEST_ROUTE) + inline static int w_t_lookup_cancel(struct sip_msg* msg, char* str, char* str2) { - LM_INFO("invalid usage - not in request route\n"); + struct cell *ret; + int i=0; + if (msg->REQ_METHOD==METHOD_CANCEL) { + ret = t_lookupOriginalT( msg ); + DBG("lookup_original: t_lookupOriginalT returned: %p\n", ret); + if (ret != T_NULL_CELL) { + /* If the parameter is set to 1, overwrite the message flags of + * the CANCEL with the flags of the INVITE */ + if (str && (get_int_fparam(&i, msg, (fparam_t*)str)==0) && i) + msg->flags = ret->uas.request->flags; + + /* The cell is reffed by t_lookupOriginalT, but T is not set. + So we must unref it before returning. */ + UNREF(ret); + return 1; + } + } else { + LOG(L_WARN, "WARNING: script error t_lookup_cancel() called for non-CANCEL request\n"); + } return -1; } - if (t_check( msg , 0 )==-1) return -1; - t=get_t(); - if ( t && t!=T_UNDEFINED ) { - ret = t_release_transaction( t ); - t_unref(msg); - return ret; - } - return 1; -} + inline static int str2proto(char *s, int len) { + if (len == 3 && !strncasecmp(s, "udp", 3)) + return PROTO_UDP; + else if (len == 3 && !strncasecmp(s, "tcp", 3)) /* tcp&tls checks will be passed in getproto() */ + return PROTO_TCP; + else if (len == 3 && !strncasecmp(s, "tls", 3)) + return PROTO_TLS; + else if (len == 4 && !strncasecmp(s, "sctp", 4)) + return PROTO_SCTP; + else if (len == 2 && !strncasecmp(s, "ws", 2)) + return PROTO_WS; + else if (len == 3 && !strncasecmp(s, "wss", 3)) { + LM_WARN("\"wss\" used somewhere...\n"); + return PROTO_WS; + } else + return PROTO_NONE; + } + + inline static struct proxy_l* t_protoaddr2proxy(char *proto_par, char *addr_par) { + struct proxy_l *proxy = 0; + avp_t* avp; + avp_value_t val; + int proto, port, err; + str s; + char *c; + + switch(((fparam_t *)proto_par)->type) { + case FPARAM_AVP: + if (!(avp = search_first_avp(((fparam_t *)proto_par)->v.avp.flags, ((fparam_t *)proto_par)->v.avp.name, &val, 0))) { + proto = PROTO_NONE; + } else { + if (avp->flags & AVP_VAL_STR) { + proto = str2proto(val.s.s, val.s.len); + } + else { + proto = val.n; + } + } + break; + + case FPARAM_INT: + proto = ((fparam_t *)proto_par)->v.i; + break; + case FPARAM_STRING: + proto = str2proto( ((fparam_t *)proto_par)->v.asciiz, strlen(((fparam_t *)proto_par)->v.asciiz)); + break; + default: + ERR("BUG: Invalid proto parameter value in t_protoaddr2proxy\n"); + return 0; + } -inline static int w_t_retransmit_reply( struct sip_msg* p_msg, char* foo, char* bar) -{ - struct cell *t; + switch(((fparam_t *)addr_par)->type) { + case FPARAM_AVP: + if (!(avp = search_first_avp(((fparam_t *)addr_par)->v.avp.flags, ((fparam_t *)addr_par)->v.avp.name, &val, 0))) { + s.len = 0; + } else { + if ((avp->flags & AVP_VAL_STR) == 0) { + LOG(L_ERR, "tm:t_protoaddr2proxy: avp <%.*s> value is not string\n", + ((fparam_t *)addr_par)->v.avp.name.s.len, ((fparam_t *)addr_par)->v.avp.name.s.s); + return 0; + } + s = val.s; + } + break; + case FPARAM_STRING: + s.s = ((fparam_t *) addr_par)->v.asciiz; + s.len = strlen(s.s); + break; - if (t_check( p_msg , 0 )==-1) - return 1; - t=get_t(); - if (t) { - if (p_msg->REQ_METHOD==METHOD_ACK) { - LOG(L_WARN, "WARNING: : ACKs transmit_replies not replied\n"); - return -1; + default: + ERR("BUG: Invalid addr parameter value in t_protoaddr2proxy\n"); + return 0; } - return t_retransmit_reply( t ); - } else - return -1; -} - - -inline static int w_t_newtran( struct sip_msg* p_msg, char* foo, char* bar ) -{ - /* t_newtran returns 0 on error (negative value means - 'transaction exists' */ - int ret; - ret = t_newtran( p_msg ); - if (ret==E_SCRIPT) { - LOG(L_ERR, "ERROR: t_newtran: " - "transaction already in process %p\n", get_t() ); - } - return ret; -} - - -inline static int w_t_on_failure( struct sip_msg* msg, char *go_to, char *foo) -{ - t_on_failure( (unsigned int )(long) go_to ); - return 1; -} - - -inline static int w_t_on_branch_failure( struct sip_msg* msg, char *go_to, char *foo) -{ - t_on_branch_failure( (unsigned int )(long) go_to ); - return 1; -} - - -inline static int w_t_on_branch( struct sip_msg* msg, char *go_to, char *foo) -{ - t_on_branch( (unsigned int )(long) go_to ); - return 1; -} - - -inline static int w_t_on_reply( struct sip_msg* msg, char *go_to, char *foo ) -{ - t_on_reply( (unsigned int )(long) go_to ); - return 1; -} - - -static int w_t_is_set(struct sip_msg* msg, char *target, char *foo ) -{ - int r; - tm_cell_t *t = NULL; - - r = 0; - t = get_t(); - if (t==T_UNDEFINED) t = NULL; - - switch(target[0]) { - case 'b': - if(t==NULL) - r = get_on_branch(); - else - r = t->on_branch; - break; - case 'f': - if(t==NULL) - r = get_on_failure(); - else - r = t->on_failure; - break; - case 'o': - if(t==NULL) - r = get_on_reply(); - else - r = t->on_reply; - break; - } - if(r) return 1; - return -1; -} - -static int fixup_t_is_set(void** param, int param_no) -{ - int len; - if (param_no==1) { - len = strlen((char*)*param); - if((len==13 && strncmp((char*)*param, "failure_route", 13)==0) - || (len==13 && strncmp((char*)*param, "onreply_route", 13)==0) - || (len==12 && strncmp((char*)*param, "branch_route", 12)==0)) { + + port = 5060; + if (s.len) { + c = memchr(s.s, ':', s.len); + if (c) { + port = str2s(c+1, s.len-(c-s.s+1), &err); + if (err!=0) { + LOG(L_ERR, "tm:t_protoaddr2proxy: bad port number <%.*s>\n", + s.len, s.s); + return 0; + } + s.len = c-s.s; + } + } + if (!s.len) { + LOG(L_ERR, "tm: protoaddr2proxy: host name is empty\n"); return 0; } - - LM_ERR("invalid parameter value: %s\n", (char*)*param); - return 1; + proxy=mk_proxy(&s, port, proto); + if (proxy==0) { + LOG(L_ERR, "tm: protoaddr2proxy: bad host name in URI <%.*s>\n", + s.len, s.s ); + return 0; + } + return proxy; } - return 0; -} -inline static int _w_t_relay_to(struct sip_msg *p_msg , - struct proxy_l *proxy, int force_proto) -{ - struct cell *t; - int res; - - if (is_route_type(FAILURE_ROUTE|BRANCH_FAILURE_ROUTE)) { - t=get_t(); - if (!t || t==T_UNDEFINED) { - LOG(L_CRIT, "BUG: w_t_relay_to: undefined T\n"); + inline static int _w_t_forward_nonack(struct sip_msg* msg, struct proxy_l* proxy, + int proto) + { + struct cell *t; + if (t_check( msg , 0 )==-1) { + LOG(L_ERR, "ERROR: forward_nonack: " + "can't forward when no transaction was set up\n"); return -1; } - res = t_forward_nonack(t, p_msg, proxy, force_proto); - if (res <= 0) { - if (res != E_CFG) { - LOG(L_ERR, "ERROR: w_t_relay_to: t_relay_to failed\n"); - /* let us save the error code, we might need it later - when the failure_route has finished (Miklos) */ + t=get_t(); + if ( t && t!=T_UNDEFINED ) { + if (msg->REQ_METHOD==METHOD_ACK) { + LOG(L_WARN,"WARNING: you don't really want to fwd hbh ACK\n"); + return -1; } - tm_error=ser_error; + return t_forward_nonack(t, msg, proxy, proto ); + } else { + DBG("DEBUG: forward_nonack: no transaction found\n"); return -1; } - return 1; } - if (is_route_type(REQUEST_ROUTE)) - return t_relay_to( p_msg, proxy, force_proto, - 0 /* no replication */ ); - LOG(L_CRIT, "ERROR: w_t_relay_to: unsupported route type: %d\n", - get_route_type()); - return 0; -} -inline static int w_t_relay_to_udp( struct sip_msg *p_msg , - char *proxy,/* struct proxy_l * expected */ - char *_foo /* nothing expected */ ) -{ - return _w_t_relay_to( p_msg, ( struct proxy_l *) proxy, PROTO_UDP); -} + inline static int w_t_forward_nonack( struct sip_msg* msg, char* proxy, + char* foo) + { + return _w_t_forward_nonack(msg, ( struct proxy_l *) proxy, PROTO_NONE); + } -/* forward to uri, but force udp as transport */ -inline static int w_t_relay_to_udp_uri( struct sip_msg *p_msg , - char *_foo, char *_bar ) -{ - return _w_t_relay_to(p_msg, (struct proxy_l *)0, PROTO_UDP); -} + + inline static int w_t_forward_nonack_uri(struct sip_msg* msg, char *foo, + char *bar) + { + return _w_t_forward_nonack(msg, 0, PROTO_NONE); + } + + + inline static int w_t_forward_nonack_udp( struct sip_msg* msg, char* proxy, + char* foo) + { + return _w_t_forward_nonack(msg, ( struct proxy_l *) proxy, PROTO_UDP); + } #ifdef USE_TCP -inline static int w_t_relay_to_tcp( struct sip_msg *p_msg , - char *proxy, /* struct proxy_l* */ - char *_foo /* nothing expected */ ) -{ - return _w_t_relay_to( p_msg, ( struct proxy_l *) proxy, PROTO_TCP); -} - -/* forward to uri, but force tcp as transport */ -inline static int w_t_relay_to_tcp_uri( struct sip_msg *p_msg , - char *_foo, char *_bar ) -{ - return _w_t_relay_to(p_msg, (struct proxy_l *)0, PROTO_TCP); -} + inline static int w_t_forward_nonack_tcp( struct sip_msg* msg, char* proxy, + char* foo) + { + return _w_t_forward_nonack(msg, ( struct proxy_l *) proxy, PROTO_TCP); + } #endif #ifdef USE_TLS -inline static int w_t_relay_to_tls( struct sip_msg *p_msg , - char *proxy, /* struct proxy_l* expected */ - char *_foo /* nothing expected */ ) -{ - return _w_t_relay_to( p_msg, ( struct proxy_l *) proxy, PROTO_TLS); -} - -/* forward to uri, but force tls as transport */ -inline static int w_t_relay_to_tls_uri( struct sip_msg *p_msg , - char *_foo, char *_bar ) -{ - return _w_t_relay_to(p_msg, (struct proxy_l *)0, PROTO_TLS); -} + inline static int w_t_forward_nonack_tls( struct sip_msg* msg, char* proxy, + char* foo) + { + return _w_t_forward_nonack(msg, ( struct proxy_l *) proxy, PROTO_TLS); + } #endif #ifdef USE_SCTP -inline static int w_t_relay_to_sctp( struct sip_msg *p_msg , - char *proxy, /* struct proxy_l* */ - char *_foo /* nothing expected */ ) -{ - return _w_t_relay_to( p_msg, ( struct proxy_l *) proxy, PROTO_SCTP); -} - -/* forward to uri, but force tcp as transport */ -inline static int w_t_relay_to_sctp_uri( struct sip_msg *p_msg , - char *_foo, char *_bar ) -{ - return _w_t_relay_to(p_msg, (struct proxy_l *)0, PROTO_SCTP); -} + inline static int w_t_forward_nonack_sctp( struct sip_msg* msg, char* proxy, + char* foo) + { + return _w_t_forward_nonack(msg, ( struct proxy_l *) proxy, PROTO_SCTP); + } #endif -inline static int w_t_relay_to_avp( struct sip_msg *p_msg , - char *proto_par, - char *addr_par ) -{ - struct proxy_l *proxy; - int r = -1; - - proxy = t_protoaddr2proxy(proto_par, addr_par); - if (proxy) { - r = _w_t_relay_to(p_msg, proxy, PROTO_NONE); - free_proxy(proxy); - pkg_free(proxy); - } - return r; -} - -int t_replicate_uri(struct sip_msg *msg, str *suri) -{ - struct proxy_l *proxy = NULL; - struct sip_uri turi; - int r = -1; - - if (suri != NULL && suri->s != NULL && suri->len > 0) - { - memset(&turi, 0, sizeof(struct sip_uri)); - if(parse_uri(suri->s, suri->len, &turi)!=0) + inline static int w_t_forward_nonack_to( struct sip_msg *p_msg , + char *proto_par, + char *addr_par ) + { + struct proxy_l *proxy; + int r = -1; + proxy = t_protoaddr2proxy(proto_par, addr_par); + if (proxy) { + r = _w_t_forward_nonack(p_msg, proxy, proxy->proto); + free_proxy(proxy); + pkg_free(proxy); + } + return r; + } + + + inline static int w_t_reply(struct sip_msg* msg, char* p1, char* p2) + { + struct cell *t; + int code, ret = -1; + str reason; + char* r; + + if (msg->REQ_METHOD==METHOD_ACK) { + LOG(L_WARN, "WARNING: t_reply: ACKs are not replied\n"); + return -1; + } + if (t_check( msg , 0 )==-1) return -1; + t=get_t(); + if (!t) { + LOG(L_ERR, "ERROR: t_reply: cannot send a t_reply to a message " + "for which no T-state has been established\n"); + return -1; + } + + if (get_int_fparam(&code, msg, (fparam_t*)p1) < 0) { + code = cfg_get(tm, tm_cfg, default_code); + } + + if (get_str_fparam(&reason, msg, (fparam_t*)p2) < 0) { + r = cfg_get(tm, tm_cfg, default_reason); + } else { + r = as_asciiz(&reason); + if (r == NULL) r = cfg_get(tm, tm_cfg, default_reason); + } + + /* if called from reply_route, make sure that unsafe version + * is called; we are already in a mutex and another mutex in + * the safe version would lead to a deadlock + */ + + t->flags |= T_ADMIN_REPLY; + if (is_route_type(FAILURE_ROUTE)) { + DBG("DEBUG: t_reply_unsafe called from w_t_reply\n"); + ret = t_reply_unsafe(t, msg, code, r); + } else if (is_route_type(REQUEST_ROUTE)) { + ret = t_reply( t, msg, code, r); + } else if (is_route_type(ONREPLY_ROUTE)) { + if (likely(t->uas.request)){ + if (is_route_type(CORE_ONREPLY_ROUTE)) + ret=t_reply(t, t->uas.request, code, r); + else + ret=t_reply_unsafe(t, t->uas.request, code, r); + }else + ret=-1; + /* t_check() above has the side effect of setting T and + * REFerencing T => we must unref and unset it. + * Note: this is needed only in the CORE_ONREPLY_ROUTE and not also in + * the TM_ONREPLY_ROUTE. + */ + if (is_route_type(CORE_ONREPLY_ROUTE)) { + UNREF( t ); + set_t(T_UNDEFINED, T_BR_UNDEFINED); + } + } else { + LOG(L_CRIT, "BUG: w_t_reply entered in unsupported mode\n"); + ret = -1; + } + + if (r && (r != cfg_get(tm, tm_cfg, default_reason))) pkg_free(r); + return ret; + } + + + inline static int w_t_release(struct sip_msg* msg, char* str, char* str2) + { + struct cell *t; + int ret; + + if(get_route_type()!=REQUEST_ROUTE) { - LM_ERR("bad replicate SIP address!\n"); + LM_INFO("invalid usage - not in request route\n"); return -1; } - proxy=mk_proxy(&turi.host, turi.port_no, turi.proto); - if (proxy==0) { - LM_ERR("cannot create proxy from URI <%.*s>\n", - suri->len, suri->s ); + if (t_check( msg , 0 )==-1) return -1; + t=get_t(); + if ( t && t!=T_UNDEFINED ) { + ret = t_release_transaction( t ); + t_unref(msg); + return ret; + } + return 1; + } + + + inline static int w_t_retransmit_reply( struct sip_msg* p_msg, char* foo, char* bar) + { + struct cell *t; + + + if (t_check( p_msg , 0 )==-1) + return 1; + t=get_t(); + if (t) { + if (p_msg->REQ_METHOD==METHOD_ACK) { + LOG(L_WARN, "WARNING: : ACKs transmit_replies not replied\n"); + return -1; + } + return t_retransmit_reply( t ); + } else return -1; + } + + + inline static int w_t_newtran( struct sip_msg* p_msg, char* foo, char* bar ) + { + /* t_newtran returns 0 on error (negative value means + * 'transaction exists' */ + int ret; + ret = t_newtran( p_msg ); + if (ret==E_SCRIPT) { + LOG(L_ERR, "ERROR: t_newtran: " + "transaction already in process %p\n", get_t() ); } + return ret; + } + - r = t_replicate(msg, proxy, proxy->proto); - free_proxy(proxy); - pkg_free(proxy); - } else { - r = t_replicate(msg, NULL, 0); + inline static int w_t_on_failure( struct sip_msg* msg, char *go_to, char *foo) + { + t_on_failure( (unsigned int )(long) go_to ); + return 1; + } + + + inline static int w_t_on_branch_failure( struct sip_msg* msg, char *go_to, char *foo) + { + t_on_branch_failure( (unsigned int )(long) go_to ); + return 1; } - return r; -} -inline static int w_t_replicate_uri(struct sip_msg *msg , - char *uri, /* sip uri as string or variable */ - char *_foo /* nothing expected */ ) -{ - str suri; - if(uri==NULL) - return t_replicate_uri(msg, NULL); + inline static int w_t_on_branch( struct sip_msg* msg, char *go_to, char *foo) + { + t_on_branch( (unsigned int )(long) go_to ); + return 1; + } - if(fixup_get_svalue(msg, (gparam_p)uri, &suri)!=0) + + inline static int w_t_on_reply( struct sip_msg* msg, char *go_to, char *foo ) { - LM_ERR("invalid replicate uri parameter"); + t_on_reply( (unsigned int )(long) go_to ); + return 1; + } + + + static int w_t_is_set(struct sip_msg* msg, char *target, char *foo ) + { + int r; + tm_cell_t *t = NULL; + + r = 0; + t = get_t(); + if (t==T_UNDEFINED) t = NULL; + + switch(target[0]) { + case 'b': + if(t==NULL) + r = get_on_branch(); + else + r = t->on_branch; + break; + case 'f': + if(t==NULL) + r = get_on_failure(); + else + r = t->on_failure; + break; + case 'o': + if(t==NULL) + r = get_on_reply(); + else + r = t->on_reply; + break; + } + if(r) return 1; return -1; } - return t_replicate_uri(msg, &suri); -} -inline static int w_t_replicate( struct sip_msg *p_msg , - char *proxy, /* struct proxy_l *proxy expected */ - char *_foo /* nothing expected */ ) -{ - return t_replicate(p_msg, ( struct proxy_l *) proxy, p_msg->rcv.proto ); -} + static int fixup_t_is_set(void** param, int param_no) + { + int len; + if (param_no==1) { + len = strlen((char*)*param); + if((len==13 && strncmp((char*)*param, "failure_route", 13)==0) + || (len==13 && strncmp((char*)*param, "onreply_route", 13)==0) + || (len==12 && strncmp((char*)*param, "branch_route", 12)==0)) { + return 0; + } + + LM_ERR("invalid parameter value: %s\n", (char*)*param); + return 1; + } + return 0; + } + + inline static int _w_t_relay_to(struct sip_msg *p_msg , + struct proxy_l *proxy, int force_proto) + { + struct cell *t; + int res; + + if (is_route_type(FAILURE_ROUTE|BRANCH_FAILURE_ROUTE)) { + t=get_t(); + if (!t || t==T_UNDEFINED) { + LOG(L_CRIT, "BUG: w_t_relay_to: undefined T\n"); + return -1; + } + res = t_forward_nonack(t, p_msg, proxy, force_proto); + if (res <= 0) { + if (res != E_CFG) { + LOG(L_ERR, "ERROR: w_t_relay_to: t_relay_to failed\n"); + /* let us save the error code, we might need it later + * when the failure_route has finished (Miklos) */ + } + tm_error=ser_error; + return -1; + } + return 1; + } + if (is_route_type(REQUEST_ROUTE)) + return t_relay_to( p_msg, proxy, force_proto, + 0 /* no replication */ ); + LOG(L_CRIT, "ERROR: w_t_relay_to: unsupported route type: %d\n", + get_route_type()); + return 0; + } -inline static int w_t_replicate_udp( struct sip_msg *p_msg , - char *proxy, /* struct proxy_l *proxy expected */ - char *_foo /* nothing expected */ ) -{ - return t_replicate(p_msg, ( struct proxy_l *) proxy, PROTO_UDP ); -} + + inline static int w_t_relay_to_udp( struct sip_msg *p_msg , + char *proxy,/* struct proxy_l * expected */ + char *_foo /* nothing expected */ ) + { + return _w_t_relay_to( p_msg, ( struct proxy_l *) proxy, PROTO_UDP); + } + + /* forward to uri, but force udp as transport */ + inline static int w_t_relay_to_udp_uri( struct sip_msg *p_msg , + char *_foo, char *_bar ) + { + return _w_t_relay_to(p_msg, (struct proxy_l *)0, PROTO_UDP); + } #ifdef USE_TCP -inline static int w_t_replicate_tcp( struct sip_msg *p_msg , - char *proxy, /* struct proxy_l *proxy expected */ - char *_foo /* nothing expected */ ) -{ - return t_replicate(p_msg, ( struct proxy_l *) proxy, PROTO_TCP ); -} + inline static int w_t_relay_to_tcp( struct sip_msg *p_msg , + char *proxy, /* struct proxy_l* */ + char *_foo /* nothing expected */ ) + { + return _w_t_relay_to( p_msg, ( struct proxy_l *) proxy, PROTO_TCP); + } + + /* forward to uri, but force tcp as transport */ + inline static int w_t_relay_to_tcp_uri( struct sip_msg *p_msg , + char *_foo, char *_bar ) + { + return _w_t_relay_to(p_msg, (struct proxy_l *)0, PROTO_TCP); + } #endif #ifdef USE_TLS -inline static int w_t_replicate_tls( struct sip_msg *p_msg , - char *proxy, /* struct proxy_l *proxy expected */ - char *_foo /* nothing expected */ ) -{ - return t_replicate(p_msg, ( struct proxy_l *) proxy, PROTO_TLS ); -} + inline static int w_t_relay_to_tls( struct sip_msg *p_msg , + char *proxy, /* struct proxy_l* expected */ + char *_foo /* nothing expected */ ) + { + return _w_t_relay_to( p_msg, ( struct proxy_l *) proxy, PROTO_TLS); + } + + /* forward to uri, but force tls as transport */ + inline static int w_t_relay_to_tls_uri( struct sip_msg *p_msg , + char *_foo, char *_bar ) + { + return _w_t_relay_to(p_msg, (struct proxy_l *)0, PROTO_TLS); + } #endif #ifdef USE_SCTP -inline static int w_t_replicate_sctp( struct sip_msg *p_msg , - char *proxy, /* struct proxy_l *proxy expected */ - char *_foo /* nothing expected */ ) -{ - return t_replicate(p_msg, ( struct proxy_l *) proxy, PROTO_SCTP ); -} + inline static int w_t_relay_to_sctp( struct sip_msg *p_msg , + char *proxy, /* struct proxy_l* */ + char *_foo /* nothing expected */ ) + { + return _w_t_relay_to( p_msg, ( struct proxy_l *) proxy, PROTO_SCTP); + } + + /* forward to uri, but force tcp as transport */ + inline static int w_t_relay_to_sctp_uri( struct sip_msg *p_msg , + char *_foo, char *_bar ) + { + return _w_t_relay_to(p_msg, (struct proxy_l *)0, PROTO_SCTP); + } #endif -inline static int w_t_replicate_to( struct sip_msg *p_msg , - char *proto_par, - char *addr_par ) -{ - struct proxy_l *proxy; - int r = -1; - proxy = t_protoaddr2proxy(proto_par, addr_par); - if (proxy) { - r = t_replicate(p_msg, proxy, proxy->proto); - free_proxy(proxy); - pkg_free(proxy); - } - return r; -} - -inline static int w_t_relay( struct sip_msg *p_msg , - char *_foo, char *_bar) -{ - return _w_t_relay_to(p_msg, (struct proxy_l *)0, PROTO_NONE); -} - - -/* like t_relay but use the specified destination and port and the same proto - * as the received msg */ -static int w_t_relay2( struct sip_msg *p_msg , char *proxy, - char *_foo) -{ - return _w_t_relay_to(p_msg, (struct proxy_l*) proxy, p_msg->rcv.proto); -} - - -/* relays CANCEL at the beginning of the script */ -inline static int w_t_relay_cancel( struct sip_msg *p_msg , - char *_foo, char *_bar) -{ - if (p_msg->REQ_METHOD!=METHOD_CANCEL) - return 1; + inline static int w_t_relay_to_avp( struct sip_msg *p_msg , + char *proto_par, + char *addr_par ) + { + struct proxy_l *proxy; + int r = -1; + + proxy = t_protoaddr2proxy(proto_par, addr_par); + if (proxy) { + r = _w_t_relay_to(p_msg, proxy, PROTO_NONE); + free_proxy(proxy); + pkg_free(proxy); + } + return r; + } + + int t_replicate_uri(struct sip_msg *msg, str *suri) + { + struct proxy_l *proxy = NULL; + struct sip_uri turi; + int r = -1; + + if (suri != NULL && suri->s != NULL && suri->len > 0) + { + memset(&turi, 0, sizeof(struct sip_uri)); + if(parse_uri(suri->s, suri->len, &turi)!=0) + { + LM_ERR("bad replicate SIP address!\n"); + return -1; + } + + proxy=mk_proxy(&turi.host, turi.port_no, turi.proto); + if (proxy==0) { + LM_ERR("cannot create proxy from URI <%.*s>\n", + suri->len, suri->s ); + return -1; + } + + r = t_replicate(msg, proxy, proxy->proto); + free_proxy(proxy); + pkg_free(proxy); + } else { + r = t_replicate(msg, NULL, 0); + } + return r; + } + + inline static int w_t_replicate_uri(struct sip_msg *msg , + char *uri, /* sip uri as string or variable */ + char *_foo /* nothing expected */ ) + { + str suri; + + if(uri==NULL) + return t_replicate_uri(msg, NULL); + + if(fixup_get_svalue(msg, (gparam_p)uri, &suri)!=0) + { + LM_ERR("invalid replicate uri parameter"); + return -1; + } + return t_replicate_uri(msg, &suri); + } + + inline static int w_t_replicate( struct sip_msg *p_msg , + char *proxy, /* struct proxy_l *proxy expected */ + char *_foo /* nothing expected */ ) + { + return t_replicate(p_msg, ( struct proxy_l *) proxy, p_msg->rcv.proto ); + } + + inline static int w_t_replicate_udp( struct sip_msg *p_msg , + char *proxy, /* struct proxy_l *proxy expected */ + char *_foo /* nothing expected */ ) + { + return t_replicate(p_msg, ( struct proxy_l *) proxy, PROTO_UDP ); + } + + +#ifdef USE_TCP + inline static int w_t_replicate_tcp( struct sip_msg *p_msg , + char *proxy, /* struct proxy_l *proxy expected */ + char *_foo /* nothing expected */ ) + { + return t_replicate(p_msg, ( struct proxy_l *) proxy, PROTO_TCP ); + } +#endif + + +#ifdef USE_TLS + inline static int w_t_replicate_tls( struct sip_msg *p_msg , + char *proxy, /* struct proxy_l *proxy expected */ + char *_foo /* nothing expected */ ) + { + return t_replicate(p_msg, ( struct proxy_l *) proxy, PROTO_TLS ); + } +#endif + + +#ifdef USE_SCTP + inline static int w_t_replicate_sctp( struct sip_msg *p_msg , + char *proxy, /* struct proxy_l *proxy expected */ + char *_foo /* nothing expected */ ) + { + return t_replicate(p_msg, ( struct proxy_l *) proxy, PROTO_SCTP ); + } +#endif + + + inline static int w_t_replicate_to( struct sip_msg *p_msg , + char *proto_par, + char *addr_par ) + { + struct proxy_l *proxy; + int r = -1; + proxy = t_protoaddr2proxy(proto_par, addr_par); + if (proxy) { + r = t_replicate(p_msg, proxy, proxy->proto); + free_proxy(proxy); + pkg_free(proxy); + } + return r; + } + + inline static int w_t_relay( struct sip_msg *p_msg , + char *_foo, char *_bar) + { + return _w_t_relay_to(p_msg, (struct proxy_l *)0, PROTO_NONE); + } + + + /* like t_relay but use the specified destination and port and the same proto + * as the received msg */ + static int w_t_relay2( struct sip_msg *p_msg , char *proxy, + char *_foo) + { + return _w_t_relay_to(p_msg, (struct proxy_l*) proxy, p_msg->rcv.proto); + } + + + /* relays CANCEL at the beginning of the script */ + inline static int w_t_relay_cancel( struct sip_msg *p_msg , + char *_foo, char *_bar) + { + if (p_msg->REQ_METHOD!=METHOD_CANCEL) + return 1; + + /* it makes no sense to use this function without reparse_invite=1 */ + if (!cfg_get(tm, tm_cfg, reparse_invite)) + LOG(L_WARN, "WARNING: t_relay_cancel is probably used with " + "wrong configuration, check the readme for details\n"); + + return t_relay_cancel(p_msg); + } + + /* set fr_inv_timeout & or fr_timeout; 0 means: use the default value */ + static int t_set_fr_all(struct sip_msg* msg, char* p1, char* p2) + { + int fr, fr_inv; + + if (get_int_fparam(&fr_inv, msg, (fparam_t*)p1) < 0) return -1; + if (p2) { + if (get_int_fparam(&fr, msg, (fparam_t*)p2) < 0) return -1; + } else { + fr = 0; + } + + return t_set_fr(msg, fr_inv, fr); + } - /* it makes no sense to use this function without reparse_invite=1 */ - if (!cfg_get(tm, tm_cfg, reparse_invite)) - LOG(L_WARN, "WARNING: t_relay_cancel is probably used with " - "wrong configuration, check the readme for details\n"); - - return t_relay_cancel(p_msg); -} - -/* set fr_inv_timeout & or fr_timeout; 0 means: use the default value */ -static int t_set_fr_all(struct sip_msg* msg, char* p1, char* p2) -{ - int fr, fr_inv; - - if (get_int_fparam(&fr_inv, msg, (fparam_t*)p1) < 0) return -1; - if (p2) { - if (get_int_fparam(&fr, msg, (fparam_t*)p2) < 0) return -1; - } else { - fr = 0; - } - - return t_set_fr(msg, fr_inv, fr); -} - -static int t_set_fr_inv(struct sip_msg* msg, char* fr_inv, char* foo) -{ - return t_set_fr_all(msg, fr_inv, (char*)0); -} - -/* reset fr_timer and fr_inv_timer to the default values */ -static int w_t_reset_fr(struct sip_msg* msg, char* foo, char* bar) -{ - return t_reset_fr(); -} - -/* set retr. intervals per transaction; 0 means: use the default value */ -static int w_t_set_retr(struct sip_msg* msg, char* p1, char* p2) -{ - int t1, t2; - - if (get_int_fparam(&t1, msg, (fparam_t*)p1) < 0) return -1; - if (p2) { - if (get_int_fparam(&t2, msg, (fparam_t*)p2) < 0) return -1; - } else { - t2 = 0; + static int t_set_fr_inv(struct sip_msg* msg, char* fr_inv, char* foo) + { + return t_set_fr_all(msg, fr_inv, (char*)0); + } + + /* reset fr_timer and fr_inv_timer to the default values */ + static int w_t_reset_fr(struct sip_msg* msg, char* foo, char* bar) + { + return t_reset_fr(); } + + /* set retr. intervals per transaction; 0 means: use the default value */ + static int w_t_set_retr(struct sip_msg* msg, char* p1, char* p2) + { + int t1, t2; + + if (get_int_fparam(&t1, msg, (fparam_t*)p1) < 0) return -1; + if (p2) { + if (get_int_fparam(&t2, msg, (fparam_t*)p2) < 0) return -1; + } else { + t2 = 0; + } #ifdef TM_DIFF_RT_TIMEOUT - return t_set_retr(msg, t1, t2); + return t_set_retr(msg, t1, t2); #else - ERR("w_t_set_retr: support for changing retransmission intervals on " - "the fly not compiled in (re-compile tm with" - " -DTM_DIFF_RT_TIMEOUT)\n"); - return -1; + ERR("w_t_set_retr: support for changing retransmission intervals on " + "the fly not compiled in (re-compile tm with" + " -DTM_DIFF_RT_TIMEOUT)\n"); + return -1; #endif -} + } -/* reset retr. t1 and t2 to the default values */ -int w_t_reset_retr(struct sip_msg* msg, char* foo, char* bar) -{ + /* reset retr. t1 and t2 to the default values */ + int w_t_reset_retr(struct sip_msg* msg, char* foo, char* bar) + { #ifdef TM_DIFF_RT_TIMEOUT - return t_reset_retr(); + return t_reset_retr(); #else - ERR("w_t_reset_retr: support for changing retransmission intervals on " - "the fly not compiled in (re-compile tm with" - " -DTM_DIFF_RT_TIMEOUT)\n"); - return -1; + ERR("w_t_reset_retr: support for changing retransmission intervals on " + "the fly not compiled in (re-compile tm with" + " -DTM_DIFF_RT_TIMEOUT)\n"); + return -1; #endif -} - -/* set maximum transaction lifetime for inv & noninv */ -static int w_t_set_max_lifetime(struct sip_msg* msg, char* p1, char* p2) -{ - int t1, t2; - - if (get_int_fparam(&t1, msg, (fparam_t*)p1) < 0) return -1; - if (p2) { - if (get_int_fparam(&t2, msg, (fparam_t*)p2) < 0) return -1; - } else { - t2 = 0; - } - return t_set_max_lifetime(msg, t1, t2); -} - -/* reset maximum invite/non-invite lifetime to the default value */ -int w_t_reset_max_lifetime(struct sip_msg* msg, char* foo, char* bar) -{ - return t_reset_max_lifetime(); -} - - - -/* helper macro, builds a function for setting a cell flag from the script. - e.g. T_SET_FLAG_GEN_FUNC(t_set_foo, T_FOO) => - static int t_set_foo(struct sip_msg* msg, char*, char* ) - that will expect fparam as first param and will set or reset T_FOO - in the current or next to be created transaction. */ + } + + /* set maximum transaction lifetime for inv & noninv */ + static int w_t_set_max_lifetime(struct sip_msg* msg, char* p1, char* p2) + { + int t1, t2; + + if (get_int_fparam(&t1, msg, (fparam_t*)p1) < 0) return -1; + if (p2) { + if (get_int_fparam(&t2, msg, (fparam_t*)p2) < 0) return -1; + } else { + t2 = 0; + } + return t_set_max_lifetime(msg, t1, t2); + } + + /* reset maximum invite/non-invite lifetime to the default value */ + int w_t_reset_max_lifetime(struct sip_msg* msg, char* foo, char* bar) + { + return t_reset_max_lifetime(); + } + + + + /** + * helper macro, builds a function for setting a cell flag from the script. + * e.g. T_SET_FLAG_GEN_FUNC(t_set_foo, T_FOO) => + * static int t_set_foo(struct sip_msg* msg, char*, char* ) + * that will expect fparam as first param and will set or reset T_FOO + * in the current or next to be created transaction. */ #define T_SET_FLAG_GEN_FUNC(fname, T_FLAG_NAME) \ -static int fname(struct sip_msg* msg, char* p1, char* p2) \ -{ \ - int state; \ - struct cell* t; \ - unsigned int set_flags; \ - unsigned int reset_flags; \ - \ - if (get_int_fparam(&state, msg, (fparam_t*)p1) < 0) return -1; \ - t=get_t(); \ - /* in REPLY_ROUTE and FAILURE_ROUTE T will be set to current transaction; \ - * in REQUEST_ROUTE T will be set only if the transaction was already \ - * created; if not -> use the static variables */ \ - if (!t || t==T_UNDEFINED ){ \ - set_flags=get_msgid_val(user_cell_set_flags, msg->id, int); \ - reset_flags=get_msgid_val(user_cell_reset_flags, msg->id, int); \ - if (state){ \ - /* set */ \ - set_flags|= T_FLAG_NAME; \ - reset_flags&=~T_FLAG_NAME; \ + static int fname(struct sip_msg* msg, char* p1, char* p2) \ + { \ + int state; \ + struct cell* t; \ + unsigned int set_flags; \ + unsigned int reset_flags; \ + \ + if (get_int_fparam(&state, msg, (fparam_t*)p1) < 0) return -1; \ + t=get_t(); \ + /* in REPLY_ROUTE and FAILURE_ROUTE T will be set to current transaction; \ + * in REQUEST_ROUTE T will be set only if the transaction was already \ + * created; if not -> use the static variables */ \ + if (!t || t==T_UNDEFINED ){ \ + set_flags=get_msgid_val(user_cell_set_flags, msg->id, int); \ + reset_flags=get_msgid_val(user_cell_reset_flags, msg->id, int); \ + if (state){ \ + /* set */ \ + set_flags|= T_FLAG_NAME; \ + reset_flags&=~T_FLAG_NAME; \ + }else{ \ + /* reset */ \ + set_flags&=~T_FLAG_NAME; \ + reset_flags|=T_FLAG_NAME; \ + } \ + set_msgid_val(user_cell_set_flags, msg->id, int, set_flags); \ + set_msgid_val(user_cell_reset_flags, msg->id, int, reset_flags); \ }else{ \ - /* reset */ \ - set_flags&=~T_FLAG_NAME; \ - reset_flags|=T_FLAG_NAME; \ - } \ - set_msgid_val(user_cell_set_flags, msg->id, int, set_flags); \ - set_msgid_val(user_cell_reset_flags, msg->id, int, reset_flags); \ - }else{ \ - if (state) \ + if (state) \ t->flags|=T_FLAG_NAME; \ - else \ + else \ t->flags&=~T_FLAG_NAME; \ - } \ - return 1; \ -} + } \ + return 1; \ + } -/* set automatically sending 100 replies on/off for the current or - * next to be created transaction */ -T_SET_FLAG_GEN_FUNC(t_set_auto_inv_100, T_AUTO_INV_100) + /* set automatically sending 100 replies on/off for the current or + * next to be created transaction */ + T_SET_FLAG_GEN_FUNC(t_set_auto_inv_100, T_AUTO_INV_100) -/* set 6xx handling for the current or next to be created transaction */ -T_SET_FLAG_GEN_FUNC(t_set_disable_6xx, T_DISABLE_6xx) + /* set 6xx handling for the current or next to be created transaction */ + T_SET_FLAG_GEN_FUNC(t_set_disable_6xx, T_DISABLE_6xx) -/* disable dns failover for the current transaction */ -T_SET_FLAG_GEN_FUNC(t_set_disable_failover, T_DISABLE_FAILOVER) + /* disable dns failover for the current transaction */ + T_SET_FLAG_GEN_FUNC(t_set_disable_failover, T_DISABLE_FAILOVER) #ifdef CANCEL_REASON_SUPPORT -/* disable/enable e2e cancel reason copy for the current transaction */ -T_SET_FLAG_GEN_FUNC(t_set_no_e2e_cancel_reason, T_NO_E2E_CANCEL_REASON) + /* disable/enable e2e cancel reason copy for the current transaction */ + T_SET_FLAG_GEN_FUNC(t_set_no_e2e_cancel_reason, T_NO_E2E_CANCEL_REASON) #endif /* CANCEL_REASON_SUPPORT */ -/* disable internal negative reply for the current transaction */ -T_SET_FLAG_GEN_FUNC(t_set_disable_internal_reply, T_DISABLE_INTERNAL_REPLY) - - -/* script function, FAILURE_ROUTE and BRANCH_FAILURE_ROUTE only, - * returns true if the choosed "failure" branch failed because of a timeout, - * -1 otherwise */ -int t_branch_timeout(struct sip_msg* msg, char* foo, char* bar) -{ - switch(get_route_type()) { - case FAILURE_ROUTE: - case BRANCH_FAILURE_ROUTE: - return (msg->msg_flags & FL_TIMEOUT)?1:-1; - default: - LOG(L_ERR, "ERROR:t_check_status: unsupported route type %d\n", - get_route_type()); - } - return -1; -} - - -/* script function, FAILURE_ROUTE and BRANCH_FAILURE_ROUTE only, - * returns true if the choosed "failure" branch ever received a reply, - * -1 otherwise */ -int t_branch_replied(struct sip_msg* msg, char* foo, char* bar) -{ - switch(get_route_type()) { - case FAILURE_ROUTE: - case BRANCH_FAILURE_ROUTE: - return (msg->msg_flags & FL_REPLIED)?1:-1; - default: - LOG(L_ERR, "ERROR:t_check_status: unsupported route type %d\n", - get_route_type()); - } - return -1; -} - - - -/* script function, returns: 1 if the transaction was canceled, -1 if not */ -int t_is_canceled(struct sip_msg* msg) -{ - struct cell *t; - int ret; - - - if (t_check( msg , 0 )==-1) return -1; - t=get_t(); - if ((t==0) || (t==T_UNDEFINED)){ - LOG(L_ERR, "ERROR: t_is_canceled: cannot check a message " - "for which no T-state has been established\n"); - ret=-1; - }else{ - ret=(t->flags & T_CANCELED)?1:-1; - } - return ret; -} - -static int w_t_is_canceled(struct sip_msg* msg, char* foo, char* bar) -{ - return t_is_canceled(msg); -} - -/* script function, returns: 1 if the transaction is currently suspended, -1 if not */ -int t_is_retr_async_reply(struct sip_msg* msg) -{ - struct cell *t; - int ret; - - if (t_check( msg , 0 )==-1) return -1; - t=get_t(); - if ((t==0) || (t==T_UNDEFINED)){ - LOG(L_ERR, "ERROR: t_is_retr_async_reply: cannot check a message " - "for which no T-state has been established\n"); - ret=-1; - }else{ - LOG(L_DBG, "TRANSACTION FLAGS IS %d\n", t->flags); - ret=(t->flags & T_ASYNC_SUSPENDED)?1:-1; - } - return ret; -} -static int w_t_is_retr_async_reply(struct sip_msg* msg, char* foo, char* bar) -{ - return t_is_retr_async_reply(msg); -} - -/* script function, returns: 1 if the transaction lifetime interval has already elapsed, -1 if not */ -int t_is_expired(struct sip_msg* msg, char* foo, char* bar) -{ - struct cell *t; - int ret; - - - if (t_check( msg , 0 )==-1) return -1; - t=get_t(); - if ((t==0) || (t==T_UNDEFINED)){ - LOG(L_ERR, "ERROR: t_is_expired: cannot check a message " - "for which no T-state has been established\n"); - ret=-1; - }else{ - ret=(TICKS_GT(t->end_of_life, get_ticks_raw()))?-1:1; - } - return ret; -} - -/* script function, returns: 1 if any of the branches did timeout, -1 if not */ -int t_any_timeout(struct sip_msg* msg, char* foo, char* bar) -{ - struct cell *t; - int r; - - if (t_check( msg , 0 )==-1) return -1; - t=get_t(); - if ((t==0) || (t==T_UNDEFINED)){ - LOG(L_ERR, "ERROR: t_any_timeout: cannot check a message " - "for which no T-state has been established\n"); - return -1; - }else{ - for (r=0; rnr_of_outgoings; r++){ - if (t->uac[r].request.flags & F_RB_TIMEOUT) - return 1; + /* disable internal negative reply for the current transaction */ + T_SET_FLAG_GEN_FUNC(t_set_disable_internal_reply, T_DISABLE_INTERNAL_REPLY) + + + /* script function, FAILURE_ROUTE and BRANCH_FAILURE_ROUTE only, + * returns true if the choosed "failure" branch failed because of a timeout, + * -1 otherwise */ + int t_branch_timeout(struct sip_msg* msg, char* foo, char* bar) + { + switch(get_route_type()) { + case FAILURE_ROUTE: + case BRANCH_FAILURE_ROUTE: + return (msg->msg_flags & FL_TIMEOUT)?1:-1; + default: + LOG(L_ERR, "ERROR:t_check_status: unsupported route type %d\n", + get_route_type()); + } + return -1; } + + + /* script function, FAILURE_ROUTE and BRANCH_FAILURE_ROUTE only, + * returns true if the choosed "failure" branch ever received a reply, + * -1 otherwise */ + int t_branch_replied(struct sip_msg* msg, char* foo, char* bar) + { + switch(get_route_type()) { + case FAILURE_ROUTE: + case BRANCH_FAILURE_ROUTE: + return (msg->msg_flags & FL_REPLIED)?1:-1; + default: + LOG(L_ERR, "ERROR:t_check_status: unsupported route type %d\n", + get_route_type()); + } + return -1; } - return -1; -} -/* script function, returns: 1 if any of the branches received at leat one - * reply, -1 if not */ -int t_any_replied(struct sip_msg* msg, char* foo, char* bar) -{ - struct cell *t; - int r; - - if (t_check( msg , 0 )==-1) return -1; - t=get_t(); - if ((t==0) || (t==T_UNDEFINED)){ - LOG(L_ERR, "ERROR: t_any_replied: cannot check a message " - "for which no T-state has been established\n"); - return -1; - }else{ - for (r=0; rnr_of_outgoings; r++){ - if (t->uac[r].request.flags & F_RB_REPLIED) - return 1; + /* script function, returns: 1 if the transaction was canceled, -1 if not */ + int t_is_canceled(struct sip_msg* msg) + { + struct cell *t; + int ret; + + if (t_check( msg , 0 )==-1) return -1; + t=get_t(); + if ((t==0) || (t==T_UNDEFINED)){ + LOG(L_ERR, "ERROR: t_is_canceled: cannot check a message " + "for which no T-state has been established\n"); + ret=-1; + }else{ + ret=(t->flags & T_CANCELED)?1:-1; } + return ret; } - return -1; -} + static int w_t_is_canceled(struct sip_msg* msg, char* foo, char* bar) + { + return t_is_canceled(msg); + } + /* script function, returns: 1 if the transaction is currently suspended, -1 if not */ + int t_is_retr_async_reply(struct sip_msg* msg) + { + struct cell *t; + int ret; -/* script function, returns: 1 if any of the branches received the - * reply code "status" */ -int t_grep_status(struct sip_msg* msg, char* status, char* bar) -{ - struct cell *t; - int r; - int code; - - if (get_int_fparam(&code, msg, (fparam_t*)status) < 0) return -1; - if (t_check( msg , 0 )==-1) return -1; - t=get_t(); - if ((t==0) || (t==T_UNDEFINED)){ - LOG(L_ERR, "ERROR: t_any_replied: cannot check a message " - "for which no T-state has been established\n"); - return -1; - }else{ - for (r=0; rnr_of_outgoings; r++){ - if ((t->uac[r].last_received==code) && - (t->uac[r].request.flags & F_RB_REPLIED)) - return 1; + if (t_check( msg , 0 )==-1) return -1; + t=get_t(); + if ((t==0) || (t==T_UNDEFINED)){ + LOG(L_ERR, "ERROR: t_is_retr_async_reply: cannot check a message " + "for which no T-state has been established\n"); + ret=-1; + }else{ + LOG(L_DBG, "TRANSACTION FLAGS IS %d\n", t->flags); + ret=(t->flags & T_ASYNC_SUSPENDED)?1:-1; } + return ret; } - return -1; -} - -/* drop all the existing replies in failure_route to make sure - * that none of them is picked up again */ -static int w_t_drop_replies(struct sip_msg* msg, char* foo, char* bar) -{ - if(foo==NULL) - t_drop_replies(1); - else if(*foo=='n') - t_drop_replies(0); - else if(*foo=='l') - t_drop_replies(2); - else - t_drop_replies(1); - return 1; -} - -/* save the message lumps after t_newtran() but before t_relay() */ -static int w_t_save_lumps(struct sip_msg* msg, char* foo, char* bar) -{ - struct cell *t; - - if (is_route_type(REQUEST_ROUTE)) { + static int w_t_is_retr_async_reply(struct sip_msg* msg, char* foo, char* bar) + { + return t_is_retr_async_reply(msg); + } + + /* script function, returns: 1 if the transaction lifetime interval has already elapsed, -1 if not */ + int t_is_expired(struct sip_msg* msg, char* foo, char* bar) + { + struct cell *t; + int ret; + + if (t_check( msg , 0 )==-1) return -1; t=get_t(); - if (!t || t==T_UNDEFINED) { - LOG(L_ERR, "ERROR: w_t_save_lumps: transaction has not been created yet\n"); + if ((t==0) || (t==T_UNDEFINED)){ + LOG(L_ERR, "ERROR: t_is_expired: cannot check a message " + "for which no T-state has been established\n"); + ret=-1; + }else{ + ret=(TICKS_GT(t->end_of_life, get_ticks_raw()))?-1:1; + } + return ret; + } + + /* script function, returns: 1 if any of the branches did timeout, -1 if not */ + int t_any_timeout(struct sip_msg* msg, char* foo, char* bar) + { + struct cell *t; + int r; + + if (t_check( msg , 0 )==-1) return -1; + t=get_t(); + if ((t==0) || (t==T_UNDEFINED)){ + LOG(L_ERR, "ERROR: t_any_timeout: cannot check a message " + "for which no T-state has been established\n"); return -1; + }else{ + for (r=0; rnr_of_outgoings; r++){ + if (t->uac[r].request.flags & F_RB_TIMEOUT) + return 1; + } } + return -1; + } - if (save_msg_lumps(t->uas.request, msg)) { - LOG(L_ERR, "ERROR: w_t_save_lumps: " - "failed to save the message lumps\n"); + + + /* script function, returns: 1 if any of the branches received at leat one + * reply, -1 if not */ + int t_any_replied(struct sip_msg* msg, char* foo, char* bar) + { + struct cell *t; + int r; + + if (t_check( msg , 0 )==-1) return -1; + t=get_t(); + if ((t==0) || (t==T_UNDEFINED)){ + LOG(L_ERR, "ERROR: t_any_replied: cannot check a message " + "for which no T-state has been established\n"); return -1; + }else{ + for (r=0; rnr_of_outgoings; r++){ + if (t->uac[r].request.flags & F_RB_REPLIED) + return 1; + } } - } /* else nothing to do, the lumps have already been saved */ - return 1; -} + return -1; + } + + /* script function, returns: 1 if any of the branches received the + * reply code "status" */ + int t_grep_status(struct sip_msg* msg, char* status, char* bar) + { + struct cell *t; + int r; + int code; -/* wrapper function needed after changes in w_t_reply */ -int w_t_reply_wrp(struct sip_msg *m, unsigned int code, char *txt) -{ - fparam_t c; - fparam_t r; - - c.type = FPARAM_INT; - c.orig = NULL; /* ? */ - c.v.i = code; - - r.type = FPARAM_STRING; - r.orig = NULL; /* ? */ - r.v.asciiz = txt; + if (get_int_fparam(&code, msg, (fparam_t*)status) < 0) return -1; + if (t_check( msg , 0 )==-1) return -1; + t=get_t(); + if ((t==0) || (t==T_UNDEFINED)){ + LOG(L_ERR, "ERROR: t_any_replied: cannot check a message " + "for which no T-state has been established\n"); + return -1; + }else{ + for (r=0; rnr_of_outgoings; r++){ + if ((t->uac[r].last_received==code) && + (t->uac[r].request.flags & F_RB_REPLIED)) + return 1; + } + } + return -1; + } - return w_t_reply(m, (char *)&c, (char*)&r); -} + /* drop all the existing replies in failure_route to make sure + * that none of them is picked up again */ + static int w_t_drop_replies(struct sip_msg* msg, char* foo, char* bar) + { + if(foo==NULL) + t_drop_replies(1); + else if(*foo=='n') + t_drop_replies(0); + else if(*foo=='l') + t_drop_replies(2); + else + t_drop_replies(1); + return 1; + } + /* save the message lumps after t_newtran() but before t_relay() */ + static int w_t_save_lumps(struct sip_msg* msg, char* foo, char* bar) + { + struct cell *t; + if (is_route_type(REQUEST_ROUTE)) { + t=get_t(); + if (!t || t==T_UNDEFINED) { + LOG(L_ERR, "ERROR: w_t_save_lumps: transaction has not been created yet\n"); + return -1; + } -/** script function, check if a msg is assoc. to a transaction. - * @return -1 (not), 1 (reply, e2e ack or cancel for an existing transaction), - * 0 (request retransmission, ack to negative reply or ack to local - * transaction) - * Note: the e2e ack matching works only for local e2e acks or for - * transactions with E2EACK* callbacks installed (but even in this - * case matching E2EACKs on proxied transaction is not entirely - * reliable: if the ACK is delayed the proxied transaction might - * be already deleted when it reaches the proxy (wait_timeout)) - */ -int t_check_trans(struct sip_msg* msg) -{ - struct cell* t; - int branch; - int ret; - - /* already processing a T */ - if(is_route_type(FAILURE_ROUTE) - || is_route_type(BRANCH_ROUTE) - || is_route_type(BRANCH_FAILURE_ROUTE) - || is_route_type(TM_ONREPLY_ROUTE)) { + if (save_msg_lumps(t->uas.request, msg)) { + LOG(L_ERR, "ERROR: w_t_save_lumps: " + "failed to save the message lumps\n"); + return -1; + } + } /* else nothing to do, the lumps have already been saved */ return 1; } - if (msg->first_line.type==SIP_REPLY) { - branch = 0; - ret = (t_check_msg( msg , &branch)==1) ? 1 : -1; - tm_ctx_set_branch_index(branch); - return ret; - } else if (msg->REQ_METHOD==METHOD_CANCEL) { - return w_t_lookup_cancel(msg, 0, 0); - } else { - switch(t_check_msg(msg, 0)){ - case -2: /* possible e2e ack */ - return 1; - case 1: /* found */ - t=get_t(); - if (msg->REQ_METHOD==METHOD_ACK){ - /* ack to neg. reply or ack to local trans. - => process it and end the script */ - /* FIXME: there's no way to distinguish here - between acks to local trans. and neg. acks */ - if (unlikely(has_tran_tmcbs(t, TMCB_ACK_NEG_IN))) - run_trans_callbacks(TMCB_ACK_NEG_IN, t, msg, - 0, msg->REQ_METHOD); - t_release_transaction(t); - } else { - /* is a retransmission */ - if (unlikely(has_tran_tmcbs(t, TMCB_REQ_RETR_IN))) - run_trans_callbacks(TMCB_REQ_RETR_IN, t, msg, - 0, msg->REQ_METHOD); - t_retransmit_reply(t); - } - /* no need for UNREF(t); set_t(0) - the end-of-script - t_unref callback will take care of them */ - return 0; /* exit from the script */ - } - /* not found or error */ + + + /* wrapper function needed after changes in w_t_reply */ + int w_t_reply_wrp(struct sip_msg *m, unsigned int code, char *txt) + { + fparam_t c; + fparam_t r; + + c.type = FPARAM_INT; + c.orig = NULL; /* ? */ + c.v.i = code; + + r.type = FPARAM_STRING; + r.orig = NULL; /* ? */ + r.v.asciiz = txt; + + return w_t_reply(m, (char *)&c, (char*)&r); } - return -1; -} -static int w_t_check_trans(struct sip_msg* msg, char* foo, char* bar) -{ - return t_check_trans(msg); -} -static int hexatoi(str *s, unsigned int* result) -{ - int i, xv, fact; - /* more than 32bit hexa? */ - if (s->len>8) + /** script function, check if a msg is assoc. to a transaction. + * @return -1 (not), 1 (reply, e2e ack or cancel for an existing transaction), + * 0 (request retransmission, ack to negative reply or ack to local + * transaction) + * Note: the e2e ack matching works only for local e2e acks or for + * transactions with E2EACK* callbacks installed (but even in this + * case matching E2EACKs on proxied transaction is not entirely + * reliable: if the ACK is delayed the proxied transaction might + * be already deleted when it reaches the proxy (wait_timeout)) + */ + int t_check_trans(struct sip_msg* msg) + { + struct cell* t; + int branch; + int ret; + + /* already processing a T */ + if(is_route_type(FAILURE_ROUTE) + || is_route_type(BRANCH_ROUTE) + || is_route_type(BRANCH_FAILURE_ROUTE) + || is_route_type(TM_ONREPLY_ROUTE)) { + return 1; + } + + if (msg->first_line.type==SIP_REPLY) { + branch = 0; + ret = (t_check_msg( msg , &branch)==1) ? 1 : -1; + tm_ctx_set_branch_index(branch); + return ret; + } else if (msg->REQ_METHOD==METHOD_CANCEL) { + return w_t_lookup_cancel(msg, 0, 0); + } else { + switch(t_check_msg(msg, 0)){ + case -2: /* possible e2e ack */ + return 1; + case 1: /* found */ + t=get_t(); + if (msg->REQ_METHOD==METHOD_ACK){ + /* ack to neg. reply or ack to local trans. + * => process it and end the script */ + /* FIXME: there's no way to distinguish here + * between acks to local trans. and neg. acks */ + if (unlikely(has_tran_tmcbs(t, TMCB_ACK_NEG_IN))) + run_trans_callbacks(TMCB_ACK_NEG_IN, t, msg, + 0, msg->REQ_METHOD); + t_release_transaction(t); + } else { + /* is a retransmission */ + if (unlikely(has_tran_tmcbs(t, TMCB_REQ_RETR_IN))) + run_trans_callbacks(TMCB_REQ_RETR_IN, t, msg, + 0, msg->REQ_METHOD); + t_retransmit_reply(t); + } + /* no need for UNREF(t); set_t(0) - the end-of-script + * t_unref callback will take care of them */ + return 0; /* exit from the script */ + } + /* not found or error */ + } return -1; + } - *result = 0; - fact = 1; + static int w_t_check_trans(struct sip_msg* msg, char* foo, char* bar) + { + return t_check_trans(msg); + } - for(i=s->len-1; i>=0 ;i--) + static int hexatoi(str *s, unsigned int* result) { - xv = hex2int(s->s[i]); - if(xv<0) + int i, xv, fact; + + /* more than 32bit hexa? */ + if (s->len>8) return -1; - *result += (xv * fact); - fact *= 16; - } - return 0; -} - -static int fixup_t_relay_to(void** param, int param_no) -{ - - int port; - int proto; - unsigned int flags; - struct proxy_l *proxy; - action_u_t *a; - str s; - str host; - - s.s = (char*)*param; - s.len = strlen(s.s); - LM_DBG("fixing (%s, %d)\n", s.s, param_no); - if (param_no==1){ - a = fixup_get_param(param, param_no, 2); - if(a==NULL) + *result = 0; + fact = 1; + + for(i=s->len-1; i>=0 ;i--) { - LM_CRIT("server error for parameter <%s>\n",s.s); - return E_UNSPEC; + xv = hex2int(s->s[i]); + if(xv<0) + return -1; + + *result += (xv * fact); + fact *= 16; } - if(a->u.string!=NULL) { - /* second parameter set, first should be proxy addr */ - if (parse_phostport(s.s, &host.s, &host.len, &port, &proto)!=0){ - LM_CRIT("invalid proxy addr parameter <%s>\n",s.s); + return 0; + } + + static int fixup_t_relay_to(void** param, int param_no) + { + + int port; + int proto; + unsigned int flags; + struct proxy_l *proxy; + action_u_t *a; + str s; + str host; + + s.s = (char*)*param; + s.len = strlen(s.s); + LM_DBG("fixing (%s, %d)\n", s.s, param_no); + if (param_no==1){ + a = fixup_get_param(param, param_no, 2); + if(a==NULL) + { + LM_CRIT("server error for parameter <%s>\n",s.s); return E_UNSPEC; } + if(a->u.string!=NULL) { + /* second parameter set, first should be proxy addr */ + if (parse_phostport(s.s, &host.s, &host.len, &port, &proto)!=0){ + LM_CRIT("invalid proxy addr parameter <%s>\n",s.s); + return E_UNSPEC; + } - proxy = mk_proxy(&host, port, proto); - if (proxy==0) { - LM_ERR("failed to build proxy structure for <%.*s>\n", host.len, host.s ); - return E_UNSPEC; + proxy = mk_proxy(&host, port, proto); + if (proxy==0) { + LM_ERR("failed to build proxy structure for <%.*s>\n", host.len, host.s ); + return E_UNSPEC; + } + *(param)=proxy; + return 0; + } else { + /* no second parameter, then is proxy addr or flags */ + flags = 0; + if (s.len>2 && s.s[0]=='0' && s.s[1]=='x') { + s.s += 2; + s.len -= 2; + if(hexatoi(&s, &flags)<0) + { + LM_CRIT("invalid hexa flags <%s>\n", s.s); + return E_UNSPEC; + } + a->u.data = (void*)(unsigned long int)flags; + *(param)= 0; + return 0; + } else { + if(str2int(&s, &flags)==0) + { + a->u.data = (void*)(unsigned long int)flags; + *(param)= 0; + return 0; + } else { + /* try proxy */ + if (parse_phostport(s.s, &host.s, &host.len, &port, &proto)!=0){ + LM_CRIT("invalid proxy addr parameter <%s>\n",s.s); + return E_UNSPEC; + } + + proxy = mk_proxy(&host, port, proto); + if (proxy==0) { + LM_ERR("failed to build proxy structure for <%.*s>\n", host.len, host.s ); + return E_UNSPEC; + } + *(param)=proxy; + return 0; + } + } } - *(param)=proxy; - return 0; - } else { - /* no second parameter, then is proxy addr or flags */ + } else if (param_no==2) { + /* flags */ flags = 0; if (s.len>2 && s.s[0]=='0' && s.s[1]=='x') { s.s += 2; @@ -2216,153 +2201,116 @@ static int fixup_t_relay_to(void** param, int param_no) LM_CRIT("invalid hexa flags <%s>\n", s.s); return E_UNSPEC; } - a->u.data = (void*)(unsigned long int)flags; - *(param)= 0; + *(param) = (void*)(unsigned long int)flags; return 0; } else { if(str2int(&s, &flags)==0) { - a->u.data = (void*)(unsigned long int)flags; - *(param)= 0; + *(param) = (void*)(unsigned long int)flags; return 0; } else { - /* try proxy */ - if (parse_phostport(s.s, &host.s, &host.len, &port, &proto)!=0){ - LM_CRIT("invalid proxy addr parameter <%s>\n",s.s); - return E_UNSPEC; - } - - proxy = mk_proxy(&host, port, proto); - if (proxy==0) { - LM_ERR("failed to build proxy structure for <%.*s>\n", host.len, host.s ); - return E_UNSPEC; - } - *(param)=proxy; - return 0; + LM_CRIT("invalid flags <%s>\n", s.s); + return E_UNSPEC; } } - } - } else if (param_no==2) { - /* flags */ - flags = 0; - if (s.len>2 && s.s[0]=='0' && s.s[1]=='x') { - s.s += 2; - s.len -= 2; - if(hexatoi(&s, &flags)<0) - { - LM_CRIT("invalid hexa flags <%s>\n", s.s); - return E_UNSPEC; - } - *(param) = (void*)(unsigned long int)flags; - return 0; } else { - if(str2int(&s, &flags)==0) - { - *(param) = (void*)(unsigned long int)flags; - return 0; - } else { - LM_CRIT("invalid flags <%s>\n", s.s); - return E_UNSPEC; - } + LM_ERR("invalid parameter number %d\n", param_no); + return E_BUG; } - } else { - LM_ERR("invalid parameter number %d\n", param_no); - return E_BUG; } -} - - -inline static int w_t_relay_to(struct sip_msg *msg, char *proxy, char *flags) -{ - unsigned int fl; - struct proxy_l *px; - fparam_t param; - fl = (unsigned int)(long)(void*)flags; - px = (struct proxy_l*)proxy; - if(flags!=0) + inline static int w_t_relay_to(struct sip_msg *msg, char *proxy, char *flags) { - memset(¶m, 0, sizeof(fparam_t)); - param.type = FPARAM_INT; - /* no auto 100 trying */ - if(fl&1) { - param.v.i = 0; - t_set_auto_inv_100(msg, (char*)(¶m), 0); - } - /* no auto negative reply */ - if(fl&2) { - param.v.i = 1; - t_set_disable_internal_reply(msg, (char*)(¶m), 0); - } - /* no dns failover */ - if(fl&4) { - param.v.i = 1; - t_set_disable_failover(msg, (char*)(¶m), 0); - } - } - return _w_t_relay_to(msg, px, PROTO_NONE); -} - + unsigned int fl; + struct proxy_l *px; + fparam_t param; -static int w_t_use_uac_headers(sip_msg_t* msg, char* foo, char* bar) -{ - tm_cell_t *t; + fl = (unsigned int)(long)(void*)flags; + px = (struct proxy_l*)proxy; - t=get_t(); - if (t!=NULL && t!=T_UNDEFINED) { - t->uas.request->msg_flags |= FL_USE_UAC_FROM|FL_USE_UAC_TO; + if(flags!=0) + { + memset(¶m, 0, sizeof(fparam_t)); + param.type = FPARAM_INT; + /* no auto 100 trying */ + if(fl&1) { + param.v.i = 0; + t_set_auto_inv_100(msg, (char*)(¶m), 0); + } + /* no auto negative reply */ + if(fl&2) { + param.v.i = 1; + t_set_disable_internal_reply(msg, (char*)(¶m), 0); + } + /* no dns failover */ + if(fl&4) { + param.v.i = 1; + t_set_disable_failover(msg, (char*)(¶m), 0); + } + } + return _w_t_relay_to(msg, px, PROTO_NONE); } - msg->msg_flags |= FL_USE_UAC_FROM|FL_USE_UAC_TO; - - return 1; -} - -/* rpc docs */ - -static const char* rpc_cancel_doc[2] = { - "Cancel a pending transaction", - 0 -}; - -static const char* rpc_reply_doc[2] = { - "Reply transaction", - 0 -}; - -static const char* tm_rpc_stats_doc[2] = { - "Print transaction statistics.", - 0 -}; -static const char* tm_rpc_hash_stats_doc[2] = { - "Prints hash table statistics (can be used only if tm is compiled" - " with -DTM_HASH_STATS).", - 0 -}; -static const char* rpc_t_uac_start_doc[2] = { - "starts a tm uac using a list of string parameters: method, ruri, dst_uri" - ", send_sock, headers (CRLF separated) and body (optional)", - 0 -}; + static int w_t_use_uac_headers(sip_msg_t* msg, char* foo, char* bar) + { + tm_cell_t *t; -static const char* rpc_t_uac_wait_doc[2] = { - "starts a tm uac and waits for the final reply, using a list of string " - "parameters: method, ruri, dst_uri send_sock, headers (CRLF separated)" - " and body (optional)", - 0 -}; + t=get_t(); + if (t!=NULL && t!=T_UNDEFINED) { + t->uas.request->msg_flags |= FL_USE_UAC_FROM|FL_USE_UAC_TO; + } + msg->msg_flags |= FL_USE_UAC_FROM|FL_USE_UAC_TO; + return 1; + } -/* rpc exports */ -static rpc_export_t tm_rpc[] = { - {"tm.cancel", rpc_cancel, rpc_cancel_doc, 0}, - {"tm.reply", rpc_reply, rpc_reply_doc, 0}, - {"tm.stats", tm_rpc_stats, tm_rpc_stats_doc, 0}, - {"tm.hash_stats", tm_rpc_hash_stats, tm_rpc_hash_stats_doc, 0}, - {"tm.t_uac_start", rpc_t_uac_start, rpc_t_uac_start_doc, 0 }, - {"tm.t_uac_wait", rpc_t_uac_wait, rpc_t_uac_wait_doc, RET_ARRAY}, - {0, 0, 0, 0} -}; + /* rpc docs */ + + static const char* rpc_cancel_doc[2] = { + "Cancel a pending transaction", + 0 + }; + + static const char* rpc_reply_doc[2] = { + "Reply transaction", + 0 + }; + + static const char* tm_rpc_stats_doc[2] = { + "Print transaction statistics.", + 0 + }; + + static const char* tm_rpc_hash_stats_doc[2] = { + "Prints hash table statistics (can be used only if tm is compiled" + " with -DTM_HASH_STATS).", + 0 + }; + + static const char* rpc_t_uac_start_doc[2] = { + "starts a tm uac using a list of string parameters: method, ruri, dst_uri" + ", send_sock, headers (CRLF separated) and body (optional)", + 0 + }; + + static const char* rpc_t_uac_wait_doc[2] = { + "starts a tm uac and waits for the final reply, using a list of string " + "parameters: method, ruri, dst_uri send_sock, headers (CRLF separated)" + " and body (optional)", + 0 + }; + + + /* rpc exports */ + static rpc_export_t tm_rpc[] = { + {"tm.cancel", rpc_cancel, rpc_cancel_doc, 0}, + {"tm.reply", rpc_reply, rpc_reply_doc, 0}, + {"tm.stats", tm_rpc_stats, tm_rpc_stats_doc, 0}, + {"tm.hash_stats", tm_rpc_hash_stats, tm_rpc_hash_stats_doc, 0}, + {"tm.t_uac_start", rpc_t_uac_start, rpc_t_uac_start_doc, 0 }, + {"tm.t_uac_wait", rpc_t_uac_wait, rpc_t_uac_wait_doc, RET_ARRAY}, + {0, 0, 0, 0} + }; From bc63f4726541d694da2184a3f41becb78966c4be Mon Sep 17 00:00:00 2001 From: Daniel-Constantin Mierla Date: Sun, 27 Mar 2016 14:21:12 +0200 Subject: [PATCH 19/32] core - mem: renamed api fields for module stats to repleft the purpose (cherry picked from commit 50ac46bfc233531f9f4be22be4aee07a8faa0325) --- mem/memapi.h | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/mem/memapi.h b/mem/memapi.h index 9f918f3ae73..28e9f8626e8 100644 --- a/mem/memapi.h +++ b/mem/memapi.h @@ -79,9 +79,9 @@ typedef struct sr_pkg_api { /*memory destroy manager*/ sr_mem_destroy_f xdestroy; /*memory stats per module*/ - sr_mem_mod_get_stats_f xstats; + sr_mem_mod_get_stats_f xmodstats; /*memory stats free per module*/ - sr_mem_mod_free_stats_f xfstats; + sr_mem_mod_free_stats_f xfmodstats; } sr_pkg_api_t; /*shared memory api*/ @@ -115,9 +115,9 @@ typedef struct sr_shm_api { /*memory destroy manager*/ sr_mem_destroy_f xdestroy; /*memory stats per module*/ - sr_mem_mod_get_stats_f xstats; + sr_mem_mod_get_stats_f xmodstats; /*memory stats free per module*/ - sr_mem_mod_free_stats_f xfstats; + sr_mem_mod_free_stats_f xfmodstats; } sr_shm_api_t; #endif From 792491709f30331e0d53bda610a7614eff6228ee Mon Sep 17 00:00:00 2001 From: Daniel-Constantin Mierla Date: Sun, 27 Mar 2016 14:21:55 +0200 Subject: [PATCH 20/32] core: mem/pkg - use module stats fields for init of managers q (cherry picked from commit b568c6533670b1400f7c12bd13169d41542c351a) --- mem/pkg.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/mem/pkg.c b/mem/pkg.c index a4f0906efbc..53166ac9326 100644 --- a/mem/pkg.c +++ b/mem/pkg.c @@ -46,8 +46,8 @@ int pkg_init_api(sr_pkg_api_t *ap) _pkg_root.xavailable = ap->xavailable; _pkg_root.xsums = ap->xsums; _pkg_root.xdestroy = ap->xdestroy; - _pkg_root.xstats = ap->xstats; - _pkg_root.xfstats = ap->xfstats; + _pkg_root.xmodstats = ap->xmodstats; + _pkg_root.xfmodstats = ap->xfmodstats; return 0; } From 7c521fcbded0a14b8bfa5488511fe0a08f105085 Mon Sep 17 00:00:00 2001 From: Daniel-Constantin Mierla Date: Sun, 27 Mar 2016 14:22:37 +0200 Subject: [PATCH 21/32] core: mem/shm - use module stats fields for init of managers (cherry picked from commit 26dbc87aac8d117bf0928eb2124ecc91e512e20f) --- mem/shm.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/mem/shm.c b/mem/shm.c index 94a99150e91..e4f4ad6f173 100644 --- a/mem/shm.c +++ b/mem/shm.c @@ -221,8 +221,8 @@ int shm_init_api(sr_shm_api_t *ap) _shm_root.xavailable = ap->xavailable; _shm_root.xsums = ap->xsums; _shm_root.xdestroy = ap->xdestroy; - _shm_root.xstats = ap->xstats; - _shm_root.xfstats = ap->xfstats; + _shm_root.xmodstats = ap->xmodstats; + _shm_root.xfmodstats = ap->xfmodstats; return 0; } From d39d166e753ade7dfbd0f439db03f7d09f91a601 Mon Sep 17 00:00:00 2001 From: Daniel-Constantin Mierla Date: Sun, 27 Mar 2016 14:23:02 +0200 Subject: [PATCH 22/32] mem/f_malloc: updates to use new api names for module stats (cherry picked from commit ec15fc65bc6d38e74fdcf6a1fa6ef10053452365) --- mem/f_malloc.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/mem/f_malloc.c b/mem/f_malloc.c index 59f809eced5..6afe7f70cc0 100644 --- a/mem/f_malloc.c +++ b/mem/f_malloc.c @@ -1067,8 +1067,8 @@ int fm_malloc_init_pkg_manager(void) ma.xavailable = fm_available; ma.xsums = fm_sums; ma.xdestroy = fm_malloc_destroy_pkg_manager; - ma.xstats = fm_mod_get_stats; - ma.xfstats = fm_mod_free_stats; + ma.xmodstats = fm_mod_get_stats; + ma.xfmodstats = fm_mod_free_stats; return pkg_init_api(&ma); } @@ -1218,8 +1218,8 @@ int fm_malloc_init_shm_manager(void) ma.xavailable = fm_shm_available; ma.xsums = fm_shm_sums; ma.xdestroy = fm_malloc_destroy_shm_manager; - ma.xstats = fm_mod_get_stats; - ma.xfstats = fm_mod_free_stats; + ma.xmodstats = fm_mod_get_stats; + ma.xfmodstats = fm_mod_free_stats; if(shm_init_api(&ma)<0) { LM_ERR("cannot initialize the core shm api\n"); From cb2c14f2dbdbc6fdcb7a0565b2718379241d655a Mon Sep 17 00:00:00 2001 From: Daniel-Constantin Mierla Date: Sun, 27 Mar 2016 14:23:46 +0200 Subject: [PATCH 23/32] mem/q_malloc: updates to use new api names for module stats (cherry picked from commit 8f2864b1845cfa2b520c0886e30d1f5df285eef6) --- mem/q_malloc.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/mem/q_malloc.c b/mem/q_malloc.c index 982682880f8..36cc15a7bb1 100644 --- a/mem/q_malloc.c +++ b/mem/q_malloc.c @@ -1032,8 +1032,8 @@ int qm_malloc_init_pkg_manager(void) ma.xavailable = qm_available; ma.xsums = qm_sums; ma.xdestroy = qm_malloc_destroy_pkg_manager; - ma.xstats = qm_mod_get_stats; - ma.xfstats = qm_mod_free_stats; + ma.xmodstats = qm_mod_get_stats; + ma.xfmodstats = qm_mod_free_stats; return pkg_init_api(&ma); } @@ -1183,8 +1183,8 @@ int qm_malloc_init_shm_manager(void) ma.xavailable = qm_shm_available; ma.xsums = qm_shm_sums; ma.xdestroy = qm_malloc_destroy_shm_manager; - ma.xstats = qm_mod_get_stats; - ma.xfstats = qm_mod_free_stats; + ma.xmodstats = qm_mod_get_stats; + ma.xfmodstats = qm_mod_free_stats; if(shm_init_api(&ma)<0) { LM_ERR("cannot initialize the core shm api\n"); From 97c2f855920f1aca0d47ed339e11cb0b2188edde Mon Sep 17 00:00:00 2001 From: Daniel-Constantin Mierla Date: Sun, 27 Mar 2016 14:24:00 +0200 Subject: [PATCH 24/32] mem/tlsf_malloc: updates to use new api names for module stats (cherry picked from commit 1eafbaf5b2d25879225b8e4c4797285dba2d460f) --- mem/tlsf_malloc.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/mem/tlsf_malloc.c b/mem/tlsf_malloc.c index 534b2e2a095..85afcfffc17 100644 --- a/mem/tlsf_malloc.c +++ b/mem/tlsf_malloc.c @@ -1358,8 +1358,8 @@ int tlsf_malloc_init_pkg_manager(void) ma.xavailable = tlsf_available; ma.xsums = tlsf_sums; ma.xdestroy = tlsf_malloc_destroy_pkg_manager; - ma.xstats = tlsf_mod_get_stats; - ma.xfstats = tlsf_mod_free_stats; + ma.xmodstats = tlsf_mod_get_stats; + ma.xfmodstats = tlsf_mod_free_stats; return pkg_init_api(&ma); } @@ -1508,8 +1508,8 @@ int tlsf_malloc_init_shm_manager(void) ma.xavailable = tlsf_shm_available; ma.xsums = tlsf_shm_sums; ma.xdestroy = tlsf_malloc_destroy_shm_manager; - ma.xstats = tlsf_mod_get_stats; - ma.xfstats = tlsf_mod_free_stats; + ma.xmodstats = tlsf_mod_get_stats; + ma.xfmodstats = tlsf_mod_free_stats; if(shm_init_api(&ma)<0) { LM_ERR("cannot initialize the core shm api\n"); From 21cb1bf26aed825cc0a2e5d7bdee0d61e1a700cc Mon Sep 17 00:00:00 2001 From: Daniel-Constantin Mierla Date: Sun, 27 Mar 2016 14:40:09 +0200 Subject: [PATCH 25/32] uuid: detect if pkg-config knows about uuid lib (cherry picked from commit 66fc01f48ea2d6fa8f20f39e1bcd01d498f8580d) --- modules/uuid/Makefile | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/modules/uuid/Makefile b/modules/uuid/Makefile index 102e57766fa..3fe7864212b 100644 --- a/modules/uuid/Makefile +++ b/modules/uuid/Makefile @@ -6,12 +6,15 @@ auto_gen= NAME=uuid.so ifeq ($(CROSS_COMPILE),) - BUILDER = $(shell which pkg-config) +BUILDER = $(shell \ + if pkg-config --exists uuid; then \ + echo 'pkg-config uuid'; \ + fi) endif ifneq ($(BUILDER),) - DEFS += $(shell $(BUILDER) --cflags uuid) - LIBS += $(shell $(BUILDER) --libs uuid) + DEFS += $(shell $(BUILDER) --cflags) + LIBS += $(shell $(BUILDER) --libs) else DEFS +=-I$(LOCALBASE)/include -I$(SYSBASE)/include LIBS+=-L$(LOCALBASE)/lib -L$(SYSBASE)/lib -luuid From ef8ee4cd13396bbd4fa2be1cd7b07a69bcd55eeb Mon Sep 17 00:00:00 2001 From: Daniel-Constantin Mierla Date: Sun, 27 Mar 2016 14:40:46 +0200 Subject: [PATCH 26/32] mem: shm - updated macros for mod stats api (cherry picked from commit e5538f1814ed5b96a01c7006d15c9192238c9b19) --- mem/shm.h | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/mem/shm.h b/mem/shm.h index cbf4c3a77be..1fdd596bee7 100644 --- a/mem/shm.h +++ b/mem/shm.h @@ -73,8 +73,8 @@ extern sr_shm_api_t _shm_root; # define shm_info(mi) _shm_root.xinfo(_shm_root.mem_block, mi) # define shm_available() _shm_root.xavailable(_shm_root.mem_block) # define shm_sums() _shm_root.xsums(_shm_root.mem_block) -# define shm_mod_get_stats(x) _shm_root.xstats(_shm_root.mem_block, x) -# define shm_mod_free_stats(x) _shm_root.xfstats(x) +# define shm_mod_get_stats(x) _shm_root.xmodstats(_shm_root.mem_block, x) +# define shm_mod_free_stats(x) _shm_root.xfmodstats(x) void* shm_core_get_pool(void); From 94e0ca56f2fd7ed56b511ab3572484cd780279a6 Mon Sep 17 00:00:00 2001 From: Daniel-Constantin Mierla Date: Mon, 28 Mar 2016 10:22:10 +0200 Subject: [PATCH 27/32] http_async_client: use pkg-config for libevent compile flags detection - re-enable pkg-config for libcurl (cherry picked from commit 88d8aabb748d2c0ab476cea9a4a17eb990b618f7) --- modules/http_async_client/Makefile | 44 +++++++++++++++++++++--------- 1 file changed, 31 insertions(+), 13 deletions(-) diff --git a/modules/http_async_client/Makefile b/modules/http_async_client/Makefile index 8ebe26f6664..a9ae495cf27 100644 --- a/modules/http_async_client/Makefile +++ b/modules/http_async_client/Makefile @@ -5,24 +5,42 @@ include ../../Makefile.defs auto_gen= NAME=http_async_client.so -#ifeq ($(CROSS_COMPILE),) -#CURL_BUILDER=$(shell \ -# if pkg-config --exists libcurl; then \ -# echo 'pkg-config libcurl'; \ -# else \ -# which curl-config; \ -# fi) -#endif +ifeq ($(CROSS_COMPILE),) +CURL_BUILDER=$(shell \ + if pkg-config --exists libcurl; then \ + echo 'pkg-config libcurl'; \ + else \ + which curl-config; \ + fi) +endif ifneq ($(CURL_BUILDER),) - DEFS += $(shell $(CURL_BUILDER) --cflags) - LIBS += $(shell $(CURL_BUILDER) --libs) -else - DEFS+=-I$(LOCALBASE)/include -I$(SYSBASE)/include - LIBS+=-L$(LOCALBASE)/lib -L$(SYSBASE)/lib -lcurl -levent + CURLDEFS += $(shell $(CURL_BUILDER) --cflags) + CURLLIBS += $(shell $(CURL_BUILDER) --libs) +else + CURLDEFS+=-I$(LOCALBASE)/include -I$(SYSBASE)/include + CURLLIBS+=-L$(LOCALBASE)/lib -L$(SYSBASE)/lib -lcurl -levent +endif + +ifeq ($(CROSS_COMPILE),) +LEVENT_BUILDER = $(shell \ + if pkg-config --exists libevent; then \ + echo 'pkg-config libevent'; \ + fi) endif +ifeq ($(LEVENT_BUILDER),) + LEVENTDEFS=-I$(LOCALBASE)/include -I$(SYSBASE)/include + LEVENTLIBS=-L$(LOCALBASE)/lib -levent +else + LEVENTDEFS = $(shell $(LEVENT_BUILDER) --cflags) + LEVENTLIBS = $(shell $(LEVENT_BUILDER) --libs) +endif + +DEFS+=$(CURLDEFS) $(LEVENTDEFS) +LIBS=$(CURLLIBS) $(LEVENTLIBS) + DEFS+=-DKAMAILIO_MOD_INTERFACE SERLIBPATH=../../lib From acb67a89ceba1428e465b1ff8e052b7683241e61 Mon Sep 17 00:00:00 2001 From: Daniel-Constantin Mierla Date: Mon, 28 Mar 2016 10:56:14 +0200 Subject: [PATCH 28/32] topos: reused stored branch attributes in case of retransmission (cherry picked from commit a4043c445b0673ca8f5ff7819caf9ac156da1e73) --- modules/topos/tps_msg.c | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-) diff --git a/modules/topos/tps_msg.c b/modules/topos/tps_msg.c index fc39d33b7fc..f35eeaff4a2 100644 --- a/modules/topos/tps_msg.c +++ b/modules/topos/tps_msg.c @@ -644,8 +644,12 @@ int tps_request_sent(sip_msg_t *msg, int dialog, int local) tps_storage_lock_get(&lkey); if(dialog==0) { - if(tps_storage_record(msg, ptsd)<0) { - goto error; + if(tps_storage_load_branch(msg, &mtsd, &stsd)!=0) { + if(tps_storage_record(msg, ptsd)<0) { + goto error; + } + } else { + ptsd = &stsd; } } @@ -667,7 +671,7 @@ int tps_request_sent(sip_msg_t *msg, int dialog, int local) tps_remove_headers(msg, HDR_CONTACT_T); tps_remove_headers(msg, HDR_VIA_T); - tps_reinsert_via(msg, ptsd, &ptsd->x_via1); + tps_reinsert_via(msg, &mtsd, &mtsd.x_via1); if(direction==TPS_DIR_UPSTREAM) { tps_reinsert_contact(msg, ptsd, &ptsd->as_contact); } else { From 543958280f732c5a9de2fbc7f84ae227e6929098 Mon Sep 17 00:00:00 2001 From: Daniel-Constantin Mierla Date: Mon, 28 Mar 2016 11:21:26 +0200 Subject: [PATCH 29/32] Makefile.defs: re-enable pkg malloc - was disabled for compile tests with system malloc --- Makefile.defs | 1 + 1 file changed, 1 insertion(+) diff --git a/Makefile.defs b/Makefile.defs index 65e7665fbed..135dd4f850e 100644 --- a/Makefile.defs +++ b/Makefile.defs @@ -626,6 +626,7 @@ C_DEFS= $(extra_defs) \ -DSER_VER=$(SER_VER) \ -DCFG_DIR='"$(cfg_target)"'\ -DRUN_DIR='"$(run_target)"'\ + -DPKG_MALLOC \ -DSHM_MEM -DSHM_MMAP \ -DDNS_IP_HACK \ -DUSE_MCAST \ From 8ce95cbe27a0244ae1db2630bcc8c513485155ca Mon Sep 17 00:00:00 2001 From: Daniel-Constantin Mierla Date: Mon, 28 Mar 2016 11:22:27 +0200 Subject: [PATCH 30/32] Makefile.defs: version set to 4.4.0-rc2 --- Makefile.defs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Makefile.defs b/Makefile.defs index 135dd4f850e..86ccf38d405 100644 --- a/Makefile.defs +++ b/Makefile.defs @@ -97,7 +97,7 @@ INSTALL_FLAVOUR=$(FLAVOUR) VERSION = 4 PATCHLEVEL = 4 SUBLEVEL = 0 -EXTRAVERSION = -rc1 +EXTRAVERSION = -rc2 # memory manager switcher # 0 - f_malloc (fast malloc) From 24d31da6fea5f177a43b492853362d56e9298ef6 Mon Sep 17 00:00:00 2001 From: Daniel-Constantin Mierla Date: Mon, 28 Mar 2016 14:37:59 +0200 Subject: [PATCH 31/32] core: mem - updated defines to pkg mod stats (cherry picked from commit 69f9328ddd959a70de8b94152704326dcca6a8cc) --- mem/pkg.h | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/mem/pkg.h b/mem/pkg.h index eb07bd2de92..c107117412f 100644 --- a/mem/pkg.h +++ b/mem/pkg.h @@ -48,8 +48,8 @@ void pkg_print_manager(void); # define pkg_info(mi) _pkg_root.xinfo(_pkg_root.mem_block, mi) # define pkg_available() _pkg_root.xavailable(_pkg_root.mem_block) # define pkg_sums() _pkg_root.xsums(_pkg_root.mem_block) -# define pkg_mod_get_stats(x) _pkg_root.xstats(_pkg_root.mem_block, x) -# define pkg_mod_free_stats(x) _pkg_root.xfstats(x) +# define pkg_mod_get_stats(x) _pkg_root.xmodstats(_pkg_root.mem_block, x) +# define pkg_mod_free_stats(x) _pkg_root.xfmodstats(x) #else /*PKG_MALLOC*/ /* use system allocator */ From ac90a7c1066cc8a5e01152a1c6bfc704f6667d98 Mon Sep 17 00:00:00 2001 From: Alexandr Dubovikov Date: Tue, 29 Mar 2016 13:53:19 +0200 Subject: [PATCH 32/32] Update hep.c --- modules/sipcapture/hep.c | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/modules/sipcapture/hep.c b/modules/sipcapture/hep.c index 6c934dcd324..bbafa5a4b6a 100644 --- a/modules/sipcapture/hep.c +++ b/modules/sipcapture/hep.c @@ -66,6 +66,9 @@ int hep_msg_received(void *data) len = (unsigned *)srevp[1]; ri = (struct receive_info *)srevp[2]; + correlation_id = NULL; + authkey = NULL; + count++; struct hep_hdr *heph; /* hep_hdr */ @@ -100,6 +103,9 @@ int hepv2_received(char *buf, unsigned int len, struct receive_info *ri){ memset(heptime, 0, sizeof(struct hep_timehdr)); struct hep_ip6hdr *hepip6h = NULL; + + correlation_id = NULL; + authkey = NULL; hep_offset = 0;