Imported Upstream version 4.3.4

changes/10/3710/1 upstream/4.3.4
Victor Seva 10 years ago
parent 453a2eb8e3
commit 51ce354295

@ -1,12 +1,13 @@
sudo: required
language: c
compiler:
- gcc
- clang
services:
- docker
before_install:
- sudo apt-get update -qq
- sudo apt-get install -y gdebi-core
- sudo test/travis/build_deps.sh precise $TRAVIS_BUILD_DIR
script: ./test/travis/build_travis.sh
- docker pull linuxmaniac/pkg-kamailio-docker:jessie
script: docker run -v $TRAVIS_BUILD_DIR:/code:rw linuxmaniac/pkg-kamailio-docker:jessie /bin/bash -c "export CC=$CC; cd /code; ./test/travis/build_travis.sh"
branches:
only:
- 'master'

@ -1,3 +1,629 @@
===================== 2015-11-25 Version 4.3.4 Released =====================
===================== Changes Since Version 4.3.4 ===========================
commit 6c2b677e38e0599e27dc7690516870d0797b096e
Author: Daniel-Constantin Mierla <miconda@gmail.com>
Date: Wed Nov 25 14:27:26 2015 +0100
Makefile.defs: version set to 4.3.4
commit 216200598ac47643b05d27add0a2c5645a2b3597
Author: Daniel-Constantin Mierla <miconda@gmail.com>
Date: Wed Nov 25 14:23:26 2015 +0100
pkg/rpm: updated spec files for v4.3.4
commit 138a552ce71c795f39ad6e35d815d182dc26e747
Author: Daniel-Constantin Mierla <miconda@gmail.com>
Date: Wed Nov 25 14:10:32 2015 +0100
cnxcc: more safety checks for call structure
(cherry picked from commit 6985a2953b0577ad8dff449c2e849f6ff15da01c)
commit 18251e590f22a37a0392e981987e3a46a3122cbe
Author: lazedo <luis.azedo@factorlusitano.com>
Date: Wed Nov 25 12:54:28 2015 +0000
kazoo : check amqp version
manual backport from master
commit 451a510d863ec7cb7a8cde0b31ca4fe8983d324c
Author: Victor Seva <linuxmaniac@torreviejawireless.org>
Date: Wed Nov 25 13:53:33 2015 +0100
pkg/kamailio/deb: update version to 4.3.4
commit 1c6fcd1bc43165cd9a8732489cb2fbe83e2aa1ac
Author: Daniel-Constantin Mierla <miconda@gmail.com>
Date: Wed Nov 25 13:19:13 2015 +0100
cnxcc: safety check before freeing call structure
- reported by GH#417
(cherry picked from commit ce5591e8f7568f98b39d9b96a2c8debe81837a07)
commit 51bf77b20de2ddca20e3376d3671beb362475550
Author: Daniel-Constantin Mierla <miconda@gmail.com>
Date: Wed Nov 25 13:11:22 2015 +0100
kazoo: check amqp version
- checks amqp version for amqp_exchange_declare
- manual backport from 29aaeb5
commit 8d8a43064f6ba7419473b139997f44bd4ef698a5
Author: Daniel-Constantin Mierla <miconda@gmail.com>
Date: Mon Nov 23 18:17:48 2015 +0100
db_mysql: explicitely set the reconenct flag via mysql cloent api
- old mode setting connection fied directly still in place, but now
should be safer if that changes
(cherry picked from commit e89c77f641311415b13b00dc9d469c0424362d53)
commit b2361d71de4208227468244754c0fc8229e7bcab
Author: Daniel-Constantin Mierla <miconda@gmail.com>
Date: Mon Nov 23 18:00:58 2015 +0100
db_mysql: extended the list of error code when to try to resend query
(cherry picked from commit 6a62cc666352fbca7f1cc5a239464b42a7afc2cb)
commit 71ff3942698e33e8f2e79c5a5ac2a35a27b060b8
Author: Daniel-Constantin Mierla <miconda@gmail.com>
Date: Mon Nov 23 17:11:51 2015 +0100
db_mysql: print error number when failing to do mysql query
(cherry picked from commit a1556c0708af959a3816e732a7bd692c5fa5f4dc)
commit 863739dec78161fdce871c281601a011572515a2
Author: Daniel-Constantin Mierla <miconda@gmail.com>
Date: Mon Nov 23 16:43:43 2015 +0100
dialog: safety bump of cseq for bye if prack was involved in call setup
- reported by GH#409
(cherry picked from commit aab6547f39d723de6a01680cbd79b9365be8092f)
commit 8962cb713c397da2960e6c3db3b58cd2e6769d43
Author: Daniel-Constantin Mierla <miconda@gmail.com>
Date: Tue Nov 17 09:14:07 2015 +0100
lib/srdb1: url parser extracts the db name before the url parameters
- some database urls can have parameters after db name, like:
driver://username:password@dbhost:port/dbname?params
- reported by Kelvin Chua for db_mongodb
(cherry picked from commit 4da5d898da9a0a8f2780dcdf864354098268a7e9)
commit 5fcac5c54fd487014efe1645f4db0e31dd6564e7
Author: Camille Oudot <camille.oudot@orange.com>
Date: Wed Nov 25 11:44:55 2015 +0100
usrloc: fix mem leak when closing expired TCP
CONN_EOF handler already decreases the reference counter for us
(cherry picked from commit daa2509a58438505a6faa57e1a8befcc667a3b28)
commit 7c46ff13e70e2d67e8bf5b8e6b90b2cf28b3b5fb
Merge: d96a409 6c11766
Author: Victor Seva <linuxmaniac@torreviejawireless.org>
Date: Tue Nov 24 16:02:57 2015 +0100
Merge pull request #414 from linuxmaniac/vseva/travis_docker_4.3
tests/travis: migrate to docker environment
commit 6c11766a2d370d90559b1f01cc8ca3dd610669c9
Author: Victor Seva <linuxmaniac@torreviejawireless.org>
Date: Tue Nov 24 15:23:44 2015 +0100
tests/travis: migrate to docker environment
- use jessie as default distribution
commit d96a409649573c8d5e08a9b04536613307ecc779
Author: Victor Seva <linuxmaniac@torreviejawireless.org>
Date: Mon Nov 23 23:08:38 2015 +0100
test/travis: build_travis.sh force error on any command
commit f07d47d7d413a1dbc4da779d7c274f88e01058e6
Author: Daniel-Constantin Mierla <miconda@gmail.com>
Date: Sun Nov 22 10:02:36 2015 +0100
core: relocate dbg message before killing children at shut down
- can race with per module log level, debugger module can be destroyed
(cherry picked from commit 5a142f7cc2899090b007654529f08b1b2f4e70b1)
commit 2823f0b09ff9d91ff52475abdf58bb030dee3773
Author: Daniel-Constantin Mierla <miconda@gmail.com>
Date: Thu Nov 19 13:58:33 2015 +0100
tm: use svpe fixup for t replicate uri param
- the function expects it for getting the value
(cherry picked from commit ea0b4e50f62f8a461b737882c383f17767851d3d)
commit 20b4c9e6294bca137d788dd0c1750f320d3e8461
Author: Daniel Rus Morales <danirus@eml.cc>
Date: Thu Nov 19 13:44:08 2015 +0100
db_postgress: fix compilation, NTOHLL and NTOHLL provided by OSX 10.10
(cherry picked from commit b37aa66fd1cf3fe99aae50adb89d4cfecf6d90d1)
commit d0c5a5835969660d43355fa91b39f1a8e08f6eb0
Author: Daniel-Constantin Mierla <miconda@gmail.com>
Date: Thu Nov 19 00:01:27 2015 +0100
kamctl: require db or ctl engine made specific for dispatcher subcommands
(cherry picked from commit d2416957e4caec8a64abec82029ea18c52a7bc2d)
commit dd4d1700a36c6d64590ad00ae8c60270d16c62c3
Author: Daniel-Constantin Mierla <miconda@gmail.com>
Date: Wed Nov 18 14:42:51 2015 +0100
usrloc: log details of contact when inserting in db failes
(cherry picked from commit 1a05910912fbf9baaf821cc30fac7485c1e67622)
commit 3969a72ebf47d9468ecfdf8c1ea3a4216b098ebf
Author: Daniel-Constantin Mierla <miconda@gmail.com>
Date: Tue Nov 17 22:51:01 2015 +0100
dmq: removed params field from dmq_node_t
- used only for setting a flag
- duplicating a node caused issues with param field not being
duplicated, resulting in potential many free of same pointer, reported
by Sebastian Damm
(cherry picked from commit 16bc7b726a21108458f354aea840cdbf5d89d6d8)
commit 851a3bb7788b0a154e8fdb9fa4f150fa0777e8b5
Author: Stefan Mititelu <stefan.mititelu@1and1.ro>
Date: Mon Nov 23 12:35:03 2015 +0200
p_usrloc: str->s string NULL check before str_dup
Don't shm_str_dup() NULL str->s strings.
Add checks to avoid shm_str_dup() warning.
commit 2fe732bd12fd45d2845626589b255a9d78acd7d1
Author: Federico Cabiddu <federico.cabiddu@gmail.com>
Date: Fri Nov 20 11:13:40 2015 +0100
tm: set next hop as dst_uri for appended branches
(cherry picked from commit 4d122e15f4599010000f6e5d2e60e9bc13b2281a)
commit 2d1b6dcf6b00291e6d81b1a847718b21f80c3d16
Author: Stefan Mititelu <stefan.mititelu@1and1.ro>
Date: Wed Nov 18 12:21:19 2015 +0200
core: NULL checks for ut.h
Add some NULL checks for shm/pkg dup functions and few others.
(cherry-picked from commit 24999a5dbf7d986942479c0670158748c263a3cd)
commit 62243d315df63909b079f731f25de23a638bcdf6
Author: Daniel-Constantin Mierla <miconda@gmail.com>
Date: Thu Nov 19 13:30:07 2015 +0100
rtpproxy: fix mismatching internal value for column setid
- on a report by Jan Hazenberg
(cherry picked from commit b89534385ef881719c85534ab7a32a500be2aa9c)
commit c064b97f79e4a4c757166704b67b98d36340d7cc
Author: Camille Oudot <camille.oudot@orange.com>
Date: Thu Nov 19 11:16:11 2015 +0100
core: exit with failure code if a child dies
(cherry picked from commit dd7854ea6f7efa6899bf59bb0d5069f0daf1def9)
commit 040a36678f104905a0066c8b6a352da59c539fee
Author: Federico Cabiddu <federico.cabiddu@gmail.com>
Date: Wed Nov 11 13:08:52 2015 +0100
cnxcc: make cnxcc locks re-entrant
(cherry picked from commit a4cdd61afad027c9bb431ceda4e71941274610ce)
commit 2665a0e7d2a2b3a02cfeb2809ec9dd0d3bafcb25
Author: Daniel-Constantin Mierla <miconda@gmail.com>
Date: Mon Nov 16 11:43:53 2015 +0100
core: print runtime dir in log message
- do logging to syslog, along with stderror for runtime dir related
errors
(cherry picked from commit 5e9f144ca214f43b2fd01917fb4983716c8916f8)
commit d260080724b8f9ec0a3c55b3cee3ce34205b814c
Author: Daniel-Constantin Mierla <miconda@gmail.com>
Date: Tue Nov 10 09:30:30 2015 +0100
core: dns cache - test for null pointers before debug checks after removing from list
- next/prev are set to null after remove from list by commit
0fbcca38574139f1cd8ba7506ee5e204be5f2da7
(cherry picked from commit 70699ae8b9159c18bdd73c3092ccb19691edf0fd)
commit 9dfa62688c71062598f66adde3ba5b34bc58ebf9
Author: Daniel-Constantin Mierla <miconda@gmail.com>
Date: Mon Nov 9 21:05:30 2015 +0100
nathelper: added examples in docs for few functions
(cherry picked from commit 2aa7683dfebedc4ef9c3fdd50fb7abd2a2d718db)
commit 8a16b37554cb668b9fcb9d0aba11157506f33672
Author: Daniel-Constantin Mierla <miconda@gmail.com>
Date: Thu Nov 5 08:58:44 2015 +0100
tm: print file name and line in free_cell() warning log message
(cherry picked from commit bbf3f2a970020116da8c4c50069713e31a268943)
commit 0066abcf28d707be7444ccb709cbeb9f37c636be
Author: Daniel-Constantin Mierla <miconda@gmail.com>
Date: Thu Nov 5 08:53:01 2015 +0100
tm: unlink cell and its timer in free function if structure still linked in clist
(cherry picked from commit 2fad76064992af047244e30c6152bf0f05a0785f)
commit ff64906a7cf9d6704dc82ab52a49ef0ed48d8fde
Author: Daniel-Constantin Mierla <miconda@gmail.com>
Date: Wed Sep 23 22:53:01 2015 +0200
tm: reset next/prev fields when unlinking transaction from hash table
(cherry picked from commit 649141185f231435bbe03fd13fe5a0e65b9fed04)
commit b69ecda51c820fbf4a4bc4de352a7b2f5e2d8d91
Author: Daniel-Constantin Mierla <miconda@gmail.com>
Date: Wed Sep 23 17:46:50 2015 +0200
tm: warn troubleshooting message for deleted transaction turned in dbg
(cherry picked from commit 92ff485409611ad345b14b784afb1be25fa188b9)
commit 171df16dea1d2c6215b6aa50a49157cf253f502f
Author: Daniel-Constantin Mierla <miconda@gmail.com>
Date: Wed Sep 23 12:43:41 2015 +0200
tm: more debug info when freeing a transaction
- attempt to catch a double free
(cherry picked from commit ef44e5b8b4292f4c4ff3a77e46bbb33e5e0f077f)
commit ad6916e60745da509cc74b8a4b576d8530b73361
Author: Daniel-Constantin Mierla <miconda@gmail.com>
Date: Thu Nov 5 08:51:25 2015 +0100
core: clist - restet prev/next when removing from clist slot
(cherry picked from commit 0fbcca38574139f1cd8ba7506ee5e204be5f2da7)
commit 213abc43fa2b3ff8fc8ab4db1859cb79298e201a
Author: Tristan Mahé <gled@remote-shell.net>
Date: Wed Nov 4 10:33:03 2015 -0800
set the log_prefix buffer size to 1024b
(cherry picked from commit 439623667d6ea5cf9dec30033df94965213e8494)
commit 22e4556c91377ecdab849fe181b6a8397bfada7c
Author: Daniel-Constantin Mierla <miconda@gmail.com>
Date: Wed Nov 11 08:59:10 2015 +0100
Makefile.defs: gcc 5.2 option -mfp32 is required by -march=r3000 for mips arch
- reported by Victor Seva, GH#394
(cherry picked from commit b2ff2745b97051625509de0f328e5b1a8f584387)
commit b5d19f21718b94fb522db5b414d43e7fdb038ebf
Author: Daniel-Constantin Mierla <miconda@gmail.com>
Date: Mon Nov 9 09:36:12 2015 +0100
Makefile.defs: removed option -minline-all-stringops for compiler on mips
- not supported, reported by Victor Seva, FS#392
(cherry picked from commit 2718efddb8e87a269af012d8661d57887e7c4d86)
commit 946e996fed4bed9a62703cdd248777e2c7ab4a89
Author: Daniel-Constantin Mierla <miconda@gmail.com>
Date: Mon Nov 9 09:21:29 2015 +0100
tls: check for support of SSLv3 method
- some versions of libssl removed support for SSLv3
- reported by Victore Seva, FS#391
(cherry picked from commit b1c6c2af7e96c0bcbdee4ff46f6faf19fdc75d9f)
commit 16be09c270e5dafd5721129c68dde7e2ababed38
Author: Daniel-Constantin Mierla <miconda@gmail.com>
Date: Wed Nov 4 10:08:02 2015 +0100
core: print src and dst addresses in tcp error log messages
(cherry picked from commit 420a11873291cca93c8b43b5766f8661d46538c5)
commit 8d82eb9a43885a1c524c5a53155f3299ce55fbb7
Author: Daniel-Constantin Mierla <miconda@gmail.com>
Date: Wed Nov 4 15:43:12 2015 +0100
nathelper: consider IPv6 brackets when checking size for keepalive request
(cherry picked from commit 27f19950f107a943c3bf9db1fddb1e4912136181)
commit 3edb10ad073c383dab8a2819d759fcc9e3bd9986
Author: Daniel-Constantin Mierla <miconda@gmail.com>
Date: Mon Nov 2 16:19:44 2015 +0100
core: parser - remove inline for parse_param()
- it gets recent compiler warnings when is an extern object
- reported by Victor Seva, GH#286
(cherry picked from commit e3a8e5772445d28a0fc6db2e432d750dbb8062da)
commit 5c9ef6ca51d51232a0e3ab4e57915a7674e876a1
Author: Daniel-Constantin Mierla <miconda@gmail.com>
Date: Mon Nov 2 15:23:31 2015 +0100
kamdbctl: divert stderr when searching for greadlink
(cherry picked from commit 2bd19e232ece9bf0a090ba34d505d9ed6c9753a5)
commit bc00c004f5c8214f814369e01f8ec78ca780cbb5
Author: Daniel-Constantin Mierla <miconda@gmail.com>
Date: Mon Nov 2 13:30:32 2015 +0100
ctl: increased default buffers size for rpc responses
- binrpc_max_body_size = 32
- binrpc_struct_max_body_size = 8
(cherry picked from commit 19756eecb2048320182667cc440cfa7d275304c9)
commit cc236c6720c3c4d91d6cf69134bb6c290d530900
Author: Daniel-Constantin Mierla <miconda@gmail.com>
Date: Tue Oct 27 11:26:23 2015 +0100
tm: added braces around initializer of cancel reason map
- reported by Yacin Caner
(cherry picked from commit fc0e6275fa61f72c1fed0f69393f609cc682888c)
commit e1b60b857f78ec459ae31a4cf6475643ec102f40
Author: Daniel-Constantin Mierla <miconda@gmail.com>
Date: Mon Oct 26 21:31:59 2015 +0100
core: fixed passed buffer size in suip2a() for ipv6
- buffer size set to IP6_MAX_STR_SIZE, it was too short and returned
value was empty addres "[]"
- the function is used only by siptrace
- patch from github pull request #381
(cherry picked from commit d6f313e61b3318924e6653c8ca1184b2016f701d)
commit 5d8315268e19538023d4127e74e166925ea216b8
Author: Daniel-Constantin Mierla <miconda@gmail.com>
Date: Fri Oct 23 18:56:45 2015 +0200
db_postgres: safety check to see if hasing is over non-null pointer
- inside implementation of replace command
(cherry picked from commit 9cd4aef84d8e7a079486ff73285a9bd6a15e8db3)
commit 4dc766a2083391b1870d34f8ee9575088b9e8e69
Author: Daniel-Constantin Mierla <miconda@gmail.com>
Date: Thu Oct 22 23:08:44 2015 +0200
db_postgres: don't free pg query structure in store result function
- it is done when freeing the result
(cherry picked from commit 56cd7a0d38c8bbee6cc3e981b7a2b78b6d47257d)
commit 4fdd11699c83f2e4c787d210ca08eb3ec2fb559a
Author: Daniel-Constantin Mierla <miconda@gmail.com>
Date: Wed Oct 21 09:49:38 2015 +0200
corex: detect ipv6 for send*() functions
(cherry picked from commit 027495fb6ac7c8f50ff9945c209bc9f7ac98d991)
commit 3dc9dd21708d3abe9db888dd0ae2ab49270a82d8
Author: Olle E. Johansson <oej@edvina.net>
Date: Tue Oct 20 20:52:10 2015 +0200
evapi fix some minor typos in debug/error messages
(cherry picked from commit 84d75d43c17b4773bb15a80c1a1f33a47424d858)
commit 67885bd0e5fd56b5dd7d4bb6f8bb7113bc1ea559
Author: Olle E. Johansson <oej@edvina.net>
Date: Mon Oct 19 09:11:20 2015 +0200
nat_traversal Add comment about lacking IPv6 support
(cherry picked from commit cc8ff059d362e0c805de2067d73f64cbd12acdb8)
commit bf236d1892abdc3e27dc01d84eca67cd1b858156
Author: Daniel-Constantin Mierla <miconda@gmail.com>
Date: Sun Oct 11 19:37:54 2015 +0200
core: mem_summary taken in consideration for runtime pkg dump callback
(cherry picked from commit 02dc876cc6d8e78bfc26c4c2318814aec22c4498)
commit ca09891f79facdc7f557ecacb31e7346e545e4a4
Author: Olle E. Johansson <oej@edvina.net>
Date: Sun Oct 11 19:26:46 2015 +0200
auth Minor update to docs, spelling errors
(cherry picked from commit a0f82365012a7980c77b076d2e48f8a38cb63742)
commit eef390eaefd9286feaae1505d566e4e41fb61e30
Author: lazedo <luis.azedo@factorlusitano.com>
Date: Wed Oct 7 11:39:37 2015 -0700
presence: use advertised ip for local contact
(cherry picked from commit 6a498f713a2522e18bed96dc4d1f361008a95502)
commit 6d3db65279e1e6bd7d45fe6ff4169e556883e21d
Author: Daniel-Constantin Mierla <miconda@gmail.com>
Date: Tue Oct 6 17:53:15 2015 +0200
tm: support to add text in Reason header for local generated CANCEL
(cherry picked from commit 743fee551c833bd31f1bfdf1a4b422886243f8b6)
commit c5a53e0f12430653f890534a1c140b84545f1ac0
Author: Daniel-Constantin Mierla <miconda@gmail.com>
Date: Sun Oct 4 06:28:39 2015 +0200
nathelper: use advertised address if send socket has one
- reported by emanuel Buu, GH#352
(cherry picked from commit 4da31d56f4b1e18fc4232c5174637c858c75e9db)
commit a56e5980e572357f9d3c0152623850c34ddb8963
Author: Stefan Mititelu <stefan.mititelu@1and1.ro>
Date: Tue Nov 3 13:08:47 2015 +0200
uac: Sanity checks
Sanity checks for decode_uri(). Add NULL and len > 0 checks.
Segfault when vsf parameter was empty in the Route: header (e.g 'vsf=').
(cherry picked from commit d956f397c8cea4774e5941bdad8f76ecc44acdd5)
commit 83938d2153d0d33f1e3248a9ae280dae38440855
Author: Stefan Mititelu <stefan.mititelu@1and1.ro>
Date: Tue Nov 3 15:58:02 2015 +0200
dialog: Sanity checks
Add NULL checks for the parse_dlg_rr_param().
Segfault when 'did' parameter was empty in the Route header (e.g. 'did=').
(cherry picked from commit 876787d977c46ffcb1288f5eb66e91145cba1061)
commit 801d9cc900a7cdd954733012540299c7ca288007
Author: Daniel-Constantin Mierla <miconda@gmail.com>
Date: Tue Oct 27 11:44:06 2015 +0100
dmq_usrloc: fixed handling of dmq_ul.get_urecord_by_ruid() response
- manual backport of master branch commits: 13cde2b and eeb3c16 (GH#373)
commit 60985a13878b9ec3b84b565c02be14927ba6357a
Author: Daniel-Constantin Mierla <miconda@gmail.com>
Date: Fri Oct 23 14:15:54 2015 +0200
usrloc: fixed number of columns when loading urecord in db mode 3
- reported by GH#373
(cherry picked from commit 922e5818b02b6d5e1f082e861f97bc8868f5ae57)
commit f699719fed8b1fffc653c272c01941730dab6d3e
Author: Daniel-Constantin Mierla <miconda@gmail.com>
Date: Tue Oct 20 19:44:47 2015 +0200
tls: init tls hooks to {0}, avoiding fields enumeration
- if a new field is added, then should be no longer needed to update
initialization
(cherry picked from commit 92c7656a37549de0eed3621ec243022400f6c6c4)
commit 6306a8fe46fc7ebf2c8b8b52177d38f9178ba659
Author: Daniel-Constantin Mierla <miconda@gmail.com>
Date: Sun Oct 11 14:35:46 2015 +0200
uac: uac.reg_dump returns an array rpc result
(cherry picked from commit b4120c53a1ba2ae2bad8b9c04963b4becc0a9700)
commit e827ccf957a341b7026b06f17686da7fcc426fc2
Author: Daniel-Constantin Mierla <miconda@gmail.com>
Date: Sun Oct 11 03:38:24 2015 +0200
textops: fix leak when subst_hf() with flag f is used
- substituion list was not freed
(cherry picked from commit 321a6140cdc7d6fd3f18f911af9825bb62575ace)
commit 0aaa2dd0afab46cb35e88d4091a9118066682059
Author: Federico Cabiddu <federico.cabiddu@gmail.com>
Date: Wed Oct 7 09:29:39 2015 +0200
tsilo: unref the transaction after appending new branches
(cherry picked from commit 3c086a85b99d59dabc48f77893d4c68199af0577)
commit 42f3e1f081d2606a500f93e5e1fd8c97690956de
Author: Federico Cabiddu <federico.cabiddu@gmail.com>
Date: Mon Sep 28 09:09:59 2015 +0200
tm: fake msg and environment to append new branches
(cherry picked from commit 6845d190f46de820fa4586b30eb2fba0aae1eb01)
commit 74042e3c00edd441e30d7aba25807f99617be375
Author: Olle E. Johansson <oej@edvina.net>
Date: Wed Oct 7 13:44:03 2015 +0200
nathelper Via header for SIP ping over IPv6 needs square brackets
(cherry picked from commit 274f1034bfb9ea0d52ef291d2f95021ca86f3081)
commit b7678a7c920f82ab23e495e76db99d7b2457395e
Author: Daniel-Constantin Mierla <miconda@gmail.com>
Date: Tue Oct 6 00:28:19 2015 +0200
acc: reset errno for converting numbers for cdr generation
- reported by Mayama Takeshi, GH#359
(cherry picked from commit caf477104c90049bf0c5e163d7eff89111448776)
===================== 2015-10-02 Version 4.3.3 Released =====================
===================== Changes Since Version 4.3.2 ===========================

@ -96,7 +96,7 @@ INSTALL_FLAVOUR=$(FLAVOUR)
# version number
VERSION = 4
PATCHLEVEL = 3
SUBLEVEL = 3
SUBLEVEL = 4
# memory manager switcher
# 0 - f_malloc (fast malloc)
@ -1271,13 +1271,15 @@ ifeq ($(CC_NAME), gcc)
CFLAGS=$(CC_OPT) -funroll-loops $(PROFILE)
#if gcc 5.0+, 4.5+ or 4.2+
ifeq (,$(strip $(filter-out 4.2+ 4.5+ 5.0+,$(CC_SHORTVER))))
CFLAGS+=-march=r3000 -minline-all-stringops \
CFLAGS+=-mfp32 -march=r3000 \
-ftree-vectorize -fno-strict-overflow
# not supported on mips: -minline-all-stringops
else
#if gcc 4.0+
ifeq ($(CC_SHORTVER), 4.x)
CFLAGS+=-march=r3000 -minline-all-stringops \
CFLAGS+=-march=r3000 \
-ftree-vectorize
# not supported on mips: -minline-all-stringops
else
#if gcc 3.4+
ifeq ($(CC_SHORTVER), 3.4)

@ -2,6 +2,6 @@
* DO NOT EDIT IT
*/
#define REPO_VER "e275bc"
#define REPO_HASH "e275bc"
#define REPO_VER "0ec860"
#define REPO_HASH "0ec860"
#define REPO_STATE ""

@ -87,7 +87,9 @@
#define clist_rm_sublist(s, e, next, prev) \
do{\
(s)->prev->next=(e)->next; \
(e)->next->prev=(s)->prev ; \
(e)->next->prev=(s)->prev; \
(s)->prev=NULL; \
(e)->next=NULL; \
}while(0)

@ -459,15 +459,15 @@ int init_dns_cache_stats(int iproc_num)
#define debug_lu_lst( txt, l) \
do{ \
if (check_lu_lst((l))){ \
if ((l) && check_lu_lst((l))){ \
dbg_lu_lst(txt " crt:", (l)); \
abort(); \
} \
if (check_lu_lst((l)->next)){ \
if (((l)->next) && check_lu_lst((l)->next)){ \
dbg_lu_lst(txt " next:", (l)); \
abort(); \
} \
if (check_lu_lst((l)->prev)){ \
if (((l)->prev) && check_lu_lst((l)->prev)){ \
dbg_lu_lst(txt " prev:", (l)); \
abort(); \
} \

@ -366,7 +366,7 @@ void dprint_color_update(int level, char f, char b)
str *log_prefix_val = NULL;
static pv_elem_t *log_prefix_pvs = NULL;
#define LOG_PREFIX_SIZE 128
#define LOG_PREFIX_SIZE 1024
static char log_prefix_buf[LOG_PREFIX_SIZE];
static str log_prefix_str;

@ -741,14 +741,14 @@ static inline char* suip2a(union sockaddr_union* su, int su_len)
return "<addr. error>";
buf[0]='[';
offs=1+ip6tosbuf((unsigned char*)su->sin6.sin6_addr.s6_addr, &buf[1],
sizeof(buf)-4);
IP6_MAX_STR_SIZE);
buf[offs]=']';
offs++;
}else
if (unlikely(su_len<sizeof(su->sin)))
return "<addr. error>";
else
offs=ip4tosbuf((unsigned char*)&su->sin.sin_addr, buf, sizeof(buf)-2);
offs=ip4tosbuf((unsigned char*)&su->sin.sin_addr, buf, IP4_MAX_STR_SIZE);
buf[offs]=0;
return buf;
}

@ -55,6 +55,30 @@ static int dupl_string(char** dst, const char* begin, const char* end)
return 0;
}
/**
* Duplicate a string name (until a params separator found)
* \param dst destination
* \param begin start of the string
* \param end end of the string
*/
static int dupl_string_name(char** dst, const char* begin, const char* end)
{
char *p;
if (*dst) pkg_free(*dst);
for(p=(char*)begin; p<end; p++) {
if(*p=='?') break;
}
*dst = pkg_malloc(p - begin + 1);
if ((*dst) == NULL) {
return -1;
}
memcpy(*dst, begin, p - begin);
(*dst)[p - begin] = '\0';
return 0;
}
/**
* Parse a database URL of form
@ -151,7 +175,7 @@ static int parse_db_url(struct db_id* id, const str* url)
case '/':
if (dupl_string(&id->host, begin, url->s + i) < 0) goto err;
if (dupl_string(&id->database, url->s + i + 1, url->s + len) < 0) goto err;
if (dupl_string_name(&id->database, url->s + i + 1, url->s + len) < 0) goto err;
return 0;
}
break;
@ -178,7 +202,7 @@ static int parse_db_url(struct db_id* id, const str* url)
id->host = prev_token;
prev_token = 0;
id->port = str2s(begin, url->s + i - begin, 0);
if (dupl_string(&id->database, url->s + i + 1, url->s + len) < 0) goto err;
if (dupl_string_name(&id->database, url->s + i + 1, url->s + len) < 0) goto err;
return 0;
}
break;
@ -193,7 +217,7 @@ static int parse_db_url(struct db_id* id, const str* url)
case '/':
if (dupl_string(&id->host, begin, url->s + i) < 0) goto err;
if (dupl_string(&id->database, url->s + i + 1, url->s + len) < 0) goto err;
if (dupl_string_name(&id->database, url->s + i + 1, url->s + len) < 0) goto err;
return 0;
}
break;
@ -202,7 +226,7 @@ static int parse_db_url(struct db_id* id, const str* url)
switch(url->s[i]) {
case '/':
id->port = str2s(begin, url->s + i - begin, 0);
if (dupl_string(&id->database, url->s + i + 1, url->s + len) < 0) goto err;
if (dupl_string_name(&id->database, url->s + i + 1, url->s + len) < 0) goto err;
return 0;
}
break;

@ -742,10 +742,14 @@ void handle_sigs(void)
}
LM_INFO("terminating due to SIGCHLD\n");
#endif
LM_DBG("terminating due to SIGCHLD\n");
/* exit */
shutdown_children(SIGTERM, 1);
LM_DBG("terminating due to SIGCHLD\n");
exit(0);
if (WIFSIGNALED(chld_status)) {
exit(1);
} else {
exit(0);
}
break;
case SIGHUP: /* ignoring it*/
@ -2316,12 +2320,14 @@ try_again:
/* create runtime dir if doesn't exist */
if (stat(runtime_dir, &st) == -1) {
if(mkdir(runtime_dir, 0700) == -1) {
fprintf(stderr, "failed to create runtime dir\n");
LM_ERR("failed to create runtime dir %s\n", runtime_dir);
fprintf(stderr, "failed to create runtime dir %s\n", runtime_dir);
goto error;
}
if(sock_uid!=-1 || sock_gid!=-1) {
if(chown(runtime_dir, sock_uid, sock_gid) == -1) {
fprintf(stderr, "failed to change owner of runtime dir\n");
LM_ERR("failed to change owner of runtime dir %s\n", runtime_dir);
fprintf(stderr, "failed to change owner of runtime dir %s\n", runtime_dir);
goto error;
}
}

@ -163,6 +163,8 @@ static int db_write_cdr( struct dlg_cell* dialog,
for(i=0; i<m; i++) {
db_cdr_keys[i] = &cdr_attrs[i];
/* reset errno, some strtoX don't reset it */
errno = 0;
switch(cdr_type_array[i]) {
case TYPE_NULL:
VAL_NULL(db_cdr_vals+i)=1;

@ -171,17 +171,17 @@ Chapter 1. Admin Guide
These three module parameters control which optional integrity checks
will be performed on the SIP message carrying digest response during
digest authentication. auth_check_register controls integrity checks to
be performed on REGISTER messages, auth_checks_no_dlg controls which
optional integrity checks will be performed on SIP requests that have
no To header field or no To tag (in other words the requests either
establishing or outside dialogs). auth_checks_in_dlg controls which
integrity checks will be performed on SIP requests within dialogs, such
as BYE or re-INVITE. The default value for all three parameters is 0
(old behaviour, no extra checks). The set of integrity checks that can
be performed on REGISTERs is typically different from sets of integrity
checks that can be performed for other SIP request types, hence we have
three independent module parameters.
SIP MD5 digest authentication. auth_check_register controls integrity
checks to be performed on REGISTER messages, auth_checks_no_dlg
controls which optional integrity checks will be performed on SIP
requests that have no To header field or no To tag (in other words the
requests either establishing or outside dialogs). auth_checks_in_dlg
controls which integrity checks will be performed on SIP requests
within dialogs, such as BYE or re-INVITE. The default value for all
three parameters is 0 (old behaviour, no extra checks). The set of
integrity checks that can be performed on REGISTERs is typically
different from sets of integrity checks that can be performed for other
SIP request types, hence we have three independent module parameters.
Without the extra checks the nonce will protect only against expired
values. Some reply attacks are still possible in the expire "window". A
@ -194,24 +194,24 @@ Chapter 1. Admin Guide
(see nonce_expire) and an MD5 over it and some secret (the MD5 is used
to make sure that nobody tampers with the nonce expire time).
When the extra checks are enabled, the nonce will include and extra MD5
When the extra checks are enabled, the nonce will include an extra MD5
over the selected part/parts of the message (see below) and some other
secret. This will be used to check if the selected part of the message
is the same when an UA tries to reuse the nonce, thus protecting or
severely limiting reply attacks.
The possible flag values for all three parameters are:
* 1 for checking if the message uri changed (uses the whole uri)
* 1 for checking if the message URI changed (uses the whole URI)
* 2 for checking the callid
* 4 for checking the from tag
* 8 for checking the source ip (see nonce.h).
* 4 for checking the From tag
* 8 for checking the source IP address (see nonce.h).
For example setting auth_checks_register to 3 would check if the callid
or the request uri changed from the REGISTER message for which the
original nonce was generated (this would allow nonce reuse only within
the same UA and for the expire time). Note that enabling the extra
checks will limit nonce caching by UAs, requiring extra challenges and
roundtrips, but will provide much better protection.
As an example setting auth_checks_register to 3 would check if the
callid or the request uri changed from the REGISTER message for which
the original nonce was generated (this would allow nonce reuse only
within the same UA and for the expire time). Note that enabling the
extra checks will limit nonce caching by UAs, requiring extra
challenges and roundtrips, but will provide much better protection.
Warning
@ -599,7 +599,7 @@ modparam("auth", "nonce_auth_max_drift", 1) # set max drift to 1 s
If set to 1, www_challenge() and proxy_challenge() functions send reply
statelessly no matter if transaction exists or not. If set to 0
(default), reply is sent statefully if transaction exists and
stelelessly otherwise.
statelessly otherwise.
Example 1.13. force_stateless_reply example
...
@ -608,12 +608,12 @@ modparam("auth", "force_stateless_reply", 1)
3.16. realm_prefix (string)
Prefix to be automatically strip from realm. As an alternative to SRV
records (not all SIP clients support SRV lookup), a subdomain of the
master domain can be defined for SIP purposes (like sip.mydomain.net
pointing to same IP address as the SRV record for mydomain.net). By
ignoring the realm_prefix "sip.", at authentication, sip.mydomain.net
will be equivalent to mydomain.net .
Prefix to be automatically stripped from the realm. As an alternative
to SRV records (not all SIP clients support SRV lookup), a subdomain of
the master domain can be defined for SIP purposes (like
sip.mydomain.net pointing to same IP address as the SRV record for
mydomain.net). By ignoring the realm_prefix "sip.", at authentication,
sip.example.com will be equivalent to example.com .
Default value is empty string.

@ -24,28 +24,28 @@
<title><varname>auth_checks_in_dlg</varname> (flags)</title>
<para>
These three module parameters control which optional integrity
checks will be performed on the SIP message carrying digest response
during digest authentication. <varname>auth_check_register</varname>
controls integrity checks to be performed on REGISTER messages,
<varname>auth_checks_no_dlg</varname> controls which optional
integrity checks will be performed on SIP requests that have no To
header field or no To tag (in other words the requests either
establishing or outside
dialogs). <varname>auth_checks_in_dlg</varname> controls which
integrity checks will be performed on SIP requests within dialogs,
such as BYE or re-INVITE. The default value for all three parameters
is 0 (old behaviour, no extra checks). The set of integrity checks
that can be performed on REGISTERs is typically different from sets of
integrity checks that can be performed for other SIP request types,
hence we have three independent module parameters.
checks will be performed on the SIP message carrying digest response
during SIP MD5 digest authentication. <varname>auth_check_register</varname>
controls integrity checks to be performed on REGISTER messages,
<varname>auth_checks_no_dlg</varname> controls which optional
integrity checks will be performed on SIP requests that have no To
header field or no To tag (in other words the requests either
establishing or outside dialogs).
<varname>auth_checks_in_dlg</varname> controls which
integrity checks will be performed on SIP requests within dialogs,
such as BYE or re-INVITE. The default value for all three parameters
is 0 (old behaviour, no extra checks). The set of integrity checks
that can be performed on REGISTERs is typically different from sets of
integrity checks that can be performed for other SIP request types,
hence we have three independent module parameters.
</para>
<para>
Without the extra checks the nonce will protect only against expired
values. Some reply attacks are still possible in the expire "window".
A possible workaround is to always force qop
authentication and always check the uri from the authorization
header, but this would not work if an upstream proxy rewrites the uri
and it will also not work with a lot of UA implementations.
A possible workaround is to always force qop authentication and
always check the uri from the authorization header, but this would
not work if an upstream proxy rewrites the uri
and it will also not work with a lot of UA implementations.
</para>
<para>
In this case the nonce value will be used only to hold
@ -54,7 +54,7 @@
tampers with the nonce expire time).
</para>
<para>
When the extra checks are enabled, the nonce will include and extra
When the extra checks are enabled, the nonce will include an extra
MD5 over the selected part/parts of the message (see below) and some
other secret. This will be used to check if the selected part of
the message is the same when an UA tries to reuse the nonce, thus
@ -65,28 +65,27 @@
<itemizedlist>
<listitem><para>
<emphasis>1</emphasis> for checking if the message
uri changed (uses the whole uri)
URI changed (uses the whole URI)
</para></listitem>
<listitem><para>
<emphasis>2</emphasis> for checking the callid
</para></listitem>
<listitem><para>
<emphasis>4</emphasis> for checking the from tag
<emphasis>4</emphasis> for checking the From tag
</para></listitem>
<listitem><para>
<emphasis>8</emphasis> for checking the source ip
<emphasis>8</emphasis> for checking the source IP address
(see nonce.h).
</para></listitem>
</itemizedlist>
</para>
<para>
For example setting
<varname>auth_checks_register</varname> to 3 would check if the
callid or the request uri changed from the REGISTER message for which
the original nonce was generated (this would allow nonce reuse only
within the same UA and for the expire time). Note that enabling
the extra checks will limit nonce caching by UAs, requiring extra
challenges and roundtrips, but will provide much better protection.
As an example setting <varname>auth_checks_register</varname> to 3
would check if the callid or the request uri changed from the REGISTER
message for which the original nonce was generated (this would allow nonce reuse only
within the same UA and for the expire time). Note that enabling
the extra checks will limit nonce caching by UAs, requiring extra
challenges and roundtrips, but will provide much better protection.
</para>
<warning><para>
Do not enable the from tag check (4) for REGISTERs
@ -155,7 +154,7 @@ modparam("auth", "auth_checks_in_dlg", 15)
The possible values are: "auth", "auth-int" and "" (unset).
</para>
<para>
The default value is not-set ("").
The default value is not-set ("").
</para>
<para>
See also:
@ -231,12 +230,12 @@ modparam("auth", "qop", "auth") # set qop=auth
</para>
<para>
See also:
<varname>qop</varname>,
<varname>nc_array_size</varname>,
<varname>nc_array_order</varname>,
<varname>nid_pool_no</varname>,
<varname>nonce_expire</varname>.
<varname>one_time_nonce</varname>.
<varname>qop</varname>,
<varname>nc_array_size</varname>,
<varname>nc_array_order</varname>,
<varname>nid_pool_no</varname>,
<varname>nonce_expire</varname>.
<varname>one_time_nonce</varname>.
</para>
<example>
<title>nonce_count example</title>
@ -302,8 +301,8 @@ route{
in the first reponse to a challenge. All the messages will be
challenged, even retransmissions. Stateful mode should be used, to
catch retransmissions before the authentication checks (using
<function>t_newtran()</function> before the authentication checks
and sending all the replies with <function>t_reply()</function>).
<function>t_newtran()</function> before the authentication checks
and sending all the replies with <function>t_reply()</function>).
</para>
<para>
<varname>one_time_nonce</varname> provides enhanced replay protections
@ -342,7 +341,7 @@ route{
<varname>one_time_nonce</varname> checks should work flawlessly.
</para>
<para>
The default value is 0 (off).
The default value is 0 (off).
</para>
<para>
See also:
@ -645,7 +644,7 @@ modparam("auth", "nonce_auth_max_drift", 1) # set max drift to 1 s
<function>proxy_challenge()</function>
functions send reply statelessly no matter if transaction
exists or not. If set to 0 (default), reply is sent statefully
if transaction exists and stelelessly otherwise.
if transaction exists and statelessly otherwise.
</para>
<example>
<title>force_stateless_reply example</title>
@ -660,13 +659,13 @@ modparam("auth", "force_stateless_reply", 1)
<section id="auth.p.realm_prefix">
<title><varname>realm_prefix</varname> (string)</title>
<para>
Prefix to be automatically strip from realm. As an alternative to
Prefix to be automatically stripped from the realm. As an alternative to
SRV records (not all SIP clients support SRV lookup), a subdomain
of the master domain can be defined for SIP purposes (like
sip.mydomain.net pointing to same IP address as the SRV
record for mydomain.net). By ignoring the realm_prefix
<quote>sip.</quote>, at authentication, sip.mydomain.net will be
equivalent to mydomain.net .
<quote>sip.</quote>, at authentication, sip.example.com will be
equivalent to example.com .
</para>
<para>
Default value is empty string.

@ -24,9 +24,6 @@
#include <stdio.h>
#include "../../locking.h"
#include "../../lock_ops.h"
#include "cnxcc_mod.h"
#include "cnxcc.h"
#include "cnxcc_check.h"
@ -40,7 +37,7 @@ void check_calls_by_money(unsigned int ticks, void *param) {
call_t *tmp_call = NULL;
int i;
lock_get(&_data.money.lock);
cnxcc_lock(_data.money.lock);
if (_data.money.credit_data_by_client->table)
for(i = 0; i < _data.money.credit_data_by_client->size; i++)
@ -54,7 +51,7 @@ void check_calls_by_money(unsigned int ticks, void *param) {
break;
}*/
lock_get(&credit_data->lock);
cnxcc_lock(credit_data->lock);
clist_foreach_safe(credit_data->call_list, call, tmp_call, next) {
int consumed_time = 0;
@ -88,7 +85,7 @@ void check_calls_by_money(unsigned int ticks, void *param) {
}
if (credit_data->concurrent_calls == 0) {
lock_release(&credit_data->lock);
cnxcc_unlock(credit_data->lock);
continue;
}
@ -112,15 +109,16 @@ void check_calls_by_money(unsigned int ticks, void *param) {
terminate_all_calls(credit_data);
// make sure the rest of the servers kill the calls belonging to this customer
redis_publish_to_kill_list(credit_data);
lock_release(&credit_data->lock);
if (_data.redis)
redis_publish_to_kill_list(credit_data);
cnxcc_unlock(credit_data->lock);
break;
}
lock_release(&credit_data->lock);
cnxcc_unlock(credit_data->lock);
}
lock_release(&_data.money.lock);
cnxcc_unlock(_data.money.lock);
}
void check_calls_by_time(unsigned int ticks, void *param) {
@ -129,7 +127,7 @@ void check_calls_by_time(unsigned int ticks, void *param) {
call_t *tmp_call = NULL;
int i;
lock_get(&_data.time.lock);
cnxcc_lock(_data.time.lock);
if (_data.time.credit_data_by_client->table)
for(i = 0; i < _data.time.credit_data_by_client->size; i++)
@ -139,7 +137,7 @@ void check_calls_by_time(unsigned int ticks, void *param) {
int total_consumed_secs = 0;
double consumption_diff = 0/*, distributed_consumption = 0*/;
lock_get(&credit_data->lock);
cnxcc_lock(credit_data->lock);
/*if (i > SAFE_ITERATION_THRESHOLD)
{
@ -169,7 +167,7 @@ void check_calls_by_time(unsigned int ticks, void *param) {
}
if (credit_data->concurrent_calls == 0) {
lock_release(&credit_data->lock);
cnxcc_unlock(credit_data->lock);
continue;
}
@ -190,13 +188,14 @@ void check_calls_by_time(unsigned int ticks, void *param) {
terminate_all_calls(credit_data);
// make sure the rest of the servers kill the calls belonging to this customer
redis_publish_to_kill_list(credit_data);
lock_release(&credit_data->lock);
if (_data.redis)
redis_publish_to_kill_list(credit_data);
cnxcc_unlock(credit_data->lock);
break;
}
lock_release(&credit_data->lock);
cnxcc_unlock(credit_data->lock);
}
lock_release(&_data.time.lock);
cnxcc_unlock(_data.time.lock);
}

@ -294,10 +294,12 @@ static int __mod_init(void) {
if (__init_hashtable(_data.channel.call_data_by_cid) != 0)
return -1;
lock_init(&_data.lock);
lock_init(&_data.time.lock);
lock_init(&_data.money.lock);
lock_init(&_data.channel.lock);
cnxcc_lock_init(_data.lock);
cnxcc_lock_init(_data.time.lock);
cnxcc_lock_init(_data.money.lock);
cnxcc_lock_init(_data.channel.lock);
register_mi_cmd(__mi_credit_control_stats, "cnxcc_stats", NULL, NULL, 0);
@ -471,45 +473,45 @@ int try_get_credit_data_entry(str *client_id, credit_data_t **credit_data) {
/* by money */
hts = &_data.money;
lock_get(&hts->lock);
cnxcc_lock(hts->lock);
cd_entry = str_hash_get(hts->credit_data_by_client, client_id->s, client_id->len);
if (cd_entry != NULL) {
*credit_data = cd_entry->u.p;
lock_release(&hts->lock);
cnxcc_unlock(hts->lock);
return 0;
}
lock_release(&hts->lock);
cnxcc_unlock(hts->lock);
/* by time */
hts = &_data.time;
lock_get(&hts->lock);
cnxcc_lock(hts->lock);
cd_entry = str_hash_get(hts->credit_data_by_client, client_id->s, client_id->len);
if (cd_entry != NULL) {
*credit_data = cd_entry->u.p;
lock_release(&hts->lock);
cnxcc_unlock(hts->lock);
return 0;
}
lock_release(&hts->lock);
cnxcc_unlock(hts->lock);
/* by channel */
hts = &_data.channel;
lock_get(&hts->lock);
cnxcc_lock(hts->lock);
cd_entry = str_hash_get(hts->credit_data_by_client, client_id->s, client_id->len);
if (cd_entry != NULL) {
*credit_data = cd_entry->u.p;
lock_release(&hts->lock);
cnxcc_unlock(hts->lock);
return 0;
}
lock_release(&hts->lock);
cnxcc_unlock(hts->lock);
return -1;
}
@ -520,45 +522,45 @@ int try_get_call_entry(str *callid, call_t **call, hash_tables_t **hts) {
/* by money */
*hts = &_data.money;
lock_get(&(*hts)->lock);
cnxcc_lock((*hts)->lock);
call_entry = str_hash_get((*hts)->call_data_by_cid, callid->s, callid->len);
if (call_entry != NULL) {
*call = call_entry->u.p;
lock_release(&(*hts)->lock);
cnxcc_unlock((*hts)->lock);
return 0;
}
lock_release(&(*hts)->lock);
cnxcc_unlock((*hts)->lock);
/* by time */
*hts = &_data.time;
lock_get(&(*hts)->lock);
cnxcc_lock((*hts)->lock);
call_entry = str_hash_get((*hts)->call_data_by_cid, callid->s, callid->len);
if (call_entry != NULL) {
*call = call_entry->u.p;
lock_release(&(*hts)->lock);
cnxcc_unlock((*hts)->lock);
return 0;
}
lock_release(&(*hts)->lock);
cnxcc_unlock((*hts)->lock);
/* by channel */
*hts = &_data.channel;
lock_get(&(*hts)->lock);
cnxcc_lock((*hts)->lock);
call_entry = str_hash_get((*hts)->call_data_by_cid, callid->s, callid->len);
if (call_entry != NULL) {
*call = call_entry->u.p;
lock_release(&(*hts)->lock);
cnxcc_unlock((*hts)->lock);
return 0;
}
lock_release(&(*hts)->lock);
cnxcc_unlock((*hts)->lock);
return -1;
}
@ -586,7 +588,7 @@ static void __stop_billing(str *callid) {
return;
}
lock_get(&hts->lock);
cnxcc_lock(hts->lock);
/*
* Search credit_data by client_id
@ -595,7 +597,7 @@ static void __stop_billing(str *callid) {
if (cd_entry == NULL) {
LM_ERR("Credit data not found for CID [%.*s], client-ID [%.*s]\n", callid->len, callid->s, call->client_id.len, call->client_id.s);
lock_release(&hts->lock);
cnxcc_unlock(hts->lock);
return;
}
@ -603,23 +605,23 @@ static void __stop_billing(str *callid) {
if (credit_data == NULL) {
LM_ERR("[%.*s]: credit_data pointer is null\n", callid->len, callid->s);
lock_release(&hts->lock);
cnxcc_unlock(hts->lock);
return;
}
lock_release(&hts->lock);
cnxcc_unlock(hts->lock);
/*
* Update calls statistics
*/
lock_get(&_data.lock);
cnxcc_lock(_data.lock);
_data.stats->active--;
_data.stats->total--;
lock_release(&_data.lock);
cnxcc_unlock(_data.lock);
lock(&credit_data->lock);
cnxcc_lock(credit_data->lock);
LM_DBG("Call [%.*s] of client-ID [%.*s], ended\n", callid->len, callid->s, call->client_id.len, call->client_id.s);
@ -653,7 +655,13 @@ static void __stop_billing(str *callid) {
* Remove (and free) the call from the list of calls of the current credit_data
*/
clist_rm(call, next, prev);
__free_call(call);
/*
* don't free the call if all the credit data is being deallocated,
* it will be freed by terminate_all_calls()
*/
if (!credit_data->deallocating) {
__free_call(call);
}
/*
* In case there are no active calls for a certain client, we remove the client-id from the hash table.
@ -663,7 +671,7 @@ static void __stop_billing(str *callid) {
LM_DBG("Removing client [%.*s] and its calls from the list\n", credit_data->call_list->client_id.len, credit_data->call_list->client_id.s);
credit_data->deallocating = 1;
lock(&hts->lock);
cnxcc_lock(hts->lock);
if (_data.redis) {
redis_clean_up_if_last(credit_data);
@ -675,7 +683,7 @@ static void __stop_billing(str *callid) {
*/
str_hash_del(cd_entry);
lock_release(&hts->lock);
cnxcc_unlock(hts->lock);
/*
* Free client_id in list's root
@ -686,7 +694,7 @@ static void __stop_billing(str *callid) {
/*
* Release the lock since we are going to free the entry down below
*/
lock_release(&credit_data->lock);
cnxcc_unlock(credit_data->lock);
/*
* Free the whole entry
@ -699,7 +707,7 @@ static void __stop_billing(str *callid) {
return;
}
lock_release(&credit_data->lock);
cnxcc_unlock(credit_data->lock);
}
static void __setup_billing(str *callid, unsigned int h_entry, unsigned int h_id) {
@ -708,7 +716,7 @@ static void __setup_billing(str *callid, unsigned int h_entry, unsigned int h_id
LM_DBG("Creating dialog for [%.*s], h_id [%u], h_entry [%u]\n", callid->len, callid->s, h_id, h_entry);
// lock_get(&_data.lock);
// cnxcc_lock(&_data);
/*
* Search call data by call-id
@ -731,21 +739,21 @@ static void __setup_billing(str *callid, unsigned int h_entry, unsigned int h_id
/*
* Update calls statistics
*/
lock_get(&_data.lock);
cnxcc_lock(_data.lock);
_data.stats->active++;
_data.stats->total++;
lock_release(&_data.lock);
cnxcc_unlock(_data.lock);
lock_get(&call->lock);
cnxcc_lock(call->lock);
call->dlg_h_entry = h_entry;
call->dlg_h_id = h_id;
LM_DBG("Call [%.*s] from client [%.*s], created\n", callid->len, callid->s, call->client_id.len, call->client_id.s);
lock_release(&call->lock);
cnxcc_unlock(call->lock);
}
static void __start_billing(str *callid, str *from_uri, str *to_uri, str tags[2]) {
@ -756,7 +764,7 @@ static void __start_billing(str *callid, str *from_uri, str *to_uri, str tags[2]
LM_DBG("Billing started for call [%.*s]\n", callid->len, callid->s);
// lock_get(&_data.lock);
// cnxcc_lock(&_data);
/*
* Search call data by call-id
@ -776,7 +784,7 @@ static void __start_billing(str *callid, str *from_uri, str *to_uri, str tags[2]
return;
}
lock_get(&hts->lock);
cnxcc_lock(hts->lock);
/*
* Search credit_data by client_id
@ -785,7 +793,7 @@ static void __start_billing(str *callid, str *from_uri, str *to_uri, str tags[2]
if (cd_entry == NULL) {
LM_ERR("Credit data not found for CID [%.*s], client-ID [%.*s]\n", callid->len, callid->s, call->client_id.len, call->client_id.s);
lock_release(&hts->lock);
cnxcc_unlock(hts->lock);
return;
}
@ -793,13 +801,13 @@ static void __start_billing(str *callid, str *from_uri, str *to_uri, str tags[2]
if (credit_data == NULL) {
LM_ERR("[%.*s]: credit_data pointer is null\n", callid->len, callid->s);
lock_release(&hts->lock);
cnxcc_unlock(hts->lock);
return;
}
lock_release(&hts->lock);
cnxcc_unlock(hts->lock);
lock(&credit_data->lock);
cnxcc_lock(credit_data->lock);
/*
* Now that the call is confirmed, we can increase the count of "concurrent_calls".
@ -834,9 +842,9 @@ static void __start_billing(str *callid, str *from_uri, str *to_uri, str tags[2]
*/
call->max_amount = credit_data->max_amount - credit_data->consumed_amount;
lock_release(&credit_data->lock);
cnxcc_unlock(credit_data->lock);
lock_get(&call->lock);
cnxcc_lock(call->lock);
/*
* Store from-tag value
@ -870,7 +878,7 @@ static void __start_billing(str *callid, str *from_uri, str *to_uri, str tags[2]
call->sip_data.to_uri.len, call->sip_data.to_uri.s,
call->sip_data.to_tag.len, call->sip_data.to_tag.s);
exit:
lock_release(&call->lock);
cnxcc_unlock(call->lock);
}
// must be called with lock held on credit_data
@ -881,13 +889,18 @@ void terminate_all_calls(credit_data_t *credit_data) {
credit_data->deallocating = 1;
clist_foreach_safe(credit_data->call_list, call, tmp, next) {
LM_DBG("Killing call with CID [%.*s]\n", call->sip_data.callid.len, call->sip_data.callid.s);
/*
* Update number of calls forced to end
*/
_data.stats->dropped++;
terminate_call(call);
if(call->sip_data.callid.s!=NULL) {
LM_DBG("Killing call with CID [%.*s]\n", call->sip_data.callid.len, call->sip_data.callid.s);
/*
* Update number of calls forced to end
*/
_data.stats->dropped++;
terminate_call(call);
__free_call(call);
} else {
LM_WARN("invalid call structure %p\n", call);
}
}
}
@ -897,6 +910,9 @@ void terminate_all_calls(credit_data_t *credit_data) {
static void __free_call(call_t *call) {
struct str_hash_entry *e = NULL;
if(call->sip_data.callid.s==NULL)
return;
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);
@ -1020,32 +1036,32 @@ error:
}
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;
struct str_hash_table *sht = NULL;
struct hash_tables *ht;
struct str_hash_entry *e = NULL;
credit_data_t *credit_data = NULL;
switch(type) {
case CREDIT_MONEY:
ht = _data.money.credit_data_by_client;
lock = &_data.money.lock;
sht = _data.money.credit_data_by_client;
ht = &_data.money;
break;
case CREDIT_TIME:
ht = _data.time.credit_data_by_client;
lock = &_data.time.lock;
sht = _data.time.credit_data_by_client;
ht = &_data.time;
break;
case CREDIT_CHANNEL:
ht = _data.channel.credit_data_by_client;
lock = &_data.channel.lock;
sht = _data.channel.credit_data_by_client;
ht = &_data.channel;
break;
default:
LM_ERR("BUG: Something went terribly wrong\n");
return NULL;
}
lock_get(lock);
e = str_hash_get(ht, client_id->s, client_id->len);
lock_release(lock);
cnxcc_lock(ht->lock);
e = str_hash_get(sht, client_id->s, client_id->len);
cnxcc_unlock(ht->lock);
/*
* Alloc new call_array_t if it doesn't exist
@ -1066,11 +1082,11 @@ static credit_data_t *__get_or_create_credit_data_entry(str *client_id, credit_t
if (credit_data == NULL)
goto no_memory;
lock_get(lock);
str_hash_add(ht, e);
lock_release(lock);
cnxcc_lock(ht->lock);
str_hash_add(sht, e);
cnxcc_unlock(ht->lock);
LM_DBG("Call didn't exist. Allocated new entry\n");
LM_DBG("Credit entry didn't exist. Allocated new entry [%p]\n", e);
}
return (credit_data_t *) e->u.p;
@ -1083,7 +1099,7 @@ no_memory:
static credit_data_t *__alloc_new_credit_data(str *client_id, credit_type_t type) {
credit_data_t *credit_data = shm_malloc(sizeof(credit_data_t));;
lock_init(&credit_data->lock);
cnxcc_lock_init(credit_data->lock);
credit_data->call_list = shm_malloc(sizeof(call_t));
@ -1135,7 +1151,8 @@ error:
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;
lock_get(&credit_data->lock);
cnxcc_lock(credit_data->lock);
if (credit_data->call_list == NULL) {
LM_ERR("Credit data call list is NULL\n");
@ -1183,7 +1200,7 @@ static call_t *__alloc_new_call_by_money(credit_data_t *credit_data, struct sip_
*/
clist_insert(credit_data->call_list, call, next, prev);
lock_init(&call->lock);
cnxcc_lock_init(call->lock);
/*
* Increase the number of calls for this client. This call is not yet confirmed.
@ -1192,21 +1209,21 @@ static call_t *__alloc_new_call_by_money(credit_data_t *credit_data, struct sip_
if (_data.redis)
redis_incr_by_int(credit_data, "number_of_calls", 1);
lock_release(&credit_data->lock);
cnxcc_unlock(credit_data->lock);
LM_DBG("New call allocated for client [%.*s]\n", call->client_id.len, call->client_id.s);
return call;
error:
lock_release(&credit_data->lock);
cnxcc_unlock(credit_data->lock);
return NULL;
}
static call_t *__alloc_new_call_by_time(credit_data_t *credit_data, struct sip_msg *msg, int max_secs) {
call_t *call = NULL;
lock_get(&credit_data->lock);
cnxcc_lock(credit_data->lock);
if (credit_data->call_list == NULL) {
LM_ERR("Credit data call list is NULL\n");
@ -1250,7 +1267,7 @@ static call_t *__alloc_new_call_by_time(credit_data_t *credit_data, struct sip_m
*/
clist_insert(credit_data->call_list, call, next, prev);
lock_init(&call->lock);
cnxcc_lock_init(call->lock);
/*
* Increase the number of calls for this client. This call is not yet confirmed.
@ -1259,21 +1276,21 @@ static call_t *__alloc_new_call_by_time(credit_data_t *credit_data, struct sip_m
if (_data.redis)
redis_incr_by_int(credit_data, "number_of_calls", 1);
lock_release(&credit_data->lock);
cnxcc_unlock(credit_data->lock);
LM_DBG("New call allocated for client [%.*s]\n", call->client_id.len, call->client_id.s);
return call;
error:
lock_release(&credit_data->lock);
cnxcc_unlock(credit_data->lock);
return NULL;
}
static call_t *alloc_new_call_by_channel(credit_data_t *credit_data, struct sip_msg *msg, int max_chan) {
call_t *call = NULL;
lock_get(&credit_data->lock);
cnxcc_lock(credit_data->lock);
if (credit_data->call_list == NULL) {
LM_ERR("Credit data call list is NULL\n");
@ -1317,7 +1334,7 @@ static call_t *alloc_new_call_by_channel(credit_data_t *credit_data, struct sip_
*/
clist_insert(credit_data->call_list, call, next, prev);
lock_init(&call->lock);
cnxcc_lock_init(call->lock);
/*
* Increase the number of calls for this client. This call is not yet confirmed.
@ -1326,7 +1343,7 @@ static call_t *alloc_new_call_by_channel(credit_data_t *credit_data, struct sip_
if (_data.redis)
redis_incr_by_int(credit_data, "number_of_calls", 1);
lock_release(&credit_data->lock);
cnxcc_unlock(credit_data->lock);
LM_DBG("New call allocated for client [%.*s]\n", call->client_id.len, call->client_id.s);
@ -1334,27 +1351,27 @@ static call_t *alloc_new_call_by_channel(credit_data_t *credit_data, struct sip_
return call;
error:
lock_release(&credit_data->lock);
cnxcc_unlock(credit_data->lock);
return NULL;
}
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;
cnxcc_lock_t lock;
struct str_hash_entry *e = NULL;
switch(type) {
case CREDIT_MONEY:
ht = _data.money.call_data_by_cid;
lock = &_data.money.lock;
lock = _data.money.lock;
break;
case CREDIT_TIME:
ht = _data.time.call_data_by_cid;
lock = &_data.time.lock;
lock = _data.time.lock;
break;
case CREDIT_CHANNEL:
ht = _data.channel.call_data_by_cid;
lock = &_data.channel.lock;
lock = _data.channel.lock;
break;
default:
LM_ERR("Something went terribly wrong\n");
@ -1400,9 +1417,9 @@ static int __add_call_by_cid(str *cid, call_t *call, credit_type_t type) {
e->u.p = call;
lock_get(lock);
cnxcc_lock(lock);
str_hash_add(ht, e);
lock_release(lock);
cnxcc_unlock(lock);
return 0;
}
@ -1805,9 +1822,9 @@ static int __update_max_time(struct sip_msg* msg, char* str_pv_client, char* str
call_t *call = NULL,
*tmp_call = NULL;
lock_get(&_data.time.lock);
cnxcc_lock(_data.time.lock);
e = str_hash_get(ht, client_id_val.rs.s, client_id_val.rs.len);
lock_release(&_data.time.lock);
cnxcc_unlock(_data.time.lock);
if (e == NULL) {
LM_ERR("Client [%.*s] was not found\n", client_id_val.rs.len, client_id_val.rs.s);
@ -1815,7 +1832,7 @@ static int __update_max_time(struct sip_msg* msg, char* str_pv_client, char* str
}
credit_data = (credit_data_t *) e->u.p;
lock_get(&credit_data->lock);
cnxcc_lock(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);
@ -1834,7 +1851,7 @@ static int __update_max_time(struct sip_msg* msg, char* str_pv_client, char* str
//redit_data->consumed_amount = 0;
lock_release(&credit_data->lock);
cnxcc_unlock(credit_data->lock);
return 1;
}

@ -25,11 +25,59 @@
#define _CNXCC_MOD_H
#include "../../locking.h"
#include "../../atomic_ops.h"
#include "../../str_hash.h"
#include "../../parser/parse_rr.h"
#define str_shm_free_if_not_null(_var_) if (_var_.s != NULL) { shm_free(_var_.s); _var_.s = NULL; _var_.len = 0; }
/*!
* \brief Init a cnxcc_lock
* \param _entry locked entry
*/
#define cnxcc_lock_init(_entry) \
lock_init(&(_entry).lock); \
(_entry).rec_lock_level = 0;
/*!
* \brief Set a cnxcc lock (re-entrant)
* \param _entry locked entry
*/
#define cnxcc_lock(_entry) \
do { \
int mypid; \
mypid = my_pid(); \
if (likely(atomic_get( &(_entry).locker_pid) != mypid)) { \
lock_get( &(_entry).lock); \
atomic_set( &(_entry).locker_pid, mypid); \
} else { \
/* locked within the same process that executed us */ \
(_entry).rec_lock_level++; \
} \
} while(0)
/*!
* \brief Release a cnxcc lock
* \param _entry locked entry
*/
#define cnxcc_unlock(_entry) \
do { \
if (likely((_entry).rec_lock_level == 0)) { \
atomic_set( &(_entry).locker_pid, 0); \
lock_release( &(_entry).lock); \
} else { \
/* recursive locked => decrease lock count */ \
(_entry).rec_lock_level--; \
} \
} while(0)
typedef struct cnxcc_lock {
gen_lock_t lock;
atomic_t locker_pid;
int rec_lock_level;
} cnxcc_lock_t;
typedef struct stats {
unsigned int total;
unsigned int active;
@ -52,13 +100,13 @@ typedef struct hash_tables {
struct str_hash_table *credit_data_by_client;
struct str_hash_table *call_data_by_cid;
gen_lock_t lock;
cnxcc_lock_t lock;
} hash_tables_t;
struct redis;
typedef struct data {
gen_lock_t lock;
cnxcc_lock_t lock;
hash_tables_t time;
hash_tables_t money;
@ -111,7 +159,7 @@ typedef struct call {
struct call *prev;
struct call *next;
gen_lock_t lock;
cnxcc_lock_t lock;
char confirmed;
double max_amount;
@ -135,7 +183,7 @@ typedef struct call_array {
} call_array_t;
typedef struct credit_data {
gen_lock_t lock;
cnxcc_lock_t lock;
double max_amount;
double consumed_amount;

@ -531,7 +531,7 @@ static void __subscription_cb(redisAsyncContext *c, void *r, void *privdata) {
if (try_get_credit_data_entry(&key, &credit_data) < 0)
return;
lock_get(&credit_data->lock);
cnxcc_lock(credit_data->lock);
if (credit_data->deallocating)
goto done; // no need to terminate the calls. They are already being terminated
@ -539,6 +539,6 @@ static void __subscription_cb(redisAsyncContext *c, void *r, void *privdata) {
LM_ALERT("Got kill list entry for key [%.*s]\n", key.len, key.s);
terminate_all_calls(credit_data);
done:
lock_release(&credit_data->lock);
cnxcc_unlock(credit_data->lock);
}

@ -24,8 +24,6 @@
#include <stdio.h>
#include "../../locking.h"
#include "../../lock_ops.h"
#include "../../rpc.h"
#include "../../rpc_lookup.h"
@ -57,11 +55,11 @@ void rpc_kill_call(rpc_t* rpc, void* ctx) {
LM_ALERT("Killing call [%.*s] via XMLRPC request\n", callid.len, callid.s);
lock_get(&call->lock);
cnxcc_lock(call->lock);
terminate_call(call);
lock_release(&call->lock);
cnxcc_unlock(call->lock);
}
void rpc_check_client_stats(rpc_t* rpc, void* ctx) {
@ -88,10 +86,10 @@ void rpc_check_client_stats(rpc_t* rpc, void* ctx) {
return;
}
lock_get(&credit_data->lock);
cnxcc_lock(credit_data->lock);
if (credit_data->number_of_calls <= 0) {
lock_release(&credit_data->lock);
cnxcc_unlock(credit_data->lock);
LM_INFO("No calls for current client\n");
return;
}
@ -136,7 +134,7 @@ void rpc_check_client_stats(rpc_t* rpc, void* ctx) {
rows.s = pkg_realloc(rows.s, rows.len + row_len);
if (rows.s == NULL) {
lock_release(&credit_data->lock);
cnxcc_unlock(credit_data->lock);
goto nomem;
}
@ -146,7 +144,7 @@ void rpc_check_client_stats(rpc_t* rpc, void* ctx) {
index++;
}
lock_release(&credit_data->lock);
cnxcc_unlock(credit_data->lock);
if (rpc->add(ctx, "S", &rows) < 0) {
LM_ERR("%s: error creating RPC struct\n", __FUNCTION__);
@ -167,13 +165,13 @@ static int iterate_over_table(hash_tables_t *hts, str *result, credit_type_t typ
char row_buffer[512];
int index = 0;
lock_get(&hts->lock);
cnxcc_lock(hts->lock);
if (hts->credit_data_by_client->table)
for(index = 0; index < hts->credit_data_by_client->size; index++)
clist_foreach_safe(&hts->credit_data_by_client->table[index], h_entry, tmp, next) {
credit_data_t *credit_data = (credit_data_t *) h_entry->u.p;
lock_get(&credit_data->lock);
cnxcc_lock(credit_data->lock);
int row_len = 0;
@ -212,13 +210,13 @@ static int iterate_over_table(hash_tables_t *hts, str *result, credit_type_t typ
return -1;
}
lock_release(&credit_data->lock);
cnxcc_unlock(credit_data->lock);
row_len = strlen(row_buffer);
result->s = pkg_realloc(result->s, result->len + row_len);
if (result->s == NULL) {
lock_release(&hts->lock);
cnxcc_unlock(hts->lock);
goto nomem;
}
@ -227,7 +225,7 @@ static int iterate_over_table(hash_tables_t *hts, str *result, credit_type_t typ
}
lock_release(&hts->lock);
cnxcc_unlock(hts->lock);
return 0;
@ -249,7 +247,7 @@ void rpc_active_clients(rpc_t* rpc, void* ctx) {
iterate_over_table(&_data.time, &rows, CREDIT_TIME);
iterate_over_table(&_data.money, &rows, CREDIT_MONEY);
if (!rpc->add(ctx, "S", &rows) < 0) {
if (rpc->add(ctx, "S", &rows) < 0) {
LM_ERR("%s: error creating RPC struct\n", __FUNCTION__);
}

@ -254,13 +254,15 @@ int corex_send(sip_msg_t *msg, gparam_t *pu, enum sip_protos proto)
ret=E_BUG;
goto error;
}
}
else
{
} else {
u = &next_hop;
u->port_no = 5060;
u->host = dest;
p = memchr(dest.s, ':', dest.len);
p = dest.s;
/* detect ipv6 */
p = memchr(p, ']', dest.len);
if (p) p++;
p = memchr(p, ':', dest.len);
if (p)
{
u->host.len = p - dest.s;

@ -235,20 +235,20 @@ modparam("ctl", "autoconversion", 1)
Set the size of binrpc buffer for RPC reply. Value represents
kilobytes.
Default: 4 (meaning 4KB);
Default: 32 (meaning 32KB);
Example 1.8. Set the binrpc_max_body_size parameter
modparam("ctl", "binrpc_max_body_size", 10)
modparam("ctl", "binrpc_max_body_size", 16)
3.8. binrpc_struct_max_body_size (integer)
Set the size of binrpc structure buffer for RPC reply. Value represents
kilobytes.
Default: 1 (meaning 1KB);
Default: 8 (meaning 8KB);
Example 1.9. Set the binrpc_struct_max_body_size parameter
modparam("ctl", "binrpc_struct_max_body_size", 3)
modparam("ctl", "binrpc_struct_max_body_size", 4)
4. SIP-router RPC Functions

@ -36,8 +36,9 @@
rpc->scan (default: not set) */
int autoconvert=0;
int binrpc_max_body_size = 4; /* multiplied by 1024 in mod init */
int binrpc_struct_max_body_size = 1; /* multiplied by 1024 in mod init */
int binrpc_max_body_size = 32; /* multiplied by 1024 in mod init */
int binrpc_struct_max_body_size = 8; /* multiplied by 1024 in mod init */
#define BINRPC_MAX_BODY binrpc_max_body_size /* maximum body for send */
#define STRUCT_MAX_BODY binrpc_struct_max_body_size
#define MAX_MSG_CHUNKS 96

@ -200,13 +200,13 @@ modparam("ctl", "autoconversion", 1)
kilobytes.
</para>
<para>
Default: 4 (meaning 4KB);
Default: 32 (meaning 32KB);
</para>
<example>
<title>Set the <varname>binrpc_max_body_size</varname> parameter
</title>
<programlisting>
modparam("ctl", "binrpc_max_body_size", 10)
modparam("ctl", "binrpc_max_body_size", 16)
</programlisting>
</example>
</section>
@ -218,13 +218,13 @@ modparam("ctl", "binrpc_max_body_size", 10)
kilobytes.
</para>
<para>
Default: 1 (meaning 1KB);
Default: 8 (meaning 8KB);
</para>
<example>
<title>Set the <varname>binrpc_struct_max_body_size</varname> parameter
</title>
<programlisting>
modparam("ctl", "binrpc_struct_max_body_size", 3)
modparam("ctl", "binrpc_struct_max_body_size", 4)
</programlisting>
</example>
</section>

@ -113,12 +113,15 @@ static int db_mysql_submit_query(const db1_con_t* _h, const str* _s)
return 0;
}
code = mysql_errno(CON_CONNECTION(_h));
if (code != CR_SERVER_GONE_ERROR && code != CR_SERVER_LOST) {
if (code!=CR_SERVER_GONE_ERROR && code!=CR_SERVER_LOST
&& code!=CR_SSL_CONNECTION_ERROR && code!=CR_CONNECTION_ERROR
&& code!=CR_CONN_HOST_ERROR && code!=CR_SERVER_LOST_EXTENDED) {
break;
}
counter_inc(mysql_cnts_h.driver_err);
}
LM_ERR("driver error on query: %s\n", mysql_error(CON_CONNECTION(_h)));
LM_ERR("driver error on query: %s (%d)\n", mysql_error(CON_CONNECTION(_h)),
mysql_errno(CON_CONNECTION(_h)));
return -2;
}

@ -43,6 +43,9 @@ struct my_con* db_mysql_new_connection(const struct db_id* id)
struct my_con* ptr;
char *host, *grp, *egrp;
unsigned int connection_flag = 0;
#if MYSQL_VERSION_ID > 50012
my_bool rec;
#endif
if (!id) {
LM_ERR("invalid parameter value\n");
@ -99,6 +102,13 @@ struct my_con* db_mysql_new_connection(const struct db_id* id)
mysql_options(ptr->con, MYSQL_OPT_CONNECT_TIMEOUT, (const char *)&db_mysql_timeout_interval);
mysql_options(ptr->con, MYSQL_OPT_READ_TIMEOUT, (const char *)&db_mysql_timeout_interval);
mysql_options(ptr->con, MYSQL_OPT_WRITE_TIMEOUT, (const char *)&db_mysql_timeout_interval);
#if MYSQL_VERSION_ID > 50012
/* set reconnect flag if enabled */
if (db_mysql_auto_reconnect) {
rec = 1;
mysql_options(ptr->con, MYSQL_OPT_RECONNECT, &rec);
}
#endif
if (db_mysql_update_affected_found) {
connection_flag |= CLIENT_FOUND_ROWS;

@ -602,7 +602,6 @@ int db_postgres_store_result(const db1_con_t* _con, db1_res_t** _r)
}
done:
db_postgres_free_query(_con);
return (rc);
}
@ -906,12 +905,12 @@ int db_postgres_replace(const db1_con_t* _h, const db_key_t* _k,
pos += VAL_UINT(&_v[i]);
break;
case DB1_STR:
pos += get_hash1_raw((VAL_STR(&_v[i])).s,
(VAL_STR(&_v[i])).len);
pos += ((VAL_STR(&_v[i])).s)?get_hash1_raw((VAL_STR(&_v[i])).s,
(VAL_STR(&_v[i])).len):0;
break;
case DB1_STRING:
pos += get_hash1_raw(VAL_STRING(&_v[i]),
strlen(VAL_STRING(&_v[i])));
pos += (VAL_STRING(&_v[i]))?get_hash1_raw(VAL_STRING(&_v[i]),
strlen(VAL_STRING(&_v[i]))):0;
break;
default:
break;

@ -93,19 +93,23 @@ union ull {
uint32_t ui32[2];
};
#if !defined(__OS_darwin) || (defined(__OS_darwin) && !defined(NTOHLL))
static inline uint64_t htonll(uint64_t in)
{
union ull* p = (union ull*)&in;
return ((uint64_t)htonl(p->ui32[0]) << 32) + (uint64_t)htonl(p->ui32[1]);
}
#endif
#if !defined(__OS_darwin) || (defined(__OS_darwin) && !defined(NTOHLL))
static inline uint64_t ntohll(uint64_t in)
{
union ull* p = (union ull*)&in;
return ((uint64_t)ntohl(p->ui32[0]) << 32) + (uint64_t)ntohl(p->ui32[1]);
}
#endif
static inline void db_int2pg_int4(struct pg_params* dst, int i,

@ -970,7 +970,29 @@ static inline int parse_dlg_rr_param(char *p, char *end, int *h_entry, int *h_id
{
char *s;
/* sanity checks */
if (!p) {
LM_ERR("NULL start of parameter string");
return -1;
}
if (!end) {
LM_ERR("NULL end of parameter string");
return -1;
}
if (!h_entry) {
LM_ERR("NULL h_entry");
return -1;
}
if (!h_id) {
LM_ERR("NULL h_id");
return -1;
}
for ( s=p ; p<end && *p!=DLG_SEPARATOR ; p++ );
if (*p!=DLG_SEPARATOR) {
LM_ERR("malformed rr param '%.*s'\n", (int)(long)(end-s), s);
return -1;

@ -999,6 +999,8 @@ void next_state_dlg(dlg_cell_t *dlg, int event,
switch (dlg->state) {
case DLG_STATE_EARLY:
case DLG_STATE_CONFIRMED_NA:
dlg->iflags |= DLG_IFLAG_PRACK;
break;
case DLG_STATE_DELETED:
break;
default:

@ -76,6 +76,7 @@
#define DLG_IFLAG_KA_DST (1<<2) /*!< send keep alive to dst */
#define DLG_IFLAG_TIMER_NORESET (1<<3) /*!< don't reset dialog timers on in-dialog messages reception */
#define DLG_IFLAG_CSEQ_DIFF (1<<4) /*!< CSeq changed in dialog */
#define DLG_IFLAG_PRACK (1<<5) /*!< PRACK was routed during initial state */
#define DLG_CALLER_LEG 0 /*!< attribute that belongs to a caller leg */
#define DLG_CALLEE_LEG 1 /*!< attribute that belongs to a callee leg */

@ -348,6 +348,11 @@ static inline int send_bye(struct dlg_cell * cell, int dir, str *hdrs)
goto err;
}
/* safety bump of cseq if prack was involved in call setup */
if(cell->iflags & DLG_IFLAG_PRACK) {
dialog_info->loc_seq.value += 80;
}
LM_DBG("sending BYE to %s\n", (dir==DLG_CALLER_LEG)?"caller":"callee");
iuid = dlg_get_iuid_shm_clone(cell);

@ -185,20 +185,12 @@ dmq_node_t* build_dmq_node(str* uri, int shm) {
}
/* if any params found */
if(params) {
if(shm) {
if(shm_duplicate_params(&ret->params, params) < 0) {
LM_ERR("error duplicating params\n");
free_params(params);
goto error;
}
if(set_dmq_node_params(ret, params) < 0) {
free_params(params);
} else {
ret->params = params;
}
if(set_dmq_node_params(ret, ret->params) < 0) {
LM_ERR("error setting parameters\n");
goto error;
}
free_params(params);
} else {
LM_DBG("no dmqnode params found\n");
}
@ -248,12 +240,8 @@ dmq_node_t* find_dmq_node_uri2(str* uri)
void destroy_dmq_node(dmq_node_t* node, int shm)
{
if(shm) {
if (node->params!=NULL)
shm_free_params(node->params);
shm_free_node(node);
} else {
if (node->params!=NULL)
free_params(node->params);
pkg_free_node(node);
}
}

@ -43,7 +43,6 @@ typedef struct dmq_node {
str orig_uri; /* original uri string - e.g. sip:127.0.0.1:5060;passive=true */
struct sip_uri uri; /* parsed uri string */
struct ip_addr ip_address; /* resolved IP address */
param_t* params; /* uri parameters */
int status; /* reserved - maybe something like active,timeout,disabled */
int last_notification; /* last notificatino receied from the node */
struct dmq_node* next; /* pointer to the next struct dmq_node */

@ -406,7 +406,7 @@ int extract_node_list(dmq_node_list_t* update_list, struct sip_msg* msg)
update_list->nodes = cur;
update_list->count++;
total_nodes++;
} else if (find->params && ret->status != find->status) {
} else if (find->uri.params.s && ret->status != find->status) {
LM_DBG("updating status on %.*s from %d to %d\n",
STR_FMT(&tmp_uri), ret->status, find->status);
ret->status = find->status;

@ -197,14 +197,14 @@ void usrloc_get_all_ucontact(dmq_node_t* node)
memcpy( &aorhash, cp, sizeof(aorhash));
cp = (char*)cp + sizeof(aorhash);
r = 0;
ptr = 0;
res = dmq_ul.get_urecord_by_ruid(_d, aorhash, &ruid, &r, &ptr);
aor = r->aor;
if (res > 0) {
LM_DBG("'%.*s' Not found in usrloc\n", aor.len, ZSW(aor.s));
dmq_ul.release_urecord(r);
dmq_ul.unlock_udomain(_d, &aor);
if (res < 0) {
LM_DBG("'%.*s' Not found in usrloc\n", ruid.len, ZSW(ruid.s));
continue;
}
aor = r->aor;
LM_DBG("- AoR: %.*s AoRhash=%d Flags=%d\n", aor.len, aor.s, aorhash, flags);
while (ptr) {

@ -114,12 +114,12 @@ static int mod_init(void)
/* init faked sip msg */
if(faked_msg_init()<0) {
LM_ERR("failed to init faked sip msg\n");
LM_ERR("failed to init faked sip message\n");
return -1;
}
if(load_tm_api( &tmb ) < 0) {
LM_INFO("cannot load the TM-functions - async relay disabled\n");
LM_INFO("cannot load the TM module functions - async relay disabled\n");
memset(&tmb, 0, sizeof(tm_api_t));
}
@ -180,7 +180,7 @@ static int child_init(int rank)
/* main function for dispatcher */
evapi_close_notify_sockets_child();
if(evapi_run_dispatcher(_evapi_bind_addr, _evapi_bind_port)<0) {
LM_ERR("failed to initialize disptacher process\n");
LM_ERR("failed to initialize evapi dispatcher process\n");
return -1;
}
}
@ -276,7 +276,7 @@ static int w_evapi_async_relay(sip_msg_t *msg, char *evdata, char *p2)
}
if(tmb.t_suspend(msg, &tindex, &tlabel)<0)
{
LM_ERR("failed to suppend request processing\n");
LM_ERR("failed to suspend request processing\n");
return -1;
}

@ -50,6 +50,17 @@ extern pv_spec_t kz_query_timeout_spec;
const amqp_bytes_t kz_amqp_empty_bytes = { 0, NULL };
const amqp_table_t kz_amqp_empty_table = { 0, NULL };
amqp_exchange_declare_ok_t * AMQP_CALL kz_amqp_exchange_declare(amqp_connection_state_t state, amqp_channel_t channel,
amqp_bytes_t exchange, amqp_bytes_t type,
amqp_boolean_t passive, amqp_boolean_t durable, amqp_table_t arguments) {
#if AMQP_VERSION_MAJOR == 0 && AMQP_VERSION_MINOR < 6
return amqp_exchange_declare(state, channel, exchange, type, passive, durable, arguments);
#else
return amqp_exchange_declare(state, channel, exchange, type, passive, durable, 0, 0, arguments);
#endif
}
static char *kz_amqp_str_dup(str *src)
{
char *res;
@ -1270,7 +1281,7 @@ int kz_amqp_bind_targeted_channel(kz_amqp_conn_ptr kz_conn, int idx )
goto error;
}
amqp_exchange_declare(kz_conn->conn, channels[idx].channel, bind->exchange, bind->exchange_type, 0, 0, kz_amqp_empty_table);
kz_amqp_exchange_declare(kz_conn->conn, channels[idx].channel, bind->exchange, bind->exchange_type, 0, 0, kz_amqp_empty_table);
if (kz_amqp_error("Declaring exchange", amqp_get_rpc_reply(kz_conn->conn)))
{
ret = -RET_AMQP_ERROR;
@ -1331,7 +1342,7 @@ int kz_amqp_bind_targeted_channel_ex(kz_amqp_conn_ptr kz_conn, int loopcount, in
goto error;
}
amqp_exchange_declare(kz_conn->conn, channels[idx].channel, bind->exchange, bind->exchange_type, 0, 0, kz_amqp_empty_table);
kz_amqp_exchange_declare(kz_conn->conn, channels[idx].channel, bind->exchange, bind->exchange_type, 0, 0, kz_amqp_empty_table);
if (kz_amqp_error("Declaring exchange", amqp_get_rpc_reply(kz_conn->conn)))
{
ret = -RET_AMQP_ERROR;
@ -1379,7 +1390,7 @@ int kz_amqp_bind_consumer_ex(kz_amqp_conn_ptr kz_conn, kz_amqp_bind_ptr bind, in
goto error;
}
amqp_exchange_declare(kz_conn->conn, chan[idx].channel, bind->exchange, bind->exchange_type, 0, 0, kz_amqp_empty_table);
kz_amqp_exchange_declare(kz_conn->conn, chan[idx].channel, bind->exchange, bind->exchange_type, 0, 0, kz_amqp_empty_table);
if (kz_amqp_error("Declaring exchange", amqp_get_rpc_reply(kz_conn->conn)))
{
ret = -RET_AMQP_ERROR;
@ -1424,7 +1435,7 @@ int kz_amqp_bind_consumer(kz_amqp_conn_ptr kz_conn, kz_amqp_bind_ptr bind)
goto error;
}
amqp_exchange_declare(kz_conn->conn, channels[idx].channel, bind->exchange, bind->exchange_type, 0, 0, kz_amqp_empty_table);
kz_amqp_exchange_declare(kz_conn->conn, channels[idx].channel, bind->exchange, bind->exchange_type, 0, 0, kz_amqp_empty_table);
if (kz_amqp_error("Declaring exchange", amqp_get_rpc_reply(kz_conn->conn)))
{
ret = -RET_AMQP_ERROR;

@ -10,7 +10,7 @@ Dan Pascu
<dan@ag-projects.com>
Copyright © 2008 Dan Pascu
Copyright © 2008 Dan Pascu
__________________________________________________________________
Table of Contents
@ -139,6 +139,8 @@ Chapter 1. Admin Guide
SIP proxies may be involved in handling registration and routing and
where the incoming and outgoing paths may not necessarily be the same,
or where the routing path may even change between consecutive dialogs.
The nat_traversal functionality is built primarily for IPv4 NAT
handling and hasn't been adapted to support IPv6 session keepalives.
2. Keepalive functionality
@ -405,7 +407,7 @@ Chapter 1. Admin Guide
each endpoint will receive exactly one keepalive message. A negative
value or zero will disable the keepalive functionality.
Default value is “60”.
Default value is "60".
Example 1.1. Setting the keepalive_interval parameter
...
@ -418,7 +420,7 @@ modparam("nat_traversal", "keepalive_interval", 90)
for this purpose are NOTIFY and OPTIONS. NOTIFY generates smaller
replies from user agents, but they are almost entirely negative
replies. Apparently almost none of the user agents understand that the
purpose of the NOTIFY with a “keep-alive” event is to keep NAT open,
purpose of the NOTIFY with a "keep-alive" event is to keep NAT open,
even though many user agents send such NOTIFY requests themselves.
However this does not affect the result at all, since the purpose is to
trigger a response from the user agent behind NAT, positive or negative
@ -433,7 +435,7 @@ modparam("nat_traversal", "keepalive_interval", 90)
times bigger than negative replies or replies to NOTIFY requests. For
this reason the default value for the used method is NOTIFY.
Default value is “NOTIFY”.
Default value is "NOTIFY".
Example 1.2. Setting the keepalive_method parameter
...
@ -448,7 +450,7 @@ modparam("nat_traversal", "keepalive_method", "OPTIONS")
keepalive message, which is the same interface on which the request
that triggered keepalive functionality arrived.
Default value is “sip:keepalive@proxy_ip” with proxy_ip being the
Default value is "sip:keepalive@proxy_ip" with proxy_ip being the
actual IP of the outgoing interface.
Example 1.3. Setting the keepalive_from parameter
@ -487,7 +489,7 @@ MyHeader: some_value\r\n")
case it will store it in the Kamailio working directory, or an absolute
path.
Default value is undefined “keepalive_state”.
Default value is undefined "keepalive_state".
Example 1.5. Setting the keepalive_state_file parameter
...
@ -501,7 +503,7 @@ tate")
5.2. fix_contact()
5.3. nat_keepalive()
5.1. client_nat_test(type)
5.1. client_nat_test(type)
Check if the client is behind NAT. What tests are performed is
specified by the type parameter which is an integer given by the sum of
@ -531,7 +533,7 @@ if (client_nat_test("3")) {
}
...
5.2. fix_contact()
5.2. fix_contact()
Will replace the IP and port in the Contact header with the IP and port
the SIP message was received from. Usually called after a succesful
@ -547,7 +549,7 @@ if (client_nat_test("3")) {
}
...
5.3. nat_keepalive()
5.3. nat_keepalive()
Trigger keepalive functionality for the source address of the request.
When called it only sets some internal flags, which will trigger later

@ -29,6 +29,8 @@
SIP proxies may be involved in handling registration and routing and
where the incoming and outgoing paths may not necessarily be the same,
or where the routing path may even change between consecutive dialogs.
The nat_traversal functionality is built primarily for IPv4 NAT handling
and hasn't been adapted to support IPv6 session keepalives.
</para>
</section>

@ -24,13 +24,13 @@ Edited by
Ovidiu Sas
Copyright (c) 2003-2008 Sippy Software, Inc.
Copyright © 2003-2008 Sippy Software, Inc.
Copyright (c) 2005 Voice Sistem SRL
Copyright © 2005 Voice Sistem SRL
Copyright (c) 2009 TuTPro Inc.
Copyright © 2009 TuTPro Inc.
Copyright (c) 2010 VoIPEmbedded Inc.
Copyright © 2010 VoIPEmbedded Inc.
__________________________________________________________________
Table of Contents
@ -108,13 +108,15 @@ Ovidiu Sas
1.16. fix_nated_sdp usage
1.17. add_rcv_paramer usage
1.18. fix_nated_register usage
1.19. add_contact_alias usage
1.20. handle_ruri_alias usage
1.21. set_contact_alias usage
1.22. $rr_count usage
1.23. $rr_top_count usage
1.24. nh_enable_ping usage
1.25. @nathelper.rewrite_contact usage
1.19. nat_uac_test usage
1.20. is_rfc1918 usage
1.21. add_contact_alias usage
1.22. handle_ruri_alias usage
1.23. set_contact_alias usage
1.24. $rr_count usage
1.25. $rr_top_count usage
1.26. nh_enable_ping usage
1.27. @nathelper.rewrite_contact usage
Chapter 1. Admin Guide
@ -454,7 +456,7 @@ modparam("nathelper", "append_sdp_oldmediaip", 1)
5.8. handle_ruri_alias()
5.9. set_contact_alias()
5.1. fix_nated_contact()
5.1. fix_nated_contact()
Rewrites the "Contact" header to contain the request's source
address:port.
@ -467,7 +469,7 @@ modparam("nathelper", "append_sdp_oldmediaip", 1)
if (search("User-Agent: Cisco ATA.*") {fix_nated_contact();};
...
5.2. fix_nated_sdp(flags [, ip_address])
5.2. fix_nated_sdp(flags [, ip_address])
Alters the SDP information in orer to facilitate NAT traversal. What
changes to be performed may be controled via the "flags" parameter.
@ -497,7 +499,7 @@ if (search("User-Agent: Cisco ATA.*") {fix_nated_contact();};
if (search("User-Agent: Cisco ATA.*") {fix_nated_sdp("3");};
...
5.3. add_rcv_param([flag]),
5.3. add_rcv_param([flag]),
Add a received parameter to the "Contact" header fields or the Contact
URI. The parameter will contain the URI created from the source IP,
@ -521,7 +523,7 @@ add_rcv_param(); # add the parameter to the Contact header
add_rcv_param("1"); # add the parameter to the Contact URI
...
5.4. fix_nated_register()
5.4. fix_nated_register()
The function creates a URI consisting of the source IP, port, and
protocol and stores the URI in an Attribute-Value-Pair. The URI will be
@ -539,7 +541,7 @@ add_rcv_param("1"); # add the parameter to the Contact URI
fix_nated_register();
...
5.5. nat_uac_test(flags)
5.5. nat_uac_test(flags)
Tries to guess if client's request originated behind a nat. The
parameter determines what heuristics is used.
@ -568,14 +570,28 @@ fix_nated_register();
This function can be used from REQUEST_ROUTE, ONREPLY_ROUTE,
FAILURE_ROUTE, BRANCH_ROUTE.
5.6. is_rfc1918(ip_address)
Example 1.19. nat_uac_test usage
...
if(nat_uac_test("19")) {
rtpproxy_manage("co");
}
...
5.6. is_rfc1918(ip_address)
Determines if the address in the parameter is an rfc1918 or rfc6598
address. The parameter allows pseudo-variables usage.
This function can be used from ANY_ROUTE.
5.7. add_contact_alias([ip_addr, port, proto])
Example 1.20. is_rfc1918 usage
...
if(is_rfc1918("$rd")) {
# domain in r-uri is private address
}
...
5.7. add_contact_alias([ip_addr, port, proto])
Adds an ";alias=ip~port~transport" parameter to the contact URI
containing either received ip, port, and transport protocol or those
@ -585,7 +601,7 @@ fix_nated_register();
This function can be used from REQUEST_ROUTE, ONREPLY_ROUTE,
BRANCH_ROUTE, and LOCAL_ROUTE.
Example 1.19. add_contact_alias usage
Example 1.21. add_contact_alias usage
...
if (!is_present_hf("Record-Route")) {
if (!add_contact_alias("$var(src_ip)", "$Rp", "tcp")) {
@ -596,7 +612,7 @@ fix_nated_register();
};
...
5.8. handle_ruri_alias()
5.8. handle_ruri_alias()
Checks if the Request URI has an "alias" parameter and if so, removes
it and sets the "$du" based on its value. Note that this means that
@ -612,7 +628,7 @@ fix_nated_register();
This function can be used from REQUEST_ROUTE, BRANCH_ROUTE, and
LOCAL_ROUTE.
Example 1.20. handle_ruri_alias usage
Example 1.22. handle_ruri_alias usage
...
if ($du == "") {
handle_ruri_alias();
@ -631,7 +647,7 @@ fix_nated_register();
};
...
5.9. set_contact_alias()
5.9. set_contact_alias()
Adds an ";alias=ip~port~transport" parameter to the contact URI
containing the received ip, port, and transport protocol. The new
@ -641,7 +657,7 @@ fix_nated_register();
This function can be used from REQUEST_ROUTE, ONREPLY_ROUTE,
BRANCH_ROUTE, and FAILURE_ROUTE.
Example 1.21. set_contact_alias usage
Example 1.23. set_contact_alias usage
...
if (!is_present_hf("Record-Route")) {
if (!set_contact_alias()) {
@ -661,7 +677,7 @@ fix_nated_register();
Number of Record Routes in received SIP request or reply.
Example 1.22. $rr_count usage
Example 1.24. $rr_count usage
...
$avp(rr_count) = $rr_count;
...
@ -673,7 +689,7 @@ fix_nated_register();
value of $rr_top_count is 1. If there is no Record Route(s), value of
$rr_top_count is 0.
Example 1.23. $rr_top_count usage
Example 1.25. $rr_top_count usage
...
if ($rr_count == $avp(rr_count) + $rr_top_count) {
route(ADD_CONTACT_ALIAS);
@ -691,7 +707,7 @@ fix_nated_register();
The function takes only one parameter - a number in decimal format.
Example 1.24. nh_enable_ping usage
Example 1.26. nh_enable_ping usage
...
$ kamctl fifo nh_enable_ping 1
...
@ -706,7 +722,7 @@ $ kamctl fifo nh_enable_ping 1
counted from 1. Only IP:port is rewritten, remaining part are left
unchanged. Full nameaddr is supported.
Example 1.25. @nathelper.rewrite_contact usage
Example 1.27. @nathelper.rewrite_contact usage
...
$c = @nathelper.rewrite_contact[1];
...
@ -721,38 +737,38 @@ Chapter 2. Frequently Asked Questions
2.1.
What happend with "rtpproxy_disable" parameter?
What happend with "rtpproxy_disable" parameter?
It was removed as it became obsolete - now "rtpproxy_sock" can take
empty value to disable the rtpproxy functionality.
It was removed as it became obsolete - now "rtpproxy_sock" can take
empty value to disable the rtpproxy functionality.
2.2.
Where can I find more about Kamailio?
Where can I find more about Kamailio?
Take a look at http://www.kamailio.org/.
Take a look at http://www.kamailio.org/.
2.3.
Where can I post a question about this module?
Where can I post a question about this module?
First at all check if your question was already answered on one of our
mailing lists:
* User Mailing List -
http://lists.sip-router.org/cgi-bin/mailman/listinfo/sr-users
* Developer Mailing List -
http://lists.sip-router.org/cgi-bin/mailman/listinfo/sr-dev
First at all check if your question was already answered on one of our
mailing lists:
* User Mailing List -
http://lists.sip-router.org/cgi-bin/mailman/listinfo/sr-users
* Developer Mailing List -
http://lists.sip-router.org/cgi-bin/mailman/listinfo/sr-dev
E-mails regarding any stable Kamailio release should be sent to
<sr-users@lists.sip-router.org> and e-mails regarding development
versions should be sent to <sr-dev@lists.sip-router.org>.
E-mails regarding any stable Kamailio release should be sent to
<sr-users@lists.sip-router.org> and e-mails regarding development
versions should be sent to <sr-dev@lists.sip-router.org>.
If you want to keep the mail private, send it to
<sr-users@lists.sip-router.org>.
If you want to keep the mail private, send it to
<sr-users@lists.sip-router.org>.
2.4.
How can I report a bug?
How can I report a bug?
Please follow the guidelines provided at:
http://sip-router.org/tracker.
Please follow the guidelines provided at:
http://sip-router.org/tracker.

@ -641,6 +641,16 @@ fix_nated_register();
<para>
This function can be used from REQUEST_ROUTE, ONREPLY_ROUTE, FAILURE_ROUTE, BRANCH_ROUTE.
</para>
<example>
<title><function>nat_uac_test</function> usage</title>
<programlisting format="linespecific">
...
if(nat_uac_test("19")) {
rtpproxy_manage("co");
}
...
</programlisting>
</example>
</section>
<section id="nathelper.f.is_rfc1918">
@ -654,6 +664,16 @@ fix_nated_register();
<para>
This function can be used from ANY_ROUTE.
</para>
<example>
<title><function>is_rfc1918</function> usage</title>
<programlisting format="linespecific">
...
if(is_rfc1918("$rd")) {
# domain in r-uri is private address
}
...
</programlisting>
</example>
</section>
<section id="nathelper.f.add_contact_alias">

@ -18,9 +18,6 @@
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*
* History:
* ---------
* 2005-07-11 created (bogdan)
*/
@ -123,10 +120,23 @@ static inline char* build_sipping(str *curi, struct socket_info* s, str *path,
static char buf[MAX_SIPPING_SIZE];
char *p;
int len;
str vaddr;
str vport;
if(s->useinfo.name.len>0)
vaddr = s->useinfo.name;
else
vaddr = s->address_str;
if(s->useinfo.port_no>0)
vport = s->useinfo.port_no_str;
else
vport = s->port_no_str;
if ( sipping_method.len + 1 + curi->len + s_len(" SIP/2.0"CRLF) +
s_len("Via: SIP/2.0/UDP ") + s->address_str.len +
1 + s->port_no_str.len + s_len(";branch=0") +
s_len("Via: SIP/2.0/UDP ") + vaddr.len +
((s->address.af==AF_INET6)?2:0) +
1 + vport.len + s_len(";branch=0") +
(path->len ? (s_len(CRLF"Route: ") + path->len) : 0) +
s_len(CRLF"From: ") + sipping_from.len + s_len(";tag=") +
ruid->len + 1 + 8 + 1 + 8 +
@ -146,9 +156,15 @@ static inline char* build_sipping(str *curi, struct socket_info* s, str *path,
*(p++) = ' ';
append_str( p, curi->s, curi->len);
append_fix( p, " SIP/2.0"CRLF"Via: SIP/2.0/UDP ");
append_str( p, s->address_str.s, s->address_str.len);
if (s->address.af == AF_INET6) { /* Via header IP is a IPv6 reference */
append_fix( p, "[");
}
append_str( p, vaddr.s, vaddr.len);
if (s->address.af == AF_INET6) {
append_fix( p, "]");
}
*(p++) = ':';
append_str( p, s->port_no_str.s, s->port_no_str.len);
append_str( p, vport.s, vport.len);
if (path->len) {
append_fix( p, ";branch=0"CRLF"Route: ");
append_str( p, path->s, path->len);

@ -60,20 +60,31 @@ ucontact_t* new_ucontact(str* _dom, str* _aor, str* _contact, ucontact_info_t* _
}
memset(c, 0, sizeof(ucontact_t));
if (shm_str_dup( &c->c, _contact) < 0) goto error;
if (shm_str_dup( &c->callid, _ci->callid) < 0) goto error;
if (shm_str_dup( &c->user_agent, _ci->user_agent) < 0) goto error;
if (_contact->s && _contact->len > 0) {
if (shm_str_dup( &c->c, _contact) < 0) goto error;
}
if (_ci->received.s && _ci->received.len) {
if (_ci->callid->s && _ci->callid->len > 0) {
if (shm_str_dup( &c->callid, _ci->callid) < 0) goto error;
}
if (_ci->user_agent->s && _ci->user_agent->len > 0) {
if (shm_str_dup( &c->user_agent, _ci->user_agent) < 0) goto error;
}
if (_ci->received.s && _ci->received.len > 0) {
if (shm_str_dup( &c->received, &_ci->received) < 0) goto error;
}
if (_ci->path && _ci->path->len) {
if (_ci->path && _ci->path->len > 0) {
if (shm_str_dup( &c->path, _ci->path) < 0) goto error;
}
if (_ci->ruid.s && _ci->ruid.len) {
if (_ci->ruid.s && _ci->ruid.len > 0) {
if (shm_str_dup( &c->ruid, &_ci->ruid) < 0) goto error;
}
if (_ci->instance.s && _ci->instance.len) {
if (_ci->instance.s && _ci->instance.len > 0) {
if (shm_str_dup( &c->instance, &_ci->instance) < 0) goto error;
}

@ -124,15 +124,18 @@ static inline int ps_fill_local_contact(struct sip_msg* msg, str *contact)
goto error;
}
ip.s= ip_addr2a(&msg->rcv.dst_ip);
if(ip.s== NULL)
{
LM_ERR("transforming ip_addr to ascii\n");
goto error;
if(msg->rcv.bind_address->useinfo.name.len>0) {
ip = msg->rcv.bind_address->useinfo.name;
} else {
ip = msg->rcv.bind_address->address_str;
}
ip.len= strlen(ip.s);
port = msg->rcv.dst_port;
if(msg->rcv.bind_address->useinfo.port_no>0) {
port = msg->rcv.bind_address->useinfo.port_no;
} else {
port = msg->rcv.bind_address->port_no;
}
if(strncmp(ip.s, "sip:", 4)!=0)
{
strncpy(contact->s, "sip:", 4);

@ -34,7 +34,7 @@ static db1_con_t *rtpp_db_handle = NULL;
str rtpp_db_url = {NULL, 0};
str rtpp_table_name = str_init("rtpproxy");
str rtpp_set_name_col = str_init("set_name");
str rtpp_setid_col = str_init("setid");
str rtpp_url_col = str_init("url");
str rtpp_weight_col = str_init("weight");
str rtpp_flags_col = str_init("flags");
@ -67,7 +67,7 @@ static int rtpp_load_db(void)
db1_res_t *res = NULL;
db_val_t *values = NULL;
db_row_t *rows = NULL;
db_key_t query_cols[] = {&rtpp_set_name_col, &rtpp_url_col, &rtpp_weight_col, &rtpp_flags_col};
db_key_t query_cols[] = {&rtpp_setid_col, &rtpp_url_col, &rtpp_weight_col, &rtpp_flags_col};
str set, url;
int weight, flags;

@ -2844,6 +2844,7 @@ static int subst_hf_f(struct sip_msg *msg, char *str_hf, char *subst, char *flag
begin=body.s;
off=begin-msg->buf;
if (lst) replace_lst_free(lst);
lst=subst_run(se, begin, msg, &nmatches);
body.s[body.len] = c;
if(lst==0 && flags!=NULL && *flags=='f')
@ -2880,7 +2881,7 @@ static int subst_hf_f(struct sip_msg *msg, char *str_hf, char *subst, char *flag
}
/* if flags set for first header, then all done */
if(flags!=NULL && *flags=='f')
return ret;
goto done;
}
if(hfl!=NULL)
{
@ -2892,6 +2893,7 @@ static int subst_hf_f(struct sip_msg *msg, char *str_hf, char *subst, char *flag
begin=body.s;
off=begin-msg->buf;
if (lst) replace_lst_free(lst);
lst=subst_run(se, begin, msg, &nmatches);
body.s[body.len] = c;
if(lst==0)
@ -2924,10 +2926,11 @@ static int subst_hf_f(struct sip_msg *msg, char *str_hf, char *subst, char *flag
}
}
error:
LM_DBG("lst was %p\n", lst);
if (lst) replace_lst_free(lst);
if (nmatches<0)
LM_ERR("%s subst_run failed\n", exports.name);
LM_DBG("lst was %p\n", lst);
done:
if (lst) replace_lst_free(lst);
return ret;
}

@ -344,9 +344,11 @@ static void init_ssl_methods(void)
ssl_methods[TLS_USE_SSLv2 - 1] = SSLv2_method();
#endif
#ifndef OPENSSL_NO_SSL3_METHOD
ssl_methods[TLS_USE_SSLv3_cli - 1] = SSLv3_client_method();
ssl_methods[TLS_USE_SSLv3_srv - 1] = SSLv3_server_method();
ssl_methods[TLS_USE_SSLv3 - 1] = SSLv3_method();
#endif
ssl_methods[TLS_USE_TLSv1_cli - 1] = TLSv1_client_method();
ssl_methods[TLS_USE_TLSv1_srv - 1] = TLSv1_server_method();

@ -115,7 +115,7 @@ unsigned int transaction_count( void )
void free_cell( struct cell* dead_cell )
void free_cell_helper( struct cell* dead_cell, const char *fname, unsigned int fline )
{
char *b;
int i;
@ -123,6 +123,14 @@ void free_cell( struct cell* dead_cell )
struct totag_elem *tt, *foo;
struct tm_callback *cbs, *cbs_tmp;
LM_DBG("freeing transaction %p from %s:%u\n", dead_cell, fname, fline);
if(dead_cell->prev_c!=NULL && dead_cell->next_c!=NULL) {
LM_WARN("removed cell %p is still linked in hash table (%s:%u)\n",
dead_cell, fname, fline);
unlink_timers(dead_cell);
remove_from_hash_table_unsafe(dead_cell);
}
release_cell_lock( dead_cell );
if (unlikely(has_tran_tmcbs(dead_cell, TMCB_DESTROY)))
run_trans_callbacks(TMCB_DESTROY, dead_cell, 0, 0, 0);

@ -552,7 +552,10 @@ struct s_table* tm_get_table(void);
struct s_table* init_hash_table(void);
void free_hash_table(void);
void free_cell( struct cell* dead_cell );
void free_cell_helper( struct cell* dead_cell, const char *fname, unsigned int fline);
#define free_cell(t) free_cell_helper((t), __FILE__, __LINE__)
struct cell* build_cell( struct sip_msg* p_msg );
#ifdef TM_HASH_STATS
@ -587,6 +590,8 @@ inline static void insert_into_hash_table_unsafe( struct cell * p_cell,
inline static void remove_from_hash_table_unsafe( struct cell * p_cell)
{
clist_rm(p_cell, next_c, prev_c);
p_cell->next_c = 0;
p_cell->prev_c = 0;
# ifdef EXTRA_DEBUG
#ifdef TM_HASH_STATS
if (_tm_table->entries[p_cell->hash_index].cur_entries==0){

@ -49,6 +49,8 @@
int t_append_branches(void) {
struct cell *t = NULL;
struct sip_msg *orig_msg = NULL;
static struct sip_msg faked_req;
short outgoings;
int success_branch;
@ -62,6 +64,7 @@ int t_append_branches(void) {
int new_branch, branch_ret, lowest_ret;
branch_bm_t added_branches;
int replies_locked = 0;
int ret = 0;
t = get_t();
if(t == NULL)
@ -106,6 +109,15 @@ int t_append_branches(void) {
set_branch_route(t->on_branch_delayed);
}
if (!fake_req(&faked_req, orig_msg, 0, NULL)) {
LOG(L_ERR, "ERROR: t_append_branches: fake_req failed\n");
return -1;
}
/* fake also the env. conforming to the fake msg */
faked_env( t, &faked_req, 0);
/* DONE with faking ;-) -> run the failure handlers */
init_branch_iterator();
while((current_uri.s=next_branch( &current_uri.len, &q, &dst_uri, &path,
@ -125,10 +137,10 @@ int t_append_branches(void) {
continue;
setbflagsval(0, bflags);
new_branch=add_uac( t, orig_msg, &current_uri,
new_branch=add_uac( t, &faked_req, &current_uri,
(dst_uri.len) ? (&dst_uri) : &current_uri,
&path, 0, si, orig_msg->fwd_send_flags,
PROTO_NONE, (dst_uri.len)?-1:UAC_SKIP_BR_DST_F, &instance,
&path, 0, si, faked_req.fwd_send_flags,
PROTO_NONE, (dst_uri.len)?0:UAC_SKIP_BR_DST_F, &instance,
&ruid, &location_ua);
LM_DBG("added branch [%.*s] with ruid [%.*s]\n", current_uri.len, current_uri.s, ruid.len, ruid.s);
@ -149,15 +161,14 @@ int t_append_branches(void) {
setbflagsval(0, backup_bflags);
/* update message flags, if changed in branch route */
t->uas.request->flags = orig_msg->flags;
t->uas.request->flags = faked_req.flags;
if (added_branches==0) {
if(lowest_ret!=E_CFG)
LOG(L_ERR, "ERROR: t_append_branch: failure to add branches\n");
LOG(L_ERR, "ERROR: t_append_branch: failure to add branches (%d)\n", lowest_ret);
ser_error=lowest_ret;
replies_locked = 0;
UNLOCK_REPLIES(t);
return lowest_ret;
ret = lowest_ret;
goto done;
}
ser_error=0; /* clear branch adding errors */
@ -167,14 +178,14 @@ int t_append_branches(void) {
for (i=outgoings; i<t->nr_of_outgoings; i++) {
if (added_branches & (1<<i)) {
branch_ret=t_send_branch(t, i, orig_msg , 0, 0 /* replies are already locked */ );
branch_ret=t_send_branch(t, i, &faked_req , 0, 0 /* replies are already locked */ );
if (branch_ret>=0){ /* some kind of success */
if (branch_ret==i) { /* success */
success_branch++;
if (unlikely(has_tran_tmcbs(t, TMCB_REQUEST_OUT)))
run_trans_callbacks_with_buf( TMCB_REQUEST_OUT,
&t->uac[nr_branches].request,
orig_msg, 0, -orig_msg->REQ_METHOD);
&faked_req, 0, -orig_msg->REQ_METHOD);
}
else /* new branch added */
added_branches |= 1<<branch_ret;
@ -188,17 +199,14 @@ int t_append_branches(void) {
* when attempting dns failover) */
ser_error=E_SEND;
/* else return the last error (?) */
/* the caller should take care and delete the transaction */
replies_locked = 0;
UNLOCK_REPLIES(t);
return -1;
ret = -1;
goto done;
}
ser_error=0; /* clear branch send errors, we have overall success */
set_kr(REQ_FWDED);
replies_locked = 0;
UNLOCK_REPLIES(t);
return 1;
ret = success_branch;
goto done;
canceled:
DBG("t_append_branches: cannot append branches to a canceled transaction\n");
@ -207,15 +215,20 @@ canceled:
/* restore backup flags from initial env */
setbflagsval(0, backup_bflags);
/* update message flags, if changed in branch route */
t->uas.request->flags = orig_msg->flags;
/* if needed unlock transaction's replies */
t->uas.request->flags = faked_req.flags;
/* restore the number of outgoing branches
* since new branches have not been completed */
t->nr_of_outgoings = outgoings;
ser_error=E_CANCELED;
ret = -1;
done:
/* restore original environment and free the fake msg */
faked_env( t, 0, 0);
free_faked_req(&faked_req,t);
if (likely(replies_locked)) {
/* restore the number of outgoing branches
* since new branches have not been completed */
t->nr_of_outgoings = outgoings;
replies_locked = 0;
UNLOCK_REPLIES(t);
}
ser_error=E_CANCELED;
return -1;
return ret;
}

@ -37,6 +37,36 @@
#include "t_hooks.h"
typedef struct cancel_reason_map {
int code;
str text;
} cancel_reason_map_t;
static cancel_reason_map_t _cancel_reason_map[] = {
{ 200, str_init("Answered elsewhere") },
{ 0, {0, 0} }
};
/**
*
*/
void cancel_reason_text(struct cancel_info* cancel_data)
{
int i;
if(cancel_data->reason.cause<=0
|| cancel_data->reason.u.text.s!=NULL) return;
for(i=0; _cancel_reason_map[i].text.s!=0; i++) {
if(_cancel_reason_map[i].code==cancel_data->reason.cause) {
cancel_data->reason.u.text = _cancel_reason_map[i].text;
return;
}
}
return;
}
/** Prepare to cancel a transaction.
* Determine which branches should be canceled and prepare them (internally
* mark them as "cancel in progress", see prepare_cancel_branch()).
@ -87,6 +117,9 @@ int cancel_uacs( struct cell *t, struct cancel_info* cancel_data, int flags)
int r;
ret=0;
cancel_reason_text(cancel_data);
/* cancel pending client transactions, if any */
for( i=0 ; i<t->nr_of_outgoings ; i++ )
if (cancel_data->cancel_bitmap & (1<<i)){

@ -1568,7 +1568,7 @@ int t_lookup_ident(struct cell ** trans, unsigned int hash_index,
prefetch_loc_r(p_cell->next_c, 1);
if(p_cell->label == label){
REF_UNSAFE(p_cell);
UNLOCK_HASH(hash_index);
UNLOCK_HASH(hash_index);
set_t(p_cell, T_BR_UNDEFINED);
*trans=p_cell;
DBG("DEBUG: t_lookup_ident: transaction found\n");

@ -319,7 +319,7 @@ static cmd_export_t cmds[]={
#endif
{"t_replicate", w_t_replicate_uri, 0, 0,
REQUEST_ROUTE},
{"t_replicate", w_t_replicate_uri, 1, fixup_var_str_1,
{"t_replicate", w_t_replicate_uri, 1, fixup_spve_null,
REQUEST_ROUTE},
{"t_replicate", w_t_replicate, 2, fixup_hostport2proxy,
REQUEST_ROUTE},

@ -49,9 +49,9 @@ int ts_append(struct sip_msg* msg, str *ruri, char *table) {
if (res != 0) {
LM_ERR("failed to retrieve record for %.*s\n", ruri->len, ruri->s);
unlock_entry_by_ruri(ruri);
return -1;
}
unlock_entry_by_ruri(ruri);
return -1;
}
ptr = _r->transactions;
@ -68,24 +68,32 @@ int ts_append(struct sip_msg* msg, str *ruri, char *table) {
int ts_append_to(struct sip_msg* msg, int tindex, int tlabel, char *table) {
struct cell *t;
struct cell *orig_t;
struct sip_msg *orig_msg;
int ret;
orig_t = _tmb.t_gett();
if(_tmb.t_lookup_ident(&t, tindex, tlabel) < 0)
{
LM_ERR("transaction [%u:%u] not found\n",
tindex, tlabel);
return -1;
ret = -1;
goto done;
}
if (t->flags & T_CANCELED) {
LM_DBG("trasaction [%u:%u] was cancelled\n",
tindex, tlabel);
return -2;
ret = -2;
goto done;
}
if (t->uas.status >= 200) {
LM_DBG("trasaction [%u:%u] sent out a final response already - %d\n",
tindex, tlabel, t->uas.status);
return -3;
ret = -3;
goto done;
}
orig_msg = t->uas.request;
@ -93,8 +101,17 @@ int ts_append_to(struct sip_msg* msg, int tindex, int tlabel, char *table) {
ret = _regapi.lookup_to_dset(orig_msg, table, NULL);
if(ret != 1) {
LM_DBG("transaction %u:%u: error updating dset (%d)\n", tindex, tlabel, ret);
return -4;
ret = -4;
goto done;
}
return _tmb.t_append_branches();
ret = _tmb.t_append_branches();
done:
/* unref the transaction which had been referred by t_lookup_ident() call.
* Restore the original transaction (if any) */
_tmb.unref_cell(t);
_tmb.t_sett(orig_t, T_BR_UNDEFINED);
return ret;
}

@ -128,6 +128,22 @@ static inline int decode_uri( str *src , str *dst)
int i,j;
signed char c;
/* sanity checks */
if (!src) {
LM_ERR("NULL src\n");
return -1;
}
if (!dst) {
LM_ERR("NULL dst\n");
return -1;
}
if (!src->s || src->len == 0) {
LM_ERR("empty src\n");
return -1;
}
/* Count '-' at end and disregard them */
for( n=0,i=src->len-1; src->s[i]=='-'; i--)
n++;

@ -1747,7 +1747,7 @@ static void rpc_uac_reg_refresh(rpc_t* rpc, void* ctx)
}
rpc_export_t uac_reg_rpc[] = {
{"uac.reg_dump", rpc_uac_reg_dump, rpc_uac_reg_dump_doc, 0},
{"uac.reg_dump", rpc_uac_reg_dump, rpc_uac_reg_dump_doc, RET_ARRAY},
{"uac.reg_info", rpc_uac_reg_info, rpc_uac_reg_info_doc, 0},
{"uac.reg_enable", rpc_uac_reg_enable, rpc_uac_reg_enable_doc, 0},
{"uac.reg_disable", rpc_uac_reg_disable, rpc_uac_reg_disable_doc, 0},

@ -680,7 +680,8 @@ int db_insert_ucontact(ucontact_t* _c)
}
if (ul_dbf.insert(ul_dbh, keys, vals, nr_cols) < 0) {
LM_ERR("inserting contact in db failed\n");
LM_ERR("inserting contact in db failed %.*s (%.*s)\n",
_c->aor->len, ZSW(_c->aor->s), _c->ruid.len, ZSW(_c->ruid.s));
return -1;
}

@ -609,7 +609,7 @@ urecord_t* db_load_urecord(db1_con_t* _c, udomain_t* _d, str *_aor)
return 0;
}
if (ul_dbf.query(_c, keys, 0, vals, columns, (use_domain)?2:1, 16, order,
if (ul_dbf.query(_c, keys, 0, vals, columns, (use_domain)?2:1, 19, order,
&res) < 0) {
LM_ERR("db_query failed\n");
return 0;
@ -793,7 +793,7 @@ urecord_t* db_load_urecord_by_ruid(db1_con_t* _c, udomain_t* _d, str *_ruid)
return 0;
}
if (ul_dbf.query(_c, keys, 0, vals, columns, 1, 18, order,
if (ul_dbf.query(_c, keys, 0, vals, columns, 1, 21, order,
&res) < 0) {
LM_ERR("db_query failed\n");
return 0;

@ -252,7 +252,6 @@ static inline int close_connection(int conid) {
msg[1] = CONN_EOF;
n = send_all(unix_tcp_sock, msg, sizeof(msg));
tcpconn_put(con);
if (unlikely(n <= 0)){
LM_ERR("failed to send close request: %s (%d)\n", strerror(errno), errno);
return 0;

@ -534,7 +534,7 @@ error:
* 0: success, but expect a next paramter
* 1: success and exepect no more parameters
*/
inline int parse_param(str *_s, pclass_t _c, param_hooks_t *_h, param_t *t)
int parse_param(str *_s, pclass_t _c, param_hooks_t *_h, param_t *t)
{
return parse_param2(_s, _c, _h, t, ';');
}

@ -143,7 +143,7 @@ typedef union param_hooks {
* 0: success, but expect a next paramter
* 1: success and exepect no more parameters
*/
extern inline int parse_param(str *_s, pclass_t _c, param_hooks_t *_h, param_t *t);
extern int parse_param(str *_s, pclass_t _c, param_hooks_t *_h, param_t *t);
/*! \brief

@ -1,5 +1,5 @@
%define name kamailio
%define ver 4.3.3
%define ver 4.3.4
%define rel 0.0%{dist}

@ -1,3 +1,9 @@
kamailio (4.3.4) UNRELEASED; urgency=medium
* update version to 4.3.4
-- Victor Seva <linuxmaniac@torreviejawireless.org> Wed, 25 Nov 2015 13:52:54 +0100
kamailio (4.3.3) unstable; urgency=medium
* update version to 4.3.3

@ -1,3 +1,9 @@
kamailio (4.3.4) UNRELEASED; urgency=medium
* update version to 4.3.4
-- Victor Seva <linuxmaniac@torreviejawireless.org> Wed, 25 Nov 2015 13:52:54 +0100
kamailio (4.3.3) unstable; urgency=medium
* update version to 4.3.3

@ -1,3 +1,9 @@
kamailio (4.3.4) UNRELEASED; urgency=medium
* update version to 4.3.4
-- Victor Seva <linuxmaniac@torreviejawireless.org> Wed, 25 Nov 2015 13:52:54 +0100
kamailio (4.3.3) unstable; urgency=medium
* update version to 4.3.3

@ -1,3 +1,9 @@
kamailio (4.3.4) UNRELEASED; urgency=medium
* update version to 4.3.4
-- Victor Seva <linuxmaniac@torreviejawireless.org> Wed, 25 Nov 2015 13:52:54 +0100
kamailio (4.3.3) unstable; urgency=medium
* update version to 4.3.3

@ -1,3 +1,9 @@
kamailio (4.3.4) UNRELEASED; urgency=medium
* update version to 4.3.4
-- Victor Seva <linuxmaniac@torreviejawireless.org> Wed, 25 Nov 2015 13:52:54 +0100
kamailio (4.3.3) unstable; urgency=medium
* update version to 4.3.3

@ -1,3 +1,9 @@
kamailio (4.3.4) UNRELEASED; urgency=medium
* update version to 4.3.4
-- Victor Seva <linuxmaniac@torreviejawireless.org> Wed, 25 Nov 2015 13:52:54 +0100
kamailio (4.3.3) unstable; urgency=medium
* update version to 4.3.3

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

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

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

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

11
pt.c

@ -528,8 +528,15 @@ void mem_dump_pkg_cb(str *gname, str *name)
possible race with a parallel cfg_set */
((struct cfg_group_core*)core_cfg)->memlog=memlog;
LOG(memlog, "Memory status (pkg) of process %d:\n", my_pid());
pkg_status();
if (cfg_get(core, core_cfg, mem_summary) & 1) {
LOG(memlog, "Memory status (pkg) of process %d:\n", my_pid());
pkg_status();
}
if (cfg_get(core, core_cfg, mem_summary) & 4) {
LOG(memlog, "Memory still-in-use summary (pkg) of process %d:\n",
my_pid());
pkg_sums();
}
((struct cfg_group_core*)core_cfg)->memlog=old_memlog;
}

@ -268,14 +268,19 @@ again:
}
}
LOG(cfg_get(core, core_cfg, corelog),
"error reading: %s (%d)\n", strerror(errno), errno);
"error reading: %s (%d) ([%s]:%u -> [%s]:%u)\n",
strerror(errno), errno,
ip_addr2a(&c->rcv.src_ip), c->rcv.src_port,
ip_addr2a(&c->rcv.dst_ip), c->rcv.dst_port);
return -1;
}
}else if (unlikely((bytes_read==0) ||
(*flags & RD_CONN_FORCE_EOF))){
c->state=S_CONN_EOF;
*flags|=RD_CONN_EOF;
LM_DBG("EOF on %p, FD %d\n", c, fd);
LM_DBG("EOF on %p, FD %d ([%s]:%u -> [%s]:%u)\n", c, fd,
ip_addr2a(&c->rcv.src_ip), c->rcv.src_port,
ip_addr2a(&c->rcv.dst_ip), c->rcv.dst_port);
}else{
if (unlikely(c->state==S_CONN_CONNECT || c->state==S_CONN_ACCEPT)){
TCP_STATS_ESTABLISHED(c->state);
@ -319,7 +324,9 @@ int tcp_read(struct tcp_connection *c, int* flags)
bytes_free=r->b_size- (int)(r->pos - r->buf);
if (unlikely(bytes_free==0)){
LM_ERR("buffer overrun, dropping\n");
LM_ERR("buffer overrun, dropping ([%s]:%u -> [%s]:%u)\n",
ip_addr2a(&c->rcv.src_ip), c->rcv.src_port,
ip_addr2a(&c->rcv.dst_ip), c->rcv.dst_port);
r->error=TCP_REQ_OVERRUN;
return -1;
}
@ -507,7 +514,7 @@ int tcp_read_headers(struct tcp_connection *c, int* read_flags)
p++;
goto skip;
} else {
LM_DBG("ERROR: no clen, p=%X\n", *p);
LM_DBG("no clen, p=%X\n", *p);
r->error=TCP_REQ_BAD_LEN;
}
}
@ -579,7 +586,7 @@ int tcp_read_headers(struct tcp_connection *c, int* read_flags)
p++;
goto skip;
} else {
LM_DBG("ERROR: no clen, p=%X\n", *p);
LM_DBG("no clen, p=%X\n", *p);
r->error=TCP_REQ_BAD_LEN;
}
}
@ -1367,7 +1374,9 @@ again:
init_dst_from_rcv(&dst, &con->rcv);
if (tcp_send(&dst, 0, CRLF, CRLF_LEN) < 0) {
LM_ERR("CRLF ping: tcp_send() failed\n");
LM_ERR("CRLF ping: tcp_send() failed ([%s]:%u -> [%s]:%u)\n",
ip_addr2a(&con->rcv.src_ip), con->rcv.src_port,
ip_addr2a(&con->rcv.dst_ip), con->rcv.dst_port);
}
ret = 0;
} else if (unlikely(req->state==H_STUN_END)) {
@ -1428,7 +1437,9 @@ again:
/*if we still have some unparsed bytes, try to parse them too*/
goto again;
} else if (unlikely(con->state==S_CONN_EOF)){
LM_DBG("EOF after reading complete request\n");
LM_DBG("EOF after reading complete request ([%s]:%u -> [%s]:%u)\n",
ip_addr2a(&con->rcv.src_ip), con->rcv.src_port,
ip_addr2a(&con->rcv.dst_ip), con->rcv.dst_port);
resp=CONN_EOF;
}
req->parsed=req->buf; /* fix req->parsed */
@ -1446,8 +1457,10 @@ void release_tcpconn(struct tcp_connection* c, long state, int unix_sock)
{
long response[2];
LM_DBG("releasing con %p, state %ld, fd=%d, id=%d\n",
c, state, c->fd, c->id);
LM_DBG("releasing con %p, state %ld, fd=%d, id=%d ([%s]:%u -> [%s]:%u)\n",
c, state, c->fd, c->id,
ip_addr2a(&c->rcv.src_ip), c->rcv.src_port,
ip_addr2a(&c->rcv.dst_ip), c->rcv.dst_port);
LM_DBG("extra_data %p\n", c->extra_data);
/* release req & signal the parent */
c->reader_pid=0; /* reset it */
@ -1479,8 +1492,11 @@ static ticks_t tcpconn_read_timeout(ticks_t t, struct timer_ln* tl, void* data)
/* if conn->state is ERROR or BAD => force timeout too */
if (unlikely(io_watch_del(&io_w, c->fd, -1, IO_FD_CLOSING)<0)){
LM_ERR("io_watch_del failed for %p"
" id %d fd %d, state %d, flags %x, main fd %d\n",
c, c->id, c->fd, c->state, c->flags, c->s);
" id %d fd %d, state %d, flags %x, main fd %d"
" ([%s]:%u -> [%s]:%u)\n",
c, c->id, c->fd, c->state, c->flags, c->s,
ip_addr2a(&c->rcv.src_ip), c->rcv.src_port,
ip_addr2a(&c->rcv.dst_ip), c->rcv.dst_port);
}
tcpconn_listrm(tcp_conn_lst, c, c_next, c_prev);
release_tcpconn(c, (c->state<0)?CONN_ERROR:CONN_RELEASE, tcpmain_sock);
@ -1594,9 +1610,11 @@ repeat_1st_read:
S_TO_TICKS(TCP_CHILD_TIMEOUT), t);
if (unlikely(io_watch_add(&io_w, s, POLLIN, F_TCPCONN, con)<0)){
LM_CRIT("io_watch_add failed for %p id %d fd %d, state %d, flags %x,"
" main fd %d, refcnt %d\n",
" main fd %d, refcnt %d ([%s]:%u -> [%s]:%u)\n",
con, con->id, con->fd, con->state, con->flags,
con->s, atomic_get(&con->refcnt));
con->s, atomic_get(&con->refcnt),
ip_addr2a(&con->rcv.src_ip), con->rcv.src_port,
ip_addr2a(&con->rcv.dst_ip), con->rcv.dst_port);
tcpconn_listrm(tcp_conn_lst, con, c_next, c_prev);
local_timer_del(&tcp_reader_ltimer, &con->timer);
goto con_error;
@ -1628,9 +1646,12 @@ read_error:
if (unlikely(io_watch_del(&io_w, con->fd, idx,
IO_FD_CLOSING) < 0)){
LM_CRIT("io_watch_del failed for %p id %d fd %d,"
" state %d, flags %x, main fd %d, refcnt %d\n",
" state %d, flags %x, main fd %d, refcnt %d"
" ([%s]:%u -> [%s]:%u)\n",
con, con->id, con->fd, con->state,
con->flags, con->s, atomic_get(&con->refcnt));
con->flags, con->s, atomic_get(&con->refcnt),
ip_addr2a(&con->rcv.src_ip), con->rcv.src_port,
ip_addr2a(&con->rcv.dst_ip), con->rcv.dst_port);
}
tcpconn_listrm(tcp_conn_lst, con, c_next, c_prev);
local_timer_del(&tcp_reader_ltimer, &con->timer);
@ -1696,7 +1717,7 @@ void tcp_receive_loop(int unix_sock)
goto error;
/* add the unix socket */
if (io_watch_add(&io_w, tcpmain_sock, POLLIN, F_TCPMAIN, 0)<0){
LM_CRIT("failed to add socket to the fd list\n");
LM_CRIT("failed to add tcp main socket to the fd list\n");
goto error;
}

@ -28,7 +28,7 @@
#ifdef TLS_HOOKS
struct tls_hooks tls_hook= {0,0,0,0,0,0,0,0};
struct tls_hooks tls_hook= {0};
static int tls_hooks_loaded=0;

92
ut.h

@ -170,8 +170,7 @@ static char fourbits2char[16] = { '0', '1', '2', '3', '4', '5',
/* converts a str to an u. short, returns the u. short and sets *err on
* error and if err!=null
*/
static inline unsigned short str2s(const char* s, unsigned int len,
int *err)
static inline unsigned short str2s(const char* s, unsigned int len, int *err)
{
unsigned short ret;
int i;
@ -619,6 +618,10 @@ static inline void strlower(str* _s)
{
int i;
if (_s == NULL) return ;
if (_s->len < 0) return ;
if (_s->s == NULL) return ;
for(i = 0; i < _s->len; i++) {
_s->s[i] = tolower(_s->s[i]);
}
@ -631,7 +634,12 @@ static inline void strlower(str* _s)
static inline int str2int(str* _s, unsigned int* _r)
{
int i;
if (_s == NULL) return -1;
if (_r == NULL) return -1;
if (_s->len < 0) return -1;
if (_s->s == NULL) return -1;
*_r = 0;
for(i = 0; i < _s->len; i++) {
if ((_s->s[i] >= '0') && (_s->s[i] <= '9')) {
@ -641,7 +649,7 @@ static inline int str2int(str* _s, unsigned int* _r)
return -1;
}
}
return 0;
}
@ -653,7 +661,10 @@ static inline int str2sint(str* _s, int* _r)
int i;
int sign;
if (_s->len == 0) return -1;
if (_s == NULL) return -1;
if (_r == NULL) return -1;
if (_s->len < 0) return -1;
if (_s->s == NULL) return -1;
*_r = 0;
sign = 1;
@ -688,14 +699,41 @@ static inline int str2sint(str* _s, int* _r)
*/
static inline int shm_str_dup(str* dst, const str* src)
{
dst->s = (char*)shm_malloc(src->len);
if (!dst->s) {
/* NULL checks */
if (dst == NULL || src == NULL) {
LM_ERR("NULL src or dst\n");
return -1;
}
/**
* fallback actions:
* - dst->len=0
* - dst->s is allocated sizeof(void*) size
* - return 0 (i.e. success)
*/
/* fallback checks */
if (src->len < 0 || src->s == NULL) {
LM_WARN("shm_str_dup fallback; dup called for src->s == NULL or src->len < 0\n");
dst->len = 0;
} else {
dst->len = src->len;
}
dst->s = (char*)shm_malloc(dst->len);
if (dst->s == NULL) {
SHM_MEM_ERROR;
return -1;
}
memcpy(dst->s, src->s, src->len);
dst->len = src->len;
/* avoid memcpy from NULL source - undefined behaviour */
if (src->s == NULL) {
LM_WARN("shm_str_dup fallback; skip memcpy for src->s == NULL\n");
return 0;
}
memcpy(dst->s, src->s, dst->len);
return 0;
}
#endif /* SHM_MEM */
@ -710,15 +748,41 @@ static inline int shm_str_dup(str* dst, const str* src)
*/
static inline int pkg_str_dup(str* dst, const str* src)
{
dst->s = (char*)pkg_malloc(src->len);
if (dst->s==NULL)
{
/* NULL checks */
if (dst == NULL || src == NULL) {
LM_ERR("NULL src or dst\n");
return -1;
}
/**
* fallback actions:
* - dst->len=0
* - dst->s is allocated sizeof(void*) size
* - return 0 (i.e. success)
*/
/* fallback checks */
if (src->len < 0 || src->s == NULL) {
LM_WARN("pkg_str_dup fallback; dup called for src->s == NULL or src->len < 0\n");
dst->len = 0;
} else {
dst->len = src->len;
}
dst->s = (char*)pkg_malloc(dst->len);
if (dst->s == NULL) {
PKG_MEM_ERROR;
return -1;
}
memcpy(dst->s, src->s, src->len);
dst->len = src->len;
/* avoid memcpy from NULL source - undefined behaviour */
if (src->s == NULL) {
LM_WARN("pkg_str_dup fallback; skip memcpy for src->s == NULL\n");
return 0;
}
memcpy(dst->s, src->s, dst->len);
return 0;
}

@ -1583,15 +1583,15 @@ cr() {
### DISPATCHER management
#
dispatcher() {
require_dbengine
require_ctlengine
case $1 in
show)
require_dbengine
mecho "dispatcher gateways"
QUERY="select * FROM $DISPATCHER_TABLE ORDER BY $DISPATCHER_SETID_COLUMN; "
$DBROCMD "$QUERY"
;;
addgw|add)
require_dbengine
shift
if [ $# -lt 2 ] ; then
merr "too few parameters"
@ -1638,6 +1638,7 @@ dispatcher() {
;;
rmgw|rm)
require_dbengine
shift
if [ $# -ne 1 ] ; then
merr "missing gateway id to be removed"
@ -1654,10 +1655,12 @@ dispatcher() {
;;
reload)
require_ctlengine
$CTLCMD ds_reload
;;
dump)
require_ctlengine
$CTLCMD ds_list
;;

@ -16,12 +16,12 @@ TEST="false"
### include resource files, if any
# check for rc file at same location with kamdbctl
which greadlink > /dev/null
which greadlink > /dev/null 2>&1
ret=$?
if [ $ret -eq 0 ] ; then
KAMCTLFULLPATH=$(greadlink -f "$0")
else
which readlink > /dev/null
which readlink > /dev/null 2>&1
ret=$?
if [ $ret -eq 0 ] ; then
KAMCTLFULLPATH=$(readlink -f "$0")

Loading…
Cancel
Save