hi,
I was recently fighting with a serial forking issue, and figured out
that t_relay() automatically appends a new branch when the RURI has been
changed. This means to me that the config below becomes incorrect:
failure_route["abcd"] {
...
rewritehostport("127.0.0.1:5062");
append_branch();
t_relay();
}
I saw two branches created with the same RURI and sent to the same
destination in parallel.
As far as I got it append_branch() should not be called any more in
failure route unless parallel forking is desired. This is great, the
only issue is that this is not mentioned in the documentation, the tm
readme file still contains the old examples, and all the configurations
under etc/ still call append_branch(). Is there any plan to update the
docs and configs before releasing the new sip-router version?
Thanks,
Miklos
Module: sip-router
Branch: master
Commit: 4cd7a346ad6dd2542c318ad371416105b60654be
URL: http://git.sip-router.org/cgi-bin/gitweb.cgi/sip-router/?a=commit;h=4cd7a34…
Author: Andrei Pelinescu-Onciul <andrei(a)iptel.org>
Committer: Andrei Pelinescu-Onciul <andrei(a)iptel.org>
Date: Sat Sep 11 08:24:23 2010 +0200
core: append_branch(): avoid identical branches
If append_branch() is used from the script, try to avoid having 2
identical branches (one for the main ruri and one because of the
append_branch()). In this case the ruri will be marked as consumed.
Reported-by: Daniel-Constantin Mierla <miconda(a)gmail.com>
Reported-and-tested-by: Miklos Tirpak <miklos(a)iptel.org>
---
action.c | 5 +++++
1 files changed, 5 insertions(+), 0 deletions(-)
diff --git a/action.c b/action.c
index 1716c34..67c6026 100644
--- a/action.c
+++ b/action.c
@@ -549,6 +549,11 @@ int do_action(struct run_act_ctx* h, struct action* a, struct sip_msg* msg)
ret=append_branch(msg, &a->val[0].u.str, &msg->dst_uri,
&msg->path_vec, a->val[1].u.number,
(flag_t)flags, msg->force_send_socket);
+ /* if the uri is the ruri and q was also not changed, mark
+ ruri as consumed, to avoid having an identical branch */
+ if ((a->val[0].u.str.s == 0 || a->val[0].u.str.len == 0) &&
+ a->val[1].u.number == Q_UNSPECIFIED)
+ ruri_mark_consumed();
break;
/* jku begin: is_length_greater_than */
Module: sip-router
Branch: master
Commit: a7bbaf7cd83b5d044ff8c7fff7b19c7ff392da74
URL: http://git.sip-router.org/cgi-bin/gitweb.cgi/sip-router/?a=commit;h=a7bbaf7…
Author: Miklos Tirpak <miklos(a)iptel.org>
Committer: Miklos Tirpak <miklos(a)iptel.org>
Date: Thu Sep 30 10:42:57 2010 +0200
tm: t_save_lumps() verifies the route type
Even though the t_save_lumps() function is registered only for
request route, in some corner case, the function might be called
from failure_route. (For example a failure route executes a request
route block which calls this function.)
This scenario resulted in overwriting the already cloned lump list
which is not allowed because of the lockless read, and also
resulted in a memory leak.
An extra check is also added to save_msg_lumps() to catch this bug.
---
modules/tm/sip_msg.c | 8 ++++++++
modules/tm/tm.c | 22 ++++++++++++----------
2 files changed, 20 insertions(+), 10 deletions(-)
diff --git a/modules/tm/sip_msg.c b/modules/tm/sip_msg.c
index e7bebcc..ab093f8 100644
--- a/modules/tm/sip_msg.c
+++ b/modules/tm/sip_msg.c
@@ -116,6 +116,14 @@ int save_msg_lumps( struct sip_msg *shm_msg, struct sip_msg *pkg_msg)
return -1;
}
+#ifdef EXTRA_DEBUG
+ membar_depends();
+ if (shm_msg->add_rm || shm_msg->body_lumps || shm_msg->reply_lump) {
+ LOG(L_ERR, "ERROR: save_msg_lumps: BUG, trying to overwrite the already cloned lumps\n");
+ return -1;
+ }
+#endif
+
/* needless to clone the lumps for ACK, they will not be used again */
if (shm_msg->REQ_METHOD == METHOD_ACK)
return 0;
diff --git a/modules/tm/tm.c b/modules/tm/tm.c
index c5cd841..e5ca753 100644
--- a/modules/tm/tm.c
+++ b/modules/tm/tm.c
@@ -1885,17 +1885,19 @@ static int w_t_save_lumps(struct sip_msg* msg, char* foo, char* bar)
#ifdef POSTPONE_MSG_CLONING
struct cell *t;
- t=get_t();
- if (!t || t==T_UNDEFINED) {
- LOG(L_ERR, "ERROR: w_t_save_lumps: transaction has not been created yet\n");
- return -1;
- }
+ if (is_route_type(REQUEST_ROUTE)) {
+ t=get_t();
+ if (!t || t==T_UNDEFINED) {
+ LOG(L_ERR, "ERROR: w_t_save_lumps: transaction has not been created yet\n");
+ return -1;
+ }
- if (save_msg_lumps(t->uas.request, msg)) {
- LOG(L_ERR, "ERROR: w_t_save_lumps: "
- "failed to save the message lumps\n");
- return -1;
- }
+ if (save_msg_lumps(t->uas.request, msg)) {
+ LOG(L_ERR, "ERROR: w_t_save_lumps: "
+ "failed to save the message lumps\n");
+ return -1;
+ }
+ } /* else nothing to do, the lumps have already been saved */
return 1;
#else
LOG(L_ERR, "ERROR: w_t_save_lumps: POSTPONE_MSG_CLONING is not defined,"
Module: sip-router
Branch: kamailio_3.0
Commit: a22dc9b151d44dede21e3f500455eab568d14f28
URL: http://git.sip-router.org/cgi-bin/gitweb.cgi/sip-router/?a=commit;h=a22dc9b…
Author: Andrei Pelinescu-Onciul <andrei(a)iptel.org>
Committer: Andrei Pelinescu-Onciul <andrei(a)iptel.org>
Date: Thu Sep 30 01:28:00 2010 +0200
mem: fix f_malloc big fragments search
In some situation (depending on previous allocation and frees)
trying to allocate a "big" fragment (>16k) would fail even if
enough memory was available (the fragment search algorithm missed
fallback to bigger buckets when using the free bitmap).
(cherry picked from commit 1ccbd33558e7e09f36f39fd984ac99a7bfd3eba2)
---
mem/f_malloc.c | 28 +++++++++++++++++++++++-----
1 files changed, 23 insertions(+), 5 deletions(-)
diff --git a/mem/f_malloc.c b/mem/f_malloc.c
index 49c4b7a..6fa88c3 100644
--- a/mem/f_malloc.c
+++ b/mem/f_malloc.c
@@ -34,6 +34,12 @@
* 2007-02-23 added fm_available() (andrei)
* 2007-06-23 added hash bitmap (andrei)
* 2009-09-28 added fm_sums() (patch from Dragos Vingarzan)
+ * 2010-03-11 fix big fragments bug (smaller fragment was wrongly
+ * returned sometimes) (andrei)
+ * 2010-03-12 fix real_used stats for realloc: a realloc that shrank an
+ * allocation accounted twice fro the frag. overhead (andrei)
+ * 2010-09-30 fixed search for big fragments using the hash bitmap
+ * (only the first bucket was tried) (andrei)
*/
@@ -336,11 +342,23 @@ void* fm_malloc(struct fm_block* qm, unsigned long size)
#ifdef F_MALLOC_HASH_BITMAP
hash=fm_bmp_first_set(qm, GET_HASH(size));
if (likely(hash>=0)){
- f=&(qm->free_hash[hash].first);
- if (likely(hash<=F_MALLOC_OPTIMIZE/ROUNDTO)) /* return first match */
- goto found;
- for(;(*f); f=&((*f)->u.nxt_free))
- if ((*f)->size>=size) goto found;
+ if (likely(hash<=F_MALLOC_OPTIMIZE/ROUNDTO)) { /* return first match */
+ f=&(qm->free_hash[hash].first);
+ goto found;
+ }
+ /* if we are here we are searching for a "big" fragment
+ between F_MALLOC_OPTIMIZE/ROUNDTO+1
+ and F_MALLOC_OPTIMIZE/ROUNDTO + (32|64) - F_MALLOC_OPTIMIZE_FACTOR
+ => 18 hash buckets on 32 bits and 50 buckets on 64 bits
+ The free hash bitmap is used to jump directly to non-empty
+ hash buckets.
+ */
+ do {
+ for(f=&(qm->free_hash[hash].first);(*f); f=&((*f)->u.nxt_free))
+ if ((*f)->size>=size) goto found;
+ hash++; /* try in next hash cell */
+ }while((hash < F_HASH_SIZE) &&
+ ((hash=fm_bmp_first_set(qm, hash)) >= 0));
}
#else /* F_MALLOC_HASH_BITMAP */
for(hash=GET_HASH(size);hash<F_HASH_SIZE;hash++){
Module: sip-router
Branch: sr_3.0
Commit: fad8152367ba9ed3bde85a4fabb85cae469e58d3
URL: http://git.sip-router.org/cgi-bin/gitweb.cgi/sip-router/?a=commit;h=fad8152…
Author: Andrei Pelinescu-Onciul <andrei(a)iptel.org>
Committer: Andrei Pelinescu-Onciul <andrei(a)iptel.org>
Date: Thu Sep 30 01:28:00 2010 +0200
mem: fix f_malloc big fragments search
In some situation (depending on previous allocation and frees)
trying to allocate a "big" fragment (>16k) would fail even if
enough memory was available (the fragment search algorithm missed
fallback to bigger buckets when using the free bitmap).
(cherry picked from commit 1ccbd33558e7e09f36f39fd984ac99a7bfd3eba2)
---
mem/f_malloc.c | 28 +++++++++++++++++++++++-----
1 files changed, 23 insertions(+), 5 deletions(-)
diff --git a/mem/f_malloc.c b/mem/f_malloc.c
index 49c4b7a..6fa88c3 100644
--- a/mem/f_malloc.c
+++ b/mem/f_malloc.c
@@ -34,6 +34,12 @@
* 2007-02-23 added fm_available() (andrei)
* 2007-06-23 added hash bitmap (andrei)
* 2009-09-28 added fm_sums() (patch from Dragos Vingarzan)
+ * 2010-03-11 fix big fragments bug (smaller fragment was wrongly
+ * returned sometimes) (andrei)
+ * 2010-03-12 fix real_used stats for realloc: a realloc that shrank an
+ * allocation accounted twice fro the frag. overhead (andrei)
+ * 2010-09-30 fixed search for big fragments using the hash bitmap
+ * (only the first bucket was tried) (andrei)
*/
@@ -336,11 +342,23 @@ void* fm_malloc(struct fm_block* qm, unsigned long size)
#ifdef F_MALLOC_HASH_BITMAP
hash=fm_bmp_first_set(qm, GET_HASH(size));
if (likely(hash>=0)){
- f=&(qm->free_hash[hash].first);
- if (likely(hash<=F_MALLOC_OPTIMIZE/ROUNDTO)) /* return first match */
- goto found;
- for(;(*f); f=&((*f)->u.nxt_free))
- if ((*f)->size>=size) goto found;
+ if (likely(hash<=F_MALLOC_OPTIMIZE/ROUNDTO)) { /* return first match */
+ f=&(qm->free_hash[hash].first);
+ goto found;
+ }
+ /* if we are here we are searching for a "big" fragment
+ between F_MALLOC_OPTIMIZE/ROUNDTO+1
+ and F_MALLOC_OPTIMIZE/ROUNDTO + (32|64) - F_MALLOC_OPTIMIZE_FACTOR
+ => 18 hash buckets on 32 bits and 50 buckets on 64 bits
+ The free hash bitmap is used to jump directly to non-empty
+ hash buckets.
+ */
+ do {
+ for(f=&(qm->free_hash[hash].first);(*f); f=&((*f)->u.nxt_free))
+ if ((*f)->size>=size) goto found;
+ hash++; /* try in next hash cell */
+ }while((hash < F_HASH_SIZE) &&
+ ((hash=fm_bmp_first_set(qm, hash)) >= 0));
}
#else /* F_MALLOC_HASH_BITMAP */
for(hash=GET_HASH(size);hash<F_HASH_SIZE;hash++){
Module: sip-router
Branch: master
Commit: 1ccbd33558e7e09f36f39fd984ac99a7bfd3eba2
URL: http://git.sip-router.org/cgi-bin/gitweb.cgi/sip-router/?a=commit;h=1ccbd33…
Author: Andrei Pelinescu-Onciul <andrei(a)iptel.org>
Committer: Andrei Pelinescu-Onciul <andrei(a)iptel.org>
Date: Thu Sep 30 01:28:00 2010 +0200
mem: fix f_malloc big fragments search
In some situation (depending on previous allocation and frees)
trying to allocate a "big" fragment (>16k) would fail even if
enough memory was available (the fragment search algorithm missed
fallback to bigger buckets when using the free bitmap).
---
mem/f_malloc.c | 28 +++++++++++++++++++++++-----
1 files changed, 23 insertions(+), 5 deletions(-)
diff --git a/mem/f_malloc.c b/mem/f_malloc.c
index 49c4b7a..6fa88c3 100644
--- a/mem/f_malloc.c
+++ b/mem/f_malloc.c
@@ -34,6 +34,12 @@
* 2007-02-23 added fm_available() (andrei)
* 2007-06-23 added hash bitmap (andrei)
* 2009-09-28 added fm_sums() (patch from Dragos Vingarzan)
+ * 2010-03-11 fix big fragments bug (smaller fragment was wrongly
+ * returned sometimes) (andrei)
+ * 2010-03-12 fix real_used stats for realloc: a realloc that shrank an
+ * allocation accounted twice fro the frag. overhead (andrei)
+ * 2010-09-30 fixed search for big fragments using the hash bitmap
+ * (only the first bucket was tried) (andrei)
*/
@@ -336,11 +342,23 @@ void* fm_malloc(struct fm_block* qm, unsigned long size)
#ifdef F_MALLOC_HASH_BITMAP
hash=fm_bmp_first_set(qm, GET_HASH(size));
if (likely(hash>=0)){
- f=&(qm->free_hash[hash].first);
- if (likely(hash<=F_MALLOC_OPTIMIZE/ROUNDTO)) /* return first match */
- goto found;
- for(;(*f); f=&((*f)->u.nxt_free))
- if ((*f)->size>=size) goto found;
+ if (likely(hash<=F_MALLOC_OPTIMIZE/ROUNDTO)) { /* return first match */
+ f=&(qm->free_hash[hash].first);
+ goto found;
+ }
+ /* if we are here we are searching for a "big" fragment
+ between F_MALLOC_OPTIMIZE/ROUNDTO+1
+ and F_MALLOC_OPTIMIZE/ROUNDTO + (32|64) - F_MALLOC_OPTIMIZE_FACTOR
+ => 18 hash buckets on 32 bits and 50 buckets on 64 bits
+ The free hash bitmap is used to jump directly to non-empty
+ hash buckets.
+ */
+ do {
+ for(f=&(qm->free_hash[hash].first);(*f); f=&((*f)->u.nxt_free))
+ if ((*f)->size>=size) goto found;
+ hash++; /* try in next hash cell */
+ }while((hash < F_HASH_SIZE) &&
+ ((hash=fm_bmp_first_set(qm, hash)) >= 0));
}
#else /* F_MALLOC_HASH_BITMAP */
for(hash=GET_HASH(size);hash<F_HASH_SIZE;hash++){