Module: sip-router
Branch: master
Commit: c125cf6f36aedb75b4f1e0b32dbe5bdd0a48b8b5
URL: http://git.sip-router.org/cgi-bin/gitweb.cgi/sip-router/?a=commit;h=c125cf6…
Author: Daniel-Constantin Mierla <miconda(a)gmail.com>
Committer: Daniel-Constantin Mierla <miconda(a)gmail.com>
Date: Thu Aug 14 14:59:09 2014 +0200
dialog: release of dialog for not-forwarded initial request done by creator
- avoid releasing new dialog in case of upstream paralel forking
or retransmission by other processes than the other which created the
dialog
- it could result in destroying the dialog in initial state if the
request was not forwarded yet, likely to happen because creator
process runs more callbacks
---
modules/dialog/dlg_handlers.c | 2 ++
modules/dialog/dlg_var.c | 9 +++++++--
modules/dialog/dlg_var.h | 1 +
3 files changed, 10 insertions(+), 2 deletions(-)
diff --git a/modules/dialog/dlg_handlers.c b/modules/dialog/dlg_handlers.c
index 947bd5b..a0daa39 100644
--- a/modules/dialog/dlg_handlers.c
+++ b/modules/dialog/dlg_handlers.c
@@ -58,6 +58,7 @@
#include "../../lib/kcore/statistics.h"
#include "../../action.h"
#include "../../script_cb.h"
+#include "../../pt.h"
#include "../../lib/kcore/faked_msg.h"
#include "../../parser/parse_from.h"
#include "../../parser/parse_cseq.h"
@@ -874,6 +875,7 @@ int dlg_new_dialog(sip_msg_t *req, struct cell *t, const int run_initial_cbs)
if_update_stat( dlg_enable_stats, processed_dlgs, 1);
+ _dlg_ctx.cpid = my_pid();
finish:
_dlg_ctx.iuid.h_entry = dlg->h_entry;
_dlg_ctx.iuid.h_id = dlg->h_id;
diff --git a/modules/dialog/dlg_var.c b/modules/dialog/dlg_var.c
index e90dfc5..8badd58 100644
--- a/modules/dialog/dlg_var.c
+++ b/modules/dialog/dlg_var.c
@@ -46,9 +46,14 @@ int dlg_cfg_cb(sip_msg_t *msg, unsigned int flags, void *cbp)
dlg = dlg_get_ctx_dialog();
if(dlg!=NULL) {
if(_dlg_ctx.t==0 && dlg->state==DLG_STATE_UNCONFIRMED) {
- LM_DBG("new dialog with no trasaction after config execution\n");
- dlg_release(dlg);
+ if(_dlg_ctx.cpid!=0 && _dlg_ctx.cpid==my_pid()) {
+ /* release to destroy dialog if created by this process
+ * and request was not forwarded */
+ LM_DBG("new dialog with no trasaction after config execution\n");
+ dlg_release(dlg);
+ }
}
+ /* get ctx dlg increased ref count - release now */
dlg_release(dlg);
}
}
diff --git a/modules/dialog/dlg_var.h b/modules/dialog/dlg_var.h
index e9f08c8..bb604b7 100644
--- a/modules/dialog/dlg_var.h
+++ b/modules/dialog/dlg_var.h
@@ -39,6 +39,7 @@ typedef struct _dlg_ctx {
int timeout;
dlg_cell_t *dlg1;
dlg_iuid_t iuid;
+ int cpid;
int set;
unsigned int dir;
int t;
Module: sip-router
Branch: master
Commit: 6fb686de57f783b3c29e5b4e11ad1509882616bb
URL: http://git.sip-router.org/cgi-bin/gitweb.cgi/sip-router/?a=commit;h=6fb686d…
Author: Daniel-Constantin Mierla <miconda(a)gmail.com>
Committer: Daniel-Constantin Mierla <miconda(a)gmail.com>
Date: Thu Aug 14 17:49:18 2014 +0200
dialog: when adding a new dialog, lock the slot until the structure is linked
- search for dialog based on sip attributes and if no result found, then
lock the hash table slot until the new structure is built and linked
in the table
- should avoid simulataneous creation for same dialog if there is a
not-handled retransmission or parallel forking upstream, resulting in
many processing managing duplicated requests
---
modules/dialog/dlg_db_handler.c | 2 +-
modules/dialog/dlg_handlers.c | 45 +++++++++++++++-----------
modules/dialog/dlg_hash.c | 65 +++++++++++++++++++++++++++++++++++---
modules/dialog/dlg_hash.h | 31 ++++++++++++++++++-
4 files changed, 116 insertions(+), 27 deletions(-)
diff --git a/modules/dialog/dlg_db_handler.c b/modules/dialog/dlg_db_handler.c
index f61aae5..7e83729 100644
--- a/modules/dialog/dlg_db_handler.c
+++ b/modules/dialog/dlg_db_handler.c
@@ -360,7 +360,7 @@ static int load_dialog_info_from_db(int dlg_hash_size, int fetch_num_rows)
}
/*link the dialog*/
- link_dlg(dlg, 0);
+ link_dlg(dlg, 0, 0);
dlg->h_id = VAL_INT(values+1);
next_id = d_table->entries[dlg->h_entry].next_id;
diff --git a/modules/dialog/dlg_handlers.c b/modules/dialog/dlg_handlers.c
index a0daa39..093b774 100644
--- a/modules/dialog/dlg_handlers.c
+++ b/modules/dialog/dlg_handlers.c
@@ -776,6 +776,7 @@ int dlg_new_dialog(sip_msg_t *req, struct cell *t, const int run_initial_cbs)
str ttag;
str req_uri;
unsigned int dir;
+ int mlock;
dlg = dlg_get_ctx_dialog();
if(dlg != NULL) {
@@ -800,18 +801,20 @@ int dlg_new_dialog(sip_msg_t *req, struct cell *t, const int run_initial_cbs)
}
trim(&req_uri);
- if (detect_spirals)
- {
- if (spiral_detected == 1)
- return 0;
-
- dir = DLG_DIR_NONE;
+ dir = DLG_DIR_NONE;
+ mlock = 1;
+ /* search dialog by SIP attributes
+ * - if not found, hash table slot is left locked, to avoid races
+ * to add 'same' dialog on parallel forking or not-handled-yet
+ * retransmissions. Release slot after linking new dialog */
+ dlg = search_dlg(&callid, &ftag, &ttag, &dir);
+ if(dlg) {
+ mlock = 0;
+ if (detect_spirals) {
+ if (spiral_detected == 1)
+ return 0;
- dlg = get_dlg(&callid, &ftag, &ttag, &dir);
- if (dlg)
- {
- if ( dlg->state != DLG_STATE_DELETED )
- {
+ if ( dlg->state != DLG_STATE_DELETED ) {
LM_DBG("Callid '%.*s' found, must be a spiraled request\n",
callid.len, callid.s);
spiral_detected = 1;
@@ -819,9 +822,12 @@ int dlg_new_dialog(sip_msg_t *req, struct cell *t, const int run_initial_cbs)
if (run_initial_cbs)
run_dlg_callbacks( DLGCB_SPIRALED, dlg, req, NULL,
DLG_DIR_DOWNSTREAM, 0);
- /* get_dlg() has incremented the ref count by 1 */
+ /* set ctx dlg id shortcuts */
+ _dlg_ctx.iuid.h_entry = dlg->h_entry;
+ _dlg_ctx.iuid.h_id = dlg->h_id;
+ /* search_dlg() has incremented the ref count by 1 */
dlg_release(dlg);
- goto finish;
+ return 0;
}
dlg_release(dlg);
}
@@ -834,16 +840,16 @@ int dlg_new_dialog(sip_msg_t *req, struct cell *t, const int run_initial_cbs)
&ftag/*from_tag*/,
&req_uri /*r-uri*/ );
- if (dlg==0)
- {
+ if (dlg==0) {
+ if(likely(mlock==1)) dlg_hash_release(&callid);
LM_ERR("failed to create new dialog\n");
return -1;
}
/* save caller's tag, cseq, contact and record route*/
if (populate_leg_info(dlg, req, t, DLG_CALLER_LEG,
- &(get_from(req)->tag_value)) !=0)
- {
+ &(get_from(req)->tag_value)) !=0) {
+ if(likely(mlock==1)) dlg_hash_release(&callid);
LM_ERR("could not add further info to the dialog\n");
shm_free(dlg);
return -1;
@@ -852,7 +858,9 @@ int dlg_new_dialog(sip_msg_t *req, struct cell *t, const int run_initial_cbs)
/* Populate initial varlist: */
dlg->vars = get_local_varlist_pointer(req, 1);
- link_dlg(dlg, 0);
+ /* if search_dlg() returned NULL, slot was kept locked */
+ link_dlg(dlg, 0, mlock);
+ if(likely(mlock==1)) dlg_hash_release(&callid);
dlg->lifetime = get_dlg_timeout(req);
s.s = _dlg_ctx.to_route_name;
@@ -876,7 +884,6 @@ int dlg_new_dialog(sip_msg_t *req, struct cell *t, const int run_initial_cbs)
if_update_stat( dlg_enable_stats, processed_dlgs, 1);
_dlg_ctx.cpid = my_pid();
-finish:
_dlg_ctx.iuid.h_entry = dlg->h_entry;
_dlg_ctx.iuid.h_id = dlg->h_id;
set_current_dialog(req, dlg);
diff --git a/modules/dialog/dlg_hash.c b/modules/dialog/dlg_hash.c
index 8220104..1e27b3b 100644
--- a/modules/dialog/dlg_hash.c
+++ b/modules/dialog/dlg_hash.c
@@ -691,10 +691,12 @@ dlg_cell_t* dlg_get_by_iuid(dlg_iuid_t *diuid)
* \param ftag from tag
* \param ttag to tag
* \param dir direction
+ * \param mode let hash table slot locked if dialog is not found
* \return dialog structure on success, NULL on failure
*/
static inline struct dlg_cell* internal_get_dlg(unsigned int h_entry,
- str *callid, str *ftag, str *ttag, unsigned int *dir)
+ str *callid, str *ftag, str *ttag,
+ unsigned int *dir, int mode)
{
struct dlg_cell *dlg;
struct dlg_entry *d_entry;
@@ -714,7 +716,7 @@ static inline struct dlg_cell* internal_get_dlg(unsigned int h_entry,
}
}
- dlg_unlock( d_table, d_entry);
+ if(likely(mode==0)) dlg_unlock( d_table, d_entry);
LM_DBG("no dialog callid='%.*s' found\n", callid->len, callid->s);
return 0;
}
@@ -743,7 +745,7 @@ struct dlg_cell* get_dlg( str *callid, str *ftag, str *ttag, unsigned int *dir)
unsigned int he;
he = core_hash(callid, 0, d_table->size);
- dlg = internal_get_dlg(he, callid, ftag, ttag, dir);
+ dlg = internal_get_dlg(he, callid, ftag, ttag, dir, 0);
if (dlg == 0) {
LM_DBG("no dialog callid='%.*s' found\n", callid->len, callid->s);
@@ -754,17 +756,68 @@ struct dlg_cell* get_dlg( str *callid, str *ftag, str *ttag, unsigned int *dir)
/*!
+ * \brief Search dialog that corresponds to CallId, From Tag and To Tag
+ *
+ * Get dialog that correspond to CallId, From Tag and To Tag.
+ * See RFC 3261, paragraph 4. Overview of Operation:
+ * "The combination of the To tag, From tag, and Call-ID completely
+ * defines a peer-to-peer SIP relationship between [two UAs] and is
+ * referred to as a dialog."
+ * Note that the caller is responsible for decrementing (or reusing)
+ * the reference counter by one again if a dialog has been found.
+ * If the dialog is not found, the hash slot is left locked, to allow
+ * linking the structure of a new dialog.
+ * \param callid callid
+ * \param ftag from tag
+ * \param ttag to tag
+ * \param dir direction
+ * \return dialog structure on success, NULL on failure (and slot locked)
+ */
+dlg_cell_t* search_dlg( str *callid, str *ftag, str *ttag, unsigned int *dir)
+{
+ struct dlg_cell *dlg;
+ unsigned int he;
+
+ he = core_hash(callid, 0, d_table->size);
+ dlg = internal_get_dlg(he, callid, ftag, ttag, dir, 1);
+
+ if (dlg == 0) {
+ LM_DBG("dialog with callid='%.*s' not found\n", callid->len, callid->s);
+ return 0;
+ }
+ return dlg;
+}
+
+
+/*!
+ * \brief Release hash table slot by call-id
+ * \param callid call-id value
+ */
+void dlg_hash_release(str *callid)
+{
+ unsigned int he;
+ struct dlg_entry *d_entry;
+
+ he = core_hash(callid, 0, d_table->size);
+ d_entry = &(d_table->entries[he]);
+ dlg_unlock(d_table, d_entry);
+}
+
+
+
+/*!
* \brief Link a dialog structure
* \param dlg dialog
* \param n extra increments for the reference counter
+ * \param mode link in safe mode (0 - lock slot; 1 - don't)
*/
-void link_dlg(struct dlg_cell *dlg, int n)
+void link_dlg(struct dlg_cell *dlg, int n, int mode)
{
struct dlg_entry *d_entry;
d_entry = &(d_table->entries[dlg->h_entry]);
- dlg_lock( d_table, d_entry);
+ if(unlikely(mode==0)) dlg_lock( d_table, d_entry);
/* keep id 0 for special cases */
dlg->h_id = 1 + d_entry->next_id++;
@@ -780,7 +833,7 @@ void link_dlg(struct dlg_cell *dlg, int n)
ref_dlg_unsafe(dlg, 1+n);
- dlg_unlock( d_table, d_entry);
+ if(unlikely(mode==0)) dlg_unlock( d_table, d_entry);
return;
}
diff --git a/modules/dialog/dlg_hash.h b/modules/dialog/dlg_hash.h
index ec3ffbb..8798ccc 100644
--- a/modules/dialog/dlg_hash.h
+++ b/modules/dialog/dlg_hash.h
@@ -318,11 +318,40 @@ dlg_cell_t* get_dlg(str *callid, str *ftag, str *ttag, unsigned int *dir);
/*!
+ * \brief Search dialog that corresponds to CallId, From Tag and To Tag
+ *
+ * Get dialog that correspond to CallId, From Tag and To Tag.
+ * See RFC 3261, paragraph 4. Overview of Operation:
+ * "The combination of the To tag, From tag, and Call-ID completely
+ * defines a peer-to-peer SIP relationship between [two UAs] and is
+ * referred to as a dialog."
+ * Note that the caller is responsible for decrementing (or reusing)
+ * the reference counter by one again if a dialog has been found.
+ * If the dialog is not found, the hash slot is left locked, to allow
+ * linking the structure of a new dialog.
+ * \param callid callid
+ * \param ftag from tag
+ * \param ttag to tag
+ * \param dir direction
+ * \return dialog structure on success, NULL on failure (and slot locked)
+ */
+dlg_cell_t* search_dlg(str *callid, str *ftag, str *ttag, unsigned int *dir);
+
+
+/*!
+ * \brief Release hash table slot by call-id
+ * \param callid call-id value
+ */
+void dlg_hash_release(str *callid);
+
+
+/*!
* \brief Link a dialog structure
* \param dlg dialog
* \param n extra increments for the reference counter
+ * \param mode link in safe mode (0 - lock slot; 1 - don't)
*/
-void link_dlg(dlg_cell_t *dlg, int n);
+void link_dlg(struct dlg_cell *dlg, int n, int mode);
/*!
THIS IS AN AUTOMATED MESSAGE, DO NOT REPLY.
The following task has a new comment added:
FS#459 - Dispatcher Round Robin Logic not Working with Dispatcher Table with FQDNs
User who did this - Daniel-Constantin Mierla (miconda)
----------
Can you give the output of:
kamctl dispatcher dump
----------
More information can be found at the following URL:
http://sip-router.org/tracker/index.php?do=details&task_id=459#comment1585
You are receiving this message because you have requested it from the Flyspray bugtracking system. If you did not expect this message or don't want to receive mails in future, you can change your notification settings at the URL shown above.
THIS IS AN AUTOMATED MESSAGE, DO NOT REPLY.
A new Flyspray task has been opened. Details are below.
User who did this - Ed James (erj01)
Attached to Project - sip-router
Summary - Dispatcher Round Robin Logic not Working with Dispatcher Table with FQDNs
Task Type - Bug Report
Category - Core
Status - Unconfirmed
Assigned To -
Operating System - Linux
Severity - High
Priority - Normal
Reported Version - 4.0
Due in Version - Undecided
Due Date - Undecided
Details - I'm using the dispatcher module (Linux Kamailio v4.0 server) to load balance between two media servers and have two records in the dispatcher table as follows:
id, setid, destination, flags, priority, description
50, 40, sip:192.168.2.111:5066;transport=tcp, 0, 0, SomeDescription
51, 40, sip:10.1.0.119:5060, 0, 0, SomeDescription
If I call ds_select_dst("40", "4") then it works perfectly and calls are sent alternately to 10.1.0.119 and 192.168.2.111 - that's all OK.
The issue arises when I use the FQDNs for these two machines in the dispatcher records so I've got:
id, setid, destination, flags, priority, description
50, 41, sip:LYNCMESLOADBAL1.RedwoodLync.com:5066;transport=tcp, 0, 0, SomeDescription
51, 41, sip:LYNCMESLOADBAL2.RedwoodLync.com:5060, 0, 0, SomeDescription
I've then got Host(A) records on the DNS server (192.168.2.1) as follows:
LYNCMESLOADBAL1.RedwoodLync.com --> 192.168.2.111
LYNCMESLOADBAL2.RedwoodLync.com --> 10.1.0.119
On the Linux box System-->Admin-->Network-->Network Configuration-->DNS I've got Primary DNS as 192.168.2.1. If I do nslookup on either of the FQDNs they work fine do I think the DNS is working.
If I call ds_select_dst("41", "4") then it sends the first call to 10.1.0.119 and then all subsequent calls to 192.168.2.111 and doesn't round robin between the two records.
So the issue is that the round robin doesn't seem to work when the dispatcher table contains FQDNs for machines for which DNS lookup does work and for which round robin does work with ip addresses.
I've tried the following to switch off any dns caching but still have the issue:
use_dns_cache=off
dns_cache_init=off
Anyone seen this before or have any suggestions ?
Thanks in advance for your help - much appreciated.
More information can be found at the following URL:
http://sip-router.org/tracker/index.php?do=details&task_id=459
You are receiving this message because you have requested it from the Flyspray bugtracking system. If you did not expect this message or don't want to receive mails in future, you can change your notification settings at the URL shown above.
THIS IS AN AUTOMATED MESSAGE, DO NOT REPLY.
The following task has a new comment added:
FS#449 - CRASH: Program terminated with signal 6, Aborted.
User who did this - Daniel-Constantin Mierla (miconda)
----------
Does it happen to have the sip traffic? If yes, can you check if there was a double INVITE (retransmission)?
I want to confirm if it is a situation that looks like a potential race.
----------
More information can be found at the following URL:
http://sip-router.org/tracker/index.php?do=details&task_id=449#comment1584
You are receiving this message because you have requested it from the Flyspray bugtracking system. If you did not expect this message or don't want to receive mails in future, you can change your notification settings at the URL shown above.
Module: sip-router
Branch: master
Commit: b6bd830ea93024324354dc3fb5eceaddbd8d20a3
URL: http://git.sip-router.org/cgi-bin/gitweb.cgi/sip-router/?a=commit;h=b6bd830…
Author: Daniel-Constantin Mierla <miconda(a)gmail.com>
Committer: Daniel-Constantin Mierla <miconda(a)gmail.com>
Date: Thu Aug 14 11:14:10 2014 +0200
lib/srutils: new files with wrappers around sha256 and other hashing functions
---
lib/srutils/shautils.c | 63 ++++++++++++++++++++++++++++++++++++++++++++++++
lib/srutils/shautils.h | 36 +++++++++++++++++++++++++++
2 files changed, 99 insertions(+), 0 deletions(-)
diff --git a/lib/srutils/shautils.c b/lib/srutils/shautils.c
new file mode 100644
index 0000000..25f9e38
--- /dev/null
+++ b/lib/srutils/shautils.c
@@ -0,0 +1,63 @@
+/*
+ * sha and other hashing utilities
+ *
+ * Copyright (C) 2014 1&1 Germany
+ *
+ * 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+
+#include "../../md5.h"
+#include "../../ut.h"
+#include "shautils.h"
+
+/*! \brief Compute MD5 checksum */
+void compute_md5(char *dst, char *src, int src_len)
+{
+ MD5_CTX context;
+ unsigned char digest[16];
+ MD5Init (&context);
+ MD5Update (&context, src, src_len);
+ U_MD5Final (digest, &context);
+ string2hex(digest, 16, dst);
+}
+
+/*! \brief Compute SHA256 checksum */
+void compute_sha256(char *dst, u_int8_t *src, int src_len)
+{
+ SHA256_CTX ctx256;
+ SHA256_Init(&ctx256);
+ SHA256_Update(&ctx256, src, src_len);
+ SHA256_End(&ctx256, dst);
+}
+
+/*! \brief Compute SHA384 checksum */
+void compute_sha384(char *dst, u_int8_t *src, int src_len)
+{
+ SHA384_CTX ctx384;
+ SHA384_Init(&ctx384);
+ SHA384_Update(&ctx384, src, src_len);
+ SHA384_End(&ctx384, dst);
+}
+
+/*! \brief Compute SHA512 checksum */
+void compute_sha512(char *dst, u_int8_t *src, int src_len)
+{
+ SHA512_CTX ctx512;
+ SHA512_Init(&ctx512);
+ SHA512_Update(&ctx512, src, src_len);
+ SHA512_End(&ctx512, dst);
+}
diff --git a/lib/srutils/shautils.h b/lib/srutils/shautils.h
new file mode 100644
index 0000000..1d7b0e4
--- /dev/null
+++ b/lib/srutils/shautils.h
@@ -0,0 +1,36 @@
+/*
+ * sha and other hashing utilities
+ *
+ * Copyright (C) 2014 1&1 Germany
+ *
+ * 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+
+#ifndef _SHAUTILS_H_
+#define _SHAUTILS_H_
+
+#include "sha256.h"
+
+void compute_md5(char *dst, char *src, int src_len);
+
+void compute_sha256(char *dst, u_int8_t *src, int src_len);
+
+void compute_sha384(char *dst, u_int8_t *src, int src_len);
+
+void compute_sha512(char *dst, u_int8_t *src, int src_len);
+
+#endif