From b16fed8a899560540ee6f0430e674f66ed3f1a4e Mon Sep 17 00:00:00 2001 From: Victor Seva Date: Sat, 14 Jun 2014 16:55:20 +0200 Subject: [PATCH] MT#7503 Imported Upstream version 4.1.4 --- ChangeLog | 488 ++++++++++++++++++++++ Makefile.defs | 2 +- autover.h | 4 +- cfg.y | 3 +- dns_cache.c | 4 +- forward.h | 2 + lib/srdb1/db.c | 2 + main.c | 12 + mem/f_malloc.c | 18 +- mem/q_malloc.c | 6 +- modules/acc/acc_cdr.c | 2 +- modules/acc/acc_logic.c | 18 +- modules/app_java/Makefile | 9 + modules/app_java/doc/app_java.xml | 10 +- modules/app_java/doc/app_java_admin.xml | 136 +++--- modules/auth/auth_mod.c | 3 +- modules/auth_db/authorize.c | 28 +- modules/auth_radius/sterman.c | 2 +- modules/cnxcc/cnxcc_check.c | 30 +- modules/cnxcc/cnxcc_mod.c | 208 +++++---- modules/cnxcc/cnxcc_select.c | 4 +- modules/db_flatstore/km_flat_con.c | 1 + modules/db_mysql/km_dbase.c | 12 +- modules/db_mysql/km_res.c | 2 + modules/dialog/dlg_handlers.c | 13 +- modules/dialog/dlg_var.c | 18 +- modules/drouting/drouting.c | 2 +- modules/ipops/ipops_pv.c | 1 + modules/mtree/mtree_mod.c | 8 +- modules/pipelimit/pipelimit.c | 2 +- modules/presence_dialoginfo/notify_body.c | 6 +- modules/pv/pv_core.c | 5 + modules/pv/pv_trans.c | 10 +- modules/rls/list.h | 10 +- modules/rls/notify.c | 2 +- modules/rls/subscribe.c | 2 + modules/rls/utils.h | 2 +- modules/rtimer/rtimer_mod.c | 6 + modules/siputils/checks.c | 2 +- modules/siputils/sipops.c | 15 +- modules/topoh/th_msg.c | 2 +- modules/websocket/ws_conn.c | 180 +++++++- modules/websocket/ws_conn.h | 8 + modules/websocket/ws_frame.c | 182 +++++--- modules/websocket/ws_handshake.c | 4 +- parser/sdp/sdp.c | 3 +- parser/sdp/sdp_helpr_funcs.c | 34 +- pkg/kamailio/centos/6/kamailio.spec | 2 +- pkg/kamailio/deb/debian/changelog | 6 + pkg/kamailio/deb/jessie/changelog | 6 + pkg/kamailio/deb/precise/changelog | 6 + pkg/kamailio/deb/squeeze/changelog | 6 + pkg/kamailio/deb/wheezy/changelog | 6 + pkg/kamailio/fedora/17/kamailio.spec | 4 +- pkg/kamailio/rpm/kamailio.init | 2 +- pkg/kamailio/rpm/kamailio.spec-4.1 | 2 +- pkg/kamailio/rpm/kamailio.spec.CenOS | 2 +- pkg/kamailio/rpm/kamailio.spec.SuSE | 2 +- route.c | 12 +- rpc_lookup.h | 2 +- rvalue.c | 1 + tcp_main.c | 11 + utils/sercmd/sercmd.c | 2 +- 63 files changed, 1225 insertions(+), 370 deletions(-) diff --git a/ChangeLog b/ChangeLog index 43955f775..471e3c7b7 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,491 @@ +===================== 2014-06-12 Version 4.1.4 Released ===================== + +===================== Changes Since Version 4.1.3 =========================== + +commit d521dff2563ddd1f64fb0c93e7cbd7a6ad254159 +Author: Daniel-Constantin Mierla +Date: Thu Jun 12 15:57:57 2014 +0200 + + Makefile.defs: version set to 4.1.4 + +commit a4f11987cd7fcabb68c377a6c61ab4238ec2cecc +Author: Daniel-Constantin Mierla +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 +Date: Thu Jun 12 15:53:36 2014 +0200 + + pkg: updated version in fedora and centos specs + +commit a2bffd8aa6f97c2496c15c26fcb487f514b347de +Author: Daniel-Constantin Mierla +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 +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 +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 +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 +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 +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 +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 +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 +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 +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 +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 +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 +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 +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 +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 +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 +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 +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 +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 +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 +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 +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 +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 +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 +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 +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 +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 +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 +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 +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 +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 +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 +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 +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 +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 +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 +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 +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 +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 +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 +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 +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 +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 +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 +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 +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 +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 +Date: Mon Apr 28 09:51:42 2014 +0200 + + pipelimit: run timer at 1000ms + + - proper execution on timer_interval + - reported by Julia + + (cherry picked from commit f9d95734ba7c04a0188077914161395c2e94f3eb) + + ===================== 2014-04-24 Version 4.1.3 Released ===================== ===================== Changes Since Version 4.1.2 =========================== diff --git a/Makefile.defs b/Makefile.defs index e7654871a..d5ff2bc20 100644 --- a/Makefile.defs +++ b/Makefile.defs @@ -164,7 +164,7 @@ INSTALL_FLAVOUR=$(FLAVOUR) # version number VERSION = 4 PATCHLEVEL = 1 -SUBLEVEL = 3 +SUBLEVEL = 4 EXTRAVERSION = # memory manager switcher diff --git a/autover.h b/autover.h index 2b5882b07..7eccd0743 100644 --- a/autover.h +++ b/autover.h @@ -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 "" diff --git a/cfg.y b/cfg.y index 195593bc4..04326e023 100644 --- a/cfg.y +++ b/cfg.y @@ -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); diff --git a/dns_cache.c b/dns_cache.c index 7465c8382..029b445b9 100644 --- a/dns_cache.c +++ b/dns_cache.c @@ -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; } diff --git a/forward.h b/forward.h index 4680a8e2b..f37754692 100644 --- a/forward.h +++ b/forward.h @@ -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); diff --git a/lib/srdb1/db.c b/lib/srdb1/db.c index 3eea70897..f717464cd 100644 --- a/lib/srdb1/db.c +++ b/lib/srdb1/db.c @@ -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; diff --git a/main.c b/main.c index 05d431e15..d8a3f89d4 100644 --- a/main.c +++ b/main.c @@ -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 diff --git a/mem/f_malloc.c b/mem/f_malloc.c index 7a0e115a2..73918cf3f 100644 --- a/mem/f_malloc.c +++ b/mem/f_malloc.c @@ -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{ diff --git a/mem/q_malloc.c b/mem/q_malloc.c index 8c36d03b1..ad0eaaacb 100644 --- a/mem/q_malloc.c +++ b/mem/q_malloc.c @@ -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{ diff --git a/modules/acc/acc_cdr.c b/modules/acc/acc_cdr.c index 68792e901..3cab76260 100644 --- a/modules/acc/acc_cdr.c +++ b/modules/acc/acc_cdr.c @@ -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; diff --git a/modules/acc/acc_logic.c b/modules/acc/acc_logic.c index 18437fc95..fa6cd8cd3 100644 --- a/modules/acc/acc_logic.c +++ b/modules/acc/acc_logic.c @@ -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; + } + } } diff --git a/modules/app_java/Makefile b/modules/app_java/Makefile index 68b8f8aa6..792a116e4 100644 --- a/modules/app_java/Makefile +++ b/modules/app_java/Makefile @@ -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 diff --git a/modules/app_java/doc/app_java.xml b/modules/app_java/doc/app_java.xml index 036039202..17800ccde 100644 --- a/modules/app_java/doc/app_java.xml +++ b/modules/app_java/doc/app_java.xml @@ -6,7 +6,6 @@ %docentities; - ]> @@ -15,8 +14,8 @@ &kamailioname; - Konstantin - Mosesov + Konstantin + Mosesov Konstantin @@ -25,11 +24,12 @@ 2013 - Konstantin Mosesov + 2014 + Konstantin Mosesov - + diff --git a/modules/app_java/doc/app_java_admin.xml b/modules/app_java/doc/app_java_admin.xml index f69f8ee6e..43f9fa1c0 100644 --- a/modules/app_java/doc/app_java_admin.xml +++ b/modules/app_java/doc/app_java_admin.xml @@ -88,8 +88,8 @@
Java runtime
- - <para>Java runtime library (JRE or JDK) is required to use this module.</para> + <title>JRE or JDK is required to use this module + Java runtime library (JRE and JDK for building app_java) is required to use this module.
@@ -166,7 +166,9 @@ modparam("app_java", "java_options", "-Djava.compiler=NONE") ... # 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") ... @@ -175,7 +177,9 @@ modparam("app_java", "java_options", "-Djava.compiler=NONE -Djava.class.path=/pa ... # 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") ... @@ -184,7 +188,9 @@ modparam("app_java", "java_options", "-verbose:gc,class,jni -Djava.compiler=NONE ... # 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") ... @@ -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, ';' . 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"); @@ -293,8 +301,8 @@ java_method_exec("ExampleMethod", "V"); # Java public int ExampleMethod() { - ... do something; - return 1; + ... do something; + return 1; } @@ -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; } @@ -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; } @@ -373,8 +382,8 @@ java_staticmethod_exec("ExampleMethod", "V"); # Java public static int ExampleMethod() { - ... do something; - return 1; + ... do something; + return 1; } @@ -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; } @@ -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; } @@ -454,8 +464,8 @@ java_s_method_exec("ExampleMethod", "V"); # Java public synchronized int ExampleMethod() { - ... do something; - return 1; + ... do something; + return 1; } @@ -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; } @@ -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; } @@ -535,8 +546,8 @@ java_s_staticmethod_exec("ExampleMethod", "V"); # Java public static synchronized int ExampleMethod() { - ... do something; - return 1; + ... do something; + return 1; } @@ -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; } @@ -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; } @@ -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; + } } diff --git a/modules/auth/auth_mod.c b/modules/auth/auth_mod.c index cdfe4590f..e0ed083ea 100644 --- a/modules/auth/auth_mod.c +++ b/modules/auth/auth_mod.c @@ -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); diff --git a/modules/auth_db/authorize.c b/modules/auth_db/authorize.c index cf97a8f1f..e2b0f4ffd 100644 --- a/modules/auth_db/authorize.c +++ b/modules/auth_db/authorize.c @@ -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) diff --git a/modules/auth_radius/sterman.c b/modules/auth_radius/sterman.c index be4dcf3ff..93cd416f2 100644 --- a/modules/auth_radius/sterman.c +++ b/modules/auth_radius/sterman.c @@ -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: diff --git a/modules/cnxcc/cnxcc_check.c b/modules/cnxcc/cnxcc_check.c index eb5889999..a5b7c93bd 100644 --- a/modules/cnxcc/cnxcc_check.c +++ b/modules/cnxcc/cnxcc_check.c @@ -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); diff --git a/modules/cnxcc/cnxcc_mod.c b/modules/cnxcc/cnxcc_mod.c index 808df1f57..22330ccc5 100644 --- a/modules/cnxcc/cnxcc_mod.c +++ b/modules/cnxcc/cnxcc_mod.c @@ -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); diff --git a/modules/cnxcc/cnxcc_select.c b/modules/cnxcc/cnxcc_select.c index 99b6d1f4d..46eb56880 100644 --- a/modules/cnxcc/cnxcc_select.c +++ b/modules/cnxcc/cnxcc_select.c @@ -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); diff --git a/modules/db_flatstore/km_flat_con.c b/modules/db_flatstore/km_flat_con.c index c4f38bb69..5a6ae403a 100644 --- a/modules/db_flatstore/km_flat_con.c +++ b/modules/db_flatstore/km_flat_con.c @@ -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; } diff --git a/modules/db_mysql/km_dbase.c b/modules/db_mysql/km_dbase.c index f644deaf6..688d4331f 100644 --- a/modules/db_mysql/km_dbase.c +++ b/modules/db_mysql/km_dbase.c @@ -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); } diff --git a/modules/db_mysql/km_res.c b/modules/db_mysql/km_res.c index 965e6dc40..3f1ca264e 100644 --- a/modules/db_mysql/km_res.c +++ b/modules/db_mysql/km_res.c @@ -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; } diff --git a/modules/dialog/dlg_handlers.c b/modules/dialog/dlg_handlers.c index 9393d7f13..21c43918c 100644 --- a/modules/dialog/dlg_handlers.c +++ b/modules/dialog/dlg_handlers.c @@ -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); } } diff --git a/modules/dialog/dlg_var.c b/modules/dialog/dlg_var.c index 111dcd8b1..4b2ca8948 100644 --- a/modules/dialog/dlg_var.c +++ b/modules/dialog/dlg_var.c @@ -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, ¶m->pvn.u.isname.name.s); + spv.s = NULL; + if(value) { + spv.len = pv_get_buffer_size(); + if(spv.lenlen+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); diff --git a/modules/drouting/drouting.c b/modules/drouting/drouting.c index 60006b17b..4322a7e92 100644 --- a/modules/drouting/drouting.c +++ b/modules/drouting/drouting.c @@ -754,7 +754,7 @@ again: } } - if (rt_info->route_idx>0 && rt_info->route_idxroute_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 */ diff --git a/modules/ipops/ipops_pv.c b/modules/ipops/ipops_pv.c index 08be1fe25..fcf0620cb 100644 --- a/modules/ipops/ipops_pv.c +++ b/modules/ipops/ipops_pv.c @@ -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; } diff --git a/modules/mtree/mtree_mod.c b/modules/mtree/mtree_mod.c index 4e32dfa90..96e6479f1 100644 --- a/modules/mtree/mtree_mod.c +++ b/modules/mtree/mtree_mod.c @@ -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); diff --git a/modules/pipelimit/pipelimit.c b/modules/pipelimit/pipelimit.c index 77d27969b..5aeb07113 100644 --- a/modules/pipelimit/pipelimit.c +++ b/modules/pipelimit/pipelimit.c @@ -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) { diff --git a/modules/presence_dialoginfo/notify_body.c b/modules/presence_dialoginfo/notify_body.c index 7f74b1fd5..92ece0a65 100644 --- a/modules/presence_dialoginfo/notify_body.c +++ b/modules/presence_dialoginfo/notify_body.c @@ -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 diff --git a/modules/pv/pv_core.c b/modules/pv/pv_core.c index 3f4883051..59a35393a 100644 --- a/modules/pv/pv_core.c +++ b/modules/pv/pv_core.c @@ -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; diff --git a/modules/pv/pv_trans.c b/modules/pv/pv_trans.c index 7c75deb75..b2561e206 100644 --- a/modules/pv/pv_trans.c +++ b/modules/pv/pv_trans.c @@ -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; } diff --git a/modules/rls/list.h b/modules/rls/list.h index c9904aa72..8c13b4dd0 100644 --- a/modules/rls/list.h +++ b/modules/rls/list.h @@ -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; diff --git a/modules/rls/notify.c b/modules/rls/notify.c index eb6a0e199..a8f3dd533 100644 --- a/modules/rls/notify.c +++ b/modules/rls/notify.c @@ -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; diff --git a/modules/rls/subscribe.c b/modules/rls/subscribe.c index d15a60178..7c4590807 100644 --- a/modules/rls/subscribe.c +++ b/modules/rls/subscribe.c @@ -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; } diff --git a/modules/rls/utils.h b/modules/rls/utils.h index 4b245e7ad..7918a9da1 100644 --- a/modules/rls/utils.h +++ b/modules/rls/utils.h @@ -21,7 +21,7 @@ * */ -#ifndef RLS_URILS_H +#ifndef RLS_UTILS_H #define RLS_UTILS_H #include "../../ut.h" diff --git a/modules/rtimer/rtimer_mod.c b/modules/rtimer/rtimer_mod.c index 03a002d8e..271b888ed 100644 --- a/modules/rtimer/rtimer_mod.c +++ b/modules/rtimer/rtimer_mod.c @@ -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 } } diff --git a/modules/siputils/checks.c b/modules/siputils/checks.c index a1a934487..7f50cfc9d 100644 --- a/modules/siputils/checks.c +++ b/modules/siputils/checks.c @@ -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; diff --git a/modules/siputils/sipops.c b/modules/siputils/sipops.c index 357d92c45..5394458a8 100644 --- a/modules/siputils/sipops.c +++ b/modules/siputils/sipops.c @@ -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) diff --git a/modules/topoh/th_msg.c b/modules/topoh/th_msg.c index 4d2575079..d572f004f 100644 --- a/modules/topoh/th_msg.c +++ b/modules/topoh/th_msg.c @@ -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); diff --git a/modules/websocket/ws_conn.c b/modules/websocket/ws_conn.c index 9f2b672b6..62a1b610e 100644 --- a/modules/websocket/ws_conn.c +++ b/modules/websocket/ws_conn.c @@ -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; diff --git a/modules/websocket/ws_conn.h b/modules/websocket/ws_conn.h index 0c7d639b1..27ba5ee70 100644 --- a/modules/websocket/ws_conn.h +++ b/modules/websocket/ws_conn.h @@ -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 */ diff --git a/modules/websocket/ws_frame.c b/modules/websocket/ws_frame.c index ba0713bec..7dc2669c0 100644 --- a/modules/websocket/ws_frame.c +++ b/modules/websocket/ws_frame.c @@ -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; } diff --git a/modules/websocket/ws_handshake.c b/modules/websocket/ws_handshake.c index 05332e47f..e89fda189 100644 --- a/modules/websocket/ws_handshake.c +++ b/modules/websocket/ws_handshake.c @@ -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 diff --git a/parser/sdp/sdp.c b/parser/sdp/sdp.c index fde60d330..1e5394083 100644 --- a/parser/sdp/sdp.c +++ b/parser/sdp/sdp.c @@ -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, diff --git a/parser/sdp/sdp_helpr_funcs.c b/parser/sdp/sdp_helpr_funcs.c index a9eb315ef..bc96e9980 100644 --- a/parser/sdp/sdp_helpr_funcs.c +++ b/parser/sdp/sdp_helpr_funcs.c @@ -204,6 +204,10 @@ other: +/** + * rfc4566: + * a=rtpmap: / [/] + */ 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; } diff --git a/pkg/kamailio/centos/6/kamailio.spec b/pkg/kamailio/centos/6/kamailio.spec index 9f0de0277..6f73f8d3e 100644 --- a/pkg/kamailio/centos/6/kamailio.spec +++ b/pkg/kamailio/centos/6/kamailio.spec @@ -1,5 +1,5 @@ %define name kamailio -%define ver 4.1.0 +%define ver 4.1.4 %define rel 0%{dist} diff --git a/pkg/kamailio/deb/debian/changelog b/pkg/kamailio/deb/debian/changelog index 7eacd5c9d..f470e3d3d 100644 --- a/pkg/kamailio/deb/debian/changelog +++ b/pkg/kamailio/deb/debian/changelog @@ -1,3 +1,9 @@ +kamailio (4.1.4) unstable; urgency=low + + * update to 4.1.4 from upstream + + -- Daniel-Constantin Mierla Thu, 12 Jun 2014 15:55:55 +0100 + kamailio (4.1.3) unstable; urgency=low * update to 4.1.3 from upstream diff --git a/pkg/kamailio/deb/jessie/changelog b/pkg/kamailio/deb/jessie/changelog index 7eacd5c9d..f470e3d3d 100644 --- a/pkg/kamailio/deb/jessie/changelog +++ b/pkg/kamailio/deb/jessie/changelog @@ -1,3 +1,9 @@ +kamailio (4.1.4) unstable; urgency=low + + * update to 4.1.4 from upstream + + -- Daniel-Constantin Mierla Thu, 12 Jun 2014 15:55:55 +0100 + kamailio (4.1.3) unstable; urgency=low * update to 4.1.3 from upstream diff --git a/pkg/kamailio/deb/precise/changelog b/pkg/kamailio/deb/precise/changelog index 7eacd5c9d..f470e3d3d 100644 --- a/pkg/kamailio/deb/precise/changelog +++ b/pkg/kamailio/deb/precise/changelog @@ -1,3 +1,9 @@ +kamailio (4.1.4) unstable; urgency=low + + * update to 4.1.4 from upstream + + -- Daniel-Constantin Mierla Thu, 12 Jun 2014 15:55:55 +0100 + kamailio (4.1.3) unstable; urgency=low * update to 4.1.3 from upstream diff --git a/pkg/kamailio/deb/squeeze/changelog b/pkg/kamailio/deb/squeeze/changelog index 7eacd5c9d..f470e3d3d 100644 --- a/pkg/kamailio/deb/squeeze/changelog +++ b/pkg/kamailio/deb/squeeze/changelog @@ -1,3 +1,9 @@ +kamailio (4.1.4) unstable; urgency=low + + * update to 4.1.4 from upstream + + -- Daniel-Constantin Mierla Thu, 12 Jun 2014 15:55:55 +0100 + kamailio (4.1.3) unstable; urgency=low * update to 4.1.3 from upstream diff --git a/pkg/kamailio/deb/wheezy/changelog b/pkg/kamailio/deb/wheezy/changelog index 7eacd5c9d..f470e3d3d 100644 --- a/pkg/kamailio/deb/wheezy/changelog +++ b/pkg/kamailio/deb/wheezy/changelog @@ -1,3 +1,9 @@ +kamailio (4.1.4) unstable; urgency=low + + * update to 4.1.4 from upstream + + -- Daniel-Constantin Mierla Thu, 12 Jun 2014 15:55:55 +0100 + kamailio (4.1.3) unstable; urgency=low * update to 4.1.3 from upstream diff --git a/pkg/kamailio/fedora/17/kamailio.spec b/pkg/kamailio/fedora/17/kamailio.spec index 2ceb8eacc..bed78d599 100644 --- a/pkg/kamailio/fedora/17/kamailio.spec +++ b/pkg/kamailio/fedora/17/kamailio.spec @@ -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} diff --git a/pkg/kamailio/rpm/kamailio.init b/pkg/kamailio/rpm/kamailio.init index 585ad77c3..cf7692971 100644 --- a/pkg/kamailio/rpm/kamailio.init +++ b/pkg/kamailio/rpm/kamailio.init @@ -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!" diff --git a/pkg/kamailio/rpm/kamailio.spec-4.1 b/pkg/kamailio/rpm/kamailio.spec-4.1 index b32568218..3f0d7e59b 100644 --- a/pkg/kamailio/rpm/kamailio.spec-4.1 +++ b/pkg/kamailio/rpm/kamailio.spec-4.1 @@ -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 diff --git a/pkg/kamailio/rpm/kamailio.spec.CenOS b/pkg/kamailio/rpm/kamailio.spec.CenOS index 87597120a..01661f86d 100644 --- a/pkg/kamailio/rpm/kamailio.spec.CenOS +++ b/pkg/kamailio/rpm/kamailio.spec.CenOS @@ -1,5 +1,5 @@ %define name kamailio -%define ver 4.1.3 +%define ver 4.1.4 %define rel 0 %define _sharedir %{_prefix}/share diff --git a/pkg/kamailio/rpm/kamailio.spec.SuSE b/pkg/kamailio/rpm/kamailio.spec.SuSE index ee4771626..9b2aa98de 100644 --- a/pkg/kamailio/rpm/kamailio.spec.SuSE +++ b/pkg/kamailio/rpm/kamailio.spec.SuSE @@ -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 diff --git a/route.c b/route.c index 1c5897c71..2a3e1b930 100644 --- a/route.c +++ b/route.c @@ -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); diff --git a/rpc_lookup.h b/rpc_lookup.h index 7988e044f..53d40b682 100644 --- a/rpc_lookup.h +++ b/rpc_lookup.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); diff --git a/rvalue.c b/rvalue.c index ddc97c28e..8e5ba2029 100644 --- a/rvalue.c +++ b/rvalue.c @@ -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; } diff --git a/tcp_main.c b/tcp_main.c index 701f90f3f..5a43d2cfc 100644 --- a/tcp_main.c +++ b/tcp_main.c @@ -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; rworkers; 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 */ diff --git a/utils/sercmd/sercmd.c b/utils/sercmd/sercmd.c index 00f10e776..fb9c0a341 100644 --- a/utils/sercmd/sercmd.c +++ b/utils/sercmd/sercmd.c @@ -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