MT#7503 Imported Upstream version 4.1.4

mr3.4.1
Victor Seva 12 years ago
parent cf0cb1056d
commit b16fed8a89

@ -1,3 +1,491 @@
===================== 2014-06-12 Version 4.1.4 Released =====================
===================== Changes Since Version 4.1.3 ===========================
commit d521dff2563ddd1f64fb0c93e7cbd7a6ad254159
Author: Daniel-Constantin Mierla <miconda@gmail.com>
Date: Thu Jun 12 15:57:57 2014 +0200
Makefile.defs: version set to 4.1.4
commit a4f11987cd7fcabb68c377a6c61ab4238ec2cecc
Author: Daniel-Constantin Mierla <miconda@gmail.com>
Date: Thu Jun 12 15:56:58 2014 +0200
pkg/deb: version set to 4.1.4 in deb specs
commit bd7e64b5c38db50f37bae250911e82808060a262
Author: Daniel-Constantin Mierla <miconda@gmail.com>
Date: Thu Jun 12 15:53:36 2014 +0200
pkg: updated version in fedora and centos specs
commit a2bffd8aa6f97c2496c15c26fcb487f514b347de
Author: Daniel-Constantin Mierla <miconda@gmail.com>
Date: Thu Jun 12 15:51:17 2014 +0200
pkg/rpm: version set to 4.1.4 in rpm specs
commit b634dbace0d0f8ecf061252423374a24288f9fe2
Author: Daniel-Constantin Mierla <miconda@gmail.com>
Date: Thu Jun 12 12:12:02 2014 +0200
acc: clear new parsed headers when evaluating acc attributes
- the structures are in pkg, while request is taken from shm clone, can
cause reference to the space of another process
- reported by Igor Potjevlesch
(cherry picked from commit e6c0c2f9871eab5a73371d48dfa24e4ece2512d8)
commit 6c3c5b977941c605aa1be2ce582b3b843dbfcafe
Author: Daniel-Constantin Mierla <miconda@gmail.com>
Date: Thu Jun 12 11:48:01 2014 +0200
acc: allow recording to the rest of backends even when setting db table fails
- such error doesn't affect radius or custom backends
(cherry picked from commit 655711330b2ffd82dc84330ef0e0fbbad82a9160)
commit be8fb6fa8a1492259a26abe4825653f1f66ff0d8
Author: Daniel-Constantin Mierla <miconda@gmail.com>
Date: Thu Jun 12 11:39:55 2014 +0200
auth: proper fixup for optional method parameter in pv_www_authenticate()
- reported by Muhammad Shahzad
(cherry picked from commit dd00819f7cca976e699a20960956abff760df957)
commit b1ab677fe8977656c65112b558661673fdeb9f52
Author: Daniel-Constantin Mierla <miconda@gmail.com>
Date: Thu Jun 12 09:59:44 2014 +0200
core: sync definition of destroy_rpcs()
- reported by Victor Seva
(cherry picked from commit 28be6c3c79c02600f03a51b2393b289fbe8c9bd9)
commit fbe73477eae716693a35615df1375dc16d7e65bb
Author: Daniel-Constantin Mierla <miconda@gmail.com>
Date: Wed Jun 11 17:12:37 2014 +0200
dialog: execute internal event_route blocks under local_route type
- request_route type triggers additional script callbacks that could
reset the transaction and can cause crashing
- reported by Nuno Miguel Reis, FS#440
(cherry picked from commit 88a9ffee284338d536b6f7e072e5c99b29d983ee)
commit fc7f840a91394d5896d54ad534d8b6c9c61ec553
Author: Daniel-Constantin Mierla <miconda@gmail.com>
Date: Fri May 30 13:34:08 2014 +0200
core/parse/sdp: proper parsing of a=rtpmap line
- error handling when malformed line, avoiding crash to due to invalid
offsetting when clockrate is missing
- reported by Michael Ricordeau, FS#435
(cherry picked from commit c842bda9dac46724c58b734d092391c79867f2fb)
commit c81c360315105e47f5fdd762ffb6490691c3c675
Author: Olle E. Johansson <oej@edvina.net>
Date: Fri May 30 09:20:49 2014 +0100
auth_radius: Improve error message to simplify debugging
(cherry picked from commit 6e51019b0a2c60178b9ca03b9bb2a5fef49ca7ba)
commit 2f8f293242b7982b1ad843f5bfbcea22bf35027d
Author: Daniel-Constantin Mierla <miconda@gmail.com>
Date: Wed May 28 15:47:10 2014 +0200
pkg/rpm: use pkg memory size when checking config in init script
- for large configs, check can fail due to low memory
(cherry picked from commit 91a362e2f1bae90e2564491560aff8bad5b04564)
commit 177723a58ee12b3cb239d993a28a063d694f3b02
Author: Konstantin Mosesov <ez@voipgroup.org.ua>
Date: Sat May 24 05:58:19 2014 +0400
Fixed misstypes and indents in docs.
(cherry picked from commit 5bede9a9a77ad01e06d849485d6ce4274eca3fd4)
commit 8375c7f308a812b1e85768a663e039e9f2a70d1e
Author: Konstantin Mosesov <ez@voipgroup.org.ua>
Date: Sat May 24 05:57:16 2014 +0400
Fixed bug with JAVA_HOME detection.
(cherry picked from commit 5a05370f35bdeb7277b2f53f5c3e95fb672d4024)
commit f2afd026ff9509151612c3b180b3d813e95484dc
Author: Carsten Bock <carsten@ng-voice.com>
Date: Thu May 22 21:07:17 2014 +0200
Core: Bugfix: Do not reset tcp_listeners: We may only listen on TCP.
(cherry picked from commit 9b9d15875aa09a5574ff0754309f4f77161d3194)
commit 4267ba4cb15da135d4cd5543fb7f8d5f2f02ef9c
Author: Daniel-Constantin Mierla <miconda@gmail.com>
Date: Wed May 21 09:55:46 2014 +0200
core: allow listening on tls without listening on tcp
- reported in FS#425
(cherry picked from commit eea7f9d04090a736c8a0f2b2a350c08635cc8e39)
commit 7453f5e3b10b4a257eb2e1e1650bfabc5f381ec5
Author: Juha Heinanen <jh@tutpro.com>
Date: Tue May 20 16:22:58 2014 +0300
modules/siputils: generate error message if parsing of is_gruu() uri fails
(cherry picked from commit 365a60772de9c1d2f19ecf52b12f6d75b348e996)
commit 93fb970b87216ea5f63b077f02bbe1c085ddc45c
Author: Daniel-Constantin Mierla <miconda@gmail.com>
Date: Tue May 20 09:16:01 2014 +0200
core: print number of parameters used for searching cfg function
(cherry picked from commit a313a8d33afdee6c7eb70cd57161aef8e70c5bcf)
commit a008e0f7d0920d061892819a121d1f07ba4b2a70
Author: Daniel-Constantin Mierla <miconda@gmail.com>
Date: Thu May 15 12:48:04 2014 +0200
core: use port 5061 for checking self when uri has transport tls
- 5060 was used, failing to match myself condition
(cherry picked from commit 2e55d7bd218c9f954da7d289ec1be090bb4d88b0)
commit fdea08a522ed6d1e30b6b8eab0e74bc47078d57d
Author: Daniel-Constantin Mierla <miconda@gmail.com>
Date: Thu May 15 12:46:14 2014 +0200
topoh: match on all ports if none is in the uri for checking self
- forcing default 5060 can fail for multi-listen case and tls
(cherry picked from commit 1d90f4de94dfc887cc6129624fd5e6ad989abd37)
commit a768ffa5a083bbddc35db59b2686046c000c0482
Author: Daniel-Constantin Mierla <miconda@gmail.com>
Date: Wed May 14 23:37:54 2014 +0200
kamcmd: proper size for memset, based on malloc
(cherry picked from commit 7134959725011baa504a027c4561e0054dd907ae)
commit 3c7e14f849884d5d145a7ab9c942acbbc9c5d282
Author: Daniel-Constantin Mierla <miconda@gmail.com>
Date: Wed May 14 23:12:33 2014 +0200
rls: proper header define guard and check of null returned value
(cherry picked from commit 4f2da3e025fa281f88e80bb841a51d6546219ae8)
commit 164b17f8677c3c877ffd697ec5fb40d0d81e12f8
Author: Daniel-Constantin Mierla <miconda@gmail.com>
Date: Wed May 14 23:08:06 2014 +0200
ipops: free dns pv structure on invalid pv name
(cherry picked from commit e53c715c74fb5b58f4f68b81acb60de66b19b8cc)
commit 386ef2f61d18966ceb70916869389f2690e0a6ef
Author: Daniel-Constantin Mierla <miconda@gmail.com>
Date: Wed May 14 23:03:19 2014 +0200
db_flatstore: free result before returning null on no more pkg
- partial allocation when doing an incomplete new connection
(cherry picked from commit 74743d6ef3bf74c1226ba5a1b6bebfbe19b06b93)
commit c5c1002be8c4f3e24d1b79b77856db2879b97c72
Author: Daniel-Constantin Mierla <miconda@gmail.com>
Date: Wed May 14 22:56:37 2014 +0200
core: free previous allocated variable if no more pkg to build rve struct
- cleaner shut down if not enough memory at startup
(cherry picked from commit ace56c6bd2221920b965185c1c9a5997cd3f2768)
commit 8c47852eff1b42727d56f9791a28525a23b25599
Author: Daniel-Constantin Mierla <miconda@gmail.com>
Date: Wed May 14 22:53:35 2014 +0200
pv: proper length for line transformation when handling last line of value
(cherry picked from commit f1a09e44268c77641216a78878f2c73c6e5a4d66)
commit 12a0a927aa3ad6dfbb18ab3fcf1927bf51098925
Author: Daniel-Constantin Mierla <miconda@gmail.com>
Date: Mon May 12 22:54:54 2014 +0200
dialog: if sending BYE fails at timeout, unref dialog
- destroy dialog structures
(cherry picked from commit e39a90e11bfed2b4445c37db1532488aa9e3e725)
commit 3457dc459acd7eba96a0cb77e7d50cfc349c303e
Author: Daniel-Constantin Mierla <miconda@gmail.com>
Date: Sat May 3 21:06:34 2014 +0200
mem/q_malloc: free old pointer if allocation in realloc fails
(cherry picked from commit 8c2888fcd33bee45cb4654222da619e70ed44ecc)
commit ce46f5482f56378beba16c68d1e5af5e5d593008
Author: Daniel-Constantin Mierla <miconda@gmail.com>
Date: Sat May 3 21:03:34 2014 +0200
mem/f_malloc: free old pointer if allocation in realloc fails
(cherry picked from commit 41a37b570758445d723d4d78b9786f8e6cb5722c)
commit 2cfb00b4a24f24cd9462305f4518797706b8f6f1
Author: Daniel-Constantin Mierla <miconda@gmail.com>
Date: Fri May 2 23:58:12 2014 +0200
mem/f_malloc: check returned pointer for bitmask index
- if null, reset slot and search on bigger chunks slots
(cherry picked from commit 892a24f7256e60e2a0116655e0052c284479b7d2)
commit 6e17d6e92c1e4b76fbea4b4b5d925ed67e4fdac7
Author: Carlos Ruiz Diaz <carlos.ruizdiaz@gmail.com>
Date: Sun Apr 27 21:22:49 2014 -0500
cnxcc: fixed deadlock when call gets terminated under certain conditions
- fixed some indentation problems introduced by Eclipse IDE
(cherry picked from commit d0f0ba702bd44524bc9f52e07341db03267b15f7)
commit 3997dcccf36579442cb92222fe0868accd64b537
Author: Daniel-Constantin Mierla <miconda@gmail.com>
Date: Wed Jun 11 19:01:17 2014 +0200
auth: enhanced log message when method param fails to be retrieved
(cherry picked from commit 35329870fe22115fd24a396b743e4814278ce46a)
commit 94ebfb5d5973ed59de84ca0e0c87052b4c80f9de
Author: Torrey Searle <tsearle@gmail.com>
Date: Mon Jun 2 19:51:19 2014 +0200
srdb1: fix memory leak in db-id
- When getting an existing connection from the pool, free the newly
created db-id as the pool connection already has a reference to the
existing one. Fixes FS#436
(cherry picked from commit 69de17d3bb1d032f9a41752362194d718336e20d)
commit 642428cf8be1c7355f91b14276e888ec505cd69a
Author: Daniel-Constantin Mierla <miconda@gmail.com>
Date: Mon May 19 08:56:38 2014 +0200
dialog: add wait-for-ack callback before response unref
- in case of a sipral for ending in a negative response from initial
state, ack to second iteration can unref prematurely the dialog
- reported by Pawel Sternal, FS#427
(cherry picked from commit d81fd1bf067b78b55ad348db2531c4ba9b10dddb)
commit 7bdaca008e1bddbe9ab4db9d70e835ba45f6a5ff
Author: Daniel-Constantin Mierla <miconda@gmail.com>
Date: Thu May 29 17:06:13 2014 +0200
pv: safety check for PAI header parsed structure
- reported by Igor Potjevlesch
(cherry picked from commit e633ca6b7e748a77825d3208e86bf9bce18944a5)
commit ad5235229f59ba5d1f4216e144291e110fee0211
Author: Daniel-Constantin Mierla <miconda@gmail.com>
Date: Wed May 14 23:28:24 2014 +0200
parser/sdp: assign stream var only if session is not null
(cherry picked from commit 1cefc0c5f83eb4b7b6ffefc6ab383d7aae6de07f)
commit 5cd3bd3a1bbcc9edffe31c0b1fdf11da43023b2c
Author: Hugh Waite <hugh.waite@acision.com>
Date: Tue May 27 15:42:08 2014 +0100
rls: Fix memory leak with duplicate entries in lists
- When duplicate detection is requested, free the string and container
- When duplicate detection is not requested, insert the duplicate anyway
commit af4f84b84ca7601bd8124fe2e82d0718c7975313
Author: Daniel-Constantin Mierla <miconda@gmail.com>
Date: Tue May 27 12:07:42 2014 +0200
db_mysql: proper handling of mysql_next_result(...) return code
- it indicates the presence of another result if return is 0
- reported by Maxim (simax), FS#434
(cherry picked from commit 37f0964278e925d5530563b38c82a57de1f7fa59)
commit 9a697d04e7bb041e1ec6748727a418866dc0ba54
Author: Daniel-Constantin Mierla <miconda@gmail.com>
Date: Mon May 26 14:47:37 2014 +0200
auth_db: auth_check() to get the auth header from the used api
- this avoids using a different auth header that might be in the request
before checking usernames in from/to headers against auth user
(cherry picked from commit 4992519eed88d94847d742c52e882082b1b41264)
commit 47a00936695c46176c3c047e0ab141b4127d08dc
Author: Daniel-Constantin Mierla <miconda@gmail.com>
Date: Sun May 18 19:07:38 2014 +0200
mtree: replace tree structure even there are no records in db table
- reload didn't replaced old tree if no records in db table
- reported by Juha Heinanen
(cherry picked from commit c36f326d3c7372b149592d438df75f3d7b0a0233)
commit f44415eee52d5c17a9b6c5e16175bd84455e9867
Author: Daniel-Constantin Mierla <miconda@gmail.com>
Date: Thu May 15 13:59:03 2014 +0200
siputils: allocate enough space to hold ending zero for tel uri in tel2sip()
- reported by Juha Heinanen
(cherry picked from commit 7992a2b8d42bb7e8bcf1738cf042013ed126a47a)
commit 9c15e8444e99f33ca2f0c920d3cbb846d407f596
Author: Daniel-Constantin Mierla <miconda@gmail.com>
Date: Wed May 14 09:58:50 2014 +0200
presence_dialoginfo: get rid of unused variables warning
- priority and winning_priority are used in an alternative winning node
selection which is disabled now
- reported by Jua Heinanen
(cherry picked from commit 4f4641ea2a4018a72558c40d4878e9af7053be2d)
commit 402e2122d1aa353ee8c10321aa1eb9315a81cd81
Author: Daniel-Constantin Mierla <miconda@gmail.com>
Date: Wed Apr 16 19:43:45 2014 +0200
db_mysql: properly free db result structure if db_mysql_convert_result() fails
- reported by Torrey Searle, FS#420
(cherry picked from commit 37983c9f57536c57c5d34ce2d8a1c8f411e61e39)
commit 74c1bd884ec2a3418dee3cbf358ab8bb7e899d7a
Author: Vitaliy Aleksandrov <vitalik.voip@gmail.com>
Date: Thu May 8 15:01:02 2014 +0100
websocket: Fix crash in websocket module
- Avoid race condition by maintaining a connection reference count
- Fixes FS#406
commit cc4a7c67f24d105a119ea492ce53f017369af296
Author: Daniel-Constantin Mierla <miconda@gmail.com>
Date: Thu May 8 08:40:28 2014 +0200
presence_dialoginfo: interetate through all 'dialog' nodes of xml document
- PUBLISH request can carry info for many dialogs
- reported and patch by Klaus Feichtinger
(cherry picked from commit 7a827a612f93b9dd938f9b78c0de3ac2d98a0c77)
commit b76eb77a36a5e751d792cb7e0d60f4750976e322
Author: Daniel-Constantin Mierla <miconda@gmail.com>
Date: Fri May 2 21:50:14 2014 +0200
dialog: copy dlg var value locally on get operation
- reference to shared memory exposes risk on accessing an invalid
pointer if anothe process updates it
- reported by Dragos Oancea
(cherry picked from commit bb3eed8aabea9f63c9922f71714aea242771db02)
commit c5781b28cd92360cf163a84312fa72c08c4737b5
Author: Daniel-Constantin Mierla <miconda@gmail.com>
Date: Tue Apr 29 20:02:19 2014 +0200
rtmier: reset avps and xavp lists after route blocks execution
- avoid leaks if someone is using avp/xavp with rtimer - there is a fake
message used there, thus not the normal sip message routing that
resets avps/xavps
(cherry picked from commit 159978cf2a98748f3225155d8946bcbd768b51e3)
commit 4455a13e8d31416dc44af455710fd7a7ff37ec11
Author: Daniel-Constantin Mierla <miconda@gmail.com>
Date: Mon Apr 28 13:51:56 2014 +0200
acc: no request is needed for setting end time on dialog termination
- callback function cdr_on_end() doesn't use it at all
- reported by Eduardo Lejarreta, FS#256
(cherry picked from commit 8fcdd23aaa49cb6c1ecb34c4c6b4a88078a860f7)
commit 70f1b7479f80ca4f5e3a45fcf772785c110d0b57
Author: Daniel-Constantin Mierla <miconda@gmail.com>
Date: Wed Apr 30 21:46:55 2014 +0200
core: compute the len for dns srv name
- fixes dns srv for cache, reported by Rob Eijgenraam, FS#426
(cherry picked from commit b834cde74f8a4b41ec24ceb8332adff8bb3922bb)
commit a9a3cebc7688dcaea7539c067c4b1bf3463040ce
Author: Daniel-Constantin Mierla <miconda@gmail.com>
Date: Thu Apr 24 18:02:34 2014 +0200
drouting: removed old contraint on route index
(cherry picked from commit c3386295d7607a58d37a65b6822bf5f98b3fefa0)
commit ee692ab89f1321ccfb24316c30fce5a90e6a9764
Author: Daniel-Constantin Mierla <miconda@gmail.com>
Date: Mon Apr 28 09:51:42 2014 +0200
pipelimit: run timer at 1000ms
- proper execution on timer_interval
- reported by Julia <juliabo@gmail.com>
(cherry picked from commit f9d95734ba7c04a0188077914161395c2e94f3eb)
===================== 2014-04-24 Version 4.1.3 Released =====================
===================== Changes Since Version 4.1.2 ===========================

@ -164,7 +164,7 @@ INSTALL_FLAVOUR=$(FLAVOUR)
# version number
VERSION = 4
PATCHLEVEL = 1
SUBLEVEL = 3
SUBLEVEL = 4
EXTRAVERSION =
# memory manager switcher

@ -2,6 +2,6 @@
* DO NOT EDIT IT
*/
#define REPO_VER "236326"
#define REPO_HASH "236326"
#define REPO_VER "39adca"
#define REPO_HASH "39adca"
#define REPO_STATE ""

@ -3269,7 +3269,8 @@ cmd:
LOG(L_ERR, "misused command %s\n", $1);
yyerror("Command cannot be used in the block\n");
} else {
LOG(L_ERR, "cfg. parser: failed to find command %s\n", $1);
LOG(L_ERR, "cfg. parser: failed to find command %s (params %ld)\n",
$1, mod_func_action->val[1].u.number);
yyerror("unknown command, missing loadmodule?\n");
}
free_mod_func_action(mod_func_action);

@ -2656,7 +2656,6 @@ struct hostent* dns_srv_sip_resolvehost(str* name, unsigned short* port,
struct hostent* he;
struct ip_addr* ip;
static char tmp[MAX_DNS_NAME]; /* tmp. buff. for SRV lookups */
int len;
str srv_name;
char srv_proto;
@ -2664,7 +2663,6 @@ struct hostent* dns_srv_sip_resolvehost(str* name, unsigned short* port,
/* not init or off => use normal, non-cached version */
return _sip_resolvehost(name, port, proto);
}
len=0;
if (proto){ /* makes sure we have a protocol set*/
if (*proto==0)
*proto=srv_proto=PROTO_UDP; /* default */
@ -2708,7 +2706,7 @@ struct hostent* dns_srv_sip_resolvehost(str* name, unsigned short* port,
}
srv_name.s=tmp;
srv_name.len=len;
srv_name.len=strlen(tmp);
if ((he=dns_srv_get_he(&srv_name, port, dns_flags))!=0)
return he;
}

@ -84,6 +84,8 @@ inline static struct socket_info* get_send_socket(struct sip_msg* msg,
}
#define GET_URI_PORT(uri) ((uri)->port_no?(uri)->port_no:(((uri)->proto==PROTO_TLS)?SIPS_PORT:SIP_PORT))
struct socket_info* get_out_socket(union sockaddr_union* to, int proto);
typedef int (*check_self_f)(str* host, unsigned short port,
unsigned short proto);

@ -325,6 +325,8 @@ db1_con_t* db_do_init2(const str* url, void* (*new_connection)(), db_pooling_t p
pool_insert((struct pool_con*)con);
} else {
LM_DBG("connection %p found in pool\n", id);
free_db_id(id); // free the new id, as we use the pool instead
id = 0;
}
res->tail = (unsigned long)con;

@ -1785,6 +1785,18 @@ static int calc_proc_no(void)
tcp_e_listeners = tcp_cfg_children_no;
}
tcp_listeners += tcp_e_listeners;
#ifdef USE_TLS
tcp_e_listeners = 0;
for (si=tls_listen, tcp_e_listeners=0; si; si=si->next) {
if(si->workers>0)
tcp_listeners += si->workers;
else {
if(tcp_listeners==0)
tcp_e_listeners = tcp_cfg_children_no;
}
}
tcp_listeners += tcp_e_listeners;
#endif
tcp_children_no = tcp_listeners;
#endif
#ifdef USE_SCTP

@ -375,9 +375,17 @@ void* fm_malloc(struct fm_block* qm, unsigned long size)
if (likely(hash>=0)){
if (likely(hash<=F_MALLOC_OPTIMIZE/ROUNDTO)) { /* return first match */
f=&(qm->free_hash[hash].first);
goto found;
if(likely(*f)) goto found;
#ifdef DBG_F_MALLOC
MDBG(" block %p hash %d empty but no. is %lu\n", qm,
hash, qm->free_hash[hash].no);
#endif
/* reset slot and try next hash */
qm->free_hash[hash].no=0;
fm_bmp_reset(qm, hash);
hash++;
}
/* if we are here we are searching for a "big" fragment
/* if we are here we are searching next hash slot or a "big" fragment
between F_MALLOC_OPTIMIZE/ROUNDTO+1
and F_MALLOC_OPTIMIZE/ROUNDTO + (32|64) - F_MALLOC_OPTIMIZE_FACTOR
=> 18 hash buckets on 32 bits and 50 buckets on 64 bits
@ -692,12 +700,12 @@ void* fm_realloc(struct fm_block* qm, void* p, unsigned long size)
if (ptr){
/* copy, need by libssl */
memcpy(ptr, p, orig_size);
}
#ifdef DBG_F_MALLOC
fm_free(qm, p, file, func, line);
fm_free(qm, p, file, func, line);
#else
fm_free(qm, p);
fm_free(qm, p);
#endif
}
p=ptr;
}
}else{

@ -653,12 +653,12 @@ void* qm_realloc(struct qm_block* qm, void* p, unsigned long size)
if (ptr){
/* copy, need by libssl */
memcpy(ptr, p, orig_size);
}
#ifdef DBG_QM_MALLOC
qm_free(qm, p, file, func, line);
qm_free(qm, p, file, func, line);
#else
qm_free(qm, p);
qm_free(qm, p);
#endif
}
p=ptr;
}
}else{

@ -569,7 +569,7 @@ static void cdr_on_end( struct dlg_cell* dialog,
int type,
struct dlg_cb_params* params)
{
if( !dialog || !params || !params->req)
if( !dialog || !params)
{
LM_ERR("invalid values\n!");
return;

@ -426,6 +426,7 @@ static inline void acc_onreply( struct cell* t, struct sip_msg *req,
{
str new_uri_bk;
int br = -1;
hdr_field_t *hdr;
/* acc_onreply is bound to TMCB_REPLY which may be called
from _reply, like when FR hits; we should not miss this
@ -466,9 +467,9 @@ static inline void acc_onreply( struct cell* t, struct sip_msg *req,
if (is_db_acc_on(req)) {
if(acc_db_set_table_name(req, db_table_acc_data, &db_table_acc)<0) {
LM_ERR("cannot set acc db table name\n");
return;
} else {
acc_db_request(req);
}
acc_db_request(req);
}
#endif
#ifdef RAD_ACC
@ -488,6 +489,19 @@ static inline void acc_onreply( struct cell* t, struct sip_msg *req,
req->new_uri = new_uri_bk;
req->parsed_uri_ok = 0;
}
/* free header's parsed structures that were added by resolving acc attributes */
for( hdr=req->headers ; hdr ; hdr=hdr->next ) {
if ( hdr->parsed && hdr_allocs_parse(hdr) &&
(hdr->parsed<(void*)t->uas.request ||
hdr->parsed>=(void*)t->uas.end_request)) {
/* header parsed filed doesn't point inside uas.request memory
* chunck -> it was added by resolving acc attributes -> free it as pkg */
DBG("removing hdr->parsed %d\n", hdr->type);
clean_hdr_field(hdr);
hdr->parsed = 0;
}
}
}

@ -20,6 +20,15 @@ JAVA_HOME ?= $(shell readlink -f /usr/bin/javac | sed "s:bin/javac::")
DEFS += $(shell pkg-config libgcj12 --cflags) -I$(JAVA_HOME)/include
LIBS += $(shell pkg-config libgcj12 --libs) -L$(JAVA_HOME)/lib -ljvm
# On Debian 7.5 there is a bug with JAVA_HOME detection.
# $(shell readlink -f /usr/bin/javac | sed "s:bin/javac::") points to perl wrapper script (/usr/bin/gcj-wrapper-4.7)
# whereas the real compiler is at /usr/bin/gcj-4.7. As the result, JAVA_HOME will not be a directory, that is incorrect.
# At this point I don't see any universal method as explicit setting this variable at the compile phase.
# -- ez
ifeq ($(shell [ -d "${JAVA_HOME}" -a -f "$(JAVA_HOME)/include/jni.h" -a -f "$(JAVA_HOME)/lib/libjvm.so" ] && echo 1 || echo 0),0)
$(error Can't locate Java Development Kit. You have to specify environment JAVA_HOME to build app_java)
endif
ifeq ($(OS), freebsd)
LIBS+=-pthread
endif

@ -6,7 +6,6 @@
<!-- Include general documentation entities -->
<!ENTITY % docentities SYSTEM "../../../docbook/entities.xml">
%docentities;
]>
<book xmlns:xi="http://www.w3.org/2001/XInclude">
@ -15,8 +14,8 @@
<productname class="trade">&kamailioname;</productname>
<authorgroup>
<author>
<firstname>Konstantin</firstname>
<surname>Mosesov</surname>
<firstname>Konstantin</firstname>
<surname>Mosesov</surname>
</author>
<editor>
<firstname>Konstantin</firstname>
@ -25,11 +24,12 @@
</authorgroup>
<copyright>
<year>2013</year>
<holder>Konstantin Mosesov</holder>
<year>2014</year>
<holder>Konstantin Mosesov</holder>
</copyright>
</bookinfo>
<toc></toc>
<xi:include xmlns:xi="http://www.w3.org/2001/XInclude" href="app_java_admin.xml"/>
<xi:include xmlns:xi="http://www.w3.org/2001/XInclude" href="app_java_admin.xml"/>
</book>

@ -88,8 +88,8 @@
<section>
<title>Java runtime</title>
<section>
<title/>
<para>Java runtime library (JRE or JDK) is required to use this module.</para>
<title>JRE or JDK is required to use this module</title>
<para>Java runtime library (JRE and JDK for building app_java) is required to use this module.</para>
</section>
</section>
<!-- end of section Java Runtime -->
@ -166,7 +166,9 @@ modparam("app_java", "java_options", "-Djava.compiler=NONE")
<programlisting format="linespecific">
...
# Assumes "application java folder" is located at /opt/kamailio/java
modparam("app_java", "java_options", "-Djava.compiler=NONE -Djava.class.path=/path/to/kamailio/modules:/opt/kamailio/java:/opt/kamailio/java/kamailio.jar")
modparam("app_java", "java_options", "-Djava.compiler=NONE
-Djava.class.path=/path/to/kamailio/modules:/opt/kamailio/java:
/opt/kamailio/java/kamailio.jar")
...
</programlisting>
</example>
@ -175,7 +177,9 @@ modparam("app_java", "java_options", "-Djava.compiler=NONE -Djava.class.path=/pa
<programlisting format="linespecific">
...
# Assumes "application java folder" is located at /opt/kamailio/java
modparam("app_java", "java_options", "-verbose:gc,class,jni -Djava.compiler=NONE -Djava.class.path=/path/to/kamailio/modules:/opt/kamailio/java:/opt/kamailio/java/kamailio.jar")
modparam("app_java", "java_options", "-verbose:gc,class,jni
-Djava.compiler=NONE -Djava.class.path=/path/to/kamailio/modules:
/opt/kamailio/java:/opt/kamailio/java/kamailio.jar")
...
</programlisting>
</example>
@ -184,7 +188,9 @@ modparam("app_java", "java_options", "-verbose:gc,class,jni -Djava.compiler=NONE
<programlisting format="linespecific">
...
# Assumes "application java folder" is located at /opt/kamailio/java
modparam("app_java", "java_options", "-Xdebug -verbose:gc,class,jni -Djava.compiler=NONE -Djava.class.path=/path/to/kamailio/modules:/opt/kamailio/java:/opt/kamailio/java/kamailio.jar")
modparam("app_java", "java_options", "-Xdebug -verbose:gc,class,jni
-Djava.compiler=NONE -Djava.class.path=/path/to/kamailio/modules:
/opt/kamailio/java:/opt/kamailio/java/kamailio.jar")
...
</programlisting>
</example>
@ -240,7 +246,8 @@ modparam("app_java", "force_cmd_exec", 1)
object L
short S
void V
Note that to specify an object, the "L" is followed by the object's class name and ends with a semi-colon, ';' .
Note that to specify an object, the "L" is followed by the
object's class name and ends with a semi-colon, ';' .
</programlisting>
</para>
<para> app_java supports the following signatures:
@ -263,7 +270,8 @@ modparam("app_java", "force_cmd_exec", 1)
Parameters are optional, ommitting a parameter meant the passed value is NULL.
Parameters count should be exactly the same as signature count.
Note 1: Arrays representation (symbol '[') is not supported yet.
Note 2: You shall use a correct signature, e.g. the following examples of combinations are invalid:
Note 2: You shall use a correct signature, e.g. the following examples of
combinations are invalid:
java_method_exec("ExampleMethod", "ZI", "False");
java_method_exec("ExampleMethod", "LI", "something", "5");
</programlisting>
@ -293,8 +301,8 @@ java_method_exec("ExampleMethod", "V");
# Java
public int ExampleMethod()
{
... do something;
return 1;
... do something;
return 1;
}
</programlisting>
</example>
@ -316,8 +324,8 @@ java_method_exec("ExampleMethod", "Ljava/lang/String;I", "$mb", "$ml");
# Java
public int ExampleMethod(String SipMessageBuffer, int SipMessageLenght)
{
... do something with buffer;
return 1;
... do something with buffer;
return 1;
}
</programlisting>
</example>
@ -339,11 +347,12 @@ java_method_exec("ExampleMethod", "ZB", "true", "0x05");
# Java
public int ExampleMethod(boolean flagSet, byte bFlag);
{
if (flagSet)
{
... do something with flags;
}
return 1;
if (flagSet)
{
... do something with flags;
}
return 1;
}
</programlisting>
</example>
@ -373,8 +382,8 @@ java_staticmethod_exec("ExampleMethod", "V");
# Java
public static int ExampleMethod()
{
... do something;
return 1;
... do something;
return 1;
}
</programlisting>
</example>
@ -396,8 +405,8 @@ java_staticmethod_exec("ExampleMethod", "Ljava/lang/String;I", "$mb", "$ml");
# Java
public static int ExampleMethod(String SipMessageBuffer, int SipMessageLenght)
{
... do something with buffer;
return 1;
... do something with buffer;
return 1;
}
</programlisting>
</example>
@ -419,11 +428,12 @@ java_staticmethod_exec("ExampleMethod", "ZB", "true", "0x05");
# Java
public static int ExampleMethod(boolean flagSet, byte bFlag);
{
if (flagSet)
{
... do something with flags;
}
return 1;
if (flagSet)
{
... do something with flags;
}
return 1;
}
</programlisting>
</example>
@ -454,8 +464,8 @@ java_s_method_exec("ExampleMethod", "V");
# Java
public synchronized int ExampleMethod()
{
... do something;
return 1;
... do something;
return 1;
}
</programlisting>
</example>
@ -477,8 +487,8 @@ java_s_method_exec("ExampleMethod", "Ljava/lang/String;I", "$mb", "$ml");
# Java
public synchronized int ExampleMethod(String SipMessageBuffer, int SipMessageLenght)
{
... do something with buffer;
return 1;
... do something with buffer;
return 1;
}
</programlisting>
</example>
@ -500,11 +510,12 @@ java_s_method_exec("ExampleMethod", "ZB", "true", "0x05");
# Java
public synchronized int ExampleMethod(boolean flagSet, byte bFlag);
{
if (flagSet)
{
... do something with flags;
}
return 1;
if (flagSet)
{
... do something with flags;
}
return 1;
}
</programlisting>
</example>
@ -535,8 +546,8 @@ java_s_staticmethod_exec("ExampleMethod", "V");
# Java
public static synchronized int ExampleMethod()
{
... do something;
return 1;
... do something;
return 1;
}
</programlisting>
</example>
@ -558,8 +569,8 @@ java_s_staticmethod_exec("ExampleMethod", "Ljava/lang/String;I", "$mb", "$ml");
# Java
public static synchronized int ExampleMethod(String SipMessageBuffer, int SipMessageLenght)
{
... do something with buffer;
return 1;
... do something with buffer;
return 1;
}
</programlisting>
</example>
@ -581,11 +592,12 @@ java_s_staticmethod_exec("ExampleMethod", "ZB", "true", "0x05");
# Java
public static synchronized int ExampleMethod(boolean flagSet, byte bFlag);
{
if (flagSet)
{
... do something with flags;
}
return 1;
if (flagSet)
{
... do something with flags;
}
return 1;
}
</programlisting>
</example>
@ -616,25 +628,25 @@ import org.siprouter.NativeInterface.*;
public class Kamailio extends NativeMethods
{
/* Here you should specify a full path to app_java.so */
static
{
System.load("/opt/kamailio/lib/kamailio/modules/app_java.so");
}
/* Constructor. Do not remove !!! */
public Kamailio()
{
}
/*
This method should be executed for each children process, immediately after forking.
Required. Do not remove !!!
*/
public int child_init(int rank)
{
return 1;
}
/* Here you should specify a full path to app_java.so */
static
{
System.load("/opt/kamailio/lib/kamailio/modules/app_java.so");
}
/* Constructor. Do not remove !!! */
public Kamailio()
{
}
/*
This method should be executed for each children process, immediately after forking.
Required. Do not remove !!!
*/
public int child_init(int rank)
{
return 1;
}
}
</programlisting>
</example>

@ -687,7 +687,7 @@ static int pv_www_authenticate2(struct sip_msg *msg, char* realm,
}
if (get_str_fparam(&smethod, msg, (fparam_t*)method) < 0) {
LM_ERR("failed to get method value\n");
LM_ERR("failed to get method value from msg %p var %p\n", msg, method);
goto error;
}
@ -830,6 +830,7 @@ static int fixup_pv_auth(void **param, int param_no)
switch(param_no) {
case 1:
case 2:
case 4:
return fixup_var_pve_str_12(param, 1);
case 3:
return fixup_var_int_12(param, 1);

@ -223,10 +223,10 @@ static int generate_avps(struct sip_msg* msg, db1_res_t* db_res)
/*
* Authorize digest credentials
* Authorize digest credentials and set the pointer to used hdr
*/
static int digest_authenticate(struct sip_msg* msg, str *realm,
str *table, hdr_types_t hftype, str *method)
static int digest_authenticate_hdr(sip_msg_t* msg, str *realm,
str *table, hdr_types_t hftype, str *method, hdr_field_t **ahdr)
{
char ha1[256];
int res;
@ -277,6 +277,7 @@ static int digest_authenticate(struct sip_msg* msg, str *realm,
}
cred = (auth_body_t*)h->parsed;
if(ahdr!=NULL) *ahdr = h;
res = get_ha1(&cred->digest.username, realm, table, ha1, &result);
if (res < 0) {
@ -315,6 +316,15 @@ end:
return ret;
}
/*
* Authorize digest credentials
*/
static int digest_authenticate(sip_msg_t* msg, str *realm,
str *table, hdr_types_t hftype, str *method)
{
return digest_authenticate_hdr(msg, realm, table, hftype, method, NULL);
}
/*
* Authenticate using Proxy-Authorize header field
@ -475,15 +485,15 @@ int auth_check(struct sip_msg* _m, char* _realm, char* _table, char *_flags)
LM_DBG("realm [%.*s] table [%.*s] flags [%d]\n", srealm.len, srealm.s,
stable.len, stable.s, iflags);
hdr = NULL;
if(_m->REQ_METHOD==METHOD_REGISTER)
ret = digest_authenticate(_m, &srealm, &stable, HDR_AUTHORIZATION_T,
&_m->first_line.u.request.method);
ret = digest_authenticate_hdr(_m, &srealm, &stable, HDR_AUTHORIZATION_T,
&_m->first_line.u.request.method, &hdr);
else
ret = digest_authenticate(_m, &srealm, &stable, HDR_PROXYAUTH_T,
&_m->first_line.u.request.method);
ret = digest_authenticate_hdr(_m, &srealm, &stable, HDR_PROXYAUTH_T,
&_m->first_line.u.request.method, &hdr);
if(ret==AUTH_OK && (iflags&AUTH_CHECK_ID_F)) {
hdr = (_m->proxy_auth==0)?_m->authorization:_m->proxy_auth;
if(ret==AUTH_OK && hdr!=NULL && (iflags&AUTH_CHECK_ID_F)) {
srealm = ((auth_body_t*)(hdr->parsed))->digest.username.user;
if((furi=parse_from_uri(_m))==NULL)

@ -409,7 +409,7 @@ int radius_authorize_sterman(struct sip_msg* _msg, dig_cred_t* _cred, str* _meth
goto err;
}
#endif
LM_ERR("authorization failed\n");
LM_ERR("authorization failed. RC auth returned %d\n", i);
}
err:

@ -36,18 +36,17 @@ extern data_t _data;
void check_calls_by_money(unsigned int ticks, void *param)
{
struct str_hash_entry *h_entry = NULL,
*tmp = NULL;
call_t *tmp_call = NULL;
*tmp = NULL;
call_t *tmp_call = NULL;
int i;
lock_get(&_data.money.lock);
if (_data.money.credit_data_by_client->table)
for(i = 0; i < _data.money.credit_data_by_client->size; i++)
clist_foreach_safe(&_data.money.credit_data_by_client->table[i], h_entry, tmp, next)
{
credit_data_t *credit_data = (credit_data_t *) h_entry->u.p;
call_t *call = NULL;
call_t *call = NULL;
double total_consumed_money = 0;
if (i > SAFE_ITERATION_THRESHOLD)
@ -55,7 +54,6 @@ void check_calls_by_money(unsigned int ticks, void *param)
LM_ERR("Too many iterations for this loop: %d", i);
break;
}
lock_get(&credit_data->lock);
clist_foreach_safe(credit_data->call_list, call, tmp_call, next)
@ -65,7 +63,7 @@ void check_calls_by_money(unsigned int ticks, void *param)
if (!call->confirmed)
continue;
consumed_time = get_current_timestamp() - call->start_timestamp;
consumed_time = get_current_timestamp() - call->start_timestamp;
if (consumed_time > call->money_based.initial_pulse)
{
@ -91,7 +89,7 @@ void check_calls_by_money(unsigned int ticks, void *param)
call->consumed_amount
);
}
if (credit_data->concurrent_calls == 0)
{
lock_release(&credit_data->lock);
@ -107,9 +105,10 @@ void check_calls_by_money(unsigned int ticks, void *param)
if (credit_data->consumed_amount >= credit_data->max_amount)
{
lock_release(&_data.money.lock);
terminate_all_calls(credit_data);
lock_release(&credit_data->lock);
break;
return;
}
lock_release(&credit_data->lock);
@ -121,8 +120,8 @@ void check_calls_by_money(unsigned int ticks, void *param)
void check_calls_by_time(unsigned int ticks, void *param)
{
struct str_hash_entry *h_entry = NULL,
*tmp = NULL;
call_t *tmp_call = NULL;
*tmp = NULL;
call_t *tmp_call = NULL;
int i;
lock_get(&_data.time.lock);
@ -132,7 +131,7 @@ void check_calls_by_time(unsigned int ticks, void *param)
clist_foreach_safe(&_data.time.credit_data_by_client->table[i], h_entry, tmp, next)
{
credit_data_t *credit_data = (credit_data_t *) h_entry->u.p;
call_t *call = NULL;
call_t *call = NULL;
int total_consumed_secs = 0;
lock_get(&credit_data->lock);
@ -150,8 +149,8 @@ void check_calls_by_time(unsigned int ticks, void *param)
if (!call->confirmed)
continue;
call->consumed_amount = get_current_timestamp() - call->start_timestamp;
total_consumed_secs += call->consumed_amount;
call->consumed_amount = get_current_timestamp() - call->start_timestamp;
total_consumed_secs += call->consumed_amount;
if (call->consumed_amount > call->max_amount)
{
@ -180,10 +179,11 @@ void check_calls_by_time(unsigned int ticks, void *param)
(int) credit_data->max_amount);
if (credit_data->consumed_amount >= credit_data->max_amount)
{
{
lock_release(&_data.time.lock);
terminate_all_calls(credit_data);
lock_release(&credit_data->lock);
break;
return;
}
lock_release(&credit_data->lock);

@ -68,12 +68,12 @@
MODULE_VERSION
#define HT_SIZE 229
#define MODULE_NAME "cnxcc"
#define NUMBER_OF_TIMERS 2
#define HT_SIZE 229
#define MODULE_NAME "cnxcc"
#define NUMBER_OF_TIMERS 2
#define TRUE 1
#define FALSE 0
#define TRUE 1
#define FALSE 0
data_t _data;
struct dlg_binds _dlgbinds;
@ -154,7 +154,7 @@ static cmd_export_t cmds[] =
static param_export_t params[] =
{
{"dlg_flag", INT_PARAM, &_data.ctrl_flag },
{"dlg_flag", INT_PARAM, &_data.ctrl_flag },
{"credit_check_period", INT_PARAM, &_data.check_period },
{ 0, 0, 0 }
};
@ -198,17 +198,17 @@ select_row_t sel_declaration[] = {
struct module_exports exports =
{
MODULE_NAME,
DEFAULT_DLFLAGS, /* dlopen flags */
DEFAULT_DLFLAGS,/* dlopen flags */
cmds,
params,
0, /* exported statistics */
0, /* exported MI functions */
mod_pvs, /* exported pseudo-variables */
0, /* extra processes */
mod_init, /* module initialization function */
0, /* exported statistics */
0, /* exported MI functions */
mod_pvs, /* exported pseudo-variables */
0, /* extra processes */
mod_init, /* module initialization function */
0,
0,
child_init /* per-child init function */
child_init /* per-child init function */
};
static int fixup_par(void** param, int param_no)
@ -261,7 +261,7 @@ static int mod_init(void)
_data.channel.credit_data_by_client = shm_malloc(sizeof(struct str_hash_table));
_data.channel.call_data_by_cid = shm_malloc(sizeof(struct str_hash_table));
_data.stats = (stats_t *) shm_malloc(sizeof(stats_t));
_data.stats = (stats_t *) shm_malloc(sizeof(stats_t));
if (!_data.stats)
{
@ -269,9 +269,9 @@ static int mod_init(void)
return -1;
}
_data.stats->active = 0;
_data.stats->active = 0;
_data.stats->dropped = 0;
_data.stats->total = 0;
_data.stats->total = 0;
if (init_hashtable(_data.time.credit_data_by_client) != 0)
return -1;
@ -336,8 +336,7 @@ static int child_init(int rank)
return -1;
}
if(fork_dummy_timer(PROC_TIMER, "CNXCC MB TIMER", 1,
check_calls_by_time, NULL, _data.check_period) < 0)
if(fork_dummy_timer(PROC_TIMER, "CNXCC MB TIMER", 1, check_calls_by_time, NULL, _data.check_period) < 0)
{
LM_ERR("failed to register MB TIMER routine as process\n");
return -1;
@ -423,11 +422,11 @@ static void notify_call_termination(str *callid, str *from_tag, str *to_tag)
int try_get_credit_data_entry(str *client_id, credit_data_t **credit_data)
{
struct str_hash_entry *cd_entry = NULL;
hash_tables_t *hts = NULL;
*credit_data = NULL;
hash_tables_t *hts = NULL;
*credit_data = NULL;
/* by money */
hts = &_data.money;
hts = &_data.money;
lock_get(&hts->lock);
cd_entry = str_hash_get(hts->credit_data_by_client, client_id->s, client_id->len);
@ -442,7 +441,7 @@ int try_get_credit_data_entry(str *client_id, credit_data_t **credit_data)
lock_release(&hts->lock);
/* by time */
hts = &_data.time;
hts = &_data.time;
lock_get(&hts->lock);
cd_entry = str_hash_get(hts->credit_data_by_client, client_id->s, client_id->len);
@ -457,7 +456,7 @@ int try_get_credit_data_entry(str *client_id, credit_data_t **credit_data)
lock_release(&hts->lock);
/* by channel */
hts = &_data.channel;
hts = &_data.channel;
lock_get(&hts->lock);
cd_entry = str_hash_get(hts->credit_data_by_client, client_id->s, client_id->len);
@ -477,11 +476,10 @@ int try_get_credit_data_entry(str *client_id, credit_data_t **credit_data)
int try_get_call_entry(str *callid, call_t **call, hash_tables_t **hts)
{
struct str_hash_entry *call_entry = NULL;
*call = NULL;
/* by money */
*hts = &_data.money;
*hts = &_data.money;
lock_get(&(*hts)->lock);
call_entry = str_hash_get((*hts)->call_data_by_cid, callid->s, callid->len);
@ -531,9 +529,9 @@ int try_get_call_entry(str *callid, call_t **call, hash_tables_t **hts)
static void stop_billing(str *callid)
{
struct str_hash_entry *cd_entry = NULL;
call_t *call = NULL;
hash_tables_t *hts = NULL;
credit_data_t *credit_data = NULL;
call_t *call = NULL;
hash_tables_t *hts = NULL;
credit_data_t *credit_data = NULL;
/*
* Search call data by call-id
@ -557,11 +555,10 @@ static void stop_billing(str *callid)
}
lock_get(&hts->lock);
/*
* Search credit_data by client_id
*/
cd_entry = str_hash_get(hts->credit_data_by_client, call->client_id.s, call->client_id.len);
cd_entry = str_hash_get(hts->credit_data_by_client, call->client_id.s, call->client_id.len);
if (cd_entry == NULL)
{
@ -580,12 +577,12 @@ static void stop_billing(str *callid)
}
lock_release(&hts->lock);
/*
* Update calls statistics
*/
lock_get(&_data.lock);
;
_data.stats->active--;
_data.stats->total--;
@ -831,7 +828,7 @@ exit:
void terminate_all_calls(credit_data_t *credit_data)
{
call_t *call = NULL,
*tmp = NULL;
*tmp = NULL;
clist_foreach_safe(credit_data->call_list, call, tmp, next)
{
@ -855,15 +852,15 @@ static void free_call(call_t *call)
LM_DBG("Freeing call [%.*s]\n", call->sip_data.callid.len, call->sip_data.callid.s);
e = str_hash_get(_data.money.call_data_by_cid, call->sip_data.callid.s, call->sip_data.callid.len);
e = str_hash_get(_data.money.call_data_by_cid, call->sip_data.callid.s, call->sip_data.callid.len);
if (e == NULL)
{
e = str_hash_get(_data.time.call_data_by_cid, call->sip_data.callid.s, call->sip_data.callid.len);
e = str_hash_get(_data.time.call_data_by_cid, call->sip_data.callid.s, call->sip_data.callid.len);
if (e == NULL)
{
e = str_hash_get(_data.channel.call_data_by_cid, call->sip_data.callid.s, call->sip_data.callid.len);
e = str_hash_get(_data.channel.call_data_by_cid, call->sip_data.callid.s, call->sip_data.callid.len);
if (e == NULL)
{
@ -910,21 +907,21 @@ static int shm_str_hash_alloc(struct str_hash_table *ht, int size)
static credit_data_t *get_or_create_credit_data_entry(str *client_id, credit_type_t type)
{
struct str_hash_table *ht = NULL;
gen_lock_t *lock = NULL;
gen_lock_t *lock = NULL;
struct str_hash_entry *e = NULL;
switch(type)
{
case CREDIT_MONEY:
ht = _data.money.credit_data_by_client;
ht = _data.money.credit_data_by_client;
lock = &_data.money.lock;
break;
case CREDIT_TIME:
ht = _data.time.credit_data_by_client;
ht = _data.time.credit_data_by_client;
lock = &_data.time.lock;
break;
case CREDIT_CHANNEL:
ht = _data.channel.credit_data_by_client;
ht = _data.channel.credit_data_by_client;
lock = &_data.channel.lock;
break;
default:
@ -934,7 +931,7 @@ static credit_data_t *get_or_create_credit_data_entry(str *client_id, credit_typ
lock_get(lock);
e = str_hash_get(ht, client_id->s, client_id->len);
e = str_hash_get(ht, client_id->s, client_id->len);
lock_release(lock);
/*
@ -947,7 +944,7 @@ static credit_data_t *get_or_create_credit_data_entry(str *client_id, credit_typ
else
{
credit_data_t *credit_data = NULL;
e = shm_malloc(sizeof(struct str_hash_entry));
e = shm_malloc(sizeof(struct str_hash_entry));
if (e == NULL)
{
@ -961,9 +958,9 @@ static credit_data_t *get_or_create_credit_data_entry(str *client_id, credit_typ
return NULL;
}
e->flags = 0;
e->u.p = (void *) shm_malloc(sizeof(credit_data_t));
credit_data = (credit_data_t *) e->u.p;
e->flags = 0;
e->u.p = (void *) shm_malloc(sizeof(credit_data_t));
credit_data = (credit_data_t *) e->u.p;
lock_init(&credit_data->lock);
@ -975,13 +972,13 @@ static credit_data_t *get_or_create_credit_data_entry(str *client_id, credit_typ
return NULL;
}
credit_data->max_amount = 0;
credit_data->max_amount = 0;
credit_data->concurrent_calls = 0;
credit_data->consumed_amount = 0;
credit_data->ended_calls_consumed_amount= 0;
credit_data->ended_calls_consumed_amount = 0;
credit_data->number_of_calls = 0;
credit_data->type = type;
credit_data->type = type;
/*
* Copy the client_id value to the root of the calls list.
@ -1018,7 +1015,7 @@ int terminate_call(call_t *call)
struct mi_root *root, *result = NULL;
struct mi_node *node, *node1 = NULL;
struct mi_cmd *end_dlg_cmd = NULL;
struct mi_cmd *end_dlg_cmd = NULL;
root = init_mi_tree(0, 0, 0);
if (root == NULL)
@ -1062,7 +1059,7 @@ int terminate_call(call_t *call)
LM_DBG("dlg_end_dlg sent to call [%.*s]\n", call->sip_data.callid.len, call->sip_data.callid.s);
free_mi_tree(root);
free_mi_tree(result);
notify_call_termination(&call->sip_data.callid, &call->sip_data.from_tag, &call->sip_data.to_tag);
return 0;
@ -1076,8 +1073,7 @@ error:
return -1;
}
static call_t *alloc_new_call_by_money(credit_data_t *credit_data,
struct sip_msg *msg, double credit, double cost_per_second, int initial_pulse, int final_pulse)
static call_t *alloc_new_call_by_money(credit_data_t *credit_data, struct sip_msg *msg, double credit, double cost_per_second, int initial_pulse, int final_pulse)
{
call_t *call = NULL;
@ -1089,7 +1085,7 @@ static call_t *alloc_new_call_by_money(credit_data_t *credit_data,
goto error;
}
call = shm_malloc(sizeof(call_t));
call = shm_malloc(sizeof(call_t));
if (call == NULL)
{
LM_ERR("No shared memory left\n");
@ -1106,11 +1102,11 @@ static call_t *alloc_new_call_by_money(credit_data_t *credit_data,
call->sip_data.to_tag.s = NULL;
call->sip_data.to_tag.len = 0;
call->sip_data.from_tag.s = NULL;
call->sip_data.from_tag.len = 0;
call->sip_data.from_tag.len = 0;
call->consumed_amount = initial_pulse * cost_per_second;
call->confirmed = FALSE;
call->max_amount = credit;
call->confirmed = FALSE;
call->max_amount = credit;
call->money_based.cost_per_second = cost_per_second;
call->money_based.initial_pulse = initial_pulse;
@ -1174,17 +1170,17 @@ static call_t *alloc_new_call_by_time(credit_data_t *credit_data, struct sip_msg
call->sip_data.to_tag.s = NULL;
call->sip_data.to_tag.len = 0;
call->sip_data.from_tag.s = NULL;
call->sip_data.from_tag.len = 0;
call->sip_data.from_tag.len = 0;
call->consumed_amount = 0;
call->confirmed = FALSE;
call->max_amount = max_secs;
call->confirmed = FALSE;
call->max_amount = max_secs;
/*
* Reference the client_id from the root of the list
*/
call->client_id.s = credit_data->call_list->client_id.s;
call->client_id.len = credit_data->call_list->client_id.len;
call->client_id.s = credit_data->call_list->client_id.s;
call->client_id.len = credit_data->call_list->client_id.len;
/*
* Insert the newly created call to the list of calls
@ -1211,7 +1207,7 @@ error:
static call_t *alloc_new_call_by_channel(credit_data_t *credit_data, struct sip_msg *msg, int max_chan)
{
call_t *call = NULL;
call_t *call = NULL;
lock_get(&credit_data->lock);
@ -1221,7 +1217,7 @@ static call_t *alloc_new_call_by_channel(credit_data_t *credit_data, struct sip_
goto error;
}
call = shm_malloc(sizeof(call_t));
call = shm_malloc(sizeof(call_t));
if (call == NULL)
{
LM_ERR("No shared memory left\n");
@ -1238,17 +1234,17 @@ static call_t *alloc_new_call_by_channel(credit_data_t *credit_data, struct sip_
call->sip_data.to_tag.s = NULL;
call->sip_data.to_tag.len = 0;
call->sip_data.from_tag.s = NULL;
call->sip_data.from_tag.len = 0;
call->sip_data.from_tag.len = 0;
call->consumed_amount = 0;
call->confirmed = FALSE;
call->max_amount = max_chan;
call->confirmed = FALSE;
call->max_amount = max_chan;
/*
* Reference the client_id from the root of the list
*/
call->client_id.s = credit_data->call_list->client_id.s;
call->client_id.len = credit_data->call_list->client_id.len;
call->client_id.s = credit_data->call_list->client_id.s;
call->client_id.len = credit_data->call_list->client_id.len;
/*
* Insert the newly created call to the list of calls
@ -1277,21 +1273,21 @@ error:
static int add_call_by_cid(str *cid, call_t *call, credit_type_t type)
{
struct str_hash_table *ht = NULL;
gen_lock_t *lock = NULL;
gen_lock_t *lock = NULL;
struct str_hash_entry *e = NULL;
switch(type)
{
case CREDIT_MONEY:
ht = _data.money.call_data_by_cid;
ht = _data.money.call_data_by_cid;
lock = &_data.money.lock;
break;
case CREDIT_TIME:
ht = _data.time.call_data_by_cid;
ht = _data.time.call_data_by_cid;
lock = &_data.time.lock;
break;
case CREDIT_CHANNEL:
ht = _data.channel.call_data_by_cid;
ht = _data.channel.call_data_by_cid;
lock = &_data.channel.lock;
break;
default:
@ -1343,7 +1339,7 @@ static int add_call_by_cid(str *cid, call_t *call, credit_type_t type)
return -1;
}
e->u.p = call;
e->u.p = call;
lock_get(lock);
str_hash_add(ht, e);
@ -1373,30 +1369,30 @@ static inline int get_pv_value(struct sip_msg* msg, pv_spec_t* spec, pv_value_t*
}
static int set_max_credit(struct sip_msg* msg,
char *str_pv_client,
char *str_pv_credit, char *str_pv_cps,
char *str_pv_inip, char *str_pv_finp)
char *str_pv_client,
char *str_pv_credit, char *str_pv_cps,
char *str_pv_inip, char *str_pv_finp)
{
credit_data_t *credit_data = NULL;
call_t *call = NULL;
call_t *call = NULL;
pv_spec_t *client_id_spec = (pv_spec_t *) str_pv_client,
*credit_spec = (pv_spec_t *) str_pv_credit,
*cps_spec = (pv_spec_t *) str_pv_cps,
pv_spec_t *client_id_spec = (pv_spec_t *) str_pv_client,
*credit_spec = (pv_spec_t *) str_pv_credit,
*cps_spec = (pv_spec_t *) str_pv_cps,
*initial_pulse_spec = (pv_spec_t *) str_pv_inip,
*final_pulse_spec = (pv_spec_t *) str_pv_finp;
*final_pulse_spec = (pv_spec_t *) str_pv_finp;
pv_value_t client_id_val,
credit_val,
cps_val,
initial_pulse_val,
final_pulse_val;
credit_val,
cps_val,
initial_pulse_val,
final_pulse_val;
double credit = 0,
cost_per_second = 0;
double credit = 0,
cost_per_second = 0;
unsigned int initial_pulse = 0,
final_pulse = 0;
unsigned int initial_pulse = 0,
final_pulse = 0;
if (msg->first_line.type == SIP_REQUEST && msg->first_line.u.request.method_value == METHOD_INVITE)
{
@ -1539,10 +1535,10 @@ static int get_channel_count(struct sip_msg* msg, char* str_pv_client, char* str
{
credit_data_t *credit_data = NULL;
pv_spec_t *chan_count_spec = (pv_spec_t *) str_pv_chan_count,
*client_id_spec = (pv_spec_t *) str_pv_client;
*client_id_spec = (pv_spec_t *) str_pv_client;
pv_value_t chan_count_val, client_id_val;
int value = -1;
int value = -1;
if (pv_get_spec_value(msg, client_id_spec, &client_id_val) != 0)
{
@ -1556,14 +1552,14 @@ static int get_channel_count(struct sip_msg* msg, char* str_pv_client, char* str
return -1;
}
if (try_get_credit_data_entry(&client_id_val.rs, &credit_data) == 0)
if (try_get_credit_data_entry(&client_id_val.rs, &credit_data) == 0)
value = credit_data->number_of_calls;
else
LM_ALERT("[%.*s] not found\n", msg->callid->body.len, msg->callid->body.s);
if (!pv_is_w(chan_count_spec))
{
LM_ERR("pvar is not writable");
LM_ERR("pvar is not writable\n");
return -1;
}
@ -1575,7 +1571,7 @@ static int get_channel_count(struct sip_msg* msg, char* str_pv_client, char* str
chan_count_val.rs.s = int2str(value, &chan_count_val.rs.len);
else
{
char buff[2] = { '-', '1' };
char buff[2] = { '-', '1' };
chan_count_val.rs.s = buff;
chan_count_val.rs.len = 2;
}
@ -1592,11 +1588,11 @@ static int get_channel_count(struct sip_msg* msg, char* str_pv_client, char* str
static int set_max_channels(struct sip_msg* msg, char* str_pv_client, char* str_pv_max_chan)
{
credit_data_t *credit_data = NULL;
call_t *call = NULL;
call_t *call = NULL;
pv_spec_t *max_chan_spec = (pv_spec_t *) str_pv_max_chan,
*client_id_spec = (pv_spec_t *) str_pv_client;
*client_id_spec = (pv_spec_t *) str_pv_client;
pv_value_t max_chan_val, client_id_val;
int max_chan = 0;
int max_chan = 0;
set_ctrl_flag(msg);
@ -1640,8 +1636,8 @@ static int set_max_channels(struct sip_msg* msg, char* str_pv_client, char* str_
}
LM_DBG("Setting up new call for client [%.*s], max-chan[%d], call-id[%.*s]\n", client_id_val.rs.len, client_id_val.rs.s,
max_chan,
msg->callid->body.len, msg->callid->body.s);
max_chan,
msg->callid->body.len, msg->callid->body.s);
if ((credit_data = get_or_create_credit_data_entry(&client_id_val.rs, CREDIT_CHANNEL)) == NULL)
{
@ -1650,7 +1646,7 @@ static int set_max_channels(struct sip_msg* msg, char* str_pv_client, char* str_
}
if (credit_data->number_of_calls + 1 > max_chan)
return -2; // you have, between calls being setup plus those established, more than you maximum quota
return -2; // you have, among calls being setup plus those established, more than you maximum quota
if (credit_data->concurrent_calls + 1 > max_chan)
return -3; // you have the max amount of established calls already
@ -1679,11 +1675,11 @@ static int set_max_channels(struct sip_msg* msg, char* str_pv_client, char* str_
static int set_max_time(struct sip_msg* msg, char* str_pv_client, char* str_pv_maxsecs)
{
credit_data_t *credit_data = NULL;
call_t *call = NULL;
call_t *call = NULL;
pv_spec_t *max_secs_spec = (pv_spec_t *) str_pv_maxsecs,
*client_id_spec = (pv_spec_t *) str_pv_client;
*client_id_spec = (pv_spec_t *) str_pv_client;
pv_value_t max_secs_val, client_id_val;
int max_secs = 0;
int max_secs = 0;
set_ctrl_flag(msg);
@ -1812,7 +1808,7 @@ static int update_max_time(struct sip_msg* msg, char* str_pv_client, char* str_p
*tmp_call = NULL;
lock_get(&_data.time.lock);
e = str_hash_get(ht, client_id_val.rs.s, client_id_val.rs.len);
e = str_hash_get(ht, client_id_val.rs.s, client_id_val.rs.len);
lock_release(&_data.time.lock);
if (e == NULL)
@ -1821,13 +1817,13 @@ static int update_max_time(struct sip_msg* msg, char* str_pv_client, char* str_p
return -1;
}
credit_data = (credit_data_t *) e->u.p;
credit_data = (credit_data_t *) e->u.p;
lock_get(&credit_data->lock);
LM_DBG("Updating max-secs for [%.*s] from [%f] to [%f]\n", e->key.len, e->key.s, credit_data->max_amount, credit_data->max_amount + secs);
credit_data->max_amount += secs;
credit_data->max_amount += secs;
if (credit_data->number_of_calls > 0)
update_fraction = secs / credit_data->number_of_calls;
@ -1840,7 +1836,7 @@ static int update_max_time(struct sip_msg* msg, char* str_pv_client, char* str_p
call->max_amount += update_fraction;
}
//redit_data->consumed_amount = 0;
//redit_data->consumed_amount = 0;
lock_release(&credit_data->lock);

@ -46,7 +46,7 @@ int sel_channels_count(str* res, select_t* s, struct sip_msg* msg)
LM_DBG("sel_channels_count for [%.*s]", s->params[2].v.s.len, s->params[2].v.s.s);
credit_data_t *credit_data = NULL;
int value = 0;
int value = 0;
if (s->params[2].v.s.len <= 0)
{
@ -54,7 +54,7 @@ int sel_channels_count(str* res, select_t* s, struct sip_msg* msg)
return -1;
}
if (try_get_credit_data_entry(&s->params[2].v.s, &credit_data) >= 0)
if (try_get_credit_data_entry(&s->params[2].v.s, &credit_data) == 0)
value = credit_data->number_of_calls;
else
LM_DBG("Client [%.*s] not found", s->params[2].v.s.len, s->params[2].v.s.s);

@ -115,6 +115,7 @@ struct flat_con* flat_new_connection(struct flat_id* id)
fn = get_name(id);
if (fn==0){
LM_ERR("get_name() failed\n");
pkg_free(res);
return 0;
}

@ -190,14 +190,14 @@ static int db_mysql_store_result(const db1_con_t* _h, db1_res_t** _r)
if (db_mysql_convert_result(_h, *_r) < 0) {
LM_ERR("error while converting result\n");
LM_DBG("freeing result set at %p\n", _r);
pkg_free(*_r);
*_r = 0;
/* all mem on Kamailio API side is already freed by
* db_mysql_convert_result in case of error, but we also need
* to free the mem from the mysql lib side */
mysql_free_result(RES_RESULT(*_r));
* to free the mem from the mysql lib side, internal pkg for it
* and *_r */
db_mysql_free_result(_h, *_r);
*_r = 0;
#if (MYSQL_VERSION_ID >= 40100)
while( mysql_more_results(CON_CONNECTION(_h)) && mysql_next_result(CON_CONNECTION(_h)) > 0 ) {
while( mysql_more_results(CON_CONNECTION(_h)) && mysql_next_result(CON_CONNECTION(_h)) == 0 ) {
MYSQL_RES *res = mysql_store_result( CON_CONNECTION(_h) );
mysql_free_result(res);
}
@ -207,7 +207,7 @@ static int db_mysql_store_result(const db1_con_t* _h, db1_res_t** _r)
done:
#if (MYSQL_VERSION_ID >= 40100)
while( mysql_more_results(CON_CONNECTION(_h)) && mysql_next_result(CON_CONNECTION(_h)) > 0 ) {
while( mysql_more_results(CON_CONNECTION(_h)) && mysql_next_result(CON_CONNECTION(_h)) == 0 ) {
MYSQL_RES *res = mysql_store_result( CON_CONNECTION(_h) );
mysql_free_result(res);
}

@ -69,6 +69,7 @@ int db_mysql_get_columns(const db1_con_t* _h, db1_res_t* _r)
}
if (db_allocate_columns(_r, RES_COL_N(_r)) != 0) {
RES_COL_N(_r) = 0;
LM_ERR("could not allocate columns\n");
return -3;
}
@ -173,6 +174,7 @@ static inline int db_mysql_convert_rows(const db1_con_t* _h, db1_res_t* _r)
if (db_allocate_rows(_r) < 0) {
LM_ERR("could not allocate rows");
RES_ROW_N(_r) = 0;
return -2;
}

@ -543,6 +543,8 @@ static void dlg_onreply(struct cell* t, int type, struct tmcb_params *param)
LM_DBG("dialog %p failed (negative reply)\n", dlg);
/* dialog setup not completed (3456XX) */
run_dlg_callbacks( DLGCB_FAILED, dlg, req, rpl, DLG_DIR_UPSTREAM, 0);
if(dlg_wait_ack==1)
dlg_set_tm_waitack(t, dlg);
/* do unref */
if (unref)
dlg_unref(dlg, unref);
@ -551,8 +553,6 @@ static void dlg_onreply(struct cell* t, int type, struct tmcb_params *param)
if_update_stat(dlg_enable_stats, failed_dlgs, 1);
if(dlg_wait_ack==1)
dlg_set_tm_waitack(t, dlg);
goto done;
}
@ -1353,7 +1353,8 @@ void dlg_ontimeout(struct dlg_tl *tl)
if(dlg->iflags&DLG_IFLAG_TIMEOUTBYE)
{
dlg_bye_all(dlg, NULL);
if(dlg_bye_all(dlg, NULL)<0)
dlg_unref(dlg, 1);
/* run event route for end of dlg */
dlg_run_event_route(dlg, NULL, dlg->state, DLG_STATE_DELETED);
dlg_unref(dlg, 1);
@ -1477,15 +1478,15 @@ void dlg_run_event_route(dlg_cell_t *dlg, sip_msg_t *msg, int ostate, int nstate
else
fmsg = msg;
if (exec_pre_script_cb(fmsg, REQUEST_CB_TYPE)>0)
if (exec_pre_script_cb(fmsg, LOCAL_CB_TYPE)>0)
{
dlg_ref(dlg, 1);
dlg_set_ctx_iuid(dlg);
LM_DBG("executing event_route %d on state %d\n", rt, nstate);
set_route_type(REQUEST_ROUTE);
set_route_type(LOCAL_ROUTE);
run_top_route(event_rt.rlist[rt], fmsg, 0);
dlg_reset_ctx_iuid();
exec_post_script_cb(fmsg, REQUEST_CB_TYPE);
exec_post_script_cb(fmsg, LOCAL_CB_TYPE);
dlg_unref(dlg, 1);
}
}

@ -284,6 +284,7 @@ int pv_get_dlg_variable(struct sip_msg *msg, pv_param_t *param, pv_value_t *res)
{
dlg_cell_t *dlg;
str * value;
str spv;
if (param==NULL || param->pvn.type!=PV_NAME_INTSTR
|| param->pvn.u.isname.type!=AVP_NAME_STR
@ -306,6 +307,19 @@ int pv_get_dlg_variable(struct sip_msg *msg, pv_param_t *param, pv_value_t *res)
/* dcm: todo - the value should be cloned for safe usage */
value = get_dlg_variable_unsafe(dlg, &param->pvn.u.isname.name.s);
spv.s = NULL;
if(value) {
spv.len = pv_get_buffer_size();
if(spv.len<value->len+1) {
LM_ERR("pv buffer too small (%d) - needed %d\n", spv.len, value->len);
} else {
spv.s = pv_get_buffer();
strncpy(spv.s, value->s, value->len);
spv.len = value->len;
spv.s[spv.len] = '\0';
}
}
print_lists(dlg);
/* unlock dialog */
@ -314,8 +328,8 @@ int pv_get_dlg_variable(struct sip_msg *msg, pv_param_t *param, pv_value_t *res)
dlg_release(dlg);
}
if (value)
return pv_get_strval(msg, param, res, value);
if (spv.s)
return pv_get_strval(msg, param, res, &spv);
return pv_get_null(msg, param, res);

@ -754,7 +754,7 @@ again:
}
}
if (rt_info->route_idx>0 && rt_info->route_idx<RT_NO) {
if (rt_info->route_idx>0 && main_rt.rlist[rt_info->route_idx]!=NULL) {
ret = run_top_route(main_rt.rlist[rt_info->route_idx], msg, 0);
if (ret<1) {
/* drop the action */

@ -261,6 +261,7 @@ int pv_parse_dns_name(pv_spec_t *sp, str *in)
error:
LM_ERR("error at PV dns name: %.*s\n", in->len, in->s);
if(dpv) pkg_free(dpv);
return -1;
}

@ -550,8 +550,7 @@ static int mt_load_db(m_tree_t *pt)
} else {
if(RES_ROW_N(db_res)==0)
{
mt_dbf.free_result(db_con, db_res);
return 0;
goto dbreloaded;
}
}
} else {
@ -561,8 +560,7 @@ static int mt_load_db(m_tree_t *pt)
{
if(ret==0)
{
mt_dbf.free_result(db_con, db_res);
return 0;
goto dbreloaded;
} else {
goto error;
}
@ -617,6 +615,8 @@ static int mt_load_db(m_tree_t *pt)
break;
}
} while(RES_ROW_N(db_res)>0);
dbreloaded:
mt_dbf.free_result(db_con, db_res);

@ -308,7 +308,7 @@ static int mod_init(void)
return -1;
}
timer_init(pl_timer, pl_timer_handle, 0, F_TIMER_FAST);
timer_add(pl_timer, MS_TO_TICKS(1500)); /* Start it after 1500ms */
timer_add(pl_timer, MS_TO_TICKS(1000)); /* Start it after 1000ms */
/* bind the SL API */
if (sl_load_api(&slb)!=0) {

@ -101,7 +101,7 @@ str* agregate_xmls(str* pres_user, str* pres_domain, str** body_array, int n)
xmlDocPtr doc = NULL;
xmlNodePtr root_node = NULL;
xmlNsPtr namespace = NULL;
int winner_priority = -1, priority;
/*int winner_priority = -1, priority;*/
xmlNodePtr p_root= NULL;
xmlDocPtr* xml_array ;
@ -111,6 +111,7 @@ str* agregate_xmls(str* pres_user, str* pres_domain, str** body_array, int n)
xmlNodePtr confirmed_node = NULL;
xmlNodePtr proceed_node = NULL;
xmlNodePtr trying_node = NULL;
xmlNodePtr next_node = NULL;
char *state = NULL;
@ -214,7 +215,8 @@ str* agregate_xmls(str* pres_user, str* pres_domain, str** body_array, int n)
goto error;
}
if (p_root->children) {
for (node = p_root->children; node; node = node->next) {
for (node = p_root->children; node; node = next_node) {
next_node = node->next;
if (node->type == XML_ELEMENT_NODE) {
LM_DBG("node type: Element, name: %s\n", node->name);
/* we do not copy the node, but unlink it and then add it ot the new node

@ -991,6 +991,11 @@ int pv_get_pai(struct sip_msg *msg, pv_param_t *param,
}
pai_body = get_pai(msg);
if(pai_body==NULL || pai_body->id==NULL)
{
LM_DBG("no P-Asserted-Identity header or empty body\n");
return pv_get_null(msg, param, res);
}
pai_uri = &pai_body->id[0];
cur_id = 0;
i = 0;

@ -126,13 +126,13 @@ static int urlencode_param(str *sin, str *sout)
{
char *at, *p;
at = sout->s;
p = sin->s;
if (sin==NULL || sout==NULL || sin->s==NULL || sout->s==NULL ||
sin->len<0 || sout->len < 3*sin->len+1)
return -1;
at = sout->s;
p = sin->s;
while (p < sin->s+sin->len) {
if (isalnum(*p) || *p == '-' || *p == '_' || *p == '.' || *p == '~')
*at++ = *p;
@ -1625,7 +1625,7 @@ int tr_eval_line(struct sip_msg *msg, tr_param_t *tp, int subtype,
if(p==NULL)
{
/* last line */
mv.len = (val->rs.s + val->rs.len) - p;
mv.len = (val->rs.s + val->rs.len) - mv.s;
} else {
mv.len = p - mv.s;
}
@ -1707,7 +1707,7 @@ int tr_eval_line(struct sip_msg *msg, tr_param_t *tp, int subtype,
if(p==NULL)
{
/* last line */
mv.len = (val->rs.s + val->rs.len) - p;
mv.len = (val->rs.s + val->rs.len) - mv.s;
} else {
mv.len = p - mv.s;
}

@ -41,8 +41,11 @@ static inline list_entry_t *list_insert(str *strng, list_entry_t *list, int *dup
if (cmp == 0)
{
if (duplicate != NULL)
{
*duplicate = 1;
return list;
pkg_free(p);
return list;
}
}
if (cmp > 0)
{
@ -58,8 +61,11 @@ static inline list_entry_t *list_insert(str *strng, list_entry_t *list, int *dup
if (cmp == 0)
{
if (duplicate != NULL)
{
*duplicate = 1;
return list;
pkg_free(p);
return list;
}
}
p->next = q->next;

@ -1366,7 +1366,7 @@ int rls_get_resource_list(str *rl_uri, str *username, str *domain,
{
/* No path specified - use all resource-lists. */
*rl_node = XMLDocGetNodeByName(*xmldoc,"resource-lists", NULL);
if(rl_node==NULL)
if(*rl_node==NULL)
{
LM_ERR("no resource-lists node in XML document\n");
goto error;

@ -1037,6 +1037,8 @@ int send_resource_subs(char* uri, void* param)
LM_WARN("%.*s has %.*s multiple times in the same resource list\n",
s->watcher_uri->len, s->watcher_uri->s,
s->pres_uri->len, s->pres_uri->s);
pkg_free(tmp_str->s);
pkg_free(tmp_str);
return 1;
}

@ -21,7 +21,7 @@
*
*/
#ifndef RLS_URILS_H
#ifndef RLS_UTILS_H
#define RLS_UTILS_H
#include "../../ut.h"

@ -37,6 +37,8 @@
#include "../../socket_info.h"
#include "../../dset.h"
#include "../../pt.h"
#include "../../usr_avp.h"
#include "../../xavp.h"
#include "../../timer_proc.h"
#include "../../script_cb.h"
#include "../../parser/parse_param.h"
@ -190,6 +192,10 @@ void stm_timer_exec(unsigned int ticks, void *param)
set_route_type(REQUEST_ROUTE);
run_top_route(main_rt.rlist[rt->route], fmsg, 0);
exec_post_script_cb(fmsg, REQUEST_CB_TYPE);
reset_avps();
#ifdef WITH_XAVP
xavp_reset_list();
#endif
}
}

@ -354,7 +354,7 @@ int tel2sip(struct sip_msg* _msg, char* _uri, char* _hostpart, char* _res)
if (strncasecmp(uri.s, "tel:", 4) != 0) return 1;
/* reserve memory for clean tel uri */
tel_uri.s = pkg_malloc(uri.len);
tel_uri.s = pkg_malloc(uri.len+1);
if (tel_uri.s == 0) {
LM_ERR("no more pkg memory\n");
return -1;

@ -92,7 +92,7 @@ int w_cmp_aor(struct sip_msg *msg, char *uri1, char *uri2)
int w_is_gruu(sip_msg_t *msg, char *uri1, char *p2)
{
str s1;
str s1, *s2;
sip_uri_t turi;
sip_uri_t *puri;
@ -103,12 +103,17 @@ int w_is_gruu(sip_msg_t *msg, char *uri1, char *p2)
LM_ERR("cannot get first parameter\n");
return -8;
}
if(parse_uri(s1.s, s1.len, &turi)!=0)
return -1;
if(parse_uri(s1.s, s1.len, &turi)!=0) {
LM_ERR("parsing of uri '%.*s' failed\n", s1.len, s1.s);
return -1;
}
puri = &turi;
} else {
if(parse_sip_msg_uri(msg)<0)
return -1;
if(parse_sip_msg_uri(msg)<0) {
s2 = GET_RURI(msg);
LM_ERR("parsing of uri '%.*s' failed\n", s2->len, s2->s);
return -1;
}
puri = &msg->parsed_uri;
}
if(puri->gr.s!=NULL)

@ -136,7 +136,7 @@ int th_get_uri_type(str *uri, int *mode, str *value)
return -1;
return 2; /* decode */
} else {
if(check_self(&puri.host, (puri.port_no)?puri.port_no:SIP_PORT, 0)==1)
if(check_self(&puri.host, (puri.port_no)?puri.port_no:0, 0)==1)
{
/* myself -- matched on all protos */
ret = th_get_param_value(&puri.params, &r2, value);

@ -47,6 +47,9 @@ gen_lock_t *wsconn_lock = NULL;
#define WSCONN_LOCK lock_get(wsconn_lock)
#define WSCONN_UNLOCK lock_release(wsconn_lock)
#define wsconn_ref(c) atomic_inc(&((c)->refcnt))
#define wsconn_unref(c) atomic_dec_and_test(&((c)->refcnt))
gen_lock_t *wsstat_lock = NULL;
ws_connection_used_list_t *wsconn_used_list = NULL;
@ -197,6 +200,8 @@ int wsconn_add(struct receive_info rcv, unsigned int sub_protocol)
int id_hash = tcp_id_hash(id);
ws_connection_t *wsc;
LM_DBG("wsconn_add id [%d]\n", id);
/* Allocate and fill in new WebSocket connection */
wsc = shm_malloc(sizeof(ws_connection_t));
if (wsc == NULL)
@ -210,6 +215,10 @@ int wsconn_add(struct receive_info rcv, unsigned int sub_protocol)
wsc->state = WS_S_OPEN;
wsc->rcv = rcv;
wsc->sub_protocol = sub_protocol;
wsc->run_event = 0;
atomic_set(&wsc->refcnt, 0);
LM_DBG("wsconn_add new wsc => [%p], ref => [%d]\n", wsc, atomic_get(&wsc->refcnt));
WSCONN_LOCK;
/* Add to WebSocket connection table */
@ -225,8 +234,12 @@ int wsconn_add(struct receive_info rcv, unsigned int sub_protocol)
wsconn_used_list->tail->used_next = wsc;
wsconn_used_list->tail = wsc;
}
wsconn_ref(wsc);
WSCONN_UNLOCK;
LM_DBG("wsconn_add added to conn_table wsc => [%p], ref => [%d]\n", wsc, atomic_get(&wsc->refcnt));
/* Update connection statistics */
lock_get(wsstat_lock);
@ -290,32 +303,29 @@ static void wsconn_run_route(ws_connection_t *wsc)
set_route_type(backup_rt);
}
int wsconn_rm(ws_connection_t *wsc, ws_conn_eventroute_t run_event_route)
static void wsconn_dtor(ws_connection_t *wsc)
{
if (!wsc)
{
LM_ERR("wsconn_rm: null pointer\n");
return -1;
}
return;
if (run_event_route == WSCONN_EVENTROUTE_YES)
LM_DBG("wsconn_dtor for [%p] refcnt [%d]\n", wsc, atomic_get(&wsc->refcnt));
if (wsc->run_event)
wsconn_run_route(wsc);
WSCONN_LOCK;
/* Remove from the WebSocket used list */
if (wsconn_used_list->head == wsc)
wsconn_used_list->head = wsc->used_next;
if (wsconn_used_list->tail == wsc)
wsconn_used_list->tail = wsc->used_prev;
if (wsc->used_prev)
wsc->used_prev->used_next = wsc->used_next;
if (wsc->used_next)
wsc->used_next->used_prev = wsc->used_prev;
shm_free(wsc);
_wsconn_rm(wsc);
WSCONN_UNLOCK;
LM_DBG("wsconn_dtor for [%p] destroyed\n", wsc);
}
return 0;
int wsconn_rm(ws_connection_t *wsc, ws_conn_eventroute_t run_event_route)
{
LM_DBG("wsconn_rm for [%p] refcnt [%d]\n", wsc, atomic_get(&wsc->refcnt));
if (run_event_route == WSCONN_EVENTROUTE_YES)
wsc->run_event = 1;
return wsconn_put(wsc);
}
int wsconn_update(ws_connection_t *wsc)
@ -366,17 +376,70 @@ void wsconn_close_now(ws_connection_t *wsc)
con->timeout = get_ticks_raw();
}
/* must be called with unlocked WSCONN_LOCK */
int wsconn_put(ws_connection_t *wsc)
{
int destroy = 0;
LM_DBG("wsconn_put start for [%p] refcnt [%d]\n", wsc, atomic_get(&wsc->refcnt));
if (!wsc)
return -1;
WSCONN_LOCK;
/* refcnt == 0*/
if (wsconn_unref(wsc))
{
/* Remove from the WebSocket used list */
if (wsconn_used_list->head == wsc)
wsconn_used_list->head = wsc->used_next;
if (wsconn_used_list->tail == wsc)
wsconn_used_list->tail = wsc->used_prev;
if (wsc->used_prev)
wsc->used_prev->used_next = wsc->used_next;
if (wsc->used_next)
wsc->used_next->used_prev = wsc->used_prev;
/* remove from wsconn_id_hash */
wsconn_listrm(wsconn_id_hash[wsc->id_hash], wsc, id_next, id_prev);
/* stat */
update_stat(ws_current_connections, -1);
if (wsc->sub_protocol == SUB_PROTOCOL_SIP)
update_stat(ws_sip_current_connections, -1);
else if (wsc->sub_protocol == SUB_PROTOCOL_MSRP)
update_stat(ws_msrp_current_connections, -1);
destroy = 1;
}
WSCONN_UNLOCK;
LM_DBG("wsconn_put end for [%p] refcnt [%d]\n", wsc, atomic_get(&wsc->refcnt));
/* wsc is removed from all lists and can be destroyed safely */
if (destroy)
wsconn_dtor(wsc);
return 0;
}
ws_connection_t *wsconn_get(int id)
{
int id_hash = tcp_id_hash(id);
ws_connection_t *wsc;
LM_DBG("wsconn_get for id [%d]\n", id);
WSCONN_LOCK;
for (wsc = wsconn_id_hash[id_hash]; wsc; wsc = wsc->id_next)
{
if (wsc->id == id)
{
wsconn_ref(wsc);
LM_DBG("wsconn_get returns wsc [%p] refcnt [%d]\n", wsc, atomic_get(&wsc->refcnt));
WSCONN_UNLOCK;
return wsc;
}
}
@ -385,6 +448,85 @@ ws_connection_t *wsconn_get(int id)
return NULL;
}
ws_connection_t **wsconn_get_list(void)
{
ws_connection_t **list = NULL;
ws_connection_t *wsc = NULL;
size_t list_size = 0;
size_t list_len = 0;
size_t i = 0;
LM_DBG("wsconn_get_list\n");
WSCONN_LOCK;
/* get the number of used connections */
wsc = wsconn_used_list->head;
while (wsc)
{
LM_DBG("counter wsc [%p] prev => [%p] next => [%p]\n", wsc, wsc->used_prev, wsc->used_next);
list_len++;
wsc = wsc->used_next;
}
if (!list_len)
goto end;
/* allocate a NULL terminated list of wsconn pointers */
list_size = (list_len + 1) * sizeof(ws_connection_t *);
list = pkg_malloc(list_size);
if (!list)
goto end;
memset(list, 0, list_size);
/* copy */
wsc = wsconn_used_list->head;
for(i = 0; i < list_len; i++)
{
if (!wsc) {
LM_ERR("Wrong list length\n");
}
list[i] = wsc;
wsconn_ref(wsc);
LM_DBG("wsc [%p] id [%d] ref++\n", wsc, wsc->id);
wsc = wsc->used_next;
}
list[list_len] = NULL; /* explicit NULL termination */
end:
WSCONN_UNLOCK;
LM_DBG("wsconn_get_list returns list [%p] with [%d] members\n", list, (int)list_len);
return list;
}
int wsconn_put_list(ws_connection_t **list_head)
{
ws_connection_t **list = NULL;
ws_connection_t *wsc = NULL;
LM_DBG("wsconn_put_list [%p]\n", list_head);
if (!list_head)
return -1;
list = list_head;
wsc = *list_head;
while (wsc)
{
wsconn_put(wsc);
wsc = *(++list);
}
pkg_free(list_head);
return 0;
}
static int add_node(struct mi_root *tree, ws_connection_t *wsc)
{
int interval;

@ -29,6 +29,8 @@
#ifndef _WS_CONN_H
#define _WS_CONN_H
#include "../../atomic_ops.h"
#include "../../lib/kcore/kstats_wrapper.h"
#include "../../lib/kmi/tree.h"
@ -57,6 +59,9 @@ typedef struct ws_connection
struct receive_info rcv;
unsigned int sub_protocol;
atomic_t refcnt;
int run_event;
} ws_connection_t;
typedef struct
@ -89,6 +94,9 @@ int wsconn_rm(ws_connection_t *wsc, ws_conn_eventroute_t run_event_route);
int wsconn_update(ws_connection_t *wsc);
void wsconn_close_now(ws_connection_t *wsc);
ws_connection_t *wsconn_get(int id);
int wsconn_put(ws_connection_t *wsc);
ws_connection_t **wsconn_get_list(void);
int wsconn_put_list(ws_connection_t **list);
struct mi_root *ws_mi_dump(struct mi_root *cmd, void *param);
#endif /* _WS_CONN_H */

@ -240,7 +240,6 @@ static int encode_and_send_ws_frame(ws_frame_t *frame, conn_close_t conn_close)
pkg_free(send_buf);
if (wsconn_rm(frame->wsc, WSCONN_EVENTROUTE_YES) < 0)
LM_ERR("removing WebSocket connection\n");
frame->wsc = NULL;
return -1;
}
init_dst_from_rcv(&dst, &con->rcv);
@ -252,10 +251,8 @@ static int encode_and_send_ws_frame(ws_frame_t *frame, conn_close_t conn_close)
LM_ERR("removing WebSocket connection\n");
tcpconn_put(con);
pkg_free(send_buf);
frame->wsc = NULL;
return -1;
}
frame->wsc = NULL;
}
if (dst.proto == PROTO_WS)
@ -308,7 +305,6 @@ static int encode_and_send_ws_frame(ws_frame_t *frame, conn_close_t conn_close)
update_stat(ws_msrp_failed_connections, 1);
if (wsconn_rm(frame->wsc, WSCONN_EVENTROUTE_YES) < 0)
LM_ERR("removing WebSocket connection\n");
frame->wsc = NULL;
tcpconn_put(con);
return -1;
}
@ -394,20 +390,19 @@ static int close_connection(ws_connection_t **p_wsc, ws_close_type_t type,
else if (sub_proto == SUB_PROTOCOL_MSRP)
update_stat(ws_msrp_remote_closed_connections,
1);
*p_wsc = NULL;
}
}
else /* if (frame->wsc->state == WS_S_CLOSING) */
{
wsconn_close_now(wsc);
*p_wsc = NULL;
}
return 0;
}
static int decode_and_validate_ws_frame(ws_frame_t *frame,
tcp_event_info_t *tcpinfo)
tcp_event_info_t *tcpinfo,
short *err_code, str *err_text)
{
unsigned int i, len = tcpinfo->len;
int mask_start, j;
@ -415,21 +410,14 @@ static int decode_and_validate_ws_frame(ws_frame_t *frame,
LM_DBG("decoding WebSocket frame\n");
if ((frame->wsc = wsconn_get(tcpinfo->con->id)) == NULL)
{
LM_ERR("WebSocket connection not found\n");
return -1;
}
wsconn_update(frame->wsc);
/* Decode and validate first 9 bits */
if (len < 2)
{
LM_WARN("message is too short\n");
if (close_connection(&frame->wsc, LOCAL_CLOSE, 1002,
str_status_protocol_error) < 0)
LM_ERR("closing connection\n");
*err_code = 1002;
*err_text = str_status_protocol_error;
return -1;
}
frame->fin = (buf[0] & 0xff) & BYTE0_MASK_FIN;
@ -443,18 +431,16 @@ static int decode_and_validate_ws_frame(ws_frame_t *frame,
{
LM_WARN("WebSocket fragmentation not supported in the sip "
"sub-protocol\n");
if (close_connection(&frame->wsc, LOCAL_CLOSE, 1002,
str_status_protocol_error) < 0)
LM_ERR("closing connection\n");
*err_code = 1002;
*err_text = str_status_protocol_error;
return -1;
}
if (frame->rsv1 || frame->rsv2 || frame->rsv3)
{
LM_WARN("WebSocket reserved fields with non-zero values\n");
if (close_connection(&frame->wsc, LOCAL_CLOSE, 1002,
str_status_protocol_error) < 0)
LM_ERR("closing connection\n");
*err_code = 1002;
*err_text = str_status_protocol_error;
return -1;
}
@ -476,9 +462,8 @@ static int decode_and_validate_ws_frame(ws_frame_t *frame,
default:
LM_WARN("unsupported opcode: 0x%x\n",
(unsigned char) frame->opcode);
if (close_connection(&frame->wsc, LOCAL_CLOSE, 1008,
str_status_unsupported_opcode) < 0)
LM_ERR("closing connection\n");
*err_code = 1008;
*err_text = str_status_unsupported_opcode;
return -1;
}
@ -486,9 +471,8 @@ static int decode_and_validate_ws_frame(ws_frame_t *frame,
{
LM_WARN("this is a server - all received messages must be "
"masked\n");
if (close_connection(&frame->wsc, LOCAL_CLOSE, 1002,
str_status_protocol_error) < 0)
LM_ERR("closing connection\n");
*err_code = 1002;
*err_text = str_status_protocol_error;
return -1;
}
@ -499,9 +483,8 @@ static int decode_and_validate_ws_frame(ws_frame_t *frame,
if (len < 4)
{
LM_WARN("message is too short\n");
if (close_connection(&frame->wsc, LOCAL_CLOSE, 1002,
str_status_protocol_error) < 0)
LM_ERR("closing connection\n");
*err_code = 1002;
*err_text = str_status_protocol_error;
return -1;
}
mask_start = 4;
@ -514,9 +497,8 @@ static int decode_and_validate_ws_frame(ws_frame_t *frame,
if (len < 10)
{
LM_WARN("message is too short\n");
if (close_connection(&frame->wsc, LOCAL_CLOSE, 1002,
str_status_protocol_error) < 0)
LM_ERR("closing connection\n");
*err_code = 1002;
*err_text = str_status_protocol_error;
return -1;
}
mask_start = 10;
@ -525,9 +507,8 @@ static int decode_and_validate_ws_frame(ws_frame_t *frame,
|| (buf[4] & 0xff) != 0 || (buf[5] & 0xff) != 0)
{
LM_WARN("message is too long\n");
if (close_connection(&frame->wsc, LOCAL_CLOSE, 1009,
str_status_message_too_big) < 0)
LM_ERR("closing connection\n");
*err_code = 1009;
*err_text = str_status_message_too_big;
return -1;
}
@ -553,9 +534,8 @@ static int decode_and_validate_ws_frame(ws_frame_t *frame,
{
LM_WARN("message not complete frame size %u but received %u\n",
frame->payload_len + mask_start + 4, len);
if (close_connection(&frame->wsc, LOCAL_CLOSE, 1002,
str_status_protocol_error) < 0)
LM_ERR("closing connection\n");
*err_code = 1002;
*err_text = str_status_protocol_error;
return -1;
}
frame->payload_data = &buf[mask_start + 4];
@ -632,6 +612,11 @@ int ws_frame_receive(void *data)
ws_frame_t frame;
tcp_event_info_t *tcpinfo = (tcp_event_info_t *) data;
int opcode = -1;
int ret = 0;
short err_code = 0;
str err_text = {NULL, 0};
update_stat(ws_received_frames, 1);
if (tcpinfo == NULL || tcpinfo->buf == NULL || tcpinfo->len <= 0)
@ -640,7 +625,26 @@ int ws_frame_receive(void *data)
return -1;
}
switch(decode_and_validate_ws_frame(&frame, tcpinfo))
/* wsc refcnt++ */
frame.wsc = wsconn_get(tcpinfo->con->id);
if (frame.wsc == NULL)
{
LM_ERR("WebSocket connection not found\n");
return -1;
}
opcode = decode_and_validate_ws_frame(&frame, tcpinfo, &err_code, &err_text);
if (opcode < 0)
{
if (close_connection(&frame.wsc, LOCAL_CLOSE, err_code, err_text) < 0)
LM_ERR("closing connection\n");
wsconn_put(frame.wsc);
return -1;
}
switch(opcode)
{
case OPCODE_TEXT_FRAME:
case OPCODE_BINARY_FRAME:
@ -649,6 +653,9 @@ int ws_frame_receive(void *data)
LM_DBG("Rx SIP message:\n%.*s\n", frame.payload_len,
frame.payload_data);
update_stat(ws_sip_received_frames, 1);
wsconn_put(frame.wsc);
return receive_msg(frame.payload_data,
frame.payload_len,
tcpinfo->rcv);
@ -667,30 +674,46 @@ int ws_frame_receive(void *data)
tev.len = frame.payload_len;
tev.rcv = tcpinfo->rcv;
tev.con = tcpinfo->con;
wsconn_put(frame.wsc);
return sr_event_exec(SREV_TCP_MSRP_FRAME,
(void *) &tev);
}
else
{
LM_ERR("no callback registerd for MSRP\n");
LM_ERR("no callback registered for MSRP\n");
wsconn_put(frame.wsc);
return -1;
}
}
case OPCODE_CLOSE:
return handle_close(&frame);
ret = handle_close(&frame);
if (frame.wsc) wsconn_put(frame.wsc);
return ret;
case OPCODE_PING:
return handle_ping(&frame);
ret = handle_ping(&frame);
if (frame.wsc) wsconn_put(frame.wsc);
return ret;
case OPCODE_PONG:
return handle_pong(&frame);
ret = handle_pong(&frame);
if (frame.wsc) wsconn_put(frame.wsc);
return ret;
default:
LM_WARN("received bad frame\n");
wsconn_put(frame.wsc);
return -1;
}
/* how can we get here ? */
wsconn_put(frame.wsc);
return 0;
}
@ -715,9 +738,14 @@ int ws_frame_transmit(void *data)
if (encode_and_send_ws_frame(&frame, CONN_CLOSE_DONT) < 0)
{
LM_ERR("sending message\n");
wsconn_put(frame.wsc);
return -1;
}
wsconn_put(frame.wsc);
return 0;
}
@ -783,8 +811,11 @@ struct mi_root *ws_mi_close(struct mi_root *cmd, void *param)
str_status_bad_param.len);
}
if (close_connection(&wsc, LOCAL_CLOSE, 1000,
str_status_normal_closure) < 0)
int ret = close_connection(&wsc, LOCAL_CLOSE, 1000, str_status_normal_closure);
wsconn_put(wsc);
if (ret < 0)
{
LM_WARN("closing connection\n");
return init_mi_tree(500, str_status_error_closing.s,
@ -834,7 +865,11 @@ static struct mi_root *mi_ping_pong(struct mi_root *cmd, void *param,
str_status_bad_param.len);
}
if (ping_pong(wsc, opcode) < 0)
int ret = ping_pong(wsc, opcode);
wsconn_put(wsc);
if (ret < 0)
{
LM_WARN("sending %s\n", OPCODE_PING ? "Ping" : "Pong");
return init_mi_tree(500, str_status_error_sending.s,
@ -858,36 +893,55 @@ void ws_keepalive(unsigned int ticks, void *param)
{
int check_time = (int) time(NULL)
- cfg_get(websocket, ws_cfg, keepalive_timeout);
ws_connection_t *wsc = wsconn_used_list->head;
ws_connection_t **list = NULL,
**list_head = NULL;
ws_connection_t *wsc = NULL;
/* get an array of pointer to all ws connection */
list_head = wsconn_get_list();
if (!list_head)
return;
list = list_head;
wsc = *list_head;
while (wsc && wsc->last_used < check_time)
{
if (wsc->state == WS_S_CLOSING
|| wsc->awaiting_pong)
if (wsc->state == WS_S_CLOSING || wsc->awaiting_pong)
{
LM_WARN("forcibly closing connection\n");
wsconn_close_now(wsc);
}
else
ping_pong(wsconn_used_list->head,
ws_keepalive_mechanism == KEEPALIVE_MECHANISM_PING
? OPCODE_PING : OPCODE_PONG);
wsc = wsconn_used_list->head;
{
int opcode = (ws_keepalive_mechanism == KEEPALIVE_MECHANISM_PING)
? OPCODE_PING
: OPCODE_PONG;
ping_pong(wsc, opcode);
}
wsc = *(++list);
}
wsconn_put_list(list_head);
}
int ws_close(sip_msg_t *msg)
{
ws_connection_t *wsc;
int ret;
if ((wsc = wsconn_get(msg->rcv.proto_reserved1)) == NULL) {
LM_ERR("failed to retrieve WebSocket connection\n");
return -1;
}
return (close_connection(&wsc, LOCAL_CLOSE, 1000,
ret = (close_connection(&wsc, LOCAL_CLOSE, 1000,
str_status_normal_closure) == 0) ? 1: 0;
wsconn_put(wsc);
return ret;
}
int ws_close2(sip_msg_t *msg, char *_status, char *_reason)
@ -895,6 +949,7 @@ int ws_close2(sip_msg_t *msg, char *_status, char *_reason)
int status;
str reason;
ws_connection_t *wsc;
int ret;
if (get_int_fparam(&status, msg, (fparam_t *) _status) < 0) {
LM_ERR("failed to get status code\n");
@ -911,7 +966,11 @@ int ws_close2(sip_msg_t *msg, char *_status, char *_reason)
return -1;
}
return (close_connection(&wsc, LOCAL_CLOSE, status, reason) == 0) ? 1: 0;
ret = (close_connection(&wsc, LOCAL_CLOSE, status, reason) == 0) ? 1: 0;
wsconn_put(wsc);
return ret;
}
int ws_close3(sip_msg_t *msg, char *_status, char *_reason, char *_con)
@ -920,6 +979,7 @@ int ws_close3(sip_msg_t *msg, char *_status, char *_reason, char *_con)
str reason;
int con;
ws_connection_t *wsc;
int ret;
if (get_int_fparam(&status, msg, (fparam_t *) _status) < 0) {
LM_ERR("failed to get status code\n");
@ -941,5 +1001,9 @@ int ws_close3(sip_msg_t *msg, char *_status, char *_reason, char *_con)
return -1;
}
return (close_connection(&wsc, LOCAL_CLOSE, status, reason) == 0) ? 1: 0;
ret = (close_connection(&wsc, LOCAL_CLOSE, status, reason) == 0) ? 1: 0;
wsconn_put(wsc);
return ret;
}

@ -427,8 +427,10 @@ int ws_handle_handshake(struct sip_msg *msg)
&headers) < 0)
{
if ((wsc = wsconn_get(msg->rcv.proto_reserved1)) != NULL)
{
wsconn_rm(wsc, WSCONN_EVENTROUTE_NO);
wsconn_put(wsc);
}
goto end;
}
else

@ -871,12 +871,13 @@ void print_sdp_stream(sdp_stream_cell_t *stream, int log_level)
void print_sdp_session(sdp_session_cell_t *session, int log_level)
{
sdp_stream_cell_t *stream = session->streams;
sdp_stream_cell_t *stream;
if (session==NULL) {
LM_ERR("NULL session\n");
return;
}
stream = session->streams;
LOG(log_level, "..session[%d]:%p=>%p '%.*s' '%.*s' '%.*s' '%.*s:%.*s' (%d)=>%p\n",
session->session_num, session, session->next,

@ -204,6 +204,10 @@ other:
/**
* rfc4566:
* a=rtpmap:<payload type> <encoding name>/<clock rate> [/<encoding parameters>]
*/
int extract_rtpmap(str *body,
str *rtpmap_payload, str *rtpmap_encoding, str *rtpmap_clockrate, str *rtpmap_parmas)
{
@ -241,30 +245,28 @@ int extract_rtpmap(str *body,
rtpmap_encoding->s = cp;
cp1 = (char*)ser_memmem(cp, "/", len, 1);
len -= cp1 - cp;
if (len <= 0 || cp == cp1) {
LM_ERR("invalid encoding in `a=rtpmap'\n");
if(cp1==NULL) {
LM_ERR("invalid encoding in `a=rtpmap' at [%.*s]\n", len, cp);
return -1;
}
len -= cp1 - cp;
rtpmap_encoding->len = cp1 - cp;
cp = cp1;
cp = cp1+1; /* skip '/' */
len--;
rtpmap_clockrate->s = cp;
cp1 = (char*)ser_memmem(cp, "/", len, 1);
len -= cp1 - cp;
if (len <= 0) {
LM_ERR("invalid encoding in `a=rtpmap:'\n");
return -1;
}
rtpmap_clockrate->s = cp + 1; /* skip '/' */
rtpmap_clockrate->len = len -1; /* skip '/' */
if ( cp == cp1) {
if(cp1==NULL) {
/* no encoding parameters */
rtpmap_clockrate->len = len;
rtpmap_parmas->s = NULL;
rtpmap_parmas->len = 0;
} else {
rtpmap_parmas->s = cp1 + 1;
rtpmap_parmas->len = cp1 - cp;
return 0;
}
rtpmap_clockrate->len = cp1 - cp;
len -= cp1 - cp;
rtpmap_parmas->s = cp1 + 1; /* skip '/' */
rtpmap_parmas->len = len - 1;
return 0;
}

@ -1,5 +1,5 @@
%define name kamailio
%define ver 4.1.0
%define ver 4.1.4
%define rel 0%{dist}

@ -1,3 +1,9 @@
kamailio (4.1.4) unstable; urgency=low
* update to 4.1.4 from upstream
-- Daniel-Constantin Mierla <miconda@gmail.com> Thu, 12 Jun 2014 15:55:55 +0100
kamailio (4.1.3) unstable; urgency=low
* update to 4.1.3 from upstream

@ -1,3 +1,9 @@
kamailio (4.1.4) unstable; urgency=low
* update to 4.1.4 from upstream
-- Daniel-Constantin Mierla <miconda@gmail.com> Thu, 12 Jun 2014 15:55:55 +0100
kamailio (4.1.3) unstable; urgency=low
* update to 4.1.3 from upstream

@ -1,3 +1,9 @@
kamailio (4.1.4) unstable; urgency=low
* update to 4.1.4 from upstream
-- Daniel-Constantin Mierla <miconda@gmail.com> Thu, 12 Jun 2014 15:55:55 +0100
kamailio (4.1.3) unstable; urgency=low
* update to 4.1.3 from upstream

@ -1,3 +1,9 @@
kamailio (4.1.4) unstable; urgency=low
* update to 4.1.4 from upstream
-- Daniel-Constantin Mierla <miconda@gmail.com> Thu, 12 Jun 2014 15:55:55 +0100
kamailio (4.1.3) unstable; urgency=low
* update to 4.1.3 from upstream

@ -1,3 +1,9 @@
kamailio (4.1.4) unstable; urgency=low
* update to 4.1.4 from upstream
-- Daniel-Constantin Mierla <miconda@gmail.com> Thu, 12 Jun 2014 15:55:55 +0100
kamailio (4.1.3) unstable; urgency=low
* update to 4.1.3 from upstream

@ -1,6 +1,6 @@
%define name kamailio
%define ver 4.1.0
%define rel dev7.2%{dist}
%define ver 4.1.4
%define rel 0%{dist}

@ -35,7 +35,7 @@ check_fork ()
check_kamailio_config ()
{
# Check if kamailio configuration is valid before starting the server
out=$($KAM -c 2>&1 > /dev/null)
out=$($KAM -M $PKG_MEMORY -c 2>&1 > /dev/null)
retcode=$?
if [ "$retcode" != '0' ]; then
echo "Not starting $DESC: invalid configuration file!"

@ -1,5 +1,5 @@
%define name kamailio
%define ver 4.1.3
%define ver 4.1.4
%define rel 0
%define EXCLUDED_MODULES mysql jabber cpl-c avp_radius auth_radius group_radius uri_radius pa postgres osp tlsops unixodbc

@ -1,5 +1,5 @@
%define name kamailio
%define ver 4.1.3
%define ver 4.1.4
%define rel 0
%define _sharedir %{_prefix}/share

@ -1,5 +1,5 @@
%define name kamailio
%define ver 4.1.3
%define ver 4.1.4
%define rel 0
%define EXCLUDED_MODULES mysql jabber cpl-c auth_radius misc_radius peering postgress pa unixodbc osp tlsops

@ -1886,8 +1886,7 @@ inline static int eval_elem(struct run_act_ctx* h, struct expr* e,
if (e->r_type==MYSELF_ST){
if (parse_sip_msg_uri(msg)<0) ret=-1;
else ret=check_self_op(e->op, &msg->parsed_uri.host,
msg->parsed_uri.port_no?
msg->parsed_uri.port_no:SIP_PORT);
GET_URI_PORT(&msg->parsed_uri));
}else{
ret=comp_str(e->op, &msg->new_uri,
e->r_type, &e->r, msg, h);
@ -1896,8 +1895,7 @@ inline static int eval_elem(struct run_act_ctx* h, struct expr* e,
if (e->r_type==MYSELF_ST){
if (parse_sip_msg_uri(msg)<0) ret=-1;
else ret=check_self_op(e->op, &msg->parsed_uri.host,
msg->parsed_uri.port_no?
msg->parsed_uri.port_no:SIP_PORT);
GET_URI_PORT(&msg->parsed_uri));
}else{
ret=comp_str(e->op, &msg->first_line.u.request.uri,
e->r_type, &e->r, msg, h);
@ -1917,8 +1915,7 @@ inline static int eval_elem(struct run_act_ctx* h, struct expr* e,
LOG(L_ERR, "ERROR: eval_elem: bad uri in From:\n");
goto error;
}
ret=check_self_op(e->op, &uri.host,
uri.port_no?uri.port_no:SIP_PORT);
ret=check_self_op(e->op, &uri.host, GET_URI_PORT(&uri));
}else{
ret=comp_str(e->op, &get_from(msg)->uri,
e->r_type, &e->r, msg, h);
@ -1939,8 +1936,7 @@ inline static int eval_elem(struct run_act_ctx* h, struct expr* e,
LOG(L_ERR, "ERROR: eval_elem: bad uri in To:\n");
goto error;
}
ret=check_self_op(e->op, &uri.host,
uri.port_no?uri.port_no:SIP_PORT);
ret=check_self_op(e->op, &uri.host, GET_URI_PORT(&uri));
}else{
ret=comp_str(e->op, &get_to(msg)->uri,
e->r_type, &e->r, msg, h);

@ -33,7 +33,7 @@ extern rpc_export_t** rpc_sarray;
extern int rpc_sarray_crt_size;
int init_rpcs(void);
int destroy_rpcs(void);
void destroy_rpcs(void);
rpc_export_t* rpc_lookup(const char* name, int len);
int rpc_register(rpc_export_t* rpc);

@ -2554,6 +2554,7 @@ struct rval_expr* mk_rval_expr_v(enum rval_type rv_type, void* val,
s=(str*)val;
v.s.s=pkg_malloc(s->len+1 /*0*/);
if (v.s.s==0){
pkg_free(rve);
ERR("memory allocation failure\n");
return 0;
}

@ -4934,6 +4934,17 @@ int tcp_init_children()
}
}
}
#ifdef USE_TLS
for(si=tls_listen; si; si=si->next) {
if(si->workers>0) {
si->workers_tcpidx = i - si->workers + 1;
for(r=0; r<si->workers; r++) {
tcp_children[i].mysocket = si;
i--;
}
}
}
#endif
tcp_sockets_gworkers = (i != tcp_children_no-1)?(1 + i + 1):0;
/* create the tcp sock_info structures */

@ -1499,7 +1499,7 @@ static int get_mi_list(int s)
/* alloc the mi_cmds array */
mi_cmds=malloc(mi_which_results*sizeof(*mi_cmds));
if (mi_cmds==0) goto error_mem;
memset(mi_cmds, 0, mi_which_results* sizeof(mi_cmds));
memset(mi_cmds, 0, mi_which_results* sizeof(*mi_cmds));
/* get the mi names list */
for (r=0; r<mi_which_no; r++){
if (mi_which_array[r].type!=BINRPC_T_STR)

Loading…
Cancel
Save