|
@@ -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);
|
|
@@ -753,18 +755,69 @@ 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;
|
|
|
}
|
|
|
|