Hi,
cancel_branch (t_cancel.c) contains a segfault in lines 284-288 when
cfg_get(tm, tm_cfg, reparse_invite) is true but t->uas.request is NULL.
My suggested fix is below but I'm not 100% sure if this is really correct.
cheers
Hello,
The memcached module cannot be built for "stock" Enterprise Linux 6 because
the versions of libmemcached/memcached that come with EL6 are the wrong
ones.
Does anyone know what the right versions are, and is it worth updating the
module documentation to specify them? That way if someone using RedHat or
CentOS wants to use the memcached module at least they know what version to
download and build.
Regards,
Peter
--
Peter Dunkley
Technical Director
Crocodile RCS Ltd
Module: sip-router
Branch: master
Commit: fc4f2216f867b00a6685abdf51b8165572f24f69
URL: http://git.sip-router.org/cgi-bin/gitweb.cgi/sip-router/?a=commit;h=fc4f221…
Author: Carlos Ruiz Diaz <carlos.ruizdiaz(a)gmail.com>
Committer: Carlos Ruiz Diaz <carlos.ruizdiaz(a)gmail.com>
Date: Thu Oct 24 11:05:17 2013 -0300
ims_charging: fixed deadlock when interim CCA timeout occurs
---
modules/ims_charging/dialog.c | 2 +
modules/ims_charging/ims_ro.c | 12 +++++++-
modules/ims_charging/ro_session_hash.h | 4 +-
modules/ims_charging/ro_timer.c | 47 ++++++++++++++++++++-----------
4 files changed, 45 insertions(+), 20 deletions(-)
diff --git a/modules/ims_charging/dialog.c b/modules/ims_charging/dialog.c
index 3e0861e..1b2453b 100644
--- a/modules/ims_charging/dialog.c
+++ b/modules/ims_charging/dialog.c
@@ -39,7 +39,9 @@ void dlg_reply(struct dlg_cell *dlg, int type, struct dlg_cb_params *_params) {
LM_ERR("Ro Session object is NULL...... aborting\n");
return;
}
+
ro_session_entry = &(ro_session_table->entries[session->h_entry]);
+
ro_session_lock(ro_session_table, ro_session_entry);
if (session->active) {
diff --git a/modules/ims_charging/ims_ro.c b/modules/ims_charging/ims_ro.c
index 724c463..72a6fe5 100644
--- a/modules/ims_charging/ims_ro.c
+++ b/modules/ims_charging/ims_ro.c
@@ -642,6 +642,16 @@ error:
cdpb.AAASessionsUnlock(auth->hash);
cdpb.AAADropCCAccSession(auth);
}
+
+ shm_free(i_req);
+ //
+ // since callback function will be never called because of the error, we need to release the lock on the session
+ // to it can be reused later.
+ //
+ struct ro_session_entry *ro_session_entry = &(ro_session_table->entries[ro_session->h_entry]);
+ unref_ro_session_unsafe(ro_session, 1, ro_session_entry);//unref from the initial timer that fired this event.
+ ro_session_unlock(ro_session_table, ro_session_entry);
+
return;
}
@@ -1029,7 +1039,7 @@ static void resume_on_initial_ccr(int is_timeout, void *param, AAAMessage *cca,
if (is_timeout) {
update_stat(ccr_timeouts, 1);
LM_ERR("Transaction timeout - did not get CCA\n");
- error_code = RO_RETURN_ERROR;
+ error_code = RO_RETURN_ERROR;
goto error0;
}
diff --git a/modules/ims_charging/ro_session_hash.h b/modules/ims_charging/ro_session_hash.h
index d57ef28..105bd37 100644
--- a/modules/ims_charging/ro_session_hash.h
+++ b/modules/ims_charging/ro_session_hash.h
@@ -78,7 +78,7 @@ extern struct ro_session_table *ro_session_table;
* \param _entry locked entry
*/
#define ro_session_lock(_table, _entry) \
- lock_set_get( (_table)->locks, (_entry)->lock_idx);
+ { LM_DBG("LOCKING %d", (_entry)->lock_idx); lock_set_get( (_table)->locks, (_entry)->lock_idx); LM_DBG("LOCKED %d", (_entry)->lock_idx);}
/*!
@@ -87,7 +87,7 @@ extern struct ro_session_table *ro_session_table;
* \param _entry locked entry
*/
#define ro_session_unlock(_table, _entry) \
- lock_set_release( (_table)->locks, (_entry)->lock_idx);
+ { LM_DBG("UNLOCKING %d", (_entry)->lock_idx); lock_set_release( (_table)->locks, (_entry)->lock_idx); LM_DBG("UNLOCKED %d", (_entry)->lock_idx); }
/*!
* \brief Reference an ro_session without locking
diff --git a/modules/ims_charging/ro_timer.c b/modules/ims_charging/ro_timer.c
index 1340c3b..797b696 100644
--- a/modules/ims_charging/ro_timer.c
+++ b/modules/ims_charging/ro_timer.c
@@ -256,19 +256,22 @@ void resume_ro_session_ontimeout(struct interim_ccr *i_req) {
time_t now = time(0);
time_t used_secs;
struct ro_session_entry *ro_session_entry = NULL;
+ int call_terminated = 0;
if (!i_req) {
LM_ERR("This is so wrong: i_req is NULL\n");
return;
}
+ ro_session_entry = &(ro_session_table->entries[i_req->ro_session->h_entry]);
+
LM_DBG("credit=%d credit_valid_for=%d", i_req->new_credit, i_req->credit_valid_for);
used_secs = now - i_req->ro_session->last_event_timestamp;
/* check to make sure diameter server is giving us sane values */
if (i_req->new_credit > i_req->credit_valid_for) {
- LM_WARN("That's weird, Diameter server gave us credit with a lower validity period :D. Setting reserved time to validity perioud instead \n");
+ LM_WARN("That's weird, Diameter server gave us credit with a lower validity period :D. Setting reserved time to validity period instead \n");
i_req->new_credit = i_req->credit_valid_for;
}
@@ -321,8 +324,21 @@ void resume_ro_session_ontimeout(struct interim_ccr *i_req) {
i_req->ro_session->event_type = no_more_credit;
int whatsleft = i_req->ro_session->reserved_secs - used_secs;
if (whatsleft <= 0) {
- LM_WARN("Immediately killing call due to no more credit\n");
+ // TODO we need to handle this situation more precisely.
+ // in case CCR times out, we get a call shutdown but the error message assumes it was due to a lack of credit.
+ //
+ LM_WARN("Immediately killing call due to no more credit *OR* no CCA received (timeout) after reservation request\n");
+
+ //
+ // we need to unlock the session or else we might get a deadlock on dlg_terminated() dialog callback.
+ // Do not unref the session because it will be made inside the dlg_terminated() function.
+ //
+
+ //unref_ro_session_unsafe(i_req->ro_session, 1, ro_session_entry);
+ ro_session_unlock(ro_session_table, ro_session_entry);
+
dlgb.lookup_terminate_dlg(i_req->ro_session->dlg_h_entry, i_req->ro_session->dlg_h_id, NULL );
+ call_terminated = 1;
}
else {
LM_DBG("No more credit for user - letting call run out of money in [%i] seconds", whatsleft);
@@ -337,10 +353,13 @@ void resume_ro_session_ontimeout(struct interim_ccr *i_req) {
}
}
- ro_session_entry = &(ro_session_table->entries[i_req->ro_session->h_entry]);
-
- unref_ro_session_unsafe(i_req->ro_session, 1, ro_session_entry);//unref from the initial timer that fired this event.
- ro_session_unlock(ro_session_table, ro_session_entry);
+ //
+ // if call was forcefully terminated, the lock was released before dlgb.lookup_terminate_dlg() function call.
+ //
+ if (!call_terminated) {
+ unref_ro_session_unsafe(i_req->ro_session, 1, ro_session_entry);//unref from the initial timer that fired this event.
+ ro_session_unlock(ro_session_table, ro_session_entry);
+ }
shm_free(i_req);
LM_DBG("Exiting async ccr interim nicely");
@@ -350,26 +369,21 @@ void resume_ro_session_ontimeout(struct interim_ccr *i_req) {
* If we cant we need to put a new timer to kill the call at the appropriate time
*/
void ro_session_ontimeout(struct ro_tl *tl) {
- time_t now, used_secs, call_time;
+ time_t now, used_secs, call_time;
LM_DBG("We have a fired timer [p=%p] and tl=[%i].\n", tl, tl->timeout);
/* find the session id for this timer*/
struct ro_session_entry *ro_session_entry = NULL;
-
- struct ro_session* ro_session;
- ro_session = ((struct ro_session*) ((char *) (tl)
- - (unsigned long) (&((struct ro_session*) 0)->ro_tl)));
+ struct ro_session* ro_session = ((struct ro_session*) ((char *) (tl) - (unsigned long) (&((struct ro_session*) 0)->ro_tl)));
if (!ro_session) {
LM_ERR("Can't find a session. This is bad");
return;
}
-// LM_ALERT("LOCKING... ");
ro_session_entry = &(ro_session_table->entries[ro_session->h_entry]);
ro_session_lock(ro_session_table, ro_session_entry);
-// LM_ALERT("LOCKED!");
LM_DBG("event-type=%d", ro_session->event_type);
@@ -428,7 +442,6 @@ void ro_session_ontimeout(struct ro_tl *tl) {
ref_ro_session_unsafe(ro_session, 1);
}
LM_ERR("Immediately killing call due to unknown error\n");
- dlgb.lookup_terminate_dlg(ro_session->dlg_h_entry, ro_session->dlg_h_id, NULL );
}
break;
@@ -439,15 +452,15 @@ void ro_session_ontimeout(struct ro_tl *tl) {
LM_INFO("Call/session must be ended - no more funds.\n");
else if (ro_session->event_type == unknown_error)
LM_ERR("last event caused an error. We will now tear down this session.\n");
-
- dlgb.lookup_terminate_dlg(ro_session->dlg_h_entry, ro_session->dlg_h_id, NULL );
}
+
update_stat(killed_calls, 1);
- unref_ro_session_unsafe(ro_session, 1, ro_session_entry); //unref from the initial timer that fired this event.
+ //unref_ro_session_unsafe(ro_session, 1, ro_session_entry); //unref from the initial timer that fired this event.
ro_session_unlock(ro_session_table, ro_session_entry);
+ dlgb.lookup_terminate_dlg(ro_session->dlg_h_entry, ro_session->dlg_h_id, NULL);
return;
}
Hello
I'd like to explain my scenario and the module I'd like to develop. I am
hoping for comments whether there are already modules like that or which
modules' API I could use to make the development easier.
Scenario:
I have two domains (A and B) with a Kamailio server in each of them
configured as presence servers. The agents from both domains want to
subscribe to few resources from domain A.
Idea:
In order to reduce traffic between the domains, the presence server from
domain B shall handle the subscriptions internally and use an internal
virtual presence-user-agent to subscribe to the resources in domain A.
SIP Messages:
Subscription:
1) Subscribe resource.domain.a, from each user agent ua_n.domain.b
2) 202 OK from kamailio.domain.b
3) If not already subscribed, Subscribe resource.domain.a from
kamailio.domain.b with virtual user-agent
4) 202 OK from kamailio.domain.a
(Repeat for each susbcriber)
(Subscription has to be refreshed by an internal timer)
Events:
1) Publish resouce.domain.a to kamailio.domain.a
2) 200 OK from kamailio.domain.a
3) Notify resource.domain.a to kamailio.domain.b
4) 200 OK from kamailio.domain.b
5) Notify resource.domain.a to each user agent ua_n.domain.b
6) 200 OK from each ua_n.domain.b
(Internally, Kamailio of domain B has to forward the incoming Notify to all
locally subscribed user-agents)
I tried using the PUA module but it does not fit all my needs. Now I think
I will have to develop my own module in order to achieve everything. Any
ideas?
Kind regards
--
*Jan **Gaida*
Ingeniero Desarrollo Software C/ Marconi 3 (PTM)
28760 Tres Cantos
Spain
jan.gaida(a)grupoamper.com | www.grupoamper.com
--
This message and any attachments are intended only for the use of the
individual to whom they are addressed and it may contain information that
is privileged or confidential. If you have received this communication by
mistake, please notify us immediately by e-mail or telephone.The storage,
recording, use or disclosure of this e-mail and its attachments by anyone
other than the intended recipient is strictly prohibited. This message has
been verified using antivirus software; however, the sender is not
responsible for any damage to hardware or software resulting from the
presence of any virus.
Este mensaje y cualquier anexo son exclusivamente para la persona a quien
van dirigidos y pueden contener información privilegiada o confidencial. Si
usted ha recibido esta comunicación por error, le agradecemos notificarlo
de inmediato por esta misma vía o por teléfono. Está prohibida su
retención, grabación, utilización o divulgación con cualquier propósito.
Este mensaje ha sido verificado con software antivirus; sin embargo, el
remitente no se hace responsable en caso de que en éste o en los archivos
adjuntos haya presencia de algún virus que pueda generar daños en los
equipos o programas del destinatario.
Module: sip-router
Branch: master
Commit: a067a3d33ad67c260a3bc377cd4203d41880ca6b
URL: http://git.sip-router.org/cgi-bin/gitweb.cgi/sip-router/?a=commit;h=a067a3d…
Author: Daniel-Constantin Mierla <miconda(a)gmail.com>
Committer: Daniel-Constantin Mierla <miconda(a)gmail.com>
Date: Thu Oct 24 07:44:03 2013 +0200
tm: use internal flags field to mark suspended replies with FL_RPL_SUSPENDED
- it was set on cfg flags, resulting in messing up with what was used in
config file
- reported by Juha Heinanen
---
modules/tm/t_reply.c | 2 +-
modules/tm/t_suspend.c | 10 +++++-----
2 files changed, 6 insertions(+), 6 deletions(-)
diff --git a/modules/tm/t_reply.c b/modules/tm/t_reply.c
index 8703750..cac9ab4 100644
--- a/modules/tm/t_reply.c
+++ b/modules/tm/t_reply.c
@@ -2520,7 +2520,7 @@ int reply_received( struct sip_msg *p_msg )
}
#endif
- if (unlikely(p_msg->flags&FL_RPL_SUSPENDED)) {
+ if (unlikely(p_msg->msg_flags&FL_RPL_SUSPENDED)) {
goto skip_send_reply;
/* suspend the reply (async), no error */
}
diff --git a/modules/tm/t_suspend.c b/modules/tm/t_suspend.c
index 9509afc..f2cacbc 100644
--- a/modules/tm/t_suspend.c
+++ b/modules/tm/t_suspend.c
@@ -107,7 +107,7 @@ int t_suspend(struct sip_msg *msg,
}
}else{
LOG(L_DBG,"DEBUG: t_suspend_reply: This is a suspend on reply - setting msg flag to SUSPEND\n");
- msg->flags |= FL_RPL_SUSPENDED;
+ msg->msg_flags |= FL_RPL_SUSPENDED;
/* this is a reply suspend find which branch */
if (t_check( msg , &branch )==-1){
@@ -280,8 +280,8 @@ int t_continue(unsigned int hash_index, unsigned int label,
/* this is a continue from a reply suspend */
LOG(L_DBG,"DEBUG: t_continue_reply: Disabling suspend branch");
- t->uac[branch].reply->flags &= ~FL_RPL_SUSPENDED;
- if (t->uas.request) t->uas.request->flags&= ~FL_RPL_SUSPENDED;
+ t->uac[branch].reply->msg_flags &= ~FL_RPL_SUSPENDED;
+ if (t->uas.request) t->uas.request->msg_flags&= ~FL_RPL_SUSPENDED;
LOG(L_DBG,"DEBUG: t_continue_reply: Setting up faked environment");
if (!fake_resp(&faked_resp, t->uac[branch].reply, 0 /* extra flags */, 0)) {
@@ -482,8 +482,8 @@ int t_cancel_suspend(unsigned int hash_index, unsigned int label)
LOG(L_DBG,"DEBUG: t_cancel_suspend_reply: This is a cancel suspend for a response\n");
- t->uac[branch].reply->flags &= ~FL_RPL_SUSPENDED;
- if (t->uas.request) t->uas.request->flags&= ~FL_RPL_SUSPENDED;
+ t->uac[branch].reply->msg_flags &= ~FL_RPL_SUSPENDED;
+ if (t->uas.request) t->uas.request->msg_flags&= ~FL_RPL_SUSPENDED;
}
return 0;
Hello,
I have been updating my .spec for CentOS 6 recently. I am trying to get as
many modules as possible into the build without needing exotic dependencies.
There is one packages that I can't include into CentOS at all (and it would
have helped me if the documentation had been updated). There are two
packages I think I can include (if people can help with a little work).
This is all summarised at the end of the email.
I'd appreciate any help people can give me.
Regards,
Peter
*Modules I can't include - but need more documentation*
- *app_mono*: simply won't compile with against the version of
mono-devel in EPEL for CentOS 6. EPEL contains mono-devel 2.4.3.1 (which is
presumably too old). The module documentation for app_mono doesn't specify
a minimum version - it would be helpful if it did.
*Modules I could include - but need a little work*
- *app_java*: this compiles with small Makefile changes (as I discussed
recently on-list). It'd be great if some Makefile guru could help-out and
adjust this so that it can compile cleanly (and through an automated
process) without needing to edit/patch the Makefile for each target system.
- *memcached*: as discussed on-list between Henning and Charles, this
should be relatively straight-forward to get working with a library version
check.
*Modules I can't/won't include*
- *db_cassandra*: requires specific versions of thrift (and thrift is
not available in the base or EPEL repos for CentOS 6 anyway)
- *db_oracle*: requires the non-free instantclient-sdk
- *osp*: requires the OSP Toolkit (not available in the base or EPEL
repos for CentOS 6)
- *jabber*: this module is obsolete
- *iptrtpproxy*: I believe this module should be obsolete (and it
certainly can't work with the standard kernel version in CentOS 6 anyway)
--
Peter Dunkley
Technical Director
Crocodile RCS Ltd