merge with upstream 3.3.2

remotes/origin/3.3+ngcp2.6
Jon Bonilla 14 years ago
parent dfeac6e182
commit cada7f70ee

@ -1,3 +1,861 @@
===================== 2012-10-16 Version 3.3.2 Released =====================
===================== Changes Since Version 3.3.1 ===========================
commit f707dcf308ea5166a7a8f6454103871b2f328311
Author: Daniel-Constantin Mierla <miconda@gmail.com>
Date: Tue Oct 16 16:22:39 2012 +0200
Makefile.defs: version set to 3.3.2
commit a956fe20290a8da8049df0f11f18f8207f83e58e
Author: Daniel-Constantin Mierla <miconda@gmail.com>
Date: Tue Oct 16 16:19:23 2012 +0200
pkg/rpm: version set to 3.3.2 for rpm specs
commit 48eb53ee1eae2cc5c2dad61350941e45f500f219
Author: Daniel-Constantin Mierla <miconda@gmail.com>
Date: Tue Oct 16 16:17:38 2012 +0200
pkg/deb: version set to 3.3.2 for deb specs
commit 47b544d4e0fe40c683566d9ffce54cc761a1eee1
Author: Dragos Dinu <dragos.dinu@1and1.ro>
Date: Mon Oct 15 18:29:48 2012 +0300
modules_k/siptrace Fixed crash when using HEP v2
(cherry picked from commit 5d9d4d017d79d4e9269bbeb019460b3c8d8695d0)
commit 35c1a5fb75c52f1adcdf4c3938530751b63a2007
Author: Olle E. Johansson <oej@edvina.net>
Date: Mon Oct 15 14:35:10 2012 +0200
INSTALL - Fixing spelling error
commit d75cb5fab10efdedbe9ec3aeaaafc84c1c6b051e
Author: Andrei Pelinescu-Onciul <andrei@iptel.org>
Date: Wed Oct 10 10:02:00 2012 +0200
tcp: fix connection alias replacing
When the TCP_ALIAS_REPLACE is set and an alias has to be added to
a connection that had 0 aliases (it can happen due to
TCP_ALIAS_REPLACE flag), the connection aliases count was wrongly
forced to 1.
For more details see:
http://lists.sip-router.org/pipermail/sr-users/2012-October/074932.html
Patch-by Jijo
(cherry picked from commit e71435b0276c89ef756fecf1bbd5e339b80e804c)
commit 5f505e26b92380b08ec2bb2865f2c1b212d2b054
Author: Daniel-Constantin Mierla <miconda@gmail.com>
Date: Tue Oct 9 16:30:24 2012 +0200
core: reset params pointers if there is a failure in parse_params()
- patch by Jijo
(cherry picked from commit b12c2df6ccb903e2ca22d34bb968f3ebc2712b89)
commit 14f091d03fc3d58cd5753719eb909d2e84aac6bf
Author: Daniel-Constantin Mierla <miconda@gmail.com>
Date: Tue Oct 9 12:29:09 2012 +0200
tm: set log level to debug for negative return code of run_top_route()
- it returns the code of last execution action, negative return is not
necessary an error
(cherry picked from commit 038780fdf40c8d5d3694538f199411810fad7a0e)
commit 94affa45a18c4c6b34341808011952b5e71d9438
Author: Daniel-Constantin Mierla <miconda@gmail.com>
Date: Tue Oct 9 11:39:16 2012 +0200
rtpproxy: safety check for rtp stats pv
- if the rtpproxy is not responding, there is no returned value and
could cause crash when doing strlen(NULL)
- return $null in case of various errors, being safer to check returned
PV value in the script against $null, rather than having undefined
value
- reported by J. Gallart
(cherry picked from commit 753f511f281b0f4406908086547225c5c0bc0d23)
commit 57005251e00d3b2e44fdba2dd1018c2b9780461d
Author: Daniel-Constantin Mierla <miconda@gmail.com>
Date: Tue Oct 9 09:13:15 2012 +0200
msrp: fixed copy&paste issue for getting To-Path size
- the parsing of From-Path was used instead
- reported by Peter Dunkley
(cherry picked from commit 146873cf2b101d6363bb20c235b7dcdb8bb54134)
commit c6f98a04cde334f5f73bd2ee69c2d696c6a09df9
Author: Daniel-Constantin Mierla <miconda@gmail.com>
Date: Wed Oct 3 14:20:27 2012 +0200
mem: fixed MDBG() parameters
- log level is not necessary for this macro
(cherry picked from commit 0193d296e39a9fc095e90682f5335a2907403474)
commit 0d5c3543eea3e48ce4f7fb92e99d3262fddef180
Author: Juha Heinanen <jh@tutpro.com>
Date: Wed Oct 3 09:27:38 2012 +0300
mem/f_malloc.c: downgraded print free(0) warning from LOG to MDBG.
(cherry picked from commit 7b6234a3e8d0427c767942327aff57ade676eb5e)
commit 35fa70d06b08d2e11fcd4b208d741310f6b60c89
Author: Daniel-Constantin Mierla <miconda@gmail.com>
Date: Tue Oct 2 21:24:09 2012 +0200
mem: enhanced the warning message for free(0) of QM in debug mode
(cherry picked from commit 41fa8653157a989ed1a77f72b25a20fd984b999d)
commit 074faa8da935de1977b504e7d052fdfe0030fc0f
Author: Daniel-Constantin Mierla <miconda@gmail.com>
Date: Fri Sep 28 14:38:42 2012 +0200
app_mono: fixed c&p typo names in examples
(cherry picked from commit f71d76c0f39f2c6b0e070e1246f371f17b45b2dd)
commit 444cb9836725441dc7245310d52898c0965deeba
Author: Daniel-Constantin Mierla <miconda@gmail.com>
Date: Thu Sep 27 14:57:51 2012 +0200
core/mem: moved safety check for null before range check in *free()
- affects only when memory debug is enabled at compilation
- apparently libssl has some free(0) which makes it not possible to work
with memory debugging (reported on irc channel)
(cherry picked from commit 927a8a1aa705438d210fc244066a8c5a5b84a746)
commit b36939476280d38464a4c0ff234a4d26fdd0306c
Author: Daniel-Constantin Mierla <miconda@gmail.com>
Date: Wed Sep 26 00:18:49 2012 +0200
registrar(k): some contact attributes were not in $ulc(...)
- ruid, reg-id and instance were not returned by $ulc(...)
(cherry picked from commit 20c436df0c81b38777052b4ba6fb425577f5c707)
commit bae37685f2d145f86f1387eb4777ad38e86d188d
Author: Daniel-Constantin Mierla <miconda@gmail.com>
Date: Tue Sep 25 13:52:05 2012 +0200
utils/misc: few updates to vim syntax highlighting
(cherry picked from commit 7943249ea75d8103d1364bcb4b6a63a2e685e88a)
commit f2ba2bfe5721060221e71294728a0921d65db53e
Author: Daniel-Constantin Mierla <miconda@gmail.com>
Date: Tue Sep 25 11:31:17 2012 +0200
sanity: fix to parameter type in example
(cherry picked from commit 779addb9df44434448f78ab17d2daa756d31d3c0)
commit 33e935c378a0ce3c09df22611ffbf0460e154471
Author: Daniel-Constantin Mierla <miconda@gmail.com>
Date: Fri Sep 21 09:44:21 2012 +0200
topoh: use L_DBG instead of L_ERR for some debugging messages
- reported by Miguel Baptista
(cherry picked from commit e8501b8eb592fa799af1fd1cfba8fa628cbfa800)
commit 929cd2e0dbd542d0eff63ad7179e438cd53bc45c
Author: Daniel-Constantin Mierla <miconda@gmail.com>
Date: Tue Sep 18 09:27:38 2012 +0200
pkg/kamailio/rpm: fixed copy&paste error for PKG_MEMORY size
(cherry picked from commit 9430ee8d313ece9c97384868ee7623c0979028f5)
commit 5c313f701968b328adc6b7d76a14b78446dc2986
Author: Daniel-Constantin Mierla <miconda@gmail.com>
Date: Tue Sep 18 09:18:52 2012 +0200
pkg/kamailio/rpm: added option to set pkg memory size for init.d script
- split of MEMORY parameter to SHM_MEMORY and PKG_MEMORY
- EXTRA_OPTIONS variable to add other command line parameters
(cherry picked from commit 9430290ad91ca775bb18f54e70308917ce1e790a)
commit f5df3a25096d01ac36eec77e61af958e9d33b3d2
Author: Marius Zbihlei <marius.zbihlei@1and1.ro>
Date: Mon Sep 17 17:34:57 2012 +0300
core:parser fix possible bug in msg_parser
If buffer was NULL, tmp was returned uninitialized, thus possible to cause problems
(cherry picked from commit cccdaead04411175c46dd660c91c037c45f80c33)
commit dc4b47f8ef20e3ee6e3d16809ca76261bc96966d
Author: Jason Penton <jason.penton@smilecoms.com>
Date: Mon Sep 17 10:55:48 2012 +0200
benchmark: fixed bug/typo in calculating time diff ;)
(cherry picked from commit d9b009ef3c430f6ea064b4a72d5b94ce842ede1d)
commit 37e67bec10e872fec3cc0dc4ef73b7f100d9f77a
Author: Daniel-Constantin Mierla <miconda@gmail.com>
Date: Tue Sep 11 08:52:53 2012 +0200
kex: documented mi statistics commands
- reported by David at lublink
(cherry picked from commit 6b7a27e81cc838de6af9a1c55edb937d1094ce98)
commit e7572ade2f0d17239999ccb60b744cfd241afe9b
Author: Daniel-Constantin Mierla <miconda@gmail.com>
Date: Fri Aug 31 10:29:45 2012 +0200
auth: print return code in log when nonce is invalid
- it will give a clue about why nonce is considered invalid
(cherry picked from commit 494b383edde7a2d193c220f3117506e4cc95932f)
commit 756b1cdab5cac039fd958c2f3909a313a1baf3ab
Author: Daniel-Constantin Mierla <miconda@gmail.com>
Date: Thu Aug 30 10:15:26 2012 +0200
db_cluster: safety check for existence of several DB API members
(cherry picked from commit 21583d47751fc7f684dac41a3bfbfc3b2c0bf3a3)
commit e4bfc9c353fd46a6b5ab726b48eaa18b35b284f8
Author: Daniel-Constantin Mierla <miconda@gmail.com>
Date: Mon Aug 27 10:37:50 2012 +0200
db_cluster: more verbosity when building cluster structures
(cherry picked from commit b53ca97379e1b4aeae80b794f23e25e9150a0e58)
commit e6a8291381ccf9773198a6c338449571ba122417
Author: Daniel-Constantin Mierla <miconda@gmail.com>
Date: Fri Aug 24 09:14:28 2012 +0200
db_cluster: use connection from write structure for db updates
- could be related to an issue reported by Øyvind Kolbu
(cherry picked from commit 4d15ba97bab58108cfedc45158d90583f67cdadf)
commit b5719b81e8f79c40963d3bb9d7954732273d4a18
Author: Daniel-Constantin Mierla <miconda@gmail.com>
Date: Sun Aug 19 21:29:06 2012 +0200
core: rephrased debug message about no 2nd via in reply
(cherry picked from commit 8bc7114c6a915985ca2f4e9ab50ea608437c7256)
commit 26ecb4932f1a265b87e6fa077c61b4feb6123262
Author: Daniel-Constantin Mierla <miconda@gmail.com>
Date: Wed Aug 15 13:01:43 2012 +0200
dispatcher(k): corrected setid_pvname parameter name
- readme listed it as setid_pvar, the source code expected setid_pvname
- reported by Dan B.
(cherry picked from commit e1149b05868b918d0bc52b2d46bb02f7799358db)
commit 90a50be6fe74e521bffcde6f8ec73467cb31d163
Author: Daniel-Constantin Mierla <miconda@gmail.com>
Date: Wed Aug 15 12:48:32 2012 +0200
dispatcher(k): corrected the variable which is set by ds_is_from_list()
- setid_pvar is used instead of grp_avp
- reported by Dan B.
(cherry picked from commit be05dfc0f4af62f9c368960fe75a810548be8b87)
commit 6c7ecd4ffaaffd78458dc1b277dd85b5debb587b
Author: Daniel-Constantin Mierla <miconda@gmail.com>
Date: Tue Aug 14 22:18:50 2012 +0200
acc(k): added notes about dynamic table name for db acc to docs
(cherry picked from commit 91d6d3c8a1484b23ff74f0cfd6356447985455a5)
commit 7287933b07dcaf6d3bfae8d482ef0c681b8ed697
Author: Daniel-Constantin Mierla <miconda@gmail.com>
Date: Tue Oct 12 14:52:07 2010 +0200
acc(k): table name for db acc can be dynamic
- you can include variables in table name and will be evaluated at
runtime:
modparam("acc", "db_table_acc", "acc_$time(year)_$time(mon)")
will write now to table acc_2010_10
- same can be done for missed_calls table name
- second parameter of acc_db_request() supports as well config variables
(cherry picked from commit e8f6a95d43b6a4340cf7e97213af5c71fa2a69e9)
(cherry picked from commit 95ee0a3ee75556a25f3a9286837a57decf6c3c91)
commit 940047788e683f88d1f72cce257e3bcb68bff782
Author: Daniel-Constantin Mierla <miconda@gmail.com>
Date: Tue Aug 14 11:19:08 2012 +0200
pkg/kamailio/rpm: execute 'success' for start operation
- reported by Andre
(cherry picked from commit f9c5c389b2412d23f1fdd35c6e97dfe7dbe44811)
commit d94df595f837bb3682162a900b3e29203e8656c5
Author: Daniel-Constantin Mierla <miconda@gmail.com>
Date: Thu Aug 9 16:14:43 2012 +0200
usrloc(k): safety check for raw_query
- db get all contacts functions requires raw_query, but not all db
modules implement it
(cherry picked from commit f61295a91bb92645ea46dea5f6101232afeb720d)
commit 2f6b9bc710acff53dea899236a81a6f9d33ec4ff
Author: Peter Dunkley <peter.dunkley@crocodile-rcs.com>
Date: Wed Oct 10 10:49:16 2012 +0100
modules_k/xcap_server: Fixed small mistake in last xcap_server fix
(cherry picked from commit 10dafd75873f9f58037680e4d72cafc4c877583f)
commit c210532ce7a2c26f8c09257d1d46ee2a641bdfb6
Merge: 587d29a befbee0
Author: Peter Dunkley <peter.dunkley@crocodile-rcs.com>
Date: Wed Oct 10 10:50:32 2012 +0100
Merge branch '3.3' of ssh://git.sip-router.org/sip-router into 3.3
* '3.3' of ssh://git.sip-router.org/sip-router:
core: Fix parser sdp bug. Reset connection IP for each stream.
tcp: fix _wbufq_insert bug
nathelper(k): nicer handling of no sdp in sdp_1918(...)
commit 587d29a574d1898b761a590ee59bc8c06b403cd9
Author: Peter Dunkley <peter.dunkley@crocodile-rcs.com>
Date: Tue Oct 9 21:07:10 2012 +0100
modules_k/xcap_server: Fixed segmentation fault
- Occurs when attempting to do an etag compare when there is no document/etag
in the database.
(cherry picked from commit d29cfab1584b8bc2672b4242a2626d9dc90c77a2)
commit befbee07c453dfb3364e33b6587efa8d57bf2ea5
Author: Vicente Hernando <vhernando@systemonenoc.com>
Date: Fri Sep 7 07:01:11 2012 -0400
core: Fix parser sdp bug. Reset connection IP for each stream.
If connection IP is not reset, then when a stream has no IP connection,
it uses former stream one instead of session default one.
(cherry picked from commit 971386c346d72a016d00c8808059bd4f0a050059)
commit 8732b63bf5371914ba0267a22f45aacefe062ad4
Author: Andrei Pelinescu-Onciul <andrei@iptel.org>
Date: Mon Oct 1 11:55:16 2012 +0200
tcp: fix _wbufq_insert bug
When _wbufq_insert was called on a connection that had already
some data added to the write buffer (another process was faster
and added some data before the process that created the connection
had a chance to do it), a wrong size was used in a memmove.
This could lead either to corrupted messages or even crashes (if
the messages were big enough to cause a buffer overflow).
Many thanks to Jijo for debugging it.
Reported-by: Jijo
(cherry picked from commit 745e30c92336bfc3f8682b2c23e02862db688d9e)
commit 7881d44ce92c953e77305545b8773d3e056ea80e
Author: Daniel-Constantin Mierla <miconda@gmail.com>
Date: Fri Oct 5 14:34:13 2012 +0200
nathelper(k): nicer handling of no sdp in sdp_1918(...)
- don't print error message if there is no sdp body
(cherry picked from commit 019bcdc56533e7ccd0e1cc7d45b1d2d8ebc868ae)
commit 3d195f2675569954a1f74128508db07cbc604ed9
Author: Richard Fuchs <rfuchs@sipwise.com>
Date: Thu Sep 20 12:08:03 2012 -0400
modules/ctl: remove limitation on number of message chunks
binrpc uses an iovec to send out replies, which is limited in size and so
severely limits the number of elements that can be returned. This patch adds
a callback function to send out and empty the iovec array every time it gets
full while it's being populated.
commit e9ccba247a1262c7b183fb66933d5ee06b765968
Author: Peter Dunkley <peter.dunkley@crocodile-rcs.com>
Date: Sun Sep 16 23:46:07 2012 +0100
modules_k/rls: Fixed race-condition on multi-server systems that can cause different NOTIFYs with the same CSeq
- Found by Hugh Waite @ Crocodile RCS and fixed by Peter Dunkley @ Crocodile RCS
(cherry picked from commit 67df57c984e040a948d01d2c6bf1a9461d271f8e)
commit d81bb6501c6b4de517a44af8fe9005dd128d0066
Author: Peter Dunkley <peter.dunkley@crocodile-rcs.com>
Date: Sun Sep 16 23:47:20 2012 +0100
modules_k/rls: Fixed segmentation fault in RLS when a resource-list is updated
- Found and fixed by Hugh Waite @ Crocodile RCS
(cherry picked from commit bde7e9465db9e7c9ecb485c57edabbd032f3b770)
commit edad1981336f706c0ee7f1b724439adba72a9c71
Author: Juha Heinanen <jh@tutpro.com>
Date: Sun Sep 16 17:20:38 2012 +0300
modules_k/usrloc: modified syslog messages on bad and non-local sockets
- Changed syslog message on non-local socket from warning to debug,
because non-local socket is ok when nathelper obtains the contacts and
overrides the socket.
- Corrected syslog messages on bad and non-local sockets.
(cherry picked from commit 424d2cabbe2e20c7ed134f6c9bd463811f2de63f)
commit 7b40fba5cfc04781c60a849bcb0e240c4e34413a
Author: Daniel-Constantin Mierla <miconda@gmail.com>
Date: Fri Sep 14 13:02:01 2012 +0200
kamctl: regeneration of sql creation scripts for pua table updates
commit 91e8cb4bf7456eeebefa96269887f6aae46626d3
Author: Peter Dunkley <peter.dunkley@crocodile-rcs.com>
Date: Tue Sep 11 13:23:23 2012 +0100
modules_k/pua: Adjusted locking for dialog insertion. Candidate fix for "temporary dialog" error reported by Juha
(cherry picked from commit b0d642016cca83c519ea9aa0e04aa9bf353e07e4)
commit 28aec07bcf81ab83d9b7af03de792cb66cf0ca3f
Author: Peter Dunkley <peter.dunkley@crocodile-rcs.com>
Date: Tue Sep 11 13:10:08 2012 +0100
modules_k/rls: Fixed segmentation fault when uploading new contact lists for a logged in subscriber
- Found and fixed by Hugh Waite @ Crocodile RCS Ltd
(cherry picked from commit 6924912be955b9f7ba47fd57b22ffe0c01eb68b2)
commit 3f540459b566641200e129c0c03ab26e6944fbdf
Author: Peter Dunkley <peter.dunkley@crocodile-rcs.com>
Date: Tue Sep 11 13:09:22 2012 +0100
modules_k/rls: Improved check for expired subscriptions in DB only mode
(cherry picked from commit af8230b1ac6a88dfb10d567e784a3c39a8f1b863)
commit 0c5d596371712e98b2b59fe6b3b0911f2252fcd0
Author: Peter Dunkley <peter.dunkley@crocodile-rcs.com>
Date: Tue Sep 11 13:08:38 2012 +0100
modules_k/rls: Fixed issues with for() loops in DB only mode
- Found and fixed by Hugh Waite @ Crocodile RCS Ltd
(cherry picked from commit 7b64e538b350ebd520b80f668045b9f3c7d68fb9)
commit 1fe1770aa372b6d22554428fb7172215e502b20c
Author: Peter Dunkley <peter.dunkley@crocodile-rcs.com>
Date: Tue Sep 11 13:06:54 2012 +0100
modules_k/rls: core_hash() not used correctly to distribute notifier traffic
- Found and fixed by Hugh Waite @ Crocodile RCS Ltd
(cherry picked from commit 5235a1d6218e0bb16f6c9998789864635f54d03e)
commit 0d1af7d98cd4053b839556cfa07c9f71874fd02e
Author: Peter Dunkley <peter.dunkley@crocodile-rcs.com>
Date: Tue Sep 11 12:59:08 2012 +0100
modules_k/pua_db: If PUA finds more than one matching dialog (when there should only be one) delete them all
- A timing difference on multiple-servers can sometimes cause this,
and (if it happens, it doesn't when the clocks are synced) you can
end up with the same error coming out lots because the DB is not
cleaned up.
(cherry picked from commit 20475258957cbf3183e5e771e9fd41dc69336096)
commit 831b80f9aecabfdfa37bcb806bc1192e46681869
Author: Peter Dunkley <peter.dunkley@crocodile-rcs.com>
Date: Tue Sep 11 13:03:32 2012 +0100
modules_k/rls: Added missing lock_release()
- Found and fixed by Hugh Waite @ Crocodile RCS Ltd
(cherry picked from commit 725020f91493d33c5fa86828a421ed465731658e)
commit 64f64efb49782bb74080193863ac2d4775816add
Author: Peter Dunkley <peter.dunkley@crocodile-rcs.com>
Date: Tue Sep 11 12:58:13 2012 +0100
modules_k/pua: Fixed incorrect check/use of update_period modparam
(cherry picked from commit ef7d43fc614276b75c560660c7e4368fd18d574d)
commit 2778f4126fdd48f4573f008726b3a3868c3d69c1
Author: Peter Dunkley <peter.dunkley@crocodile-rcs.com>
Date: Tue Sep 11 13:05:15 2012 +0100
modules_k/rls: Fixed issues to do with expiry and rls_expires_offset
- These cause particular problems on multi-server systems.
- Found and fixed by Hugh Waite @ Crocodile RCS Ltd
(cherry picked from commit 6eccc8b61e848977012d6efa1fb5aae61f8d441e)
commit c2616fb78a9828203fbc9e885d96f07364df5000
Author: Peter Dunkley <peter.dunkley@crocodile-rcs.com>
Date: Tue Sep 11 12:55:49 2012 +0100
modules_k/presence: Fixed some problems with for() loops in DB only mode
- Found and fixed by Hugh Waite @ Crocodile RCS Ltd
(cherry picked from commit cd6415240ff243842b4e11b095103f00fd64d0d9)
commit 42a123c416d5906bfefd7eaae8ef81cacda80a41
Author: Peter Dunkley <peter.dunkley@crocodile-rcs.com>
Date: Tue Sep 11 12:56:52 2012 +0100
modules_k/presence: Improved check for expired dialogs in DB only mode with notifier tasks
(cherry picked from commit d9087dbbf411f71486a4ce765aa5d6dfeb531f9c)
commit 262982b13c887c15e4c5a4d667530aad3fb8801c
Author: Peter Dunkley <peter.dunkley@crocodile-rcs.com>
Date: Tue Sep 11 12:53:58 2012 +0100
modules_k/presence: core_hash not used correctly to distribute notifier traffic
- Found and fixed by Hugh Waite @ Crocodile RCS Ltd
(cherry picked from commit 4b9aa7f144b8cf3e6da775563528913ed79e0553)
commit b4c70bca1cb3f0dc722bd89933fa566e790837a1
Author: Peter Dunkley <peter.dunkley@crocodile-rcs.com>
Date: Tue Sep 11 12:51:33 2012 +0100
modules_k/presence: Fixed inconsistencies in use of expires_offset for removing subcriptions
- These caused particular problems on mulit-server, DB only, systems
- Found and fixed by Hugh Waite @ Crocodile RCS Ltd.
(cherry picked from commit a29a2a81bc541af020955dbda0d352445fef5788)
commit ed672fdde6d6adbe7066162a6b1cbae8cc3948a8
Author: Peter Dunkley <peter.dunkley@crocodile-rcs.com>
Date: Tue Sep 11 12:54:51 2012 +0100
modules_k/presence: Fixed level of a diagnostic message
(cherry picked from commit 3635a0d920f0d03e85b8b97a44d878f0f8d13931)
commit 82ca28c8a523c015b69a3c56d02983356faefc54
Author: Juha Heinanen <jh@tutpro.com>
Date: Fri Sep 7 19:16:37 2012 +0300
db schema: removed unique requirement from pua expires_idx
- TODO: change also other than mysql table structures
(cherry picked from commit bedb7fdc6d02e92fbf52ad4acb6dfcbb49f0bc49)
commit 4f34d95ebc689702376bfdeb63be65d1e774455a
Author: Vicente Hernando <vhernando@systemonenoc.com>
Date: Wed Sep 5 06:44:39 2012 -0400
sdpops: Fix memory leakage in w_get_sdp function.
(cherry picked from commit d1d2494c966d65828d1920296056da840a11efd9)
commit e663ddd6e3ff55cd43f1a21561f7c60a94420d36
Author: Daniel-Constantin Mierla <miconda@gmail.com>
Date: Wed Sep 5 08:58:18 2012 +0200
dialog(k): fixed the name of event route
- it is 'dialog:failed' instead of 'dialog:failure'
- reported by Uri Shacked
(cherry picked from commit 163f860ef7c0ed9a720207499d054e7f68b139df)
commit 5771e1ed6c7b92ebab9e2da0251315498a5190e1
Author: Michal Karas <largon@largon.net>
Date: Thu Jul 12 17:38:15 2012 +0200
parser/sdp: prevent manipulation with freed structure
- FS#244
commit f5997ba82e066d667d8fdf48a0eb8f284abe70be
Author: Carsten Bock <carsten@ng-voice.com>
Date: Mon Sep 3 21:31:58 2012 +0200
b/f: In case of IPv6 Option in the RTP-Command, the pointers and the length need to be updated.
commit d7452228134c42522ef84c1dbdcdc2cfd0bbf331
Author: Daniel-Constantin Mierla <miconda@gmail.com>
Date: Thu Aug 2 10:16:31 2012 +0200
core: added md5 wrapper functions to build with Colin Plumb's md5 code
Author: Tzafrir Cohen <tzafrir@debian.org>
(cherry picked from commit bcff862df5b937e3a6ff87e4415e0039fd989908)
commit fbd4acae2d732908a9624c727b8b0306e1c166cd
Author: Daniel-Constantin Mierla <miconda@gmail.com>
Date: Thu Aug 2 10:13:00 2012 +0200
core: Use Colin Plumb's MD5 implementation
Origin: http://anonscm.debian.org/gitweb/?p=dpkg/dpkg.git;a=summary
Author: Tzafrir Cohen <tzafrir@debian.org>
Borrowed the md5 code from dpkg instead of the existing md5.[ch]
This makes the code compatible with Debian packing rules and
restrictions regarding license for distribution
(cherry picked from commit e6d912ad036aa92604ba3f2bf65cc4c4ba3e4d2f)
commit 20dacf5225e63fc8ff573272f41572f452272c7d
Author: Iñaki Baz Castillo <ibc@aliax.net>
Date: Thu Aug 16 16:17:51 2012 +0200
Process CANCEL before in-dialog requests. This prevents issues with some devices sending buggy CANCEL with To-tag when cancelling an initial INVITE.
(cherry picked from commit 8a7a06f4d9c78f6da0558806d988c817fd6d0018)
commit cd1e3909f03f837a583b9ea30ffd6089b8ba8db2
Author: Iñaki Baz Castillo <ibc@aliax.net>
Date: Thu Aug 16 16:13:50 2012 +0200
Add Record-Route for in-dialog NOTIFY as per RFC 6665.
(cherry picked from commit d661028060369e702f5882b6492040bd71fb900a)
commit 80e5d5689963ab01a9ab3b3ba7d39f08df59b213
Author: Daniel-Constantin Mierla <miconda@gmail.com>
Date: Fri Jun 29 16:06:42 2012 +0200
kamailio.cfg: use add_contact_alias()/handle_uri_alias() for NATed calls
(cherry picked from commit 9d720b83c9dd27e927627132ec052b15efeba518)
commit 5c217004880461e5d121a4b9640539e6bb5bc8bb
Author: Juha Heinanen <jh@tutpro.com>
Date: Sat Sep 1 13:32:18 2012 +0300
modules/dialplan: always set type of attrs pvar value
- Type of attrs pvar value was not set when dp_translate didn't result
in any change.
(cherry picked from commit 28a7300cd83e135b1c0d5488cb289fc7415fbd8c)
commit 2665ef8706201ba0e98344fd0e9b455a275a8c53
Author: Anca Vamanu <anca.vamanu@1and1.ro>
Date: Thu Aug 30 17:39:47 2012 +0300
modules/db_cassandra Updated in doc location table schema
(cherry picked from commit 82bb7a8b67e488e7089d194fa5f96e9ae61dfb03)
commit 26d2413bba1c7b9fbc5bfa84acc3499bf08c5cd6
Author: Anca Vamanu <anca.vamanu@1and1.ro>
Date: Thu Aug 30 17:21:29 2012 +0300
modules/db_cassandra: Fixed segmentation fault in case of bad table schema
Reported by Boudewyn Ligthart.
(cherry picked from commit 0f8f21e390e8442cf1f527d3654dedc5a40bfcea)
commit 8ad086aa81bc6ca4fb762264ffcc5e53be819ec2
Author: Anca Vamanu <anca.vamanu@1and1.ro>
Date: Fri Jul 13 16:50:07 2012 +0300
lib/srdb1 : put pooling constans into separate header file to reduce
include dependancy
(cherry picked from commit f3ff581dbd0a53c4c5eafdf829bef0c25e8e8f28)
commit bb0b3b1e3218a2ad919b590ed6961f021fc72857
Author: Anca Vamanu <anca.vamanu@1and1.ro>
Date: Thu Aug 30 12:24:24 2012 +0300
modules/db_cassandra: Updated replace function to the new signature
(cherry picked from commit 512013f324dd6faa37e26302a267afb07252812a)
commit c79aef1753fb02a35f299fd0fb861d82c34226e7
Author: Richard Fuchs <rfuchs@sipwise.com>
Date: Wed Aug 29 15:47:10 2012 -0400
modules_k/nathelper: fix a= lines inserted out of order
RFC 4566 dictates a particular order of fields in the SDP body, in particular
media-specific a= lines must be last fields within an m= block. Inserting
them right after the m= lines violates this order if other fields (such as
c=) are present, causing parse errors in some clients. So instead, insert
them at the end of each m= block.
commit 12c25ac2a5dbc77b4f025f81a18eb4b07cfccee7
Author: Anca Vamanu <anca.vamanu@1and1.ro>
Date: Wed Aug 29 19:33:51 2012 +0300
kamctl/dbcassandra: Updated schema for cassandra location table
(cherry picked from commit ae7047e05a7ff05a1707446286e2837fa49671dc)
commit db68eb7863263785f1fbf13be092f05f484c9171
Author: Jon Bonilla <manwe@aholab.ehu.es>
Date: Mon Aug 27 12:26:59 2012 +0200
pkg/deb: Wrap and sort
Use wrap-and-sort command
Credits to Michael Prokop <mprokop@sipwise.com>
commit 8604b9b40464793153f871e3334da7c81589de44
Author: Jon Bonilla <manwe@aholab.ehu.es>
Date: Mon Aug 27 11:38:47 2012 +0200
pkg/deb Don't conflict with -dbg any more
commit aae4e4537eefa525d03874aaf165048a09d1febf
Author: Peter Dunkley <peter.dunkley@crocodile-rcs.com>
Date: Tue Aug 21 15:21:54 2012 +0100
modules_k/rls: Some incorrect pkg_free() calls in DB only code
- Found and fixed by Hugh Waite @ Crocodile RCS
(cherry picked from commit 9b77e69de0953f9f6f48d4c1cf06f7e593469912)
commit 9de930d083af681fc85fc4cee90dfadbbaadb89c
Author: Peter Dunkley <peter.dunkley@crocodile-rcs.com>
Date: Tue Aug 21 15:21:03 2012 +0100
modules_k/pua: transaction not ended before calling send_publish() from TM call-back
- Found by Hugh Waite @ Crocodile RCS and fixed by Peter Dunkley
@ Crocodile RCS
(cherry picked from commit b9e77beaee850303ffa736cb4043d21a1806fa4f)
commit fb51d3815292c27245b26d1f4a4f6c9b190f9200
Author: Peter Dunkley <peter.dunkley@crocodile-rcs.com>
Date: Tue Aug 21 15:19:51 2012 +0100
modules/db_postgres: libpq requires null terminated string, but Kamailio internal str type is not (necessarily) null-terminated
- Found and fixed by Paul Pankhurst @ Crocodile RCS
(cherry picked from commit f20713462410211370e762abb463f0ceafd36d8d)
commit 92254d15ebf880fee454e73a8b1d3b2fa9966180
Author: Jon Bonilla <manwe@aholab.ehu.es>
Date: Thu Aug 16 09:24:47 2012 +0200
pkg/deb Build kamailio-dbg package
(cherry picked from commit 79e99ae5cbe7016f22454faf4f9e9f5a463a4f7d)
commit 985f9382703a0f5a493f8a4594220304276c2bd4
Author: Peter Dunkley <peter.dunkley@crocodile-rcs.com>
Date: Tue Aug 14 15:53:07 2012 +0100
modules_k/rls: Fixed incorrect table version check
- Found by Hugh Waite @ Crocodile RCS
(cherry picked from commit e22e5f83115d9f1e33c27ae437d93d7701330a8c)
commit d94040eca0a9900fcf0b9f1140e3afeb38c9fcba
Author: Peter Dunkley <peter.dunkley@crocodile-rcs.com>
Date: Tue Aug 14 15:52:37 2012 +0100
modules_k/rls: Fixed memory leak in rls under some error conditions
- Found and fixed by Hugh Waite @ Crocodile RCS
(cherry picked from commit de8b241ea39284cce4c7e1850fcf3cef4c4c4a0a)
commit ff72de945a70b9eedb6eca08677b93e618faeb94
Author: Richard Fuchs <rfuchs@sipwise.com>
Date: Mon Aug 13 13:10:37 2012 -0400
modules/lcr, modules_k/regex: Fix stack overflow from pcre_fullinfo(PCRE_INFO_SIZE)
Fix instances where pcre_fullinfo(PCRE_INFO_SIZE) was given only an "int"
argument, which results in stack overflow on some 64-bit platforms where
an "int" is only 32 bits long. It expects a "size_t" argument, which is
64 bits long.
commit dd26ed0cc3233fcf64635a8d2ee27361352b711a
Author: Peter Dunkley <peter.dunkley@crocodile-rcs.com>
Date: Mon Aug 13 15:48:18 2012 +0100
modules_k/pua: Fixed double-free in pua
(cherry picked from commit 5387288eac896a0710fb1c55cc4837e973e04946)
commit 03f8f4d9c4304ac0a8f629e1c94230ab70b58917
Author: Peter Dunkley <peter.dunkley@crocodile-rcs.com>
Date: Mon Aug 13 15:50:05 2012 +0100
modules_k/rls: Added DB transaction code around rls_presentity insert/replace
(cherry picked from commit 65dcb2d0e72757d51b0ee51c457c5440278444bc)
commit 52f1ea5eb0067e94207dcfaa461260d96b2635bc
Author: Peter Dunkley <peter.dunkley@crocodile-rcs.com>
Date: Mon Aug 13 15:49:09 2012 +0100
modules_k/rls: Fixed memory leak in rls
- Issue fixed by Paul Pankhurst and Peter Dunkley @ Crocodile RCS
(cherry picked from commit c9628aa038ad7099a72af67f9284e5d0a9b78173)
commit 8db3e9c29b2cf1ff5c6f93411d3e9a90f7eb82ef
Author: Daniel-Constantin Mierla <miconda@gmail.com>
Date: Thu Aug 9 08:50:20 2012 +0200
rr(k): fixed offset in building new route header
- related to the previous fix done to strict routing intermediary hop
(cherry picked from commit e154b2fb9f02d56d9c6a4b2d285791151ae0c8a3)
commit 25c6efc8d245c339c77748f93c222188769a7be8
Author: Peter Dunkley <peter.dunkley@crocodile-rcs.com>
Date: Wed Aug 8 12:05:44 2012 +0100
modules_k/rls: Fixed memory leak in RLS
- Leak only happens when there is more than one Record-Route: header
- Fixed by Hugh Waite @ Crocodile RCS
(cherry picked from commit c1240aa21a534f1c1a5bdaaebd9c29fe4984a4bb)
commit 56312a26e3e35692e7c1485015fb11d16de6f5ed
Author: Peter Dunkley <peter.dunkley@crocodile-rcs.com>
Date: Sun Aug 5 16:43:42 2012 +0100
pkg/kamailio/fedora/17: Fixed appliance problem
commit 7795ef185365eab558ed2c98e8d995f47fa823bb
Author: Peter Dunkley <peter.dunkley@crocodile-rcs.com>
Date: Fri Aug 3 14:38:49 2012 +0100
modules_k/dispatcher: Dispatcher reload MI command not returning errors correctly
- Fix by Hugh Waite @ Crocodile RCS
(cherry picked from commit 5c83492470e8d1a706933915fcfbf6cfe2e0fd55)
commit a87a6a94e26176511cf2cc7e5260d5c1f0861add
Author: Peter Dunkley <peter.dunkley@crocodile-rcs.com>
Date: Fri Aug 3 14:39:49 2012 +0100
modules_k/rls: Fixed segmentation fault in RLS
- Fix by Paul Pankhurst @ Crocodile RCS
(cherry picked from commit 49f25c402871a619404b61e29ff496c71daad8be)
commit 1bd1c77b7c35cbdf88a09020954f4b780e08697d
Author: Peter Dunkley <peter.dunkley@crocodile-rcs.com>
Date: Fri Aug 3 11:34:31 2012 +0100
pkg/kamailio/fedora/16: Updated version in .spec file
commit d7de94a452185fca7ae4ea1cb5bb9bd775b73d5e
Author: Peter Dunkley <peter.dunkley@crocodile-rcs.com>
Date: Fri Aug 3 11:32:28 2012 +0100
pkg/kamailio/fedora/17: Fixed typo in appliance files
(cherry picked from commit 79a614ced2283264e3746cfcfd32fe4245f6496b)
commit a0ffdb7eb2b1478a98422123c78e15ce2b21449f
Author: Daniel-Constantin Mierla <miconda@gmail.com>
Date: Fri Aug 3 09:20:03 2012 +0200
rr(k): add missing '<' in Route header for strict routing
- if next hop is strict router after loose routing, moving the r-uri to
last Route header was missing '<' in front of the address
- reported by Varsha Venkatraramani
(cherry picked from commit 090be2532da73f51043f9ba5f4b221fe338d60fa)
===================== 2012-08-02 Version 3.3.1 Released =====================
===================== Changes Since Version 3.3.0 ===========================

@ -51,7 +51,7 @@ The two major SIP server flavours are:
- Kamailio (former OpenSER)
Starting with version 3.0.0, the two SIP server flavours are built from
same source code three.
same source code tree.
SER flavor is the one built by default - historically speaking, it is the
first open source SIP server started in 2001. Kamailio forked from SER in

@ -170,7 +170,7 @@ module_group_postgres=$(module_group_postgres_driver) $(module_group_db)
# For radius
module_group_radius=acc_radius auth_radius misc_radius avp_radius uri_radius \
peering pcem
peering
# For presence
# kamailio modules
@ -226,7 +226,7 @@ module_group_kpostgres=db_postgres
module_group_kcpl=cpl-c
# K radius modules
module_group_kradius=acc_radius auth_radius misc_radius peering pcem
module_group_kradius=acc_radius auth_radius misc_radius peering
# K unixodbc module
module_group_kunixodbc=db_unixodbc
@ -309,7 +309,7 @@ else
db_sqlite db_unixodbc db_cassandra memcached mi_xmlrpc \
perl perlvdb purple \
snmpstats xmpp \
carrierroute peering pcem \
carrierroute peering \
dialplan lcr utils presence presence_mwi \
presence_dialoginfo presence_xml pua pua_bla \
pua_dialoginfo pua_usrloc pua_xmpp \
@ -884,7 +884,7 @@ sunpkg:
.PHONY: install
install: mk_params="compile_for_install=yes"
install: install-bin install-every-module \
install: install-bin install-every-module install-cfg \
install-doc install-man install-utils install-share
.PHONY: dbinstall

@ -161,7 +161,7 @@ INSTALL_FLAVOUR=$(FLAVOUR)
#version number
VERSION = 3
PATCHLEVEL = 3
SUBLEVEL = 1
SUBLEVEL = 2
EXTRAVERSION =
# memory debugger switcher

@ -452,11 +452,6 @@ request_route {
# NAT detection
route(NATDETECT);
# handle requests within SIP dialogs
route(WITHINDLG);
### only initial requests (no To tag)
# CANCEL processing
if (is_method("CANCEL"))
{
@ -465,6 +460,11 @@ request_route {
exit;
}
# handle requests within SIP dialogs
route(WITHINDLG);
### only initial requests (no To tag)
t_check_trans();
# authentication
@ -569,14 +569,19 @@ route[WITHINDLG] {
# sequential request withing a dialog should
# take the path determined by record-routing
if (loose_route()) {
route(DLGURI);
if (is_method("BYE")) {
setflag(FLT_ACC); # do accounting ...
setflag(FLT_ACCFAILED); # ... even if the transaction fails
}
if ( is_method("ACK") ) {
else if ( is_method("ACK") ) {
# ACK is forwarded statelessy
route(NATMANAGE);
}
else if ( is_method("NOTIFY") ) {
# Add Record-Route for in-dialog NOTIFY as per RFC 6665.
record_route();
}
route(RELAY);
} else {
if (is_method("SUBSCRIBE") && uri == myself) {
@ -736,7 +741,7 @@ route[NATDETECT] {
if (is_method("REGISTER")) {
fix_nated_register();
} else {
fix_nated_contact();
add_contact_alias();
}
setflag(FLT_NATS);
}
@ -766,13 +771,23 @@ route[NATMANAGE] {
}
if (is_reply()) {
if(isbflagset(FLB_NATB)) {
fix_nated_contact();
add_contact_alias();
}
}
#!endif
return;
}
# URI update for dialog requests
route[DLGURI] {
#!ifdef WITH_NAT
if(!isdsturiset()) {
handle_ruri_alias();
}
#!endif
return;
}
# Routing to foreign domains
route[SIPOUT] {
if (!uri==myself)

@ -793,7 +793,7 @@ int forward_reply(struct sip_msg* msg)
|| (msg->via2==0) || (msg->via2->error!=PARSE_OK))
{
/* no second via => error */
LOG(L_DBG, "broken reply to forward - no 2nd via\n");
LOG(L_DBG, "reply cannot be forwarded - no 2nd via\n");
goto error;
}

@ -50,12 +50,7 @@
#include "db_cap.h"
#include "db_con.h"
#include "db_row.h"
typedef enum {
DB_POOLING_PERMITTED,
DB_POOLING_NONE
} db_pooling_t;
#include "db_pooling.h"
/**
* \brief Specify table name that will be used for subsequent operations.

@ -31,7 +31,7 @@
#define _DB1_ID_H
#include "../../str.h"
#include "db.h"
#include "db_pooling.h"
/** Structure representing a database ID */
struct db_id {

@ -0,0 +1,41 @@
/*
* $Id$
*
* Copyright (C) 2001-2003 FhG Fokus
* Copyright (C) 2007-2008 1&1 Internet AG
*
* This file is part of Kamailio, a free SIP server.
*
* Kamailio is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version
*
* Kamailio is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
/**
* \file lib/srdb1/db_pooling.h
* \ingroup db1
* \brief Defines Pooling states
*
*/
#ifndef DB1_POOLING_H
#define DB1_POOLING_H
typedef enum {
DB_POOLING_PERMITTED,
DB_POOLING_NONE
} db_pooling_t;
#endif /* DB1_POOLING_H */

@ -163,7 +163,6 @@
<index>
<name>expires_idx</name>
<colref linkend="expires"/>
<unique/>
</index>
<index>

534
md5.c

@ -1,343 +1,249 @@
/*
* MD5C.C - RSA Data Security, Inc., MD5 message-digest algorithm
* Copyright (C) 1991-2, RSA Data Security, Inc. Created 1991. All
* rights reserved.
* License to copy and use this software is granted provided that it
* is identified as the "RSA Data Security, Inc. MD5 Message-Digest
* Algorithm" in all material mentioning or referencing this software
* or this function.
*
* License is also granted to make and use derivative works provided
* that such works are identified as "derived from the RSA Data
* Security, Inc. MD5 Message-Digest Algorithm" in all material
* mentioning or referencing the derived work.
*
* RSA Data Security, Inc. makes no representations concerning either
* the merchantability of this software or the suitability of this
* software for any particular purpose. It is provided "as is"
* without express or implied warranty of any kind.
*
* These notices must be retained in any copies of any part of this
* documentation and/or software.
/* $OpenBSD: md5.c,v 1.7 2004/05/28 15:10:27 millert Exp $ */
/*
* This code implements the MD5 message-digest algorithm.
* The algorithm is due to Ron Rivest. This code was
* written by Colin Plumb in 1993, no copyright is claimed.
* This code is in the public domain; do with it what you wish.
*
* Equivalent code is available from RSA Data Security, Inc.
* This code has been tested against that, and is equivalent,
* except that you don't need to include two pages of legalese
* with every copy.
*
* To compute the message digest of a chunk of bytes, declare an
* MD5Context structure, pass it to MD5Init, call MD5Update as
* needed on buffers full of bytes, and then call MD5Final, which
* will fill a supplied 16-byte array with the digest.
*/
/*!
* \file
* \brief SIP-router core :: md5 hash support
* \ingroup core
* Module: \ref core
*/
#include <sys/types.h>
#include <string.h>
#include "md5.h"
/**
* \name Constants for MD5Transform routine
*/
/*@{ */
#define S11 7
#define S12 12
#define S13 17
#define S14 22
#define S21 5
#define S22 9
#define S23 14
#define S24 20
#define S31 4
#define S32 11
#define S33 16
#define S34 23
#define S41 6
#define S42 10
#define S43 15
#define S44 21
/*@} */
static void MD5Transform(unsigned int [4], unsigned char [64]);
static void Encode(unsigned char *, unsigned int *, unsigned int);
static void Decode(unsigned int *, unsigned char *, unsigned int);
#include "md5.h"
static unsigned char PADDING[64] = {
0x80, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
#define PUT_64BIT_LE(cp, value) do { \
(cp)[7] = (value) >> 56; \
(cp)[6] = (value) >> 48; \
(cp)[5] = (value) >> 40; \
(cp)[4] = (value) >> 32; \
(cp)[3] = (value) >> 24; \
(cp)[2] = (value) >> 16; \
(cp)[1] = (value) >> 8; \
(cp)[0] = (value); } while (0)
#define PUT_32BIT_LE(cp, value) do { \
(cp)[3] = (value) >> 24; \
(cp)[2] = (value) >> 16; \
(cp)[1] = (value) >> 8; \
(cp)[0] = (value); } while (0)
static u_int8_t PADDING[MD5_BLOCK_LENGTH] = {
0x80, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
};
/**
* \name F, G, H and I are basic MD5 functions
/*
* Start MD5 accumulation. Set bit count to 0 and buffer to mysterious
* initialization constants.
*/
/*@{ */
#define F(x, y, z) (((x) & (y)) | ((~x) & (z)))
#define G(x, y, z) (((x) & (z)) | ((y) & (~z)))
#define H(x, y, z) ((x) ^ (y) ^ (z))
#define I(x, y, z) ((y) ^ ((x) | (~z)))
/*@} */
/**
* \brief ROTATE_LEFT rotates x left n bits
*/
#define ROTATE_LEFT(x, n) (((x) << (n)) | ((x) >> (32-(n))))
/**
* \name FF, GG, HH, and II transformations for rounds 1, 2, 3, and 4
* FF, GG, HH, and II transformations for rounds 1, 2, 3, and 4.
* Rotation is separate from addition to prevent recomputation.
*/
/*@{ */
#define FF(a, b, c, d, x, s, ac) { \
(a) += F ((b), (c), (d)) + (x) + (unsigned int)(ac); \
(a) = ROTATE_LEFT ((a), (s)); \
(a) += (b); \
}
#define GG(a, b, c, d, x, s, ac) { \
(a) += G ((b), (c), (d)) + (x) + (unsigned int)(ac); \
(a) = ROTATE_LEFT ((a), (s)); \
(a) += (b); \
}
#define HH(a, b, c, d, x, s, ac) { \
(a) += H ((b), (c), (d)) + (x) + (unsigned int)(ac); \
(a) = ROTATE_LEFT ((a), (s)); \
(a) += (b); \
}
#define II(a, b, c, d, x, s, ac) { \
(a) += I ((b), (c), (d)) + (x) + (unsigned int)(ac); \
(a) = ROTATE_LEFT ((a), (s)); \
(a) += (b); \
}
/*@} */
/**
* \brief MD5 context initialization
*
* MD5 context initialization. Begins an MD5 operation, writing a new context.
* \param context initialized context
*/
void MD5Init (MD5_CTX *context)
void
MD5Init(MD5_CTX *ctx)
{
context->count[0] = context->count[1] = 0;
/* Load magic initialization constants.
*/
context->state[0] = 0x67452301;
context->state[1] = 0xefcdab89;
context->state[2] = 0x98badcfe;
context->state[3] = 0x10325476;
ctx->count = 0;
ctx->state[0] = 0x67452301;
ctx->state[1] = 0xefcdab89;
ctx->state[2] = 0x98badcfe;
ctx->state[3] = 0x10325476;
}
/**
* \brief MD5 block update operation
*
* MD5 block update operation. Continues an MD5 message-digest
* operation, processing another message block, and updating the
* context.
* \param context context
* \param input input block
* \param inputLen length of input block
/*
* Update context to reflect the concatenation of another buffer full
* of bytes.
*/
void U_MD5Update (MD5_CTX *context, unsigned char *input, unsigned int inputLen)
void
U_MD5Update(MD5_CTX *ctx, const unsigned char *input, size_t len)
{
unsigned int i, index, partLen;
/* Compute number of bytes mod 64 */
index = (unsigned int)((context->count[0] >> 3) & 0x3F);
/* Update number of bits */
if ((context->count[0] += ((unsigned int)inputLen << 3))
< ((unsigned int)inputLen << 3))
context->count[1]++;
context->count[1] += ((unsigned int)inputLen >> 29);
partLen = 64 - index;
/* Transform as many times as possible.
*/
if (inputLen >= partLen) {
memcpy
((unsigned char *)&context->buffer[index], (unsigned char *)input, partLen);
MD5Transform (context->state, context->buffer);
for (i = partLen; i + 63 < inputLen; i += 64)
MD5Transform (context->state, &input[i]);
index = 0;
}
else
i = 0;
/* Buffer remaining input */
memcpy
((unsigned char *)&context->buffer[index], (unsigned char *)&input[i],
inputLen-i);
size_t have, need;
/* Check how many bytes we already have and how many more we need. */
have = (size_t)((ctx->count >> 3) & (MD5_BLOCK_LENGTH - 1));
need = MD5_BLOCK_LENGTH - have;
/* Update bitcount */
ctx->count += (u_int64_t)len << 3;
if (len >= need) {
if (have != 0) {
memcpy(ctx->buffer + have, input, need);
MD5Transform(ctx->state, ctx->buffer);
input += need;
len -= need;
have = 0;
}
/* Process data in MD5_BLOCK_LENGTH-byte chunks. */
while (len >= MD5_BLOCK_LENGTH) {
MD5Transform(ctx->state, input);
input += MD5_BLOCK_LENGTH;
len -= MD5_BLOCK_LENGTH;
}
}
/* Handle any remaining bytes of data. */
if (len != 0)
memcpy(ctx->buffer + have, input, len);
}
/**
* \brief MD5 finalization
*
* MD5 finalization. Ends an MD5 message-digest operation, writing the
* the message digest and zeroizing the context.
* \param digest message digest
* \param context context
/*
* Pad pad to 64-byte boundary with the bit pattern
* 1 0* (64-bit count of bits processed, MSB-first)
*/
void U_MD5Final (unsigned char digest[16], MD5_CTX *context)
void
MD5Pad(MD5_CTX *ctx)
{
unsigned char bits[8];
unsigned int index, padLen;
/* Save number of bits */
Encode (bits, context->count, 8);
/* Pad out to 56 mod 64.
*/
index = (unsigned int)((context->count[0] >> 3) & 0x3f);
padLen = (index < 56) ? (56 - index) : (120 - index);
U_MD5Update (context, PADDING, padLen);
/* Append length (before padding) */
U_MD5Update (context, bits, 8);
/* Store state in digest */
Encode (digest, context->state, 16);
/* Zeroize sensitive information.
*/
memset ((unsigned char *)context, 0, sizeof (*context));
u_int8_t count[8];
size_t padlen;
/* Convert count to 8 bytes in little endian order. */
PUT_64BIT_LE(count, ctx->count);
/* Pad out to 56 mod 64. */
padlen = MD5_BLOCK_LENGTH -
((ctx->count >> 3) & (MD5_BLOCK_LENGTH - 1));
if (padlen < 1 + 8)
padlen += MD5_BLOCK_LENGTH;
U_MD5Update(ctx, PADDING, padlen - 8); /* padlen - 8 <= 64 */
U_MD5Update(ctx, count, 8);
}
/**
* \brief MD5 basic transformation
*
* MD5 basic transformation. Transforms state based on block.
* \param state transformed state
* \param block block input for transformation
/*
* Final wrapup--call MD5Pad, fill in digest and zero out ctx.
*/
static void MD5Transform (unsigned int state[4], unsigned char block[64])
void
U_MD5Final(unsigned char digest[MD5_DIGEST_LENGTH], MD5_CTX *ctx)
{
unsigned int a = state[0], b = state[1], c = state[2], d = state[3], x[16];
Decode (x, block, 64);
/* Round 1 */
FF (a, b, c, d, x[ 0], S11, 0xd76aa478); /* 1 */
FF (d, a, b, c, x[ 1], S12, 0xe8c7b756); /* 2 */
FF (c, d, a, b, x[ 2], S13, 0x242070db); /* 3 */
FF (b, c, d, a, x[ 3], S14, 0xc1bdceee); /* 4 */
FF (a, b, c, d, x[ 4], S11, 0xf57c0faf); /* 5 */
FF (d, a, b, c, x[ 5], S12, 0x4787c62a); /* 6 */
FF (c, d, a, b, x[ 6], S13, 0xa8304613); /* 7 */
FF (b, c, d, a, x[ 7], S14, 0xfd469501); /* 8 */
FF (a, b, c, d, x[ 8], S11, 0x698098d8); /* 9 */
FF (d, a, b, c, x[ 9], S12, 0x8b44f7af); /* 10 */
FF (c, d, a, b, x[10], S13, 0xffff5bb1); /* 11 */
FF (b, c, d, a, x[11], S14, 0x895cd7be); /* 12 */
FF (a, b, c, d, x[12], S11, 0x6b901122); /* 13 */
FF (d, a, b, c, x[13], S12, 0xfd987193); /* 14 */
FF (c, d, a, b, x[14], S13, 0xa679438e); /* 15 */
FF (b, c, d, a, x[15], S14, 0x49b40821); /* 16 */
/* Round 2 */
GG (a, b, c, d, x[ 1], S21, 0xf61e2562); /* 17 */
GG (d, a, b, c, x[ 6], S22, 0xc040b340); /* 18 */
GG (c, d, a, b, x[11], S23, 0x265e5a51); /* 19 */
GG (b, c, d, a, x[ 0], S24, 0xe9b6c7aa); /* 20 */
GG (a, b, c, d, x[ 5], S21, 0xd62f105d); /* 21 */
GG (d, a, b, c, x[10], S22, 0x2441453); /* 22 */
GG (c, d, a, b, x[15], S23, 0xd8a1e681); /* 23 */
GG (b, c, d, a, x[ 4], S24, 0xe7d3fbc8); /* 24 */
GG (a, b, c, d, x[ 9], S21, 0x21e1cde6); /* 25 */
GG (d, a, b, c, x[14], S22, 0xc33707d6); /* 26 */
GG (c, d, a, b, x[ 3], S23, 0xf4d50d87); /* 27 */
GG (b, c, d, a, x[ 8], S24, 0x455a14ed); /* 28 */
GG (a, b, c, d, x[13], S21, 0xa9e3e905); /* 29 */
GG (d, a, b, c, x[ 2], S22, 0xfcefa3f8); /* 30 */
GG (c, d, a, b, x[ 7], S23, 0x676f02d9); /* 31 */
GG (b, c, d, a, x[12], S24, 0x8d2a4c8a); /* 32 */
/* Round 3 */
HH (a, b, c, d, x[ 5], S31, 0xfffa3942); /* 33 */
HH (d, a, b, c, x[ 8], S32, 0x8771f681); /* 34 */
HH (c, d, a, b, x[11], S33, 0x6d9d6122); /* 35 */
HH (b, c, d, a, x[14], S34, 0xfde5380c); /* 36 */
HH (a, b, c, d, x[ 1], S31, 0xa4beea44); /* 37 */
HH (d, a, b, c, x[ 4], S32, 0x4bdecfa9); /* 38 */
HH (c, d, a, b, x[ 7], S33, 0xf6bb4b60); /* 39 */
HH (b, c, d, a, x[10], S34, 0xbebfbc70); /* 40 */
HH (a, b, c, d, x[13], S31, 0x289b7ec6); /* 41 */
HH (d, a, b, c, x[ 0], S32, 0xeaa127fa); /* 42 */
HH (c, d, a, b, x[ 3], S33, 0xd4ef3085); /* 43 */
HH (b, c, d, a, x[ 6], S34, 0x4881d05); /* 44 */
HH (a, b, c, d, x[ 9], S31, 0xd9d4d039); /* 45 */
HH (d, a, b, c, x[12], S32, 0xe6db99e5); /* 46 */
HH (c, d, a, b, x[15], S33, 0x1fa27cf8); /* 47 */
HH (b, c, d, a, x[ 2], S34, 0xc4ac5665); /* 48 */
/* Round 4 */
II (a, b, c, d, x[ 0], S41, 0xf4292244); /* 49 */
II (d, a, b, c, x[ 7], S42, 0x432aff97); /* 50 */
II (c, d, a, b, x[14], S43, 0xab9423a7); /* 51 */
II (b, c, d, a, x[ 5], S44, 0xfc93a039); /* 52 */
II (a, b, c, d, x[12], S41, 0x655b59c3); /* 53 */
II (d, a, b, c, x[ 3], S42, 0x8f0ccc92); /* 54 */
II (c, d, a, b, x[10], S43, 0xffeff47d); /* 55 */
II (b, c, d, a, x[ 1], S44, 0x85845dd1); /* 56 */
II (a, b, c, d, x[ 8], S41, 0x6fa87e4f); /* 57 */
II (d, a, b, c, x[15], S42, 0xfe2ce6e0); /* 58 */
II (c, d, a, b, x[ 6], S43, 0xa3014314); /* 59 */
II (b, c, d, a, x[13], S44, 0x4e0811a1); /* 60 */
II (a, b, c, d, x[ 4], S41, 0xf7537e82); /* 61 */
II (d, a, b, c, x[11], S42, 0xbd3af235); /* 62 */
II (c, d, a, b, x[ 2], S43, 0x2ad7d2bb); /* 63 */
II (b, c, d, a, x[ 9], S44, 0xeb86d391); /* 64 */
int i;
MD5Pad(ctx);
if (digest != NULL) {
for (i = 0; i < 4; i++)
PUT_32BIT_LE(digest + i * 4, ctx->state[i]);
memset(ctx, 0, sizeof(*ctx));
}
}
state[0] += a;
state[1] += b;
state[2] += c;
state[3] += d;
/* Zeroize sensitive information.
*/
memset ((unsigned char *)x, 0, sizeof (x));
}
/* The four core functions - F1 is optimized somewhat */
/**
* \brief Encodes input (unsigned int) into output (unsigned char)
*
* Encodes input (unsigned int) into output (unsigned char). Assumes len is
* a multiple of 4.
* \param output output character
* \param input integer input
* \param len length of output
*/
static void Encode (unsigned char *output, unsigned int *input, unsigned int len)
{
unsigned int i, j;
/* #define F1(x, y, z) (x & y | ~x & z) */
#define F1(x, y, z) (z ^ (x & (y ^ z)))
#define F2(x, y, z) F1(z, x, y)
#define F3(x, y, z) (x ^ y ^ z)
#define F4(x, y, z) (y ^ (x | ~z))
for (i = 0, j = 0; j < len; i++, j += 4) {
output[j] = (unsigned char)(input[i] & 0xff);
output[j+1] = (unsigned char)((input[i] >> 8) & 0xff);
output[j+2] = (unsigned char)((input[i] >> 16) & 0xff);
output[j+3] = (unsigned char)((input[i] >> 24) & 0xff);
}
}
/* This is the central step in the MD5 algorithm. */
#define MD5STEP(f, w, x, y, z, data, s) \
( w += f(x, y, z) + data, w = w<<s | w>>(32-s), w += x )
/**
* \brief Decodes input (unsigned char) into output (unsigned int)
*
* Decodes input (unsigned char) into output (unsigned int). Assumes len is
* a multiple of 4.
* \param output output integer
* \param input input character
* \param len length of input
/*
* The core of the MD5 algorithm, this alters an existing MD5 hash to
* reflect the addition of 16 longwords of new data. MD5Update blocks
* the data and converts bytes into longwords for this routine.
*/
static void Decode (unsigned int *output, unsigned char *input, unsigned int len)
void
MD5Transform(u_int32_t state[4], const u_int8_t block[MD5_BLOCK_LENGTH])
{
unsigned int i, j;
for (i = 0, j = 0; j < len; i++, j += 4)
output[i] = ((unsigned int)input[j]) | (((unsigned int)input[j+1]) << 8) |
(((unsigned int)input[j+2]) << 16) | (((unsigned int)input[j+3]) << 24);
u_int32_t a, b, c, d, in[MD5_BLOCK_LENGTH / 4];
#ifndef WORDS_BIGENDIAN
memcpy(in, block, sizeof(in));
#else
for (a = 0; a < MD5_BLOCK_LENGTH / 4; a++) {
in[a] = (u_int32_t)(
(u_int32_t)(block[a * 4 + 0]) |
(u_int32_t)(block[a * 4 + 1]) << 8 |
(u_int32_t)(block[a * 4 + 2]) << 16 |
(u_int32_t)(block[a * 4 + 3]) << 24);
}
#endif
a = state[0];
b = state[1];
c = state[2];
d = state[3];
MD5STEP(F1, a, b, c, d, in[ 0] + 0xd76aa478, 7);
MD5STEP(F1, d, a, b, c, in[ 1] + 0xe8c7b756, 12);
MD5STEP(F1, c, d, a, b, in[ 2] + 0x242070db, 17);
MD5STEP(F1, b, c, d, a, in[ 3] + 0xc1bdceee, 22);
MD5STEP(F1, a, b, c, d, in[ 4] + 0xf57c0faf, 7);
MD5STEP(F1, d, a, b, c, in[ 5] + 0x4787c62a, 12);
MD5STEP(F1, c, d, a, b, in[ 6] + 0xa8304613, 17);
MD5STEP(F1, b, c, d, a, in[ 7] + 0xfd469501, 22);
MD5STEP(F1, a, b, c, d, in[ 8] + 0x698098d8, 7);
MD5STEP(F1, d, a, b, c, in[ 9] + 0x8b44f7af, 12);
MD5STEP(F1, c, d, a, b, in[10] + 0xffff5bb1, 17);
MD5STEP(F1, b, c, d, a, in[11] + 0x895cd7be, 22);
MD5STEP(F1, a, b, c, d, in[12] + 0x6b901122, 7);
MD5STEP(F1, d, a, b, c, in[13] + 0xfd987193, 12);
MD5STEP(F1, c, d, a, b, in[14] + 0xa679438e, 17);
MD5STEP(F1, b, c, d, a, in[15] + 0x49b40821, 22);
MD5STEP(F2, a, b, c, d, in[ 1] + 0xf61e2562, 5);
MD5STEP(F2, d, a, b, c, in[ 6] + 0xc040b340, 9);
MD5STEP(F2, c, d, a, b, in[11] + 0x265e5a51, 14);
MD5STEP(F2, b, c, d, a, in[ 0] + 0xe9b6c7aa, 20);
MD5STEP(F2, a, b, c, d, in[ 5] + 0xd62f105d, 5);
MD5STEP(F2, d, a, b, c, in[10] + 0x02441453, 9);
MD5STEP(F2, c, d, a, b, in[15] + 0xd8a1e681, 14);
MD5STEP(F2, b, c, d, a, in[ 4] + 0xe7d3fbc8, 20);
MD5STEP(F2, a, b, c, d, in[ 9] + 0x21e1cde6, 5);
MD5STEP(F2, d, a, b, c, in[14] + 0xc33707d6, 9);
MD5STEP(F2, c, d, a, b, in[ 3] + 0xf4d50d87, 14);
MD5STEP(F2, b, c, d, a, in[ 8] + 0x455a14ed, 20);
MD5STEP(F2, a, b, c, d, in[13] + 0xa9e3e905, 5);
MD5STEP(F2, d, a, b, c, in[ 2] + 0xfcefa3f8, 9);
MD5STEP(F2, c, d, a, b, in[ 7] + 0x676f02d9, 14);
MD5STEP(F2, b, c, d, a, in[12] + 0x8d2a4c8a, 20);
MD5STEP(F3, a, b, c, d, in[ 5] + 0xfffa3942, 4);
MD5STEP(F3, d, a, b, c, in[ 8] + 0x8771f681, 11);
MD5STEP(F3, c, d, a, b, in[11] + 0x6d9d6122, 16);
MD5STEP(F3, b, c, d, a, in[14] + 0xfde5380c, 23);
MD5STEP(F3, a, b, c, d, in[ 1] + 0xa4beea44, 4);
MD5STEP(F3, d, a, b, c, in[ 4] + 0x4bdecfa9, 11);
MD5STEP(F3, c, d, a, b, in[ 7] + 0xf6bb4b60, 16);
MD5STEP(F3, b, c, d, a, in[10] + 0xbebfbc70, 23);
MD5STEP(F3, a, b, c, d, in[13] + 0x289b7ec6, 4);
MD5STEP(F3, d, a, b, c, in[ 0] + 0xeaa127fa, 11);
MD5STEP(F3, c, d, a, b, in[ 3] + 0xd4ef3085, 16);
MD5STEP(F3, b, c, d, a, in[ 6] + 0x04881d05, 23);
MD5STEP(F3, a, b, c, d, in[ 9] + 0xd9d4d039, 4);
MD5STEP(F3, d, a, b, c, in[12] + 0xe6db99e5, 11);
MD5STEP(F3, c, d, a, b, in[15] + 0x1fa27cf8, 16);
MD5STEP(F3, b, c, d, a, in[2 ] + 0xc4ac5665, 23);
MD5STEP(F4, a, b, c, d, in[ 0] + 0xf4292244, 6);
MD5STEP(F4, d, a, b, c, in[7 ] + 0x432aff97, 10);
MD5STEP(F4, c, d, a, b, in[14] + 0xab9423a7, 15);
MD5STEP(F4, b, c, d, a, in[5 ] + 0xfc93a039, 21);
MD5STEP(F4, a, b, c, d, in[12] + 0x655b59c3, 6);
MD5STEP(F4, d, a, b, c, in[3 ] + 0x8f0ccc92, 10);
MD5STEP(F4, c, d, a, b, in[10] + 0xffeff47d, 15);
MD5STEP(F4, b, c, d, a, in[1 ] + 0x85845dd1, 21);
MD5STEP(F4, a, b, c, d, in[8 ] + 0x6fa87e4f, 6);
MD5STEP(F4, d, a, b, c, in[15] + 0xfe2ce6e0, 10);
MD5STEP(F4, c, d, a, b, in[6 ] + 0xa3014314, 15);
MD5STEP(F4, b, c, d, a, in[13] + 0x4e0811a1, 21);
MD5STEP(F4, a, b, c, d, in[4 ] + 0xf7537e82, 6);
MD5STEP(F4, d, a, b, c, in[11] + 0xbd3af235, 10);
MD5STEP(F4, c, d, a, b, in[2 ] + 0x2ad7d2bb, 15);
MD5STEP(F4, b, c, d, a, in[9 ] + 0xeb86d391, 21);
state[0] += a;
state[1] += b;
state[2] += c;
state[3] += d;
}

123
md5.h

@ -1,102 +1,45 @@
/* $OpenBSD: md5.h,v 1.15 2004/05/03 17:30:14 millert Exp $ */
/*
* Copyright (C) 1991-2, RSA Data Security, Inc. Created 1991. All
* rights reserved.
*
* License to copy and use this software is granted provided that it
* is identified as the "RSA Data Security, Inc. MD5 Message-Digest
* Algorithm" in all material mentioning or referencing this software
* or this function.
*
* License is also granted to make and use derivative works provided
* that such works are identified as "derived from the RSA Data
* Security, Inc. MD5 Message-Digest Algorithm" in all material
* mentioning or referencing the derived work.
*
* RSA Data Security, Inc. makes no representations concerning either
* the merchantability of this software or the suitability of this
* software for any particular purpose. It is provided "as is"
* without express or implied warranty of any kind.
*
* These notices must be retained in any copies of any part of this
* documentation and/or software.
* This code implements the MD5 message-digest algorithm.
* The algorithm is due to Ron Rivest. This code was
* written by Colin Plumb in 1993, no copyright is claimed.
* This code is in the public domain; do with it what you wish.
*
* Equivalent code is available from RSA Data Security, Inc.
* This code has been tested against that, and is equivalent,
* except that you don't need to include two pages of legalese
* with every copy.
*/
/*!
* \file
* \brief SIP-router core :: md5 hash support
* \ingroup core
* Module: \ref core
*/
#ifndef _MD5_H_
#define _MD5_H_
#ifndef MD5_H
#define MD5_H
#define MD5_BLOCK_LENGTH 64
#define MD5_DIGEST_LENGTH 16
#define MD5_DIGEST_STRING_LENGTH (MD5_DIGEST_LENGTH * 2 + 1)
/**
* \brief MD5 context
*/
typedef struct {
unsigned int state[4]; /* state (ABCD) */
unsigned int count[2]; /* number of bits, modulo 2^64 (lsb first) */
unsigned char buffer[64]; /* input buffer */
} MD5_CTX;
/**
* \brief MD5 context initialization
*
* MD5 context initialization. Begins an MD5 operation, writing a new context.
* \param context initialized context
*/
void MD5Init (MD5_CTX *context);
/* Probably not the proper place, but will do for Debian: */
#include <sys/types.h>
/**
* \brief MD5 block update operation
*
* MD5 block update operation. Continues an MD5 message-digest
* operation, processing another message block, and updating the
* context.
* \param context context
* \param input input block
* \param inputLen length of input block
*/
void U_MD5Update (MD5_CTX *context, unsigned char *input, unsigned int inputLen);
typedef struct MD5Context {
u_int32_t state[4]; /* state */
u_int64_t count; /* number of bits, mod 2^64 */
unsigned char buffer[MD5_BLOCK_LENGTH]; /* input buffer */
} MD5_CTX;
/**
* \brief MD5 finalization
*
* MD5 finalization. Ends an MD5 message-digest operation, writing the
* the message digest and zeroizing the context.
* \param digest message digest
* \param context context
*/
void U_MD5Final (unsigned char digest[16], MD5_CTX *context);
void MD5Init(MD5_CTX *);
void U_MD5Update(MD5_CTX *, const unsigned char *, size_t);
void MD5Pad(MD5_CTX *);
void U_MD5Final(unsigned char [MD5_DIGEST_LENGTH], MD5_CTX *);
void MD5Transform(u_int32_t [4], const unsigned char [MD5_BLOCK_LENGTH]);
/*!
* \brief Small wrapper around MD5Update
*
* Small wrapper around MD5Update, because everybody uses this on 'str' types
* \param context MD5 context
* \param input input block
* \param inputLen length of input block
* \note please not use this in new code
* \todo review and fix all wrong usage
*/
static inline void MD5Update (MD5_CTX *context, char *input, unsigned int inputLen)
{
return U_MD5Update(context, (unsigned char *)input, inputLen);
static inline void MD5Update(MD5_CTX *ctx, const char *str, size_t len) {
U_MD5Update(ctx, (const unsigned char *)str, len);
}
/*!
* \brief Small wrapper around MD5Final
*
* Small wrapper around MD5Final, because everybody uses this on 'str' types
* \param digest message digest
* \param context MD5 context
* \note please not use this in new code
* \todo review and fix all wrong usage
*/
static inline void MD5Final (char digest[16], MD5_CTX *context)
{
U_MD5Final((unsigned char *)digest, context);
static inline void MD5Final(char buf[MD5_DIGEST_LENGTH], MD5_CTX *ctx) {
U_MD5Final((unsigned char *)buf, ctx);
}
#endif /* MD5_H */
#endif /* _MD5_H_ */

@ -507,18 +507,21 @@ void fm_free(struct fm_block* qm, void* p)
#ifdef DBG_F_MALLOC
MDBG("fm_free(%p, %p), called from %s: %s(%d)\n", qm, p, file, func, line);
#endif
if (p==0) {
MDBG("WARNING:fm_free: free(0) called\n");
return;
}
#ifdef DBG_F_MALLOC
if (p>(void*)qm->last_frag || p<(void*)qm->first_frag){
LOG(L_CRIT, "BUG: fm_free: bad pointer %p (out of memory block!),"
" called from %s: %s(%d) - aborting\n", p,
file, func, line);
if(likely(cfg_get(core, core_cfg, mem_safety)==0))
abort();
else return;
}
#endif
if (p==0) {
LOG(L_WARN, "WARNING:fm_free: free(0) called\n");
return;
}
f=(struct fm_frag*) ((char*)p-sizeof(struct fm_frag));
#ifdef DBG_F_MALLOC
MDBG("fm_free: freeing block alloc'ed from %s: %s(%ld)\n",

@ -435,18 +435,29 @@ void qm_free(struct qm_block* qm, void* p)
#ifdef DBG_QM_MALLOC
MDBG("qm_free(%p, %p), called from %s: %s(%d)\n", qm, p, file, func, line);
#endif
if (p==0) {
#ifdef DBG_QM_MALLOC
LOG(L_WARN, "WARNING:qm_free: free(0) called from %s: %s(%d)\n", file, func, line);
#else
LOG(L_WARN, "WARNING:qm_free: free(0) called\n");
#endif
return;
}
#ifdef DBG_QM_MALLOC
if (p>(void*)qm->last_frag_end || p<(void*)qm->first_frag){
LOG(L_CRIT, "BUG: qm_free: bad pointer %p (out of memory block!)"
" called from %s: %s(%d) - aborting\n", p, file, func, line);
if(likely(cfg_get(core, core_cfg, mem_safety)==0))
abort();
else return;
}
#endif
if (p==0) {
LOG(L_WARN, "WARNING:qm_free: free(0) called\n");
return;
}
f=(struct qm_frag*) ((char*)p-sizeof(struct qm_frag));
#ifdef DBG_QM_MALLOC
qm_debug_frag(qm, f);
if (f->u.is_free){
@ -455,6 +466,7 @@ void qm_free(struct qm_block* qm, void* p)
p, file, func, line, f->file, f->func, f->line);
if(likely(cfg_get(core, core_cfg, mem_safety)==0))
abort();
else return;
}
MDBG("qm_free: freeing frag. %p alloc'ed from %s: %s(%ld)\n",
f, f->file, f->func, f->line);

@ -16,7 +16,7 @@ Alex Balashov
<abalashov@evaristesys.com>
Copyright © 2012 Daniel-Constantin Mierla (asipto.com)
Copyright © 2012 Daniel-Constantin Mierla (asipto.com)
__________________________________________________________________
Table of Contents
@ -43,8 +43,8 @@ Alex Balashov
List of Examples
1.1. Set load parameter
1.2. lua_dofile usage
1.3. lua_run usage
1.2. mono_exec usage
1.3. mono_run usage
Chapter 1. Admin Guide
@ -113,7 +113,7 @@ Chapter 1. Admin Guide
Set the path to the Mono assembly to be loaded at startup. You can use
mono_run(param) to execute the assembly at runtime.
Default value is “null”.
Default value is "null".
Example 1.1. Set load parameter
...
@ -125,7 +125,7 @@ modparam("app_mono", "load", "/usr/local/etc/kamailio/mono/myscript.exe")
4.1. mono_exec(path [, param])
4.2. mono_run([param])
4.1. mono_exec(path [, param])
4.1. mono_exec(path [, param])
Execute the managed code assembly stored in 'path'. The path can be a
string with pseudo-variables evaluated at runtime. A second parameter
@ -135,12 +135,12 @@ modparam("app_mono", "load", "/usr/local/etc/kamailio/mono/myscript.exe")
change to it is immediately live. This function cannot be used if
'load' parameter is set.
Example 1.2. lua_dofile usage
Example 1.2. mono_exec usage
...
mono_exec("/usr/local/etc/kamailio/mono/myscript.exe");
...
4.2. mono_run([param])
4.2. mono_run([param])
Execute the assembly specified by 'load' module parameter. The assembly
is loaded at startup, so changes to it will be effective only after
@ -150,7 +150,7 @@ mono_exec("/usr/local/etc/kamailio/mono/myscript.exe");
assembly. It can be a string with pseudo-variables; these will be
evaluated at runtime.
Example 1.3. lua_run usage
Example 1.3. mono_run usage
...
if(!mono_run("myparam"))
{

@ -111,7 +111,7 @@ modparam("app_mono", "load", "/usr/local/etc/kamailio/mono/myscript.exe")
parameter is set.
</para>
<example>
<title><function>lua_dofile</function> usage</title>
<title><function>mono_exec</function> usage</title>
<programlisting format="linespecific">
...
mono_exec("/usr/local/etc/kamailio/mono/myscript.exe");
@ -135,7 +135,7 @@ mono_exec("/usr/local/etc/kamailio/mono/myscript.exe");
evaluated at runtime.
</para>
<example>
<title><function>lua_run</function> usage</title>
<title><function>mono_run</function> usage</title>
<programlisting format="linespecific">
...
if(!mono_run("myparam"))

@ -145,7 +145,7 @@ static int auth_check_hdr_md5(struct sip_msg* msg, auth_body_t* auth,
*auth_res = NONCE_REUSED;
return 0;
} else {
DBG("auth:pre_auth: Invalid nonce value received\n");
DBG("auth:pre_auth: Invalid nonce value received (ret %d)\n", ret);
*auth_res = NOT_AUTHENTICATED;
return 0;
}

@ -194,7 +194,8 @@ default_validation_class='UTF8Type' and key_validation_class='UTF8Type';
...
callid(string) cflags(int) contact(string) cseq(int) expires(timestamp) flags
(int) last_modified(int) methods(int) path(string) q(double) received(string) so
cket(string) user_agent(string) username(string)
cket(string) user_agent(string) username(string) ruid(string) instance(string) r
eg_id(int)
username
contact
...

@ -136,7 +136,7 @@ int db_cassa_bind_api(db_func_t *dbb)
dbb->query = db_cassa_query;
dbb->free_result = db_cassa_free_result;
dbb->insert = db_cassa_insert;
dbb->replace = db_cassa_insert;
dbb->replace = db_cassa_replace;
dbb->insert_update = db_cassa_insert;
dbb->delete = db_cassa_delete;
dbb->update = db_cassa_update;

@ -535,7 +535,7 @@ ColumnVecPtr cassa_translate_query(const db1_con_t* _h, const db_key_t* _k,
while(1) {
CON_CASSA(_h)->con->get_range_slices(key_slice_vect, cparent, sp, keyRange, oac::ConsistencyLevel::ONE);
/* construct cassa_result */
LM_DBG("Retuned %d key slices\n", key_slice_vect.size());
LM_DBG("Retuned %d key slices\n", (int)key_slice_vect.size());
for(unsigned int i = 0; i< key_slice_vect.size(); i++) {
if(key_slice_vect[i].columns.size()==0) {
continue;
@ -645,6 +645,7 @@ int db_cassa_query(const db1_con_t* _h, const db_key_t* _k, const db_op_t* _op,
if (! RES_NAMES(db_res)[col]) {
LM_ERR("no private memory left\n");
dbcassa_lock_release(tbc);
RES_COL_N(db_res) = col;
db_free_columns(db_res);
goto error;
}
@ -656,6 +657,7 @@ int db_cassa_query(const db1_con_t* _h, const db_key_t* _k, const db_op_t* _op,
if(!colp) {
LM_ERR("No column with name [%.*s] found\n", _c[col]->len, _c[col]->s);
dbcassa_lock_release(tbc);
RES_COL_N(db_res) = col;
db_free_columns(db_res);
goto error;
}
@ -881,6 +883,12 @@ int db_cassa_modify(const db1_con_t* _h, const db_key_t* _k, const db_val_t* _v,
return -1;
}
int db_cassa_replace(const db1_con_t* _h, const db_key_t* _k, const db_val_t* _v,
int _n, const int _un, const int _m)
{
LM_DBG("db_cassa_replace:\n");
return db_cassa_modify(_h, _k, _v, _k, _v, _n, _n);
}
int db_cassa_insert(const db1_con_t* _h, const db_key_t* _k, const db_val_t* _v,
int _n)

@ -71,6 +71,12 @@ int db_cassa_insert(const db1_con_t* _h, const db_key_t* _k, const db_val_t* _v,
int _n);
/*
* Replace a row into table - same as insert for cassandra
*/
int db_cassa_replace(const db1_con_t* _h, const db_key_t* _k, const db_val_t* _v,
int _n, const int _un, const int _m);
/*
* Delete a row from table
*/

@ -214,7 +214,7 @@ default_validation_class='UTF8Type' and key_validation_class='UTF8Type';
<programlisting format="linespecific">
...
callid(string) cflags(int) contact(string) cseq(int) <emphasis>expires(timestamp)</emphasis> flags(int) last_modified(int) methods(int) path(string) q(double) received(string) socket(string) user_agent(string) username(string)
callid(string) cflags(int) contact(string) cseq(int) <emphasis>expires(timestamp)</emphasis> flags(int) last_modified(int) methods(int) path(string) q(double) received(string) socket(string) user_agent(string) username(string) ruid(string) instance(string) reg_id(int)
<emphasis>username</emphasis>
<emphasis>contact</emphasis>
...

@ -163,6 +163,7 @@ void db_postgres_close(db1_con_t* _h)
*/
static int db_postgres_submit_query(const db1_con_t* _con, const str* _s)
{
char *s=NULL;
int i, retries;
ExecStatusType pqresult;
@ -199,17 +200,29 @@ static int db_postgres_submit_query(const db1_con_t* _con, const str* _s)
else
retries = pg_retries;
s = pkg_malloc((_s->len+1)*sizeof(char));
if (s==NULL)
{
LM_ERR("%p db_postgres_submit_query Out of Memory: Query: %.*s\n", _con, _s->len, _s->s);
return -1;
}
memcpy( s, _s->s, _s->len );
s[_s->len] = '\0';
for(i = 0; i <= retries; i++) {
/* free any previous query that is laying about */
db_postgres_free_query(_con);
/* exec the query */
if (PQsendQuery(CON_CONNECTION(_con), _s->s)) {
if (PQsendQuery(CON_CONNECTION(_con), s)) {
pqresult = PQresultStatus(CON_RESULT(_con));
if((pqresult!=PGRES_FATAL_ERROR)
|| (PQstatus(CON_CONNECTION(_con))==CONNECTION_OK))
{
LM_DBG("sending query ok: %p (%d) - [%.*s]\n",
_con, pqresult, _s->len, _s->s);
pkg_free(s);
return 0;
}
LM_WARN("postgres result check failed with code %d (%s)\n",
@ -226,6 +239,7 @@ static int db_postgres_submit_query(const db1_con_t* _con, const str* _s)
}
LM_ERR("%p PQsendQuery Error: %s Query: %.*s\n", _con,
PQerrorMessage(CON_CONNECTION(_con)), _s->len, _s->s);
pkg_free(s);
return -1;
}

@ -277,13 +277,14 @@ static int dp_update(struct sip_msg * msg, pv_spec_t * src, pv_spec_t * dest,
int no_change;
pv_value_t val;
no_change = (dest->type == PVT_NONE) || (!repl->s);
memset(&val, 0, sizeof(pv_value_t));
val.flags = PV_VAL_STR;
no_change = (dest->type == PVT_NONE) || (!repl->s) || (!repl->len);
if (no_change)
goto set_attr_pvar;
memset(&val, 0, sizeof(pv_value_t));
val.flags = PV_VAL_STR;
val.rs = *repl;
if(dest->setf(msg, &dest->pvp, (int)EQ_T, &val)<0)

@ -147,9 +147,41 @@ int rule_translate(struct sip_msg *msg, str string, dpl_node_t * rule,
subst_comp = rule->subst_comp;
repl_comp = rule->repl_comp;
if (!subst_comp) {
/*simply copy from the replacing string*/
if(!repl_comp || !repl_comp->replacement.s || repl_comp->replacement.len == 0){
if(!repl_comp){
LM_DBG("null replacement\n");
return 0;
}
if(subst_comp){
/*just in case something went wrong at load time*/
rc = pcre_fullinfo(subst_comp, NULL, PCRE_INFO_CAPTURECOUNT,
&cap_cnt);
if (rc != 0) {
LM_ERR("pcre_fullinfo on compiled pattern yielded error: %d\n",
rc);
return -1;;
}
if(repl_comp->max_pmatch > cap_cnt){
LM_ERR("illegal access to the %i-th subexpr of the subst expr\n",
repl_comp->max_pmatch);
return -1;
}
/*search for the pattern from the compiled subst_exp*/
if (pcre_exec(rule->subst_comp, NULL, string.s, string.len,
0, 0, ovector, 3 * (MAX_REPLACE_WITH + 1)) <= 0) {
LM_ERR("the string %.*s matched "
"the match_exp %.*s but not the subst_exp %.*s!\n",
string.len, string.s,
rule->match_exp.len, rule->match_exp.s,
rule->subst_exp.len, rule->subst_exp.s);
return -1;
}
}
/*simply copy from the replacing string*/
if(!subst_comp || (repl_comp->n_escapes <=0)){
if(!repl_comp->replacement.s || repl_comp->replacement.len == 0){
LM_ERR("invalid replacing string\n");
goto error;
}
@ -162,156 +194,108 @@ int rule_translate(struct sip_msg *msg, str string, dpl_node_t * rule,
return 0;
}
/*just in case something went wrong at load time*/
rc = pcre_fullinfo(subst_comp, NULL, PCRE_INFO_CAPTURECOUNT,
&cap_cnt);
if (rc != 0) {
LM_ERR("pcre_fullinfo on compiled pattern yielded error: %d\n",
rc);
return -1;;
}
if(repl_comp && repl_comp->max_pmatch > cap_cnt){
LM_ERR("illegal access to the %i-th subexpr of the subst expr\n",
repl_comp->max_pmatch);
return -1;
}
/* offset- offset in the replacement string */
result->len = repl_nb = offset = 0;
p=repl_comp->replacement.s;
/*search for the pattern from the compiled subst_exp*/
if (pcre_exec(rule->subst_comp, NULL, string.s, string.len,
0, 0, ovector, 3 * (MAX_REPLACE_WITH + 1)) <= 0) {
LM_ERR("the string %.*s matched "
"the match_exp %.*s but not the subst_exp %.*s!\n",
string.len, string.s,
rule->match_exp.len, rule->match_exp.s,
rule->subst_exp.len, rule->subst_exp.s);
return -1;
}
/* copy non-matched prefix of string to output */
if (ovector[0] > 0) {
if (ovector[0] >= MAX_PHONE_NB_DIGITS) {
LM_ERR("overflow\n");
goto error;
}
memcpy(result->s, string.s, ovector[0]);
result->len += ovector[0];
}
while( repl_nb < repl_comp->n_escapes){
if (repl_comp) {
/* offset- offset in the replacement string */
repl_nb = offset = 0;
p=repl_comp->replacement.s;
token = repl_comp->replace[repl_nb];
while( repl_nb < repl_comp->n_escapes){
token = repl_comp->replace[repl_nb];
if(offset< token.offset){
if((repl_comp->replacement.len < offset)||
if(offset< token.offset){
if((repl_comp->replacement.len < offset)||
(result->len + token.offset -offset >= MAX_PHONE_NB_DIGITS)){
LM_ERR("invalid length\n");
LM_ERR("invalid length\n");
goto error;
}
/*copy from the replacing string*/
size = token.offset - offset;
memcpy(result->s + result->len, p + offset, size);
LM_DBG("copying <%.*s> from replacing string\n",
size, p + offset);
result->len += size;
offset = token.offset;
}
switch(token.type) {
case REPLACE_NMATCH:
/*copy from the match subexpression*/
match_nb = token.u.nmatch * 2;
match.s = string.s + ovector[match_nb];
match.len = ovector[match_nb + 1] - ovector[match_nb];
if(result->len + match.len >= MAX_PHONE_NB_DIGITS){
LM_ERR("overflow\n");
goto error;
}
/*copy from the replacing string*/
size = token.offset - offset;
memcpy(result->s + result->len, p + offset, size);
LM_DBG("copying <%.*s> from replacing string\n",
size, p + offset);
result->len += size;
offset = token.offset;
}
switch(token.type) {
case REPLACE_NMATCH:
/*copy from the match subexpression*/
match_nb = token.u.nmatch * 2;
match.s = string.s + ovector[match_nb];
match.len = ovector[match_nb + 1] - ovector[match_nb];
if(result->len + match.len >= MAX_PHONE_NB_DIGITS){
LM_ERR("overflow\n");
goto error;
}
memcpy(result->s + result->len, match.s, match.len);
LM_DBG("copying match <%.*s> token size %d\n",
match.len, match.s, token.size);
result->len += match.len;
offset += token.size;
memcpy(result->s + result->len, match.s, match.len);
LM_DBG("copying match <%.*s> token size %d\n",
match.len, match.s, token.size);
result->len += match.len;
offset += token.size;
break;
case REPLACE_CHAR:
if(result->len + 1>= MAX_PHONE_NB_DIGITS){
LM_ERR("overflow\n");
goto error;
}
*(result->s + result->len) = token.u.c;
LM_DBG("copying char <%c> token size %d\n",
case REPLACE_CHAR:
if(result->len + 1>= MAX_PHONE_NB_DIGITS){
LM_ERR("overflow\n");
goto error;
}
*(result->s + result->len) = token.u.c;
LM_DBG("copying char <%c> token size %d\n",
token.u.c, token.size);
result->len++;
offset += token.size;
result->len++;
offset += token.size;
break;
case REPLACE_URI:
if ( msg== NULL || msg->first_line.type!=SIP_REQUEST){
LM_CRIT("uri substitution attempt on no request"
case REPLACE_URI:
if ( msg== NULL || msg->first_line.type!=SIP_REQUEST){
LM_CRIT("uri substitution attempt on no request"
" message\n");
break; /* ignore, we can continue */
}
uri= (msg->new_uri.s)?(&msg->new_uri):
(&msg->first_line.u.request.uri);
if(result->len+uri->len>=MAX_PHONE_NB_DIGITS){
LM_ERR("overflow\n");
goto error;
}
memcpy(result->s + result->len, uri->s, uri->len);
LM_DBG("copying uri <%.*s> token size %d\n",
break; /* ignore, we can continue */
}
uri= (msg->new_uri.s)?(&msg->new_uri):
(&msg->first_line.u.request.uri);
if(result->len+uri->len>=MAX_PHONE_NB_DIGITS){
LM_ERR("overflow\n");
goto error;
}
memcpy(result->s + result->len, uri->s, uri->len);
LM_DBG("copying uri <%.*s> token size %d\n",
uri->len, uri->s, token.size);
result->len+=uri->len;
offset += token.size;
result->len+=uri->len;
offset += token.size;
break;
case REPLACE_SPEC:
if (msg== NULL) {
LM_DBG("replace spec attempted on no message\n");
break;
}
if (pv_get_spec_value(msg, &token.u.spec, &sv) != 0) {
LM_CRIT("item substitution returned error\n");
break; /* ignore, we can continue */
}
if(result->len+sv.rs.len>=MAX_PHONE_NB_DIGITS){
LM_ERR("rule_translate: overflow\n");
goto error;
}
memcpy(result->s + result->len, sv.rs.s,
sv.rs.len);
LM_DBG("copying pvar value <%.*s> token size %d\n",
case REPLACE_SPEC:
if (msg== NULL) {
LM_DBG("replace spec attempted on no message\n");
break;
}
if (pv_get_spec_value(msg, &token.u.spec, &sv) != 0) {
LM_CRIT("item substitution returned error\n");
break; /* ignore, we can continue */
}
if(result->len+sv.rs.len>=MAX_PHONE_NB_DIGITS){
LM_ERR("rule_translate: overflow\n");
goto error;
}
memcpy(result->s + result->len, sv.rs.s,
sv.rs.len);
LM_DBG("copying pvar value <%.*s> token size %d\n",
sv.rs.len, sv.rs.s, token.size);
result->len+=sv.rs.len;
offset += token.size;
result->len+=sv.rs.len;
offset += token.size;
break;
default:
LM_CRIT("unknown type %d\n", repl_comp->replace[repl_nb].type);
/* ignore it */
}
repl_nb++;
}
/* anything left? */
if(offset < repl_comp->replacement.len){
/*copy from the replacing string*/
size = repl_comp->replacement.len - offset;
memcpy(result->s + result->len, p + offset, size);
LM_DBG("copying leftover <%.*s> from replacing string\n",
size, p + offset);
result->len += size;
default:
LM_CRIT("unknown type %d\n", repl_comp->replace[repl_nb].type);
/* ignore it */
}
repl_nb++;
}
/* copy non-matched suffix of string to output */
size = string.len - ovector[1];
if (size > 0) {
if (result->len + size >= MAX_PHONE_NB_DIGITS) {
LM_ERR("overflow\n");
goto error;
}
memcpy(result->s + result->len, string.s + ovector[1], size);
/* anything left? */
if( repl_nb && offset < repl_comp->replacement.len){
/*copy from the replacing string*/
size = repl_comp->replacement.len - offset;
memcpy(result->s + result->len, p + offset, size);
LM_DBG("copying leftover <%.*s> from replacing string\n",
size, p + offset);
result->len += size;
}

@ -260,7 +260,7 @@ int pv_get_msrp(sip_msg_t *msg, pv_param_t *param, pv_value_t *res)
sar = (str_array_t*)hdr->parsed.data;
return pv_get_uintval(msg, param, res, sar->size);
case 18:
if(msrp_parse_hdr_from_path(mf)<0)
if(msrp_parse_hdr_to_path(mf)<0)
return pv_get_null(msg, param, res);
hdr = msrp_get_hdr_by_id(mf, MSRP_HDR_TO_PATH);
if(hdr==NULL)

@ -283,8 +283,7 @@ static int alter_mediaport(struct sip_msg *, str *, str *, str *, int);
static int alter_rtcp(struct sip_msg *msg, str *body, str *oldport, str *newport);
static char *gencookie();
static int rtpp_test(struct rtpp_node*, int, int);
static int unforce_rtp_proxy0_f(struct sip_msg *, char *, char *);
static int unforce_rtp_proxy1_f(struct sip_msg *, char *, char *);
static int unforce_rtp_proxy_f(struct sip_msg *, char *, char *);
static int force_rtp_proxy(struct sip_msg *, char *, char *, int, int);
static int start_recording_f(struct sip_msg *, char *, char *);
static int rtpproxy_answer1_f(struct sip_msg *, char *, char *);
@ -350,16 +349,10 @@ static cmd_export_t cmds[] = {
{"set_rtp_proxy_set", (cmd_function)set_rtp_proxy_set_f, 1,
fixup_set_id, 0,
ANY_ROUTE},
{"unforce_rtp_proxy", (cmd_function)unforce_rtp_proxy0_f, 0,
{"unforce_rtp_proxy", (cmd_function)unforce_rtp_proxy_f, 0,
0, 0,
ANY_ROUTE},
{"unforce_rtp_proxy", (cmd_function)unforce_rtp_proxy1_f, 1,
0, 0,
ANY_ROUTE},
{"rtpproxy_destroy", (cmd_function)unforce_rtp_proxy0_f, 0,
0, 0,
ANY_ROUTE},
{"rtpproxy_destroy", (cmd_function)unforce_rtp_proxy1_f, 1,
{"rtpproxy_destroy", (cmd_function)unforce_rtp_proxy_f, 0,
0, 0,
ANY_ROUTE},
{"start_recording", (cmd_function)start_recording_f, 0,
@ -1645,14 +1638,7 @@ found:
}
static int
unforce_rtp_proxy0_f(struct sip_msg* msg, char* str1, char* str2)
{
char arg[1] = {'\0'};
return unforce_rtp_proxy1_f(msg, arg, str2);
}
static int
unforce_rtp_proxy1_f(struct sip_msg* msg, char* str1, char* str2)
unforce_rtp_proxy_f(struct sip_msg* msg, char* str1, char* str2)
{
str callid, from_tag, to_tag, viabranch;
char *cp;
@ -1754,7 +1740,7 @@ rtpproxy_manage(struct sip_msg *msg, char *flags, char *ip)
return -1;
if(method==METHOD_CANCEL || method==METHOD_BYE)
return unforce_rtp_proxy0_f(msg, 0, 0);
return unforce_rtp_proxy_f(msg, 0, 0);
if(ip==NULL)
{
@ -1780,13 +1766,13 @@ rtpproxy_manage(struct sip_msg *msg, char *flags, char *ip)
&& tmb.t_gett()!=T_UNDEFINED)
tmb.t_gett()->uas.request->msg_flags |= FL_SDP_BODY;
if(route_type==FAILURE_ROUTE)
return unforce_rtp_proxy0_f(msg, 0, 0);
return unforce_rtp_proxy_f(msg, 0, 0);
return force_rtp_proxy(msg, flags, (cp!=NULL)?newip:ip, 1,
(ip!=NULL)?1:0);
}
} else if(msg->first_line.type == SIP_REPLY) {
if(msg->first_line.u.reply.statuscode>=300)
return unforce_rtp_proxy0_f(msg, 0, 0);
return unforce_rtp_proxy_f(msg, 0, 0);
if(nosdp==0) {
if(method==METHOD_UPDATE)
return force_rtp_proxy(msg, flags, (cp!=NULL)?newip:ip, 0,
@ -2547,19 +2533,20 @@ pv_get_rtpstat_f(struct sip_msg *msg, pv_param_t *param,
str from_tag = {0, 0};
str to_tag = {0, 0};
struct rtpp_node *node;
struct iovec v[1 + 4 + 3 + 1] = {{NULL, 0}, {"Q", 1}, {" ", 1}, {NULL, 0}, {" ", 1}, {NULL, 0}, {";1 ", 3}, {";1", }, {NULL, 0}};
struct iovec v[1 + 4 + 3 + 1] = {{NULL, 0}, {"Q", 1}, {" ", 1}, {NULL, 0},
{" ", 1}, {NULL, 0}, {";1 ", 3}, {";1", }, {NULL, 0}};
if (get_callid(msg, &callid) == -1 || callid.len == 0) {
LM_ERR("can't get Call-Id field\n");
return -1;
return pv_get_null(msg, param, res);
}
if (get_to_tag(msg, &to_tag) == -1) {
LM_ERR("can't get To tag\n");
return -1;
return pv_get_null(msg, param, res);
}
if (get_from_tag(msg, &from_tag) == -1 || from_tag.len == 0) {
LM_ERR("can't get From tag\n");
return -1;
return pv_get_null(msg, param, res);
}
if(msg->id != current_msg_id){
selected_rtpp_set = default_rtpp_set;
@ -2586,6 +2573,8 @@ pv_get_rtpstat_f(struct sip_msg *msg, pv_param_t *param,
nitems = 6;
}
ret_val.s = send_rtpp_command(node, v, nitems);
if(ret_val.s==NULL)
return pv_get_null(msg, param, res);
ret_val.len = strlen(ret_val.s);
return pv_get_strval(msg, param, res, &ret_val);
}

@ -4,7 +4,7 @@ Nils Ohlmeier
iptelorg GmbH
Copyright © 2006 iptelorg GmbH
Copyright © 2006 iptelorg GmbH
__________________________________________________________________
1.1. Overview
@ -84,7 +84,7 @@ Nils Ohlmeier
Example 1. Set default_checks parameter
...
modparam("sanity", "default_checks", "1")
modparam("sanity", "default_checks", 1)
...
1.3.2. uri_checks (integer)
@ -128,7 +128,7 @@ modparam("sanity", "autodrop", 1)
1.4. Functions
1.4.1. sanity_check([msg_checks [, uri_checks]])
1.4.1. sanity_check([msg_checks [, uri_checks]])
This function makes a row of sanity checks over the given SIP request.
The behavior of the function is also controled by 'autodrop' parameter.

@ -33,7 +33,7 @@
<title>Set <varname>default_checks</varname> parameter</title>
<programlisting>
...
modparam("sanity", "default_checks", "1")
modparam("sanity", "default_checks", 1)
...
</programlisting>
</example>

@ -338,7 +338,7 @@ static int prepare_new_uac( struct cell *t, struct sip_msg *i_req,
if (run_top_route(branch_rt.rlist[branch_route], i_req, &ctx)
< 0)
{
LOG(L_ERR, "Error in run_top_route\n");
LOG(L_DBG, "negative return code in run_top_route\n");
}
/* update dst send_flags and send socket*/
snd_flags=i_req->fwd_send_flags;

@ -76,8 +76,8 @@ void th_mask_init(void)
_th_key.len = strlen(_th_key.s);
memcpy(_th_EB64, TH_EB64I, sizeof(TH_EB64I));
th_shuffle(_th_EB64, 64);
LM_ERR("+++ %s\n", TH_EB64I);
LM_ERR("+++ %s\n", _th_EB64);
LM_DBG("original table: %s\n", TH_EB64I);
LM_DBG("updated table: %s\n", _th_EB64);
for(i=0; i<256; i++)
_th_DB64[i] = -1;
for(i=0; i<64; i++)

@ -29,11 +29,11 @@ Sven Knoblich
1&1 Internet AG
<sven.knoblich@1und1.de>
Copyright © 2002, 2003 FhG FOKUS
Copyright © 2002, 2003 FhG FOKUS
Copyright © 2004, 2006 Voice Sistem SRL
Copyright © 2004, 2006 Voice Sistem SRL
Copyright © 2011 1&1 Internet AG
Copyright © 2011 1&1 Internet AG
Revision History
Revision $Revision$ $Date$
__________________________________________________________________
@ -119,9 +119,12 @@ Sven Knoblich
6.36. diameter_client_port (int)
6.37. diameter_extra (string)
6.38. cdr_enable (integer)
6.39. cdr_start_when_confirmed (integer)
6.40. cdr_log_facility (integer)
6.41. cdr_log_extra (string)
6.39. cdr_start_on_confirmed (integer)
6.40. cdr_facility (integer)
6.41. cdr_extra (string)
6.42. cdr_start_id (string)
6.43. cdr_end_id (string)
6.44. cdr_duration_id (string)
7. Functions
@ -172,13 +175,16 @@ Sven Knoblich
1.36. diameter_client_host example
1.37. diameter_extra example
1.38. cdr_enable example
1.39. cdr_start_when_confirmed example
1.40. cdr_log_facility example
1.41. cdr_log_extra example
1.42. acc_log_request usage
1.43. acc_db_request usage
1.44. acc_rad_request usage
1.45. acc_diam_request usage
1.39. cdr_start_on_confirmed example
1.40. cdr_facility example
1.41. cdr_extra example
1.42. cdr_start_id example
1.43. cdr_end_id example
1.44. cdr_duration_id example
1.45. acc_log_request usage
1.46. acc_db_request usage
1.47. acc_rad_request usage
1.48. acc_diam_request usage
Chapter 1. Admin Guide
@ -261,9 +267,12 @@ Chapter 1. Admin Guide
6.36. diameter_client_port (int)
6.37. diameter_extra (string)
6.38. cdr_enable (integer)
6.39. cdr_start_when_confirmed (integer)
6.40. cdr_log_facility (integer)
6.41. cdr_log_extra (string)
6.39. cdr_start_on_confirmed (integer)
6.40. cdr_facility (integer)
6.41. cdr_extra (string)
6.42. cdr_start_id (string)
6.43. cdr_end_id (string)
6.44. cdr_duration_id (string)
7. Functions
@ -281,7 +290,7 @@ Chapter 1. Admin Guide
To account a transaction and to choose which set of backends to be
used, the script writer just has to set some flags (see the module
parameters section for flag definitions Section 6, “Parameters”). If
parameters section for flag definitions Section 6, "Parameters"). If
the accounting flag for a specific backend is set, the acc module will
then report on completed transaction. A typical usage of the module
takes no acc-specific script command -- the functionality binds
@ -293,7 +302,7 @@ Chapter 1. Admin Guide
The accounting module will log by default a fixed set of attributes for
the transaction - if you customize your accounting by adding more
information to be logged, please see the next chapter about extra
accounting - Section 2, “Extra accounting”.
accounting - Section 2, "Extra accounting".
The fixed minimal accounting information is:
* Request Method name
@ -500,8 +509,8 @@ Note
4.1. Overview
It is possible to generate and log Call Data Records (CDRs) directly
from Kamailio in addition to transaction-based logging. Apart from a
In addition to transaction-based logging, it is possible to generate
and log Call Data Records (CDRs) directly from Kamailio. Apart from a
basic set of CDR fields which are always included (covering start time,
end time, and duration), the approach allows flexible specification of
additional fields that should be taken into account using the
@ -525,19 +534,24 @@ Note
information given will not be stored in the CDR as they cannot be
accessed by the end of the call when the CDR is logged.
Note that CDR generation does not involve any kind of database storage
(yet). In order to persist the CDRs into a database you will have to
set up an exterior process (i.e., a script living outside of Kamailio)
and implement the storage task yourself.
4.2. CDR Extra
This section is similar to the “LOG accounting” part of Section 2,
“Extra accounting”.
This section is similar to the "LOG accounting" part of Section 2,
"Extra accounting".
4.2.1. Definitions and syntax
Selection of extra information is done similar to the transaction extra
Section 2.2, “Definitions and syntax”.
* cdr_log_extra = cdr_extra_definition (';'cdr_extra_definition)*
Section 2.2, "Definitions and syntax".
* cdr_extra = cdr_extra_definition (';'cdr_extra_definition)*
* cdr_extra_definition = cdr_log_name '=' pseudo_variable
See also Section 6.41, “cdr_log_extra (string)”.
See also Section 6.41, "cdr_extra (string)".
The full list of supported pseudo-variables in Sip-Router is available
at: http://sip-router.org/wiki/cookbooks/pseudo-variables/devel
@ -546,7 +560,7 @@ Note
4.3.1. Overview
As mentioned in Section 3, “Multi Call-Legs accounting”, a leg
As mentioned in Section 3, "Multi Call-Legs accounting", a leg
represents a parallel or forwarded call. In contrast to the normal
accounting the cdr logging uses dialogs instead of transaction to log
data. This may reduce the amount of information but it also make it
@ -557,7 +571,7 @@ Note
4.3.2. Configuration
When you route messages multiple times through your proxy (e.g. to
handle “call-forwardings”) you have to use detect_spirals from the
handle "call-forwardings") you have to use detect_spirals from the
dialog modules. Otherwise the proxy can't identify and reuse existing
dialogs.
@ -608,9 +622,9 @@ $dlg_var(callee) = $avp(callee); #callee='C'
listed modules must be loaded before this module):
* tm -- Transaction Manager
* a database module -- If SQL support is used.
* rr -- Record Route, if “detect_direction” module parameter is
* rr -- Record Route, if "detect_direction" module parameter is
enabled.
* dialog -- Dialog, if “cdr_enable” module parameter is enabled.
* dialog -- Dialog, if "cdr_enable" module parameter is enabled.
5.2. External Libraries or Applications
@ -659,9 +673,12 @@ $dlg_var(callee) = $avp(callee); #callee='C'
6.36. diameter_client_port (int)
6.37. diameter_extra (string)
6.38. cdr_enable (integer)
6.39. cdr_start_when_confirmed (integer)
6.40. cdr_log_facility (integer)
6.41. cdr_log_extra (string)
6.39. cdr_start_on_confirmed (integer)
6.40. cdr_facility (integer)
6.41. cdr_extra (string)
6.42. cdr_start_id (string)
6.43. cdr_end_id (string)
6.44. cdr_duration_id (string)
6.1. early_media (integer)
@ -748,7 +765,7 @@ modparam("acc", "acc_prepare_flag", 5)
6.8. multi_leg_info (string)
Defines the AVP set to be used in per-call-leg accounting. See
Section 3, “Multi Call-Legs accounting” for a detailed description of
Section 3, "Multi Call-Legs accounting" for a detailed description of
the Multi Call-Legs accounting.
If empty, the multi-leg accounting support will be disabled.
@ -809,7 +826,7 @@ modparam("acc", "log_facility", "LOG_DAEMON")
6.13. log_extra (string)
Extra values to be logged. See section Section 2, “Extra accounting”
Extra values to be logged. See section Section 2, "Extra accounting"
for more details.
Default value is NULL.
@ -828,7 +845,7 @@ modparam("acc", "log_extra", "ua=$hdr(User-Agent);uuid=$avp(i:123)")
If the parameter is set to empty string, the RADIUS accounting support
will be disabled (even if compiled).
Default value is “NULL”.
Default value is "NULL".
Example 1.14. radius_config example
modparam("acc", "radius_config", "/etc/radiusclient/radiusclient.conf")
@ -865,7 +882,7 @@ modparam("acc", "service_type", 16)
6.18. radius_extra (string)
Extra values to be logged via RADIUS - RADIUS specific. See section
Section 2, “Extra accounting” for more details.
Section 2, "Extra accounting" for more details.
Default value is NULL.
@ -894,18 +911,21 @@ modparam("acc", "db_missed_flag", 3)
6.21. db_table_acc (string)
Table name of accounting successfull calls -- database specific.
Table name of accounting successfull calls -- database specific. It can
contain config variables that will be evaluated at runtime.
Default value is “acc”
Default value is "acc"
Example 1.21. db_table_acc example
modparam("acc", "db_table_acc", "myacc_table")
modparam("acc", "db_table_acc", "acc_$time(year)_$time(mon)")
6.22. db_table_missed_calls (string)
Table name for accounting missed calls -- database specific.
Table name for accounting missed calls -- database specific. It can
contain config variables that will be evaluated at runtime.
Default value is “missed_calls”
Default value is "missed_calls"
Example 1.22. db_table_missed_calls example
modparam("acc", "db_table_missed_calls", "myMC_table")
@ -915,7 +935,7 @@ modparam("acc", "db_table_missed_calls", "myMC_table")
SQL address -- database specific. If is set to NULL or emty string, the
SQL support is disabled.
Default value is “NULL” (SQL disabled).
Default value is "NULL" (SQL disabled).
Example 1.23. db_url example
modparam("acc", "db_url", "mysql://user:password@localhost/openser")
@ -925,7 +945,7 @@ modparam("acc", "db_url", "mysql://user:password@localhost/openser")
Column name in accounting table to store the request's method name as
string.
Default value is “method”.
Default value is "method".
Example 1.24. acc_method_column example
modparam("acc", "acc_method_column", "method")
@ -934,7 +954,7 @@ modparam("acc", "acc_method_column", "method")
Column name in accounting table to store the From header TAG parameter.
Default value is “from_tag”.
Default value is "from_tag".
Example 1.25. acc_from_tag_column example
modparam("acc", "acc_from_tag_column", "from_tag")
@ -943,7 +963,7 @@ modparam("acc", "acc_from_tag_column", "from_tag")
Column name in accounting table to store the To header TAG parameter.
Default value is “to_tag”.
Default value is "to_tag".
Example 1.26. acc_to_tag_column example
modparam("acc", "acc_to_tag_column", "to_tag")
@ -952,7 +972,7 @@ modparam("acc", "acc_to_tag_column", "to_tag")
Column name in accounting table to store the request's Callid value.
Default value is “callid”.
Default value is "callid".
Example 1.27. acc_callid_column example
modparam("acc", "acc_callid_column", "callid")
@ -962,7 +982,7 @@ modparam("acc", "acc_callid_column", "callid")
Column name in accounting table to store the final reply's numric code
value in string format.
Default value is “sip_code”.
Default value is "sip_code".
Example 1.28. acc_sip_code_column example
modparam("acc", "acc_sip_code_column", "sip_code")
@ -972,7 +992,7 @@ modparam("acc", "acc_sip_code_column", "sip_code")
Column name in accounting table to store the final reply's reason
phrase value.
Default value is “sip_reason”.
Default value is "sip_reason".
Example 1.29. acc_sip_reason_column example
modparam("acc", "acc_sip_reason_column", "sip_reason")
@ -982,7 +1002,7 @@ modparam("acc", "acc_sip_reason_column", "sip_reason")
Column name in accounting table to store the time stamp of the
transaction completion in date-time format.
Default value is “time”.
Default value is "time".
Example 1.30. acc_time_column example
modparam("acc", "acc_time_column", "time")
@ -990,7 +1010,7 @@ modparam("acc", "acc_time_column", "time")
6.31. db_extra (string)
Extra values to be logged into database - DB specific. See section
Section 2, “Extra accounting” for more details.
Section 2, "Extra accounting" for more details.
Default value is NULL.
@ -1033,7 +1053,7 @@ modparam("acc", "diameter_missed_flag", 3)
Hostname of the machine where the DIAMETER Client is running --
DIAMETER specific.
Default value is “localhost”.
Default value is "localhost".
Example 1.35. diameter_client_host example
modparam("acc", "diameter_client_host", "3a_server.net")
@ -1051,7 +1071,7 @@ modparam("acc", "diameter_client_port", 3000)
6.37. diameter_extra (string)
Extra values to be logged via DIAMETER - DIAMETER specific. See section
Section 2, “Extra accounting” for more details.
Section 2, "Extra accounting" for more details.
Default value is NULL.
@ -1067,7 +1087,7 @@ modparam("acc", "diameter_extra", "7846=$hdr(Content-type);7847=$avp(s:email)")
Example 1.38. cdr_enable example
modparam("acc", "cdr_enable", 1)
6.39. cdr_start_when_confirmed (integer)
6.39. cdr_start_on_confirmed (integer)
Should the start time be taken from the time when the dialog is
created, or when the dialog is confirmed?
@ -1075,28 +1095,55 @@ modparam("acc", "cdr_enable", 1)
0 - use time of dialog creation (default). 1 - use time of dialog
confirmation.
Example 1.39. cdr_start_when_confirmed example
modparam("acc", "cdr_start_when_confirmed", 1)
Example 1.39. cdr_start_on_confirmed example
modparam("acc", "cdr_start_on_confirmed", 1)
6.40. cdr_log_facility (integer)
6.40. cdr_facility (integer)
Log facility to which CDR messages are issued to syslog. This allows to
easily seperate CDR-specific logging from the other log messages.
Default value is LOG_DAEMON.
Example 1.40. cdr_log_facility example
modparam("acc", "cdr_log_facility", "LOG_DAEMON")
Example 1.40. cdr_facility example
modparam("acc", "cdr_facility", "LOG_DAEMON")
6.41. cdr_log_extra (string)
6.41. cdr_extra (string)
Set of pseudo-variables defining custom CDR fields. See Section 4.2,
“CDR Extra” for more details.
"CDR Extra" for more details.
Default value is NULL.
Example 1.41. cdr_log_extra example
modparam("acc", "cdr_log_extra", "c1=$dlg_var(caller);c2=$dlg_var(callee)"
Example 1.41. cdr_extra example
modparam("acc", "cdr_extra", "c1=$dlg_var(caller);c2=$dlg_var(callee)"
6.42. cdr_start_id (string)
Modifying the start id which is used to store the start time.
Default value is 'st'
Example 1.42. cdr_start_id example
modparam("acc", "cdr_start_id", "start")
6.43. cdr_end_id (string)
Modifying the end id which is used to store the end time.
Default value is 'et'
Example 1.43. cdr_end_id example
modparam("acc", "cdr_end_id", "end")
6.44. cdr_duration_id (string)
Modifying the duration id which is used to store the duration.
Default value is 'd'
Example 1.44. cdr_duration_id example
modparam("acc", "cdr_duration_id", "start")
7. Functions
@ -1105,7 +1152,7 @@ modparam("acc", "cdr_log_extra", "c1=$dlg_var(caller);c2=$dlg_var(callee)"
7.3. acc_rad_request(comment)
7.4. acc_diam_request(comment)
7.1. acc_log_request(comment)
7.1. acc_log_request(comment)
acc_request reports on a request, for example, it can be used to report
on missed calls to off-line users who are replied 404 - Not Found. To
@ -1117,44 +1164,46 @@ modparam("acc", "cdr_log_extra", "c1=$dlg_var(caller);c2=$dlg_var(callee)"
This function can be used from ANY_ROUTE.
Example 1.42. acc_log_request usage
Example 1.45. acc_log_request usage
...
acc_log_request("Some comment");
...
7.2. acc_db_request(comment, table)
7.2. acc_db_request(comment, table)
Like acc_log_request, acc_db_request reports on a request. The report
is sent to database at “db_url”, in the table referred to in the second
is sent to database at "db_url", in the table referred to in the second
action parameter.
Meaning of the parameters is as follows:
* comment - Comment to be appended.
* table - Database table to be used.
* table - Database table to be used. It can contain config variables
that are evaluated at runtime.
This function can be used from ANY_ROUTE.
Example 1.43. acc_db_request usage
Example 1.46. acc_db_request usage
...
acc_log_request("Some comment", "Some table");
acc_log_request("Some comment", "SomeTable");
acc_log_request("Some comment", "acc_$time(year)_$time(mon)");
...
7.3. acc_rad_request(comment)
7.3. acc_rad_request(comment)
Like acc_log_request, acc_rad_request reports on a request. It reports
to radius server as configured in “radius_config”.
to radius server as configured in "radius_config".
Meaning of the parameters is as follows:
* comment - Comment to be appended.
This function can be used from ANY_ROUTE.
Example 1.44. acc_rad_request usage
Example 1.47. acc_rad_request usage
...
acc_rad_request("Some comment");
...
7.4. acc_diam_request(comment)
7.4. acc_diam_request(comment)
Like acc_log_request, acc_diam_request reports on a request. It reports
to the configured Diameter server.
@ -1164,7 +1213,7 @@ acc_rad_request("Some comment");
This function can be used from ANY_ROUTE.
Example 1.45. acc_diam_request usage
Example 1.48. acc_diam_request usage
...
acc_diam_request("Some comment");
...
@ -1180,55 +1229,55 @@ Chapter 2. Frequently Asked Questions
2.1.
What happend with old log_fmt parameter
What happend with old log_fmt parameter
The parameter became obsolete with the restructure of the data logged
by ACC module (refer to the Overview chapter). For similar behaviour
you can use the extra accouting (see the coresponding chapter).
The parameter became obsolete with the restructure of the data logged
by ACC module (refer to the Overview chapter). For similar behaviour
you can use the extra accouting (see the coresponding chapter).
2.2.
What happend with old multi_leg_enabled parameter
What happend with old multi_leg_enabled parameter
The parameter becaome obsolete by the addition of the new
multi_leg_info parameter. The multi-leg accouting is automatically
enabled when multi_leg_info is defined.
The parameter becaome obsolete by the addition of the new
multi_leg_info parameter. The multi-leg accouting is automatically
enabled when multi_leg_info is defined.
2.3.
What happend with old src_leg_avp_id and dst_leg_avp_id parameters
What happend with old src_leg_avp_id and dst_leg_avp_id parameters
The parameter was replaced by the more generic new parameter
multi_leg_info. This allows logging (per-leg) of more information than
just dst and src.
The parameter was replaced by the more generic new parameter
multi_leg_info. This allows logging (per-leg) of more information than
just dst and src.
2.4.
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.5.
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.6.
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.

@ -125,14 +125,6 @@ int core2strar(struct sip_msg *req, str *c_vals, int *i_vals, char *t_vals)
struct hdr_field *from;
struct hdr_field *to;
struct timeval tv;
struct timezone tz;
struct tm *tm;
uint64_t time_hires;
gettimeofday(&tv, &tz);
tm = localtime(&tv.tv_sec);
/* method : request/reply - cseq parsed in acc_preparse_req() */
c_vals[0] = get_cseq(req)->method;
t_vals[0] = TYPE_STR;
@ -182,10 +174,6 @@ int core2strar(struct sip_msg *req, str *c_vals, int *i_vals, char *t_vals)
t_vals[5] = TYPE_STR;
acc_env.ts = time(NULL);
time_hires = (tv.tv_sec * 1000) + tv.tv_usec / 1000;
acc_env.time_hires = time_hires;
return ACC_CORE_LEN;
}
@ -318,8 +306,7 @@ static void acc_db_init_keys(void)
db_keys[n++] = &acc_sipcode_col;
db_keys[n++] = &acc_sipreason_col;
db_keys[n++] = &acc_time_col;
db_keys[n++] = &acc_time_hires_col;
time_idx = n-2;
time_idx = n-1;
/* init the extra db keys */
for(extra=db_extra; extra ; extra=extra->next)
@ -335,7 +322,6 @@ static void acc_db_init_keys(void)
VAL_NULL(db_vals+i)=0;
}
VAL_TYPE(db_vals+time_idx)=DB1_DATETIME;
VAL_TYPE(db_vals+time_idx+1)=DB1_DOUBLE;
}
@ -394,8 +380,7 @@ int acc_db_request( struct sip_msg *rq)
VAL_STR(db_vals+i) = val_arr[i];
/* time value */
VAL_TIME(db_vals+(m++)) = acc_env.ts;
VAL_DOUBLE(db_vals+(m++)) = ((double) acc_env.time_hires) / 1000;
i = m;
/* extra columns */
m += extra2strar( db_extra, rq, val_arr+m, int_arr+m, type_arr+m);

@ -57,7 +57,6 @@ typedef struct acc_enviroment {
struct hdr_field *to;
str text;
time_t ts;
uint64_t time_hires;
} acc_enviroment_t;
/* acc extra parameter */

@ -39,6 +39,7 @@
#include <string.h>
#include "../../dprint.h"
#include "../../sr_module.h"
#include "../../parser/parse_from.h"
#include "../../parser/parse_content.h"
#include "../../modules/tm/tm_load.h"
@ -102,8 +103,6 @@ struct acc_enviroment acc_env;
#define is_acc_prepare_on(_rq) \
(is_acc_flag_set(_rq,acc_prepare_flag))
static void tmcb_func( struct cell* t, int type, struct tmcb_params *ps );
@ -181,6 +180,35 @@ int w_acc_log_request(struct sip_msg *rq, char *comment, char *foo)
#ifdef SQL_ACC
int acc_db_set_table_name(struct sip_msg *msg, void *param, str *table)
{
#define DB_TABLE_NAME_SIZE 64
static char db_table_name_buf[DB_TABLE_NAME_SIZE];
str dbtable;
if(param!=NULL) {
if(get_str_fparam(&dbtable, msg, (fparam_t*)param)<0) {
LM_ERR("cannot get acc db table name\n");
return -1;
}
if(dbtable.len>=DB_TABLE_NAME_SIZE) {
LM_ERR("acc db table name too big [%.*s] max %d\n",
dbtable.len, dbtable.s, DB_TABLE_NAME_SIZE);
return -1;
}
strncpy(db_table_name_buf, dbtable.s, dbtable.len);
env_set_text(db_table_name_buf, dbtable.len);
} else {
if(table==NULL) {
LM_ERR("no acc table name\n");
return -1;
}
env_set_text(table->s, table->len);
}
return 0;
}
int w_acc_db_request(struct sip_msg *rq, char *comment, char *table)
{
if (!table) {
@ -189,9 +217,12 @@ int w_acc_db_request(struct sip_msg *rq, char *comment, char *table)
}
if (acc_preparse_req(rq)<0)
return -1;
if(acc_db_set_table_name(rq, (void*)table, NULL)<0) {
LM_ERR("cannot set table name\n");
return -1;
}
env_set_to( rq->to );
env_set_comment((struct acc_param*)comment);
env_set_text(table, strlen(table));
return acc_db_request(rq);
}
#endif
@ -339,7 +370,10 @@ static inline void on_missed(struct cell *t, struct sip_msg *req,
}
#ifdef SQL_ACC
if (is_db_mc_on(req)) {
env_set_text(db_table_mc.s, db_table_mc.len);
if(acc_db_set_table_name(req, db_table_mc_data, &db_table_mc)<0) {
LM_ERR("cannot set missed call db table name\n");
return;
}
acc_db_request( req );
flags_to_reset |= db_missed_flag;
}
@ -410,7 +444,10 @@ static inline void acc_onreply( struct cell* t, struct sip_msg *req,
}
#ifdef SQL_ACC
if (is_db_acc_on(req)) {
env_set_text( db_table_acc.s, db_table_acc.len);
if(acc_db_set_table_name(req, db_table_acc_data, &db_table_acc)<0) {
LM_ERR("cannot set acc db table name\n");
return;
}
acc_db_request(req);
}
#endif
@ -451,7 +488,10 @@ static inline void acc_onack( struct cell* t, struct sip_msg *req,
}
#ifdef SQL_ACC
if (is_db_acc_on(req)) {
env_set_text( db_table_acc.s, db_table_acc.len);
if(acc_db_set_table_name(ack, db_table_acc_data, &db_table_acc)<0) {
LM_ERR("cannot set acc db table name\n");
return;
}
acc_db_request( ack );
}
#endif

@ -184,7 +184,9 @@ static char *db_extra_str = 0; /*!< db extra variables */
struct acc_extra *db_extra = 0;
static str db_url = {NULL, 0}; /*!< Database url */
str db_table_acc = str_init("acc"); /*!< name of database tables */
void *db_table_acc_data = NULL;
str db_table_mc = str_init("missed_calls");
void *db_table_mc_data = NULL;
/* names of columns in tables acc/missed calls*/
str acc_method_col = str_init("method");
str acc_fromtag_col = str_init("from_tag");
@ -193,7 +195,6 @@ str acc_callid_col = str_init("callid");
str acc_sipcode_col = str_init("sip_code");
str acc_sipreason_col = str_init("sip_reason");
str acc_time_col = str_init("time");
str acc_time_hires_col = str_init("time_hires");
int acc_db_insert_mode = 0;
#endif
@ -288,7 +289,6 @@ static param_export_t params[] = {
{"acc_sip_code_column", STR_PARAM, &acc_sipcode_col.s },
{"acc_sip_reason_column",STR_PARAM, &acc_sipreason_col.s },
{"acc_time_column", STR_PARAM, &acc_time_col.s },
{"acc_time_hires_column", STR_PARAM, &acc_time_hires_col.s },
{"db_insert_mode", INT_PARAM, &acc_db_insert_mode },
#endif
{0,0,0}
@ -352,6 +352,8 @@ static int acc_fixup(void** param, int param_no)
if (db_url.s==0) {
pkg_free(p);
*param = 0;
} else {
return fixup_var_pve_str_12(param, 2);
}
#endif
}
@ -423,7 +425,27 @@ static int mod_init( void )
}
}
db_table_acc.len = strlen(db_table_acc.s);
if(db_table_acc.len!=3 || strncmp(db_table_acc.s, "acc", 3)!=0)
{
db_table_acc_data = db_table_acc.s;
if(fixup_var_pve_str_12(&db_table_acc_data, 1)<0)
{
LM_ERR("unable to parse acc table name [%.*s]\n",
db_table_acc.len, db_table_acc.s);
return -1;
}
}
db_table_mc.len = strlen(db_table_mc.s);
if(db_table_mc.len!=12 || strncmp(db_table_mc.s, "missed_calls", 12)!=0)
{
db_table_mc_data = db_table_mc.s;
if(fixup_var_pve_str_12(&db_table_mc_data, 1)<0)
{
LM_ERR("unable to parse mc table name [%.*s]\n",
db_table_mc.len, db_table_mc.s);
return -1;
}
}
acc_method_col.len = strlen(acc_method_col.s);
acc_fromtag_col.len = strlen(acc_fromtag_col.s);
acc_totag_col.len = strlen(acc_totag_col.s);
@ -431,7 +453,6 @@ static int mod_init( void )
acc_sipcode_col.len = strlen(acc_sipcode_col.s);
acc_sipreason_col.len = strlen(acc_sipreason_col.s);
acc_time_col.len = strlen(acc_time_col.s);
acc_time_hires_col.len = strlen(acc_time_hires_col.s);
#endif
if (log_facility_str) {

@ -78,7 +78,9 @@ extern int db_flag;
extern int db_missed_flag;
extern str db_table_acc;
extern void *db_table_acc_data;
extern str db_table_mc;
extern void *db_table_mc_data;
extern str acc_method_col;
extern str acc_fromuri_col;
@ -90,7 +92,6 @@ extern str acc_cseqno_col;
extern str acc_sipcode_col;
extern str acc_sipreason_col;
extern str acc_time_col;
extern str acc_time_hires_col;
#endif /* SQL_ACC */

@ -853,7 +853,8 @@ modparam("acc", "db_missed_flag", 3)
<section>
<title><varname>db_table_acc</varname> (string)</title>
<para>
Table name of accounting successfull calls -- database specific.
Table name of accounting successfull calls -- database specific. It
can contain config variables that will be evaluated at runtime.
</para>
<para>
Default value is <quote>acc</quote>
@ -862,13 +863,15 @@ modparam("acc", "db_missed_flag", 3)
<title>db_table_acc example</title>
<programlisting format="linespecific">
modparam("acc", "db_table_acc", "myacc_table")
modparam("acc", "db_table_acc", "acc_$time(year)_$time(mon)")
</programlisting>
</example>
</section>
<section>
<title><varname>db_table_missed_calls</varname> (string)</title>
<para>
Table name for accounting missed calls -- database specific.
Table name for accounting missed calls -- database specific. It
can contain config variables that will be evaluated at runtime.
</para>
<para>
Default value is <quote>missed_calls</quote>
@ -1283,7 +1286,8 @@ acc_log_request("Some comment");
<para><emphasis>comment</emphasis> - Comment to be appended.</para>
</listitem>
<listitem>
<para><emphasis>table</emphasis> - Database table to be used.</para>
<para><emphasis>table</emphasis> - Database table to be used. It
can contain config variables that are evaluated at runtime.</para>
</listitem>
</itemizedlist>
<para>
@ -1293,7 +1297,8 @@ acc_log_request("Some comment");
<title>acc_db_request usage</title>
<programlisting format="linespecific">
...
acc_log_request("Some comment", "Some table");
acc_log_request("Some comment", "SomeTable");
acc_log_request("Some comment", "acc_$time(year)_$time(mon)");
...
</programlisting>
</example>

@ -88,8 +88,8 @@ inline unsigned long long bm_diff_time(bm_timeval_t *t1, bm_timeval_t *t2)
{
unsigned long long tdiff;
tdiff = t1->tv_sec - t1->tv_sec;
tdiff = t2->tv_sec - t1->tv_sec;
#ifdef BM_CLOCK_REALTIME
tdiff = tdiff*1000000000 + t2->tv_nsec - t1->tv_nsec;
#else

@ -136,7 +136,7 @@
{\
LM_DBG("serial operation - cluster [%.*s] (%d/%d)\n",\
cls->name.len, cls->name.s, i, j);\
dbh = cls->rlist[i].clist[j]->dbh;\
dbh = cls->wlist[i].clist[j]->dbh;\
ret = cls->wlist[i].clist[j]->dbf.command;\
if (ret==0) {\
cls->usedcon = cls->wlist[i].clist[j];\
@ -159,7 +159,7 @@
{\
LM_DBG("round robin operation - cluster [%.*s] (%d/%d)\n",\
cls->name.len, cls->name.s, i, j);\
dbh = cls->rlist[i].clist[j]->dbh;\
dbh = cls->wlist[i].clist[j]->dbh;\
ret = cls->wlist[i].clist[j]->dbf.command;\
if (ret==0)\
{\
@ -183,7 +183,7 @@
{\
LM_DBG("parallel operation - cluster [%.*s] (%d/%d)\n",\
cls->name.len, cls->name.s, i, j);\
dbh = cls->rlist[i].clist[j]->dbh;\
dbh = cls->wlist[i].clist[j]->dbh;\
rc = cls->wlist[i].clist[j]->dbf.command;\
if(rc==0) {\
cls->usedcon = cls->wlist[i].clist[j];\
@ -309,7 +309,8 @@ int db_cluster_fetch_result(const db1_con_t* _h, db1_res_t** _r, const int nrows
dbcl_cls_t *cls=NULL;
LM_DBG("executing db cluster fetch-result command\n");
cls = (dbcl_cls_t*)_h->tail;
if(cls->usedcon==NULL || cls->usedcon->dbh==NULL)
if(cls->usedcon==NULL || cls->usedcon->dbh==NULL
|| cls->usedcon->dbf.fetch_result==NULL)
return -1;
return cls->usedcon->dbf.fetch_result(cls->usedcon->dbh, _r, nrows);
}
@ -376,7 +377,8 @@ int db_cluster_last_inserted_id(const db1_con_t* _h)
dbcl_cls_t *cls=NULL;
LM_DBG("executing db cluster last inserted id command\n");
cls = (dbcl_cls_t*)_h->tail;
if(cls->usedcon==NULL || cls->usedcon->dbh==NULL)
if(cls->usedcon==NULL || cls->usedcon->dbh==NULL
|| cls->usedcon->dbf.last_inserted_id==NULL)
return -1;
return cls->usedcon->dbf.last_inserted_id(cls->usedcon->dbh);
}
@ -390,7 +392,8 @@ int db_cluster_affected_rows(const db1_con_t* _h)
dbcl_cls_t *cls=NULL;
LM_DBG("executing db cluster affected-rows command\n");
cls = (dbcl_cls_t*)_h->tail;
if(cls->usedcon==NULL || cls->usedcon->dbh==NULL)
if(cls->usedcon==NULL || cls->usedcon->dbh==NULL
|| cls->usedcon->dbf.affected_rows==NULL)
return -1;
return cls->usedcon->dbf.affected_rows(cls->usedcon->dbh);
}

@ -262,6 +262,8 @@ int dbcl_cls_set_connections(dbcl_cls_t *cls, str *cons)
cls->rlist[i].mode = s.s[1] | 32;
cls->rlist[i].prio = i;
cls->rlist[i].clist[cls->rlist[i].clen] = sc;
LM_DBG("added con-id [%.*s] to rlist[%d] at [%d]\n",
pit->name.len, pit->name.s, i, cls->rlist[i].clen);
cls->rlist[i].clen++;
} else {
LM_WARN("too many read connections in cluster - con-id [%.*s]\n",
@ -289,6 +291,8 @@ int dbcl_cls_set_connections(dbcl_cls_t *cls, str *cons)
cls->wlist[i].mode = s.s[3] | 32;
cls->wlist[i].prio = i;
cls->wlist[i].clist[cls->wlist[i].clen] = sc;
LM_DBG("added con-id [%.*s] to wlist[%d] at [%d]\n",
pit->name.len, pit->name.s, i, cls->wlist[i].clen);
cls->wlist[i].clen++;
} else {
LM_WARN("too many write connections in cluster - con-id [%.*s]\n",

@ -149,7 +149,7 @@ Alex Balashov
11.1. event_route[dialog:start]
11.2. event_route[dialog:end]
11.3. event_route[dialog:failure]
11.3. event_route[dialog:failed]
2. Developer Guide
@ -348,7 +348,7 @@ Chapter 1. Admin Guide
11.1. event_route[dialog:start]
11.2. event_route[dialog:end]
11.3. event_route[dialog:failure]
11.3. event_route[dialog:failed]
1. Overview
@ -1783,7 +1783,7 @@ dlg_set_property("ka-dst");
11.1. event_route[dialog:start]
11.2. event_route[dialog:end]
11.3. event_route[dialog:failure]
11.3. event_route[dialog:failed]
11.1. event_route[dialog:start]
@ -1793,7 +1793,7 @@ dlg_set_property("ka-dst");
Executed when BYE is processed or dialog timed out.
11.3. event_route[dialog:failure]
11.3. event_route[dialog:failed]
Executed when dialog is not completed (+300 reply to INVITE).

@ -2316,7 +2316,7 @@ dlg_set_property("ka-dst");
</para>
</section>
<section>
<title><varname>event_route[dialog:failure]</varname></title>
<title><varname>event_route[dialog:failed]</varname></title>
<para>
Executed when dialog is not completed (+300 reply to INVITE).
</para>

@ -51,7 +51,7 @@ Carsten Bock
3.14. dstid_avp (str)
3.15. attrs_avp (str)
3.16. hash_pvar (str)
3.17. setid_pvar (str)
3.17. setid_pvname (str)
3.18. ds_ping_method (string)
3.19. ds_ping_from (string)
3.20. ds_ping_interval (int)
@ -118,7 +118,7 @@ Carsten Bock
1.15. Set the "attrs_avp" parameter
1.16. Use $avp(i:273) for hashing:
1.17. Use combination of PVs for hashing:
1.18. Set the "setid_pvar" parameter
1.18. Set the "setid_pvname" parameter
1.19. Set the "ds_ping_method" parameter
1.20. Set the "ds_ping_from" parameter
1.21. Set the "ds_ping_interval" parameter
@ -165,7 +165,7 @@ Chapter 1. Admin Guide
3.14. dstid_avp (str)
3.15. attrs_avp (str)
3.16. hash_pvar (str)
3.17. setid_pvar (str)
3.17. setid_pvname (str)
3.18. ds_ping_method (string)
3.19. ds_ping_from (string)
3.20. ds_ping_interval (int)
@ -263,7 +263,7 @@ Chapter 1. Admin Guide
3.14. dstid_avp (str)
3.15. attrs_avp (str)
3.16. hash_pvar (str)
3.17. setid_pvar (str)
3.17. setid_pvname (str)
3.18. ds_ping_method (string)
3.19. ds_ping_from (string)
3.20. ds_ping_interval (int)
@ -509,16 +509,16 @@ Note
modparam("dispatcher", "hash_pvar", "hash the $fU@$ci")
...
3.17. setid_pvar (str)
3.17. setid_pvname (str)
The name of the PV where to store the set ID (group ID) when calling
ds_is_from_list() with no parameter.
Default value is "null" - don't set PV.
Example 1.18. Set the "setid_pvar" parameter
Example 1.18. Set the "setid_pvname" parameter
...
modparam("dispatcher", "setid_pvar", "$var(setid)")
modparam("dispatcher", "setid_pvname", "$var(setid)")
...
3.18. ds_ping_method (string)
@ -811,7 +811,8 @@ failure_route[tryagain] {
Parameter groupid is optional, when it is missing, then the matching
will be done against all addresses in all groups. Upon a match, the
'grp_avp' will be set to groupid of matching address.
variable specified by 'setid_pvname' parameter will be set to groupid
of matching address.
This function can be used from ANY_ROUTE.

@ -455,7 +455,7 @@ modparam("dispatcher", "force_dst", 1)
</example>
</section>
<section>
<title><varname>setid_pvar</varname> (str)</title>
<title><varname>setid_pvname</varname> (str)</title>
<para>
The name of the PV where to store the set ID (group ID) when calling
ds_is_from_list() with no parameter.
@ -466,10 +466,10 @@ modparam("dispatcher", "force_dst", 1)
</emphasis>
</para>
<example>
<title>Set the <quote>setid_pvar</quote> parameter</title>
<title>Set the <quote>setid_pvname</quote> parameter</title>
<programlisting format="linespecific">
...
modparam("dispatcher", "setid_pvar", "$var(setid)")
modparam("dispatcher", "setid_pvname", "$var(setid)")
...
</programlisting>
</example>
@ -965,7 +965,8 @@ failure_route[tryagain] {
<para>
Parameter groupid is optional, when it is missing, then the matching
will be done against all addresses in all groups. Upon a match, the
'grp_avp' will be set to groupid of matching address.
variable specified by 'setid_pvname' parameter will be set to groupid
of matching address.
</para>
<para>
This function can be used from ANY_ROUTE.

@ -49,6 +49,9 @@ Daniel-Constantin Mierla
4.4. uptime
4.5. version
4.6. which
4.7. get_statistics
4.8. reset_statistics
4.9. clear_statistics
5. RPC Commands
@ -106,6 +109,9 @@ Chapter 1. Admin Guide
4.4. uptime
4.5. version
4.6. which
4.7. get_statistics
4.8. reset_statistics
4.9. clear_statistics
5. RPC Commands
@ -397,6 +403,9 @@ resetdebug();
4.4. uptime
4.5. version
4.6. which
4.7. get_statistics
4.8. reset_statistics
4.9. clear_statistics
4.1. arg
@ -470,6 +479,48 @@ resetdebug();
:which:_reply_fifo_file_
_empty_line_
4.7. get_statistics
Print the list of available internal statistics.
Name: get_statistics
Parameters: statsid - which statistics to be printed. If set to 'all'
then all statistics are printed; if set to 'statsgroup:' then all
statistics in the group are printed; if set to 'statsname' then the
statistics identified by the name is printed.
MI FIFO Command Format:
:get_statistics:_reply_fifo_file_
_statsid_
_empty_line_
4.8. reset_statistics
Reset internal statistics.
Name: reset_statistics
Parameters: statsid - which statistics to be reset, give as name.
MI FIFO Command Format:
:reset_statistics:_reply_fifo_file_
_statsid_
_empty_line_
4.9. clear_statistics
Return statistics and reset their value in one command.
Name: get_statistics
Parameters: statsid - same as for get_statistics.
MI FIFO Command Format:
:clear_statistics:_reply_fifo_file_
_statsid_
_empty_line_
5. RPC Commands
5.1. pkg.stats

@ -572,6 +572,73 @@ resetdebug();
_empty_line_
</programlisting>
</section>
<section>
<title>
<function moreinfo="none">get_statistics</function>
</title>
<para>
Print the list of available internal statistics.
</para>
<para>
Name: <emphasis>get_statistics</emphasis>
</para>
<para>Parameters: <emphasis>statsid</emphasis> - which statistics to
be printed. If set to 'all' then all statistics are printed; if
set to 'statsgroup:' then all statistics in the group are printed;
if set to 'statsname' then the statistics identified by the name
is printed.</para>
<para>
MI FIFO Command Format:
</para>
<programlisting format="linespecific">
:get_statistics:_reply_fifo_file_
_statsid_
_empty_line_
</programlisting>
</section>
<section>
<title>
<function moreinfo="none">reset_statistics</function>
</title>
<para>
Reset internal statistics.
</para>
<para>
Name: <emphasis>reset_statistics</emphasis>
</para>
<para>Parameters: <emphasis>statsid</emphasis> - which statistics to
be reset, give as name.</para>
<para>
MI FIFO Command Format:
</para>
<programlisting format="linespecific">
:reset_statistics:_reply_fifo_file_
_statsid_
_empty_line_
</programlisting>
</section>
<section>
<title>
<function moreinfo="none">clear_statistics</function>
</title>
<para>
Return statistics and reset their value in one command.
</para>
<para>
Name: <emphasis>get_statistics</emphasis>
</para>
<para>Parameters: <emphasis>statsid</emphasis> - same as for
get_statistics.</para>
<para>
MI FIFO Command Format:
</para>
<programlisting format="linespecific">
:clear_statistics:_reply_fifo_file_
_statsid_
_empty_line_
</programlisting>
</section>
</section>
<section>

@ -1191,12 +1191,15 @@ sdp_1918(struct sip_msg* msg)
{
str *ip;
int pf;
int ret;
int sdp_session_num, sdp_stream_num;
sdp_session_cell_t* sdp_session;
sdp_stream_cell_t* sdp_stream;
if(0 != parse_sdp(msg)) {
LM_ERR("Unable to parse sdp\n");
ret = parse_sdp(msg);
if(ret != 0) {
if(ret < 0)
LM_ERR("Unable to parse sdp\n");
return 0;
}

@ -246,7 +246,7 @@ int get_wi_subs_db(subs_t* subs, watcher_t* watchers)
int n_result_cols = 0;
int n_query_cols = 0;
int i;
int status_col, expires_col, watcher_user_col, watcher_domain_col, callid_col;
int status_col, watcher_user_col, watcher_domain_col, callid_col;
query_cols[n_query_cols] = &str_presentity_uri_col;
query_ops[n_query_cols] = OP_EQ;
@ -266,11 +266,10 @@ int get_wi_subs_db(subs_t* subs, watcher_t* watchers)
query_ops[n_query_cols] = OP_GT;
query_vals[n_query_cols].type = DB1_INT;
query_vals[n_query_cols].nul = 0;
query_vals[n_query_cols].val.int_val = (int)time(NULL) - expires_offset;
query_vals[n_query_cols].val.int_val = (int)time(NULL) + expires_offset;
n_query_cols++;
result_cols[status_col=n_result_cols++] = &str_status_col;
result_cols[expires_col=n_result_cols++] = &str_expires_col;
result_cols[watcher_user_col=n_result_cols++] = &str_watcher_username_col;
result_cols[watcher_domain_col=n_result_cols++] = &str_watcher_domain_col;
result_cols[callid_col=n_result_cols++] = &str_callid_col;
@ -581,11 +580,11 @@ error:
str* get_p_notify_body(str pres_uri, pres_ev_t* event, str* etag,
str* contact)
{
db_key_t query_cols[6];
db_val_t query_vals[6];
db_key_t result_cols[6];
db_key_t query_cols[3];
db_val_t query_vals[3];
db_key_t result_cols[3];
db1_res_t *result = NULL;
int body_col, expires_col, etag_col= 0, sender_col;
int body_col, etag_col= 0, sender_col;
str** body_array= NULL;
str* notify_body= NULL;
db_row_t *row= NULL ;
@ -646,7 +645,6 @@ str* get_p_notify_body(str pres_uri, pres_ev_t* event, str* etag,
n_query_cols++;
result_cols[body_col=n_result_cols++] = &str_body_col;
result_cols[expires_col=n_result_cols++] = &str_expires_col;
result_cols[etag_col=n_result_cols++] = &str_etag_col;
result_cols[sender_col=n_result_cols++] = &str_sender_col;
@ -1087,9 +1085,6 @@ int get_subs_db(str* pres_uri, pres_ev_t* event, str* sender,
row = &result->rows[i];
row_vals = ROW_VALUES(row);
// if(row_vals[expires_col].val.int_val< (int)time(NULL))
// continue;
if(row_vals[reason_col].val.string_val) {
if(strlen(row_vals[reason_col].val.string_val) != 0)
continue;
@ -1145,11 +1140,10 @@ int get_subs_db(str* pres_uri, pres_ev_t* event, str* sender,
s.event= event;
s.local_cseq = row_vals[cseq_col].val.int_val +1;
if(row_vals[expires_col].val.int_val < (int)time(NULL))
if(row_vals[expires_col].val.int_val < (int)time(NULL) + expires_offset)
s.expires = 0;
else
s.expires = row_vals[expires_col].val.int_val -
(int)time(NULL);
s.expires = row_vals[expires_col].val.int_val - (int)time(NULL);
s.version = row_vals[version_col].val.int_val +1;
s_new= mem_copy_subs(&s, PKG_MEM_TYPE);
@ -2229,9 +2223,9 @@ int set_wipeer_subs_updated(str *pres_uri, pres_ev_t *event, int full)
update_cols[n_update_cols] = &str_updated_col;
update_vals[n_update_cols].type = DB1_INT;
update_vals[n_update_cols].nul = 0;
update_vals[n_update_cols].val.int_val = core_hash(&callid,
&from_tag, (pres_waitn_time * pres_notifier_poll_rate
* pres_notifier_processes) - 1);
update_vals[n_update_cols].val.int_val =
core_hash(&callid, &from_tag, 0) % (pres_waitn_time *
pres_notifier_poll_rate * pres_notifier_processes);
n_update_cols++;
if (full)
@ -2289,9 +2283,10 @@ int set_updated(subs_t *sub)
update_cols[0] = &str_updated_col;
update_vals[0].type = DB1_INT;
update_vals[0].nul = 0;
update_vals[0].val.int_val = core_hash(&sub->callid, &sub->from_tag,
(pres_waitn_time * pres_notifier_poll_rate
* pres_notifier_processes) - 1);
update_vals[0].val.int_val =
core_hash(&sub->callid, &sub->from_tag, 0) %
(pres_waitn_time * pres_notifier_poll_rate
* pres_notifier_processes);
if (pa_dbf.use_table(pa_db, &active_watchers_table) < 0)
{
@ -2810,7 +2805,7 @@ int process_dialogs(int round, int presence_winfo)
if (dialog->n <= 0)
{
LM_WARN("record not found\n");
LM_INFO("record not found - this may be observed in multi-server systems\n");
if (cleanup_missing_dialog(&sub) < 0)
LM_ERR("cleaning up after missing record\n");
goto next_dialog;
@ -2845,13 +2840,11 @@ int process_dialogs(int round, int presence_winfo)
cached_updated_winfo = sub.updated_winfo
= VAL_INT(&dvalues[updated_winfo_col]);
if (VAL_INT(&dvalues[expires_col]) > now)
if (VAL_INT(&dvalues[expires_col]) > now + expires_offset)
sub.expires = VAL_INT(&dvalues[expires_col]) - now;
else
sub.expires = 0;
if (sub.expires < expires_offset) sub.expires = 0;
sub.updated = round;
if ((notify_sent = notifier_notify(&sub, &updated, &end_transaction)) < 0)

@ -1277,11 +1277,11 @@ static int update_pw_dialogs_dbonlymode(subs_t* subs, subs_t** subs_array)
return 0;
}
rows = RES_ROWS(result);
/* get the results and fill in return data structure */
for (loop=0; loop <nr_rows; loop++)
{
rows = RES_ROWS(result);
row_vals = ROW_VALUES(rows);
row_vals = ROW_VALUES(&rows[loop]);
memset(&s, 0, sizeof(subs_t));
s.status= subs->status;
@ -1348,10 +1348,10 @@ static int update_pw_dialogs_dbonlymode(subs_t* subs, subs_t** subs_array)
s.expires = row_vals[r_expires_col].val.int_val;
if( s.expires < (int)time(NULL) )
s.expires = 0;
else
if( s.expires > (int)time(NULL) + expires_offset)
s.expires -= (int)time(NULL);
else
s.expires = 0;
s.version = row_vals[r_version_col].val.int_val;
@ -1407,9 +1407,9 @@ static int update_pw_dialogs_dbonlymode(subs_t* subs, subs_t** subs_array)
* pres_notifier_processes));
} else {
db_vals[n_update_cols].val.int_val =
core_hash(&subs->callid, &subs->from_tag,
core_hash(&subs->callid, &subs->from_tag, 0) %
(pres_waitn_time * pres_notifier_poll_rate
* pres_notifier_processes) - 1);
* pres_notifier_processes);
}
n_update_cols++;

@ -470,9 +470,9 @@ int update_subscription_notifier(struct sip_msg* msg, subs_t* subs,
*sent_reply= 0;
/* Set the notifier/update fields for the subscription */
subs->updated = core_hash(&subs->callid, &subs->from_tag,
subs->updated = core_hash(&subs->callid, &subs->from_tag, 0) %
(pres_waitn_time * pres_notifier_poll_rate
* pres_notifier_processes) - 1);
* pres_notifier_processes);
if (subs->event->type & WINFO_TYPE)
subs->updated_winfo = UPDATED_TYPE;
else if (subs->event->wipeer)
@ -1581,9 +1581,9 @@ int handle_expired_subs(subs_t* s)
void update_db_subs_timer_notifier(void)
{
db_key_t query_cols[1], result_cols[3];
db_val_t query_vals[1], *values;
db_op_t query_ops[1];
db_key_t query_cols[2], result_cols[3];
db_val_t query_vals[2], *values;
db_op_t query_ops[2];
db_row_t *rows;
db1_res_t *result = NULL;
int n_query_cols = 0, n_result_cols = 0;
@ -1610,6 +1610,13 @@ void update_db_subs_timer_notifier(void)
query_ops[n_query_cols]= OP_LT;
n_query_cols++;
query_cols[n_query_cols]= &str_updated_col;
query_vals[n_query_cols].type = DB1_INT;
query_vals[n_query_cols].nul = 0;
query_vals[n_query_cols].val.int_val= NO_UPDATE_TYPE;
query_ops[n_query_cols]= OP_EQ;
n_query_cols++;
result_cols[r_callid_col=n_result_cols++] = &str_callid_col;
result_cols[r_to_tag_col=n_result_cols++] = &str_to_tag_col;
result_cols[r_from_tag_col=n_result_cols++] = &str_from_tag_col;
@ -1634,6 +1641,7 @@ void update_db_subs_timer_notifier(void)
for (i = 0; i <RES_ROW_N(result); i++)
{
values = ROW_VALUES(&rows[i]);
memset(&subs, 0, sizeof(subs_t));
subs.callid.s = (char *) VAL_STRING(&values[r_callid_col]);
subs.callid.len = strlen(subs.callid.s);

@ -235,7 +235,7 @@ void update_htable(ua_pres_t* p, time_t desired_expires, int expires,
}
}
/* insert in front; so when searching the most recent result is returned*/
void _insert_htable(ua_pres_t* presentity, unsigned int hash_code)
void insert_htable(ua_pres_t* presentity, unsigned int hash_code)
{
ua_pres_t* p= NULL;
@ -253,18 +253,6 @@ void _insert_htable(ua_pres_t* presentity, unsigned int hash_code)
p->next= presentity;
}
void insert_htable(ua_pres_t* presentity)
{
unsigned int hash_code;
hash_code= core_hash(presentity->pres_uri,presentity->watcher_uri, HASH_SIZE);
lock_get(&HashT->p_records[hash_code].lock);
_insert_htable(presentity, hash_code);
lock_release(&HashT->p_records[hash_code].lock);
}
/* This function used to perform a search to find the hash table
entry that matches the presentity it is passed. However,
everywhere it is used it is passed a pointer to the correct
@ -349,7 +337,7 @@ int convert_temporary_dialog(ua_pres_t *dialog)
else
return -1;
_insert_htable(dialog, hash_code);
insert_htable(dialog, hash_code);
lock_release(&HashT->p_records[hash_code].lock);
@ -695,4 +683,4 @@ list_entry_t *get_subs_list(str *did)
}
done:
return list;
}
}

@ -116,7 +116,8 @@ htable_t* new_htable(void);
ua_pres_t* search_htable(ua_pres_t* pres, unsigned int hash_code);
void insert_htable(ua_pres_t* presentity );
void insert_htable(ua_pres_t* presentity, unsigned int hash_code);
void update_htable(ua_pres_t* presentity,time_t desired_expires,
int expires, str* etag, unsigned int hash_code, str* contact);

@ -268,8 +268,13 @@ static int mod_init(void)
startup_time = (int) time(NULL);
if (update_period > 0) /* probably should check > 5 here!! -croc */
if (update_period > 5)
register_timer(hashT_clean, 0, update_period- 5);
else if (update_period != 0)
{
LM_ERR("update_period must be 0 or > 5\n");
return -1;
}
if (dbmode != PUA_DB_ONLY)
{
@ -386,6 +391,7 @@ static int db_restore(void)
int watcher_col,callid_col,totag_col,fromtag_col,cseq_col,remote_contact_col;
int event_col,contact_col,tuple_col,record_route_col, extra_headers_col;
int version_col;
unsigned int hash_code;
if (dbmode==PUA_DB_ONLY)
{
@ -638,7 +644,11 @@ static int db_restore(void)
}
print_ua_pres(p);
insert_htable(p);
hash_code= core_hash(p->pres_uri, p->watcher_uri, HASH_SIZE);
lock_get(&HashT->p_records[hash_code].lock);
insert_htable(p, hash_code);
lock_release(&HashT->p_records[hash_code].lock);
}
} while((db_fetch_next(&pua_dbf, pua_fetch_rows, pua_db, &res)==1)

@ -614,6 +614,8 @@ int convert_temporary_dialog_puadb(ua_pres_t *pres)
query_vals[n_query_cols].val.str_val.len = 0;
n_query_cols++;
if (pua_dbf.replace != NULL)
{
if (pua_dbf.replace(pua_db, query_cols, query_vals, n_query_cols,
@ -1210,11 +1212,14 @@ ua_pres_t *get_dialog_puadb(str pres_id, str *pres_uri, ua_pres_t *result, db1_r
pua_dbf.free_result(pua_db, res);
return(NULL);
}
if (nr_rows != 1)
else if (nr_rows > 1)
{
LM_ERR("Too many rows found (%d)\n", nr_rows);
LM_ERR("Too many rows found (%d)... deleting\n", nr_rows);
pua_dbf.free_result(pua_db, res);
if (pua_dbf.delete(pua_db, q_cols, 0, q_vals, n_query_cols) < 0)
LM_ERR("deleting record(s)\n");
return(NULL);
}

@ -207,6 +207,7 @@ void publ_cback_func(struct cell *t, int type, struct tmcb_params *ps)
db1_res_t *res=NULL;
ua_pres_t dbpres;
str pres_uri={0,0}, watcher_uri={0,0}, extra_headers={0,0};
int end_transaction = 1;
memset(&dbpres, 0, sizeof(dbpres));
dbpres.pres_uri = &pres_uri;
@ -275,6 +276,17 @@ void publ_cback_func(struct cell *t, int type, struct tmcb_params *ps)
publ.extra_headers= hentity->extra_headers;
publ.cb_param= hentity->cb_param;
if (dbmode == PUA_DB_ONLY && pua_dbf.end_transaction)
{
if (pua_dbf.end_transaction(pua_db) < 0)
{
LM_ERR("in end_transaction\n");
goto error;
}
}
end_transaction = 0;
if(send_publish(&publ)< 0)
{
LM_ERR("when trying to send PUBLISH\n");
@ -410,7 +422,9 @@ void publ_cback_func(struct cell *t, int type, struct tmcb_params *ps)
}
else
{
insert_htable(presentity);
lock_get(&HashT->p_records[hash_code].lock);
insert_htable(presentity, hash_code);
lock_release(&HashT->p_records[hash_code].lock);
}
LM_DBG("***Inserted in hash table\n");
@ -432,7 +446,7 @@ done:
if (res) free_results_puadb(res);
if (dbmode == PUA_DB_ONLY && pua_dbf.end_transaction)
if (dbmode == PUA_DB_ONLY && pua_dbf.end_transaction && end_transaction)
{
if (pua_dbf.end_transaction(pua_db) < 0)
{

@ -1011,9 +1011,6 @@ int send_subscribe(subs_info_t* subs)
int size;
insert:
if (dbmode!=PUA_DB_ONLY)
lock_release(&HashT->p_records[hash_code].lock);
if (subs->expires == 0)
/* Don't create a new dialog when expires == 0 */
goto done;
@ -1123,7 +1120,8 @@ insert:
}
else
{
insert_htable(presentity);
insert_htable(presentity, hash_code);
lock_release(&HashT->p_records[hash_code].lock);
}
uac_r.dialog->rem_target.s = 0;

@ -258,6 +258,16 @@ int pv_get_ulc(struct sip_msg *msg, pv_param_t *param,
case 17: /* count */
return pv_get_sintval(msg, param, res, rpp->nrc);
break;
case 18: /* ruid */
return pv_get_strval(msg, param, res, &c->ruid);
break;
case 19: /* reg-id */
return pv_get_uintval(msg, param, res, c->reg_id);
break;
case 20: /* instance */
if(c->instance.len>0)
return pv_get_strval(msg, param, res, &c->instance);
break;
}
return pv_get_null(msg, param, res);
@ -341,6 +351,8 @@ int pv_parse_ulc_name(pv_spec_p sp, str *in)
rp->attr = 4;
else if(strncmp(pa.s, "cseq", 4)==0)
rp->attr = 9;
else if(strncmp(pa.s, "ruid", 4)==0)
rp->attr = 18;
else goto error;
break;
case 5:
@ -348,6 +360,8 @@ int pv_parse_ulc_name(pv_spec_p sp, str *in)
rp->attr = 10;
else if(strncmp(pa.s, "count", 5)==0)
rp->attr = 17;
else if(strncmp(pa.s, "regid", 5)==0)
rp->attr = 19;
else goto error;
break;
case 6:
@ -375,6 +389,8 @@ int pv_parse_ulc_name(pv_spec_p sp, str *in)
rp->attr = 5;
else if(strncmp(pa.s, "modified", 8)==0)
rp->attr = 15;
else if(strncmp(pa.s, "instance", 8)==0)
rp->attr = 20;
else goto error;
break;
case 10:
@ -461,7 +477,8 @@ int pv_fetch_contacts(struct sip_msg* msg, char* table, char* uri,
while(ptr)
{
olen = (ptr->c.len + ptr->received.len + ptr->path.len
+ ptr->callid.len + ptr->user_agent.len)*sizeof(char) + ilen;
+ ptr->callid.len + ptr->user_agent.len + ptr->ruid.len
+ ptr->instance.len)*sizeof(char) + ilen;
c0 = (ucontact_t*)pkg_malloc(olen);
if(c0==NULL)
{
@ -506,6 +523,20 @@ int pv_fetch_contacts(struct sip_msg* msg, char* table, char* uri,
c0->user_agent.len = ptr->user_agent.len;
p += c0->user_agent.len;
}
if(ptr->ruid.s!=NULL)
{
c0->ruid.s = p;
memcpy(c0->ruid.s, ptr->ruid.s, ptr->ruid.len);
c0->ruid.len = ptr->ruid.len;
p += c0->ruid.len;
}
if(ptr->instance.s!=NULL)
{
c0->instance.s = p;
memcpy(c0->instance.s, ptr->instance.s, ptr->instance.len);
c0->instance.len = ptr->instance.len;
p += c0->instance.len;
}
if(ptr0==NULL)
{

@ -127,17 +127,22 @@ void get_dialog_from_did(char* did, subs_t **dialog, unsigned int *hash_code)
/* save dialog info */
*dialog= pres_copy_subs(s, PKG_MEM_TYPE);
if(*dialog== NULL)
{
LM_ERR("while copying subs_t structure\n");
lock_release(&rls_table[*hash_code].lock);
return;
}
}
if(*dialog== NULL)
{
LM_ERR("while copying subs_t structure\n");
}
if ((*dialog)->expires < (int)time(NULL))
(*dialog)->expires = 0;
else
(*dialog)->expires -= (int)time(NULL);
if (dbmode != RLS_DB_ONLY)
lock_release(&rls_table[*hash_code].lock);
(*dialog)->expires -= (int)time(NULL);
}
int send_notify(xmlDocPtr * rlmi_doc, char * buf, int buf_len,
@ -715,9 +720,9 @@ int rls_handle_notify(struct sip_msg* msg, char* c1, char* c2)
query_vals[n_query_cols].nul = 0;
if (dbmode == RLS_DB_ONLY)
query_vals[n_query_cols].val.int_val=
core_hash(res_id, NULL,
core_hash(res_id, NULL, 0) %
(waitn_time * rls_notifier_poll_rate
* rls_notifier_processes) - 1);
* rls_notifier_processes);
else
query_vals[n_query_cols].val.int_val = UPDATED_TYPE;
n_query_cols++;
@ -994,15 +999,10 @@ static void timer_send_full_state_notifies(int round)
sub.remote_cseq = VAL_INT(&values[rcseq_col]);
sub.status = VAL_INT(&values[status_col]);
sub.version = VAL_INT(&values[version_col]);
if (VAL_INT(&values[expires_col]) > now)
if (VAL_INT(&values[expires_col]) > now + rls_expires_offset)
{
sub.expires = VAL_INT(&values[expires_col]) - now;
else
sub.expires = 0;
if (sub.expires < rls_expires_offset) sub.expires = 0;
if (sub.expires != 0)
{
if (rls_get_service_list(&sub.pres_uri, &sub.watcher_user,
&sub.watcher_domain, &service_node, &doc) < 0)
{
@ -1026,6 +1026,7 @@ static void timer_send_full_state_notifies(int round)
}
else
{
sub.expires = 0;
rls_send_notify(&sub, NULL, NULL, NULL);
delete_rlsdb(&sub.callid, &sub.to_tag, &sub.from_tag);
}
@ -1153,7 +1154,7 @@ void rls_presentity_clean(unsigned int ticks,void *param)
query_ops[0]= OP_LT;
query_vals[0].nul= 0;
query_vals[0].type= DB1_INT;
query_vals[0].val.int_val= (int)time(NULL) - 10;
query_vals[0].val.int_val= (int)time(NULL) - rls_expires_offset;
if (rlpres_dbf.use_table(rlpres_db, &rlpres_table) < 0)
{

@ -116,12 +116,12 @@ int delete_expired_subs_rlsdb( void )
{
db_key_t query_cols[3], result_cols[3], update_cols[1];
db_val_t query_vals[3], update_vals[1], *values;
db_op_t query_ops[1];
db_op_t query_ops[2];
db_row_t *rows;
db1_res_t *result = NULL;
int n_query_cols = 0, n_result_cols = 0;
int r_callid_col = 0, r_to_tag_col = 0, r_from_tag_col = 0;
int i;
int i, nr_rows;
subs_t subs;
str rlsubs_did = {0, 0};
@ -144,6 +144,13 @@ int delete_expired_subs_rlsdb( void )
query_ops[n_query_cols]= OP_LT;
n_query_cols++;
query_cols[n_query_cols]= &str_updated_col;
query_vals[n_query_cols].type = DB1_INT;
query_vals[n_query_cols].nul = 0;
query_vals[n_query_cols].val.int_val= NO_UPDATE_TYPE;
query_ops[n_query_cols]= OP_EQ;
n_query_cols++;
result_cols[r_callid_col=n_result_cols++] = &str_callid_col;
result_cols[r_to_tag_col=n_result_cols++] = &str_to_tag_col;
result_cols[r_from_tag_col=n_result_cols++] = &str_from_tag_col;
@ -157,10 +164,13 @@ int delete_expired_subs_rlsdb( void )
if(result == NULL) goto error;
for (i = 0; i <RES_ROW_N(result); i++)
rows = RES_ROWS(result);
nr_rows = RES_ROW_N(result);
for (i = 0; i < nr_rows; i++)
{
rows = RES_ROWS(result);
values = ROW_VALUES(rows);
memset(&subs, 0, sizeof(subs_t));
values = ROW_VALUES(&rows[i]);
subs.callid.s = (char *) VAL_STRING(&values[r_callid_col]);
subs.callid.len = strlen(subs.callid.s);
@ -174,8 +184,8 @@ int delete_expired_subs_rlsdb( void )
LM_ERR("cannot build rls subs did\n");
goto error;
}
subs.updated = core_hash(&rlsubs_did, NULL,
(waitn_time * rls_notifier_poll_rate * rls_notifier_processes) - 1);
subs.updated = core_hash(&rlsubs_did, NULL, 0) %
(waitn_time * rls_notifier_poll_rate * rls_notifier_processes);
n_query_cols = 0;
@ -415,11 +425,11 @@ int update_all_subs_rlsdb(str *watcher_user, str *watcher_domain, str *evt)
nr_rows = RES_ROW_N(result);
rows = RES_ROWS(result);
/* get the results and fill in return data structure */
for (loop=0; loop <nr_rows; loop++)
{
rows = RES_ROWS(result);
values = ROW_VALUES(rows);
values = ROW_VALUES(&rows[loop]);
size= sizeof(subs_t) +
( strlen(VAL_STRING(values+r_pres_uri_col))
@ -798,6 +808,13 @@ int get_dialog_subscribe_rlsdb(subs_t *subs)
r_version = VAL_INT(&values[version_col]);
r_record_route = (char *)VAL_STRING(&values[rroute_col]);
if ( r_remote_cseq >= subs->remote_cseq)
{
LM_DBG("stored cseq= %d\n", r_remote_cseq);
rls_dbf.free_result(rls_db, result);
return(401); /*stale cseq code */
}
if(strlen(r_pres_uri) > 0)
{
subs->pres_uri.s =
@ -805,7 +822,6 @@ int get_dialog_subscribe_rlsdb(subs_t *subs)
if(subs->pres_uri.s==NULL)
{
LM_ERR( "Out of Memory\n" );
pkg_free(subs->pres_uri.s);
rls_dbf.free_result(rls_db, result);
return(-1);
}
@ -814,13 +830,6 @@ int get_dialog_subscribe_rlsdb(subs_t *subs)
subs->pres_uri.len= strlen(r_pres_uri);
}
if ( r_remote_cseq >= subs->remote_cseq)
{
LM_DBG("stored cseq= %d\n", r_remote_cseq);
rls_dbf.free_result(rls_db, result);
return(401); /*stale cseq code */
}
if(strlen(r_record_route) > 0)
{
subs->record_route.s =
@ -828,7 +837,6 @@ int get_dialog_subscribe_rlsdb(subs_t *subs)
if(subs->record_route.s==NULL)
{
LM_ERR( "Out of Memory\n" );
pkg_free(subs->record_route.s);
rls_dbf.free_result(rls_db, result);
return(-1);
}
@ -848,8 +856,8 @@ int get_dialog_subscribe_rlsdb(subs_t *subs)
subs_t *get_dialog_notify_rlsdb(str callid, str to_tag, str from_tag)
{
db_key_t query_cols[3];
db_val_t query_vals[3];
db_key_t query_cols[4];
db_val_t query_vals[4];
db_key_t result_cols[22];
int n_query_cols = 0, n_result_cols=0;
int r_pres_uri_col,r_to_user_col,r_to_domain_col;
@ -897,6 +905,12 @@ subs_t *get_dialog_notify_rlsdb(str callid, str to_tag, str from_tag)
query_vals[n_query_cols].nul = 0;
query_vals[n_query_cols].val.str_val= from_tag;
n_query_cols++;
query_cols[n_query_cols] = &str_updated_col;
query_vals[n_query_cols].type = DB1_INT;
query_vals[n_query_cols].nul = 0;
query_vals[n_query_cols].val.int_val= NO_UPDATE_TYPE;
n_query_cols++;
result_cols[r_pres_uri_col=n_result_cols++] = &str_presentity_uri_col;
result_cols[r_to_user_col=n_result_cols++] = &str_to_user_col;

@ -69,9 +69,6 @@ int resource_subscriptions(subs_t* subs, xmlNodePtr rl_node);
int update_rlsubs( subs_t* subs,unsigned int hash_code);
int remove_expired_rlsubs( subs_t* subs,unsigned int hash_code);
list_entry_t *rls_contact_list = NULL;
list_entry_t *rls_subs_list = NULL;
/**
* return the XML node for rls-services matching uri
*/
@ -327,7 +324,7 @@ int reply_200(struct sip_msg* msg, str* contact, int expires)
LM_ERR("no more pkg memory\n");
return -1;
}
hdr_append.len = sprintf(hdr_append.s, "Expires: %d\r\n", expires);
hdr_append.len = sprintf(hdr_append.s, "Expires: %d\r\n", expires);
if(hdr_append.len< 0)
{
LM_ERR("unsuccessful sprintf\n");
@ -586,8 +583,8 @@ int rls_handle_subscribe(struct sip_msg* msg, str watcher_user, str watcher_doma
LM_ERR("cannot build rls subs did\n");
goto error;
}
subs.updated = core_hash(&rlsubs_did, NULL,
(waitn_time * rls_notifier_poll_rate * rls_notifier_processes) - 1);
subs.updated = core_hash(&rlsubs_did, NULL, 0) %
(waitn_time * rls_notifier_poll_rate * rls_notifier_processes);
if(get_to(msg)->tag_value.s==NULL || get_to(msg)->tag_value.len==0)
{ /* initial Subscribe */
@ -920,7 +917,9 @@ int send_resource_subs(char* uri, void* param)
str pres_uri, *tmp_str;
struct sip_uri parsed_pres_uri;
int duplicate = 0;
subs_info_t *s = (subs_info_t *) param;
subs_info_t *s = (subs_info_t *) ((void**)param)[0];
list_entry_t **rls_contact_list = (list_entry_t **) ((void**)param)[1];
pres_uri.s = uri;
pres_uri.len = strlen(uri);
@ -962,7 +961,7 @@ int send_resource_subs(char* uri, void* param)
}
memcpy(tmp_str->s, pres_uri.s, pres_uri.len);
tmp_str->len = pres_uri.len;
rls_contact_list = list_insert(tmp_str, rls_contact_list, &duplicate);
*rls_contact_list = list_insert(tmp_str, *rls_contact_list, &duplicate);
if (duplicate != 0)
{
LM_WARN("%.*s has %.*s multiple times in the same resource list\n",
@ -984,6 +983,9 @@ int resource_subscriptions(subs_t* subs, xmlNodePtr xmlnode)
str extra_headers;
str did_str= {0, 0};
str *tmp_str;
list_entry_t *rls_contact_list = NULL;
list_entry_t *rls_subs_list = NULL;
void* params[2] = {&s, &rls_contact_list};
/* if is initial send an initial Subscribe
* else search in hash table for a previous subscription */
@ -1024,25 +1026,10 @@ int resource_subscriptions(subs_t* subs, xmlNodePtr xmlnode)
s.internal_update_flag = subs->internal_update_flag;
if (rls_contact_list != NULL)
{
LM_WARN("contact list is not empty\n");
list_free(&rls_contact_list);
}
if (subs->internal_update_flag == INTERNAL_UPDATE_TRUE)
{
if (rls_subs_list != NULL)
{
LM_WARN("subscriber list is not empty\n");
list_free(&rls_subs_list);
}
}
counter = 0;
if(process_list_and_exec(xmlnode, subs->watcher_user, subs->watcher_domain,
send_resource_subs, (void*)(&s))<0)
send_resource_subs, params)<0)
{
LM_ERR("while processing list\n");
goto error;
@ -1071,15 +1058,13 @@ int resource_subscriptions(subs_t* subs, xmlNodePtr xmlnode)
{
LM_DBG("Removing subscription for %.*s\n", tmp_str->len, tmp_str->s);
s.expires = 0;
send_resource_subs(tmp_str->s, (void*)(&s));
send_resource_subs(tmp_str->s, params);
pkg_free(tmp_str->s);
pkg_free(tmp_str);
}
}
else
{
if (rls_contact_list != NULL)
list_free(&rls_contact_list);
}
pkg_free(wuri.s);
pkg_free(did_str.s);
@ -1111,13 +1096,16 @@ void update_a_sub(subs_t *subs_copy)
{
xmlDocPtr doc = NULL;
xmlNodePtr service_node = NULL;
int now = (int)time(NULL);
if ((subs_copy->expires -= (int)time(NULL)) <= 0)
if (subs_copy->expires < now)
{
subs_copy->expires = 0;
LM_WARN("found expired subscription for: %.*s\n",
subs_copy->pres_uri.len, subs_copy->pres_uri.s);
goto done;
}
subs_copy->expires -= now;
if(rls_get_service_list(&subs_copy->pres_uri, &subs_copy->watcher_user,
&subs_copy->watcher_domain, &service_node, &doc)<0)

@ -1604,6 +1604,9 @@ static int trace_send_hep_duplicate(str *body, str *from, str *to)
}
hdr.hp_l +=len;
if (hep_version == 2){
len += sizeof(struct hep_timehdr);
}
len += sizeof(struct hep_hdr) + body->len;
buffer = (void *)pkg_malloc(len+1);
if (buffer==0){

@ -110,6 +110,11 @@ static inline int get_all_db_ucontacts(void *buf, int len, unsigned int flags,
void *cp;
int shortage, needed;
if(ul_dbf.raw_query==NULL) {
LM_WARN("DB raw query support is required, but not implemented\n");
return -1;
}
cp = buf;
shortage = 0;
/* Reserve space for terminating 0000 */
@ -201,12 +206,12 @@ static inline int get_all_db_ucontacts(void *buf, int len, unsigned int flags,
} else {
if (parse_phostport( p, &host.s, &host.len,
&port, &proto)!=0) {
LM_ERR("bad socket <%s>...ignoring\n", p);
LM_ERR("bad socket <%s>...set to 0\n", p);
sock = 0;
} else {
sock = grep_sock_info( &host, (unsigned short)port, proto);
if (sock==0) {
LM_WARN("non-local socket <%s>...ignoring\n", p);
LM_DBG("non-local socket <%s>...set to 0\n", p);
}
}
}

@ -525,10 +525,8 @@ struct mi_root* mi_usrloc_add(struct mi_root *cmd, void *param)
if (str2q( &ci.q, node->value.s, node->value.len) < 0)
goto bad_syntax;
/* path value (param 6) */
/* unused value (param 6) FIXME */
node = node->next;
if(strncmp(node->value.s, "0", 1) != 0 && node->value.len > 1)
ci.path = &node->value;
/* flags value (param 7) */
node = node->next;

@ -1339,6 +1339,12 @@ static int check_preconditions(sip_msg_t *msg, str etag_hdr)
static int check_match_header(str body, str *etag)
{
if (etag == NULL)
return -1;
if (etag->s == NULL || etag->len == 0)
return -1;
do
{
char *start_pos, *end_pos, *old_body_pos;

@ -91,7 +91,7 @@ unsigned int global_req_flags = 0;
char* get_hdr_field(char* buf, char* end, struct hdr_field* hdr)
{
char* tmp;
char *tmp = 0;
char *match;
struct via_body *vb;
struct cseq_body* cseq_b;

@ -555,6 +555,7 @@ int parse_params(str* _s, pclass_t _c, param_hooks_t* _h, param_t** _p)
error:
if (t) pkg_free(t);
free_params(*_p);
*_p = 0;
return -2;
ok:

@ -451,6 +451,8 @@ static int parse_sdp_session(str *sdp_body, int session_num, str *cnt_disp, sdp_
/* c2p will point to per-media "c=" */
c2p = find_sdp_line(m1p, m2p, 'c');
sdp_ip.s = NULL;
sdp_ip.len = 0;
if (c2p) {
/* Extract stream address */
tmpstr1.s = c2p;
@ -721,12 +723,13 @@ int parse_sdp(struct sip_msg* _m)
if (res != 0) {
LM_DBG("free_sdp\n");
free_sdp((sdp_info_t**)(void*)&_m->body);
return res;
return res;
}
/* The whole body is SDP */
((sdp_info_t*)_m->body)->raw_sdp.s = body.s;
((sdp_info_t*)_m->body)->raw_sdp.len = body.len;
return 0;
return res;
break;
default:
LM_DBG("TYPE_APPLICATION: unknown %d\n",mime&0x00ff);
return -1;

@ -808,7 +808,7 @@ inline static int _wbufq_insert(struct tcp_connection* c, const char* data,
}
if ((q->first==q->last) && ((q->last->b_size-q->last_used)>=size)){
/* one block with enough space in it for size bytes */
memmove(q->first->buf+size, q->first->buf, size);
memmove(q->first->buf+size, q->first->buf, q->last_used);
memcpy(q->first->buf, data, size);
q->last_used+=size;
}else{
@ -1339,11 +1339,14 @@ int tcpconn_finish_connect( struct tcp_connection* c,
/* remove all the aliases except the first one and re-add them
* (there shouldn't be more then the 3 default aliases at this
* stage) */
for (r=1; r<c->aliases; r++){
a=&c->con_aliases[r];
tcpconn_listrm(tcpconn_aliases_hash[a->hash], a, next, prev);
if (c->aliases > 1) {
for (r=1; r<c->aliases; r++){
a=&c->con_aliases[r];
tcpconn_listrm(tcpconn_aliases_hash[a->hash],
a, next, prev);
}
c->aliases=1;
}
c->aliases=1;
/* add the local_ip:0 and local_ip:local_port aliases */
_tcpconn_add_alias_unsafe(c, c->rcv.src_port, &c->rcv.dst_ip,
0, new_conn_alias_flags);

@ -8,7 +8,7 @@ all:
install-if-newer: install
install: install-bin install-man install-modules
install: install-cfg install-bin install-man install-modules
install-cfg: $(cfg_prefix)/$(cfg_dir)
# kamctl config

@ -102,10 +102,10 @@ CREATE TABLE pua (
remote_contact VARCHAR(128) NOT NULL,
version INTEGER NOT NULL,
extra_headers TEXT NOT NULL,
CONSTRAINT pua_pua_idx UNIQUE (etag, tuple_id, call_id, from_tag),
CONSTRAINT pua_expires_idx UNIQUE (expires)
CONSTRAINT pua_pua_idx UNIQUE (etag, tuple_id, call_id, from_tag)
);
CREATE INDEX pua_expires_idx ON pua (expires);
CREATE INDEX pua_dialog1_idx ON pua (call_id, from_tag, to_tag);
CREATE INDEX pua_dialog2_idx ON pua (pres_id, pres_uri);
CREATE INDEX pua_tmp_dlg1_idx ON pua (call_id, from_tag);

@ -1,3 +1,3 @@
callid(string) cflags(int) contact(string) cseq(int) expires(timestamp) flags(int) last_modified(int) methods(int) path(string) q(double) received(string) socket(string) user_agent(string) username(string)
callid(string) cflags(int) contact(string) cseq(int) expires(timestamp) flags(int) last_modified(int) methods(int) path(string) q(double) received(string) socket(string) user_agent(string) username(string) ruid(string) instance(string) reg_id(int)
username
contact

@ -2201,17 +2201,10 @@ usrloc() {
UL_EXPIRES=0
UL_FLAGS=0
BR_FLAGS=0
UL_PATH=0
elif [ $# -eq 4 ] ; then
UL_EXPIRES=$4
UL_FLAGS=0
BR_FLAGS=0
UL_PATH=0
elif [ $# -eq 5 ] ; then
UL_EXPIRES=$4
UL_FLAGS=0
BR_FLAGS=0
UL_PATH="$5"
else
usage_usrloc
exit 1
@ -2244,7 +2237,7 @@ usrloc() {
fi
$CTLCMD ul_add "$USRLOC_TABLE" "$OSERUSER@$OSERDOMAIN" "$2" \
"$UL_EXPIRES" "1.00" "$UL_PATH" "$UL_FLAGS" "$BR_FLAGS" "$ALL_METHODS"
"$UL_EXPIRES" "1.00" "0" "$UL_FLAGS" "$BR_FLAGS" "$ALL_METHODS"
exit $?
;;
rm)

@ -102,10 +102,10 @@ CREATE TABLE pua (
remote_contact VARCHAR(128) NOT NULL,
version INT(11) NOT NULL,
extra_headers TEXT NOT NULL,
CONSTRAINT pua_idx UNIQUE (etag, tuple_id, call_id, from_tag),
CONSTRAINT expires_idx UNIQUE (expires)
CONSTRAINT pua_idx UNIQUE (etag, tuple_id, call_id, from_tag)
) ENGINE=MyISAM;
CREATE INDEX expires_idx ON pua (expires);
CREATE INDEX dialog1_idx ON pua (call_id, from_tag, to_tag);
CREATE INDEX dialog2_idx ON pua (pres_id, pres_uri);
CREATE INDEX tmp_dlg1_idx ON pua (call_id, from_tag);

@ -134,8 +134,7 @@ CREATE TABLE pua (
remote_contact VARCHAR2(128),
version NUMBER(10),
extra_headers CLOB,
CONSTRAINT pua_pua_idx UNIQUE (etag, tuple_id, call_id, from_tag),
CONSTRAINT pua_expires_idx UNIQUE (expires)
CONSTRAINT pua_pua_idx UNIQUE (etag, tuple_id, call_id, from_tag)
);
CREATE OR REPLACE TRIGGER pua_tr
@ -146,6 +145,7 @@ END pua_tr;
/
BEGIN map2users('pua'); END;
/
CREATE INDEX pua_expires_idx ON pua (expires);
CREATE INDEX pua_dialog1_idx ON pua (call_id, from_tag, to_tag);
CREATE INDEX pua_dialog2_idx ON pua (pres_id, pres_uri);
CREATE INDEX pua_tmp_dlg1_idx ON pua (call_id, from_tag);

@ -102,10 +102,10 @@ CREATE TABLE pua (
remote_contact VARCHAR(128) NOT NULL,
version INTEGER NOT NULL,
extra_headers TEXT NOT NULL,
CONSTRAINT pua_pua_idx UNIQUE (etag, tuple_id, call_id, from_tag),
CONSTRAINT pua_expires_idx UNIQUE (expires)
CONSTRAINT pua_pua_idx UNIQUE (etag, tuple_id, call_id, from_tag)
);
CREATE INDEX pua_expires_idx ON pua (expires);
CREATE INDEX pua_dialog1_idx ON pua (call_id, from_tag, to_tag);
CREATE INDEX pua_dialog2_idx ON pua (pres_id, pres_uri);
CREATE INDEX pua_tmp_dlg1_idx ON pua (call_id, from_tag);

@ -6,7 +6,13 @@ func! s:cfgType()
if getline(n) =~ '^\s*#!\(KAMAILIO\|OPENSER\|SER\|ALL\|MAXCOMPAT\)'
set filetype=ser
return
elseif getline(n) =~ '^\s*modparam\s*(\s*"[^"]\+"'
elseif getline(n) =~ '^\s*#!\(define\|ifdef\|endif\|subst\|substdef\)'
set filetype=ser
return
elseif getline(n) =~ '^\s*!!\(define\|ifdef\|endif\|subst\|substdef\)'
set filetype=ser
return
elseif getline(n) =~ '^\s*modparam\s*(\s*"[^"]\+"'
set filetype=ser
return
elseif getline(n) =~ '^\s*route\s*{\s*'

@ -34,7 +34,7 @@ syn keyword serTodo TODO FIXME XXX contained
syn match serOperator '!\|&&\|||\|=[~=]\?\|>\|<\|+\|-\|/\|\*\||\|&\|^\|\~\|defined\|eq\|ieq\|ne\|ine\|mod' display contained
syn region serCppComment start='/\*' end='\*/' contains=serTodo
syn match serHashDefine '#!define\s\|#!ifdef\s\|#!ifndef\s\|#!endif\|#!else\|#!subst\|!!define\s\|!!ifdef\s\|!!ifndef\s\|!!endif\|!!else\|!!subst\|#!KAMAILIO\|#!OPENSER\|#!SER\|#!MAXCOMPAT\|#!ALL'
syn match serHashDefine '#!define\s\|#!ifdef\s\|#!ifndef\s\|#!endif\|#!else\|#!substdef\|#!subst\|!!define\s\|!!ifdef\s\|!!ifndef\s\|!!endif\|!!else\|!!substdef\|!!subst\|#!KAMAILIO\|#!OPENSER\|#!SER\|#!MAXCOMPAT\|#!ALL'
" syn match serHashDefine '^\s*#!.+$'
syn match serHashComment '#[^!].*$\|#$' contains=serTodo
@ -43,7 +43,7 @@ syn match serNumber '[0-9]\+' contained
syn region serString matchgroup=Normal start='"' skip='\\"' end='"' contained contains=serVariable,serStringEscape
syn match serVariable "$[a-zA-Z_][a-zA-Z0-9_]*\(([^)]\+)\)\?" contained
syn match serIdentifier '[a-zA-Z_][a-zA-Z0-9_]*' contained
syn keyword serStatement route if else switch case default break exit return drop while include_file contained
syn keyword serStatement route if else switch case default break exit return drop while include_file import_file contained
syn keyword serSpecial yes no on off true false enabled disabled contained
syn keyword serCoreKeyword af dst_ip dst_port from_uri method msg:len proto status snd_af snd_ip snd_port snd_proto src_ip src_port to_af to_ip to_port to_proto to_uri uri uri:host uri:port contained

Loading…
Cancel
Save