|
@@ -71,6 +71,49 @@
|
|
struct dlg_table *d_table = 0;
|
|
struct dlg_table *d_table = 0;
|
|
|
|
|
|
|
|
|
|
|
|
+/*!
|
|
|
|
+ * \brief Reference a dialog without locking
|
|
|
|
+ * \param _dlg dialog
|
|
|
|
+ * \param _cnt increment for the reference counter
|
|
|
|
+ */
|
|
|
|
+#define ref_dlg_unsafe(_dlg,_cnt) \
|
|
|
|
+ do { \
|
|
|
|
+ (_dlg)->ref += (_cnt); \
|
|
|
|
+ LM_DBG("ref dlg %p with %d -> %d\n", \
|
|
|
|
+ (_dlg),(_cnt),(_dlg)->ref); \
|
|
|
|
+ }while(0)
|
|
|
|
+
|
|
|
|
+
|
|
|
|
+/*!
|
|
|
|
+ * \brief Unreference a dialog without locking
|
|
|
|
+ * \param _dlg dialog
|
|
|
|
+ * \param _cnt decrement for the reference counter
|
|
|
|
+ * \param _d_entry dialog entry
|
|
|
|
+ */
|
|
|
|
+#define unref_dlg_unsafe(_dlg,_cnt,_d_entry) \
|
|
|
|
+ do { \
|
|
|
|
+ (_dlg)->ref -= (_cnt); \
|
|
|
|
+ LM_DBG("unref dlg %p with %d -> %d\n",\
|
|
|
|
+ (_dlg),(_cnt),(_dlg)->ref);\
|
|
|
|
+ if ((_dlg)->ref<0) {\
|
|
|
|
+ LM_CRIT("bogus ref %d with cnt %d for dlg %p [%u:%u] "\
|
|
|
|
+ "with clid '%.*s' and tags '%.*s' '%.*s'\n",\
|
|
|
|
+ (_dlg)->ref, _cnt, _dlg,\
|
|
|
|
+ (_dlg)->h_entry, (_dlg)->h_id,\
|
|
|
|
+ (_dlg)->callid.len, (_dlg)->callid.s,\
|
|
|
|
+ (_dlg)->tag[DLG_CALLER_LEG].len,\
|
|
|
|
+ (_dlg)->tag[DLG_CALLER_LEG].s,\
|
|
|
|
+ (_dlg)->tag[DLG_CALLEE_LEG].len,\
|
|
|
|
+ (_dlg)->tag[DLG_CALLEE_LEG].s); \
|
|
|
|
+ }\
|
|
|
|
+ if ((_dlg)->ref<=0) { \
|
|
|
|
+ unlink_unsafe_dlg( _d_entry, _dlg);\
|
|
|
|
+ LM_DBG("ref <=0 for dialog %p\n",_dlg);\
|
|
|
|
+ destroy_dlg(_dlg);\
|
|
|
|
+ }\
|
|
|
|
+ }while(0)
|
|
|
|
+
|
|
|
|
+
|
|
/*!
|
|
/*!
|
|
* \brief Initialize the global dialog table
|
|
* \brief Initialize the global dialog table
|
|
* \param size size of the table
|
|
* \param size size of the table
|
|
@@ -387,19 +430,18 @@ error:
|
|
|
|
|
|
/*!
|
|
/*!
|
|
* \brief Lookup a dialog in the global list
|
|
* \brief Lookup a dialog in the global list
|
|
|
|
+ *
|
|
|
|
+ * Note that the caller is responsible for decrementing (or reusing)
|
|
|
|
+ * the reference counter by one again iff a dialog has been found.
|
|
* \param h_entry number of the hash table entry
|
|
* \param h_entry number of the hash table entry
|
|
* \param h_id id of the hash table entry
|
|
* \param h_id id of the hash table entry
|
|
- * \param del will set to 1 if dialog is deleted
|
|
|
|
- * \return dialog structure on success, NULL on failure or if not found
|
|
|
|
|
|
+ * \return dialog structure on success, NULL on failure
|
|
*/
|
|
*/
|
|
-struct dlg_cell* lookup_dlg( unsigned int h_entry, unsigned int h_id, unsigned int *del)
|
|
|
|
|
|
+struct dlg_cell* lookup_dlg( unsigned int h_entry, unsigned int h_id)
|
|
{
|
|
{
|
|
struct dlg_cell *dlg;
|
|
struct dlg_cell *dlg;
|
|
struct dlg_entry *d_entry;
|
|
struct dlg_entry *d_entry;
|
|
|
|
|
|
- if (del != NULL)
|
|
|
|
- *del = 0;
|
|
|
|
-
|
|
|
|
if (h_entry>=d_table->size)
|
|
if (h_entry>=d_table->size)
|
|
goto not_found;
|
|
goto not_found;
|
|
|
|
|
|
@@ -409,14 +451,7 @@ struct dlg_cell* lookup_dlg( unsigned int h_entry, unsigned int h_id, unsigned i
|
|
|
|
|
|
for( dlg=d_entry->first ; dlg ; dlg=dlg->next ) {
|
|
for( dlg=d_entry->first ; dlg ; dlg=dlg->next ) {
|
|
if (dlg->h_id == h_id) {
|
|
if (dlg->h_id == h_id) {
|
|
- if (dlg->state==DLG_STATE_DELETED) {
|
|
|
|
- if (del != NULL)
|
|
|
|
- *del = 1;
|
|
|
|
- dlg_unlock( d_table, d_entry);
|
|
|
|
- goto not_found;
|
|
|
|
- }
|
|
|
|
- dlg->ref++;
|
|
|
|
- LM_DBG("ref dlg %p with 1 -> %d\n", dlg, dlg->ref);
|
|
|
|
|
|
+ ref_dlg_unsafe(dlg, 1);
|
|
dlg_unlock( d_table, d_entry);
|
|
dlg_unlock( d_table, d_entry);
|
|
LM_DBG("dialog id=%u found on entry %u\n", h_id, h_entry);
|
|
LM_DBG("dialog id=%u found on entry %u\n", h_id, h_entry);
|
|
return dlg;
|
|
return dlg;
|
|
@@ -438,18 +473,14 @@ not_found:
|
|
* \param ttag to tag
|
|
* \param ttag to tag
|
|
* \param dir direction
|
|
* \param dir direction
|
|
* \param del will set to 1 if dialog is deleted
|
|
* \param del will set to 1 if dialog is deleted
|
|
- * \return dialog structure on success, NULL on failure or if not found
|
|
|
|
|
|
+ * \return dialog structure on success, NULL on failure
|
|
*/
|
|
*/
|
|
static inline struct dlg_cell* internal_get_dlg(unsigned int h_entry,
|
|
static inline struct dlg_cell* internal_get_dlg(unsigned int h_entry,
|
|
- str *callid, str *ftag, str *ttag, unsigned int *dir,
|
|
|
|
- unsigned int *del)
|
|
|
|
|
|
+ str *callid, str *ftag, str *ttag, unsigned int *dir)
|
|
{
|
|
{
|
|
struct dlg_cell *dlg;
|
|
struct dlg_cell *dlg;
|
|
struct dlg_entry *d_entry;
|
|
struct dlg_entry *d_entry;
|
|
|
|
|
|
- if (del != NULL)
|
|
|
|
- *del = 0;
|
|
|
|
-
|
|
|
|
d_entry = &(d_table->entries[h_entry]);
|
|
d_entry = &(d_table->entries[h_entry]);
|
|
|
|
|
|
dlg_lock( d_table, d_entry);
|
|
dlg_lock( d_table, d_entry);
|
|
@@ -457,14 +488,7 @@ static inline struct dlg_cell* internal_get_dlg(unsigned int h_entry,
|
|
for( dlg = d_entry->first ; dlg ; dlg = dlg->next ) {
|
|
for( dlg = d_entry->first ; dlg ; dlg = dlg->next ) {
|
|
/* Check callid / fromtag / totag */
|
|
/* Check callid / fromtag / totag */
|
|
if (match_dialog( dlg, callid, ftag, ttag, dir)==1) {
|
|
if (match_dialog( dlg, callid, ftag, ttag, dir)==1) {
|
|
- if (dlg->state==DLG_STATE_DELETED) {
|
|
|
|
- if (del != NULL)
|
|
|
|
- *del = 1;
|
|
|
|
- dlg_unlock( d_table, d_entry);
|
|
|
|
- goto not_found;
|
|
|
|
- }
|
|
|
|
- dlg->ref++;
|
|
|
|
- LM_DBG("ref dlg %p with 1 -> %d\n", dlg, dlg->ref);
|
|
|
|
|
|
+ ref_dlg_unsafe(dlg, 1);
|
|
dlg_unlock( d_table, d_entry);
|
|
dlg_unlock( d_table, d_entry);
|
|
LM_DBG("dialog callid='%.*s' found\n on entry %u, dir=%d\n",
|
|
LM_DBG("dialog callid='%.*s' found\n on entry %u, dir=%d\n",
|
|
callid->len, callid->s,h_entry,*dir);
|
|
callid->len, callid->s,h_entry,*dir);
|
|
@@ -473,8 +497,6 @@ static inline struct dlg_cell* internal_get_dlg(unsigned int h_entry,
|
|
}
|
|
}
|
|
|
|
|
|
dlg_unlock( d_table, d_entry);
|
|
dlg_unlock( d_table, d_entry);
|
|
-
|
|
|
|
-not_found:
|
|
|
|
LM_DBG("no dialog callid='%.*s' found\n", callid->len, callid->s);
|
|
LM_DBG("no dialog callid='%.*s' found\n", callid->len, callid->s);
|
|
return 0;
|
|
return 0;
|
|
}
|
|
}
|
|
@@ -489,22 +511,22 @@ not_found:
|
|
* "The combination of the To tag, From tag, and Call-ID completely
|
|
* "The combination of the To tag, From tag, and Call-ID completely
|
|
* defines a peer-to-peer SIP relationship between [two UAs] and is
|
|
* defines a peer-to-peer SIP relationship between [two UAs] and is
|
|
* referred to as a dialog."
|
|
* referred to as a dialog."
|
|
|
|
+ * Note that the caller is responsible for decrementing (or reusing)
|
|
|
|
+ * the reference counter by one again iff a dialog has been found.
|
|
* \param callid callid
|
|
* \param callid callid
|
|
* \param ftag from tag
|
|
* \param ftag from tag
|
|
* \param ttag to tag
|
|
* \param ttag to tag
|
|
* \param dir direction
|
|
* \param dir direction
|
|
- * \param del deleted dialog information
|
|
|
|
* \return dialog structure on success, NULL on failure
|
|
* \return dialog structure on success, NULL on failure
|
|
*/
|
|
*/
|
|
-struct dlg_cell* get_dlg( str *callid, str *ftag, str *ttag, unsigned int *dir,
|
|
|
|
- unsigned int *del)
|
|
|
|
|
|
+struct dlg_cell* get_dlg( str *callid, str *ftag, str *ttag, unsigned int *dir)
|
|
{
|
|
{
|
|
struct dlg_cell *dlg;
|
|
struct dlg_cell *dlg;
|
|
|
|
|
|
if ((dlg = internal_get_dlg(core_hash(callid, 0,
|
|
if ((dlg = internal_get_dlg(core_hash(callid, 0,
|
|
- d_table->size), callid, ftag, ttag, dir, del)) == 0 &&
|
|
|
|
|
|
+ d_table->size), callid, ftag, ttag, dir)) == 0 &&
|
|
(dlg = internal_get_dlg(core_hash(callid, ttag->len
|
|
(dlg = internal_get_dlg(core_hash(callid, ttag->len
|
|
- ?ttag:0, d_table->size), callid, ftag, ttag, dir, del)) == 0) {
|
|
|
|
|
|
+ ?ttag:0, d_table->size), callid, ftag, ttag, dir)) == 0) {
|
|
LM_DBG("no dialog callid='%.*s' found\n", callid->len, callid->s);
|
|
LM_DBG("no dialog callid='%.*s' found\n", callid->len, callid->s);
|
|
return 0;
|
|
return 0;
|
|
}
|
|
}
|
|
@@ -534,58 +556,13 @@ void link_dlg(struct dlg_cell *dlg, int n)
|
|
d_entry->last = dlg;
|
|
d_entry->last = dlg;
|
|
}
|
|
}
|
|
|
|
|
|
- dlg->ref += 1 + n;
|
|
|
|
-
|
|
|
|
- LM_DBG("ref dlg %p with %d -> %d\n", dlg, n+1, dlg->ref);
|
|
|
|
|
|
+ ref_dlg_unsafe(dlg, 1+n);
|
|
|
|
|
|
dlg_unlock( d_table, d_entry);
|
|
dlg_unlock( d_table, d_entry);
|
|
return;
|
|
return;
|
|
}
|
|
}
|
|
|
|
|
|
|
|
|
|
-/*!
|
|
|
|
- * \brief Reference a dialog without locking
|
|
|
|
- * \param _dlg dialog
|
|
|
|
- * \param _cnt increment for the reference counter
|
|
|
|
- */
|
|
|
|
-#define ref_dlg_unsafe(_dlg,_cnt) \
|
|
|
|
- do { \
|
|
|
|
- (_dlg)->ref += (_cnt); \
|
|
|
|
- LM_DBG("ref dlg %p with %d -> %d\n", \
|
|
|
|
- (_dlg),(_cnt),(_dlg)->ref); \
|
|
|
|
- }while(0)
|
|
|
|
-
|
|
|
|
-
|
|
|
|
-/*!
|
|
|
|
- * \brief Unreference a dialog without locking
|
|
|
|
- * \param _dlg dialog
|
|
|
|
- * \param _cnt decrement for the reference counter
|
|
|
|
- * \param _d_entry dialog entry
|
|
|
|
- */
|
|
|
|
-#define unref_dlg_unsafe(_dlg,_cnt,_d_entry) \
|
|
|
|
- do { \
|
|
|
|
- (_dlg)->ref -= (_cnt); \
|
|
|
|
- LM_DBG("unref dlg %p with %d -> %d\n",\
|
|
|
|
- (_dlg),(_cnt),(_dlg)->ref);\
|
|
|
|
- if ((_dlg)->ref<0) {\
|
|
|
|
- LM_CRIT("bogus ref %d with cnt %d for dlg %p [%u:%u] "\
|
|
|
|
- "with clid '%.*s' and tags '%.*s' '%.*s'\n",\
|
|
|
|
- (_dlg)->ref, _cnt, _dlg,\
|
|
|
|
- (_dlg)->h_entry, (_dlg)->h_id,\
|
|
|
|
- (_dlg)->callid.len, (_dlg)->callid.s,\
|
|
|
|
- (_dlg)->tag[DLG_CALLER_LEG].len,\
|
|
|
|
- (_dlg)->tag[DLG_CALLER_LEG].s,\
|
|
|
|
- (_dlg)->tag[DLG_CALLEE_LEG].len,\
|
|
|
|
- (_dlg)->tag[DLG_CALLEE_LEG].s); \
|
|
|
|
- }\
|
|
|
|
- if ((_dlg)->ref<=0) { \
|
|
|
|
- unlink_unsafe_dlg( _d_entry, _dlg);\
|
|
|
|
- LM_DBG("ref <=0 for dialog %p\n",_dlg);\
|
|
|
|
- destroy_dlg(_dlg);\
|
|
|
|
- }\
|
|
|
|
- }while(0)
|
|
|
|
-
|
|
|
|
-
|
|
|
|
/*!
|
|
/*!
|
|
* \brief Refefence a dialog with locking
|
|
* \brief Refefence a dialog with locking
|
|
* \see ref_dlg_unsafe
|
|
* \see ref_dlg_unsafe
|