|
@@ -11,25 +11,25 @@ static struct rtpengine_hash_table *rtpengine_hash_table;
|
|
static int hash_table_size;
|
|
static int hash_table_size;
|
|
|
|
|
|
/* from sipwise rtpengine */
|
|
/* from sipwise rtpengine */
|
|
-static int str_cmp_str(const str *a, const str *b) {
|
|
|
|
- if (a->len < b->len)
|
|
|
|
|
|
+static int str_cmp_str(const str a, const str b) {
|
|
|
|
+ if (a.len < b.len)
|
|
return -1;
|
|
return -1;
|
|
- if (a->len > b->len)
|
|
|
|
|
|
+ if (a.len > b.len)
|
|
return 1;
|
|
return 1;
|
|
- if (a->len == 0 && b->len == 0)
|
|
|
|
|
|
+ if (a.len == 0 && b.len == 0)
|
|
return 0;
|
|
return 0;
|
|
- return memcmp(a->s, b->s, a->len);
|
|
|
|
|
|
+ return memcmp(a.s, b.s, a.len);
|
|
}
|
|
}
|
|
|
|
|
|
/* from sipwise rtpengine */
|
|
/* from sipwise rtpengine */
|
|
-static int str_equal(str *a, str *b) {
|
|
|
|
|
|
+static int str_equal(str a, str b) {
|
|
return (str_cmp_str(a, b) == 0);
|
|
return (str_cmp_str(a, b) == 0);
|
|
}
|
|
}
|
|
|
|
|
|
/* from sipwise rtpengine */
|
|
/* from sipwise rtpengine */
|
|
-static unsigned int str_hash(str *s) {
|
|
|
|
|
|
+static unsigned int str_hash(str s) {
|
|
unsigned int ret = 5381;
|
|
unsigned int ret = 5381;
|
|
- str it = *s;
|
|
|
|
|
|
+ str it = s;
|
|
|
|
|
|
while (it.len > 0) {
|
|
while (it.len > 0) {
|
|
ret = (ret << 5) + ret + *it.s;
|
|
ret = (ret << 5) + ret + *it.s;
|
|
@@ -40,7 +40,7 @@ static unsigned int str_hash(str *s) {
|
|
return ret % hash_table_size;
|
|
return ret % hash_table_size;
|
|
}
|
|
}
|
|
|
|
|
|
-/* rtpengine glib hash API */
|
|
|
|
|
|
+/* rtpengine hash API */
|
|
int rtpengine_hash_table_init(int size) {
|
|
int rtpengine_hash_table_init(int size) {
|
|
int i;
|
|
int i;
|
|
|
|
|
|
@@ -58,6 +58,7 @@ int rtpengine_hash_table_init(int size) {
|
|
LM_ERR("no shm left to create rtpengine_hash_table\n");
|
|
LM_ERR("no shm left to create rtpengine_hash_table\n");
|
|
return 0;
|
|
return 0;
|
|
}
|
|
}
|
|
|
|
+ memset(rtpengine_hash_table, 0, sizeof(struct rtpengine_hash_table));
|
|
|
|
|
|
// init hashtable entry_list
|
|
// init hashtable entry_list
|
|
rtpengine_hash_table->entry_list = shm_malloc(hash_table_size * sizeof(struct rtpengine_hash_entry));
|
|
rtpengine_hash_table->entry_list = shm_malloc(hash_table_size * sizeof(struct rtpengine_hash_entry));
|
|
@@ -97,7 +98,6 @@ int rtpengine_hash_table_init(int size) {
|
|
|
|
|
|
int rtpengine_hash_table_destroy() {
|
|
int rtpengine_hash_table_destroy() {
|
|
int i;
|
|
int i;
|
|
- struct rtpengine_hash_entry *entry, *last_entry;
|
|
|
|
|
|
|
|
// check rtpengine hashtable
|
|
// check rtpengine hashtable
|
|
if (!rtpengine_hash_table) {
|
|
if (!rtpengine_hash_table) {
|
|
@@ -113,16 +113,11 @@ int rtpengine_hash_table_destroy() {
|
|
return 0;
|
|
return 0;
|
|
}
|
|
}
|
|
|
|
|
|
- // destroy hashtable entry_list[i]
|
|
|
|
lock_get(rtpengine_hash_lock);
|
|
lock_get(rtpengine_hash_lock);
|
|
|
|
+
|
|
|
|
+ // destroy hashtable entry_list[i]
|
|
for (i = 0; i < hash_table_size; i++) {
|
|
for (i = 0; i < hash_table_size; i++) {
|
|
- entry = rtpengine_hash_table->entry_list[i];
|
|
|
|
- while (entry) {
|
|
|
|
- last_entry = entry;
|
|
|
|
- entry = entry->next;
|
|
|
|
- shm_free(last_entry->callid.s);
|
|
|
|
- shm_free(last_entry);
|
|
|
|
- }
|
|
|
|
|
|
+ rtpengine_hash_table_free_entry_list(rtpengine_hash_table->entry_list[i]);
|
|
}
|
|
}
|
|
|
|
|
|
// destroy hashtable entry_list
|
|
// destroy hashtable entry_list
|
|
@@ -132,6 +127,7 @@ int rtpengine_hash_table_destroy() {
|
|
// destroy hashtable
|
|
// destroy hashtable
|
|
shm_free(rtpengine_hash_table);
|
|
shm_free(rtpengine_hash_table);
|
|
rtpengine_hash_table = NULL;
|
|
rtpengine_hash_table = NULL;
|
|
|
|
+
|
|
lock_release(rtpengine_hash_lock);
|
|
lock_release(rtpengine_hash_lock);
|
|
|
|
|
|
// destroy lock
|
|
// destroy lock
|
|
@@ -145,7 +141,7 @@ int rtpengine_hash_table_destroy() {
|
|
return 1;
|
|
return 1;
|
|
}
|
|
}
|
|
|
|
|
|
-int rtpengine_hash_table_insert(str *key, struct rtpengine_hash_entry *value) {
|
|
|
|
|
|
+int rtpengine_hash_table_insert(str callid, str viabranch, struct rtpengine_hash_entry *value) {
|
|
struct rtpengine_hash_entry *entry, *last_entry;
|
|
struct rtpengine_hash_entry *entry, *last_entry;
|
|
struct rtpengine_hash_entry *new_entry = (struct rtpengine_hash_entry *) value;
|
|
struct rtpengine_hash_entry *new_entry = (struct rtpengine_hash_entry *) value;
|
|
unsigned int hash_index;
|
|
unsigned int hash_index;
|
|
@@ -163,18 +159,21 @@ int rtpengine_hash_table_insert(str *key, struct rtpengine_hash_entry *value) {
|
|
}
|
|
}
|
|
|
|
|
|
// get entry list
|
|
// get entry list
|
|
- hash_index = str_hash(key);
|
|
|
|
|
|
+ hash_index = str_hash(callid);
|
|
entry = rtpengine_hash_table->entry_list[hash_index];
|
|
entry = rtpengine_hash_table->entry_list[hash_index];
|
|
last_entry = entry;
|
|
last_entry = entry;
|
|
|
|
|
|
// lock
|
|
// lock
|
|
lock_get(rtpengine_hash_lock);
|
|
lock_get(rtpengine_hash_lock);
|
|
while (entry) {
|
|
while (entry) {
|
|
- // if key found, don't add new entry
|
|
|
|
- if (str_equal(&entry->callid, &new_entry->callid)) {
|
|
|
|
|
|
+ // if found, don't add new entry
|
|
|
|
+ if (str_equal(entry->callid, new_entry->callid) &&
|
|
|
|
+ str_equal(entry->viabranch, new_entry->viabranch)) {
|
|
// unlock
|
|
// unlock
|
|
lock_release(rtpengine_hash_lock);
|
|
lock_release(rtpengine_hash_lock);
|
|
- LM_ERR("Call id %.*s already in hashtable, ignore new value", entry->callid.len, entry->callid.s);
|
|
|
|
|
|
+ LM_NOTICE("callid=%.*s, viabranch=%.*s already in hashtable, ignore new value",
|
|
|
|
+ entry->callid.len, entry->callid.s,
|
|
|
|
+ entry->viabranch.len, entry->viabranch.s);
|
|
return 0;
|
|
return 0;
|
|
}
|
|
}
|
|
|
|
|
|
@@ -184,8 +183,7 @@ int rtpengine_hash_table_insert(str *key, struct rtpengine_hash_entry *value) {
|
|
last_entry->next = entry->next;
|
|
last_entry->next = entry->next;
|
|
|
|
|
|
// free current entry; entry points to unknown
|
|
// free current entry; entry points to unknown
|
|
- shm_free(entry->callid.s);
|
|
|
|
- shm_free(entry);
|
|
|
|
|
|
+ rtpengine_hash_table_free_entry(entry);
|
|
|
|
|
|
// set pointers
|
|
// set pointers
|
|
entry = last_entry;
|
|
entry = last_entry;
|
|
@@ -210,7 +208,7 @@ int rtpengine_hash_table_insert(str *key, struct rtpengine_hash_entry *value) {
|
|
return 1;
|
|
return 1;
|
|
}
|
|
}
|
|
|
|
|
|
-int rtpengine_hash_table_remove(str *key) {
|
|
|
|
|
|
+int rtpengine_hash_table_remove(str callid, str viabranch) {
|
|
struct rtpengine_hash_entry *entry, *last_entry;
|
|
struct rtpengine_hash_entry *entry, *last_entry;
|
|
unsigned int hash_index;
|
|
unsigned int hash_index;
|
|
|
|
|
|
@@ -227,19 +225,19 @@ int rtpengine_hash_table_remove(str *key) {
|
|
}
|
|
}
|
|
|
|
|
|
// get first entry from entry list; jump over unused list head
|
|
// get first entry from entry list; jump over unused list head
|
|
- hash_index = str_hash(key);
|
|
|
|
|
|
+ hash_index = str_hash(callid);
|
|
entry = rtpengine_hash_table->entry_list[hash_index];
|
|
entry = rtpengine_hash_table->entry_list[hash_index];
|
|
last_entry = entry;
|
|
last_entry = entry;
|
|
|
|
|
|
// lock
|
|
// lock
|
|
lock_get(rtpengine_hash_lock);
|
|
lock_get(rtpengine_hash_lock);
|
|
while (entry) {
|
|
while (entry) {
|
|
- // if key found, delete entry
|
|
|
|
- if (str_equal(&entry->callid, (str *)key)) {
|
|
|
|
|
|
+ // if callid found, delete entry
|
|
|
|
+ if (str_equal(entry->callid, callid) &&
|
|
|
|
+ str_equal(entry->viabranch, viabranch)) {
|
|
// free entry
|
|
// free entry
|
|
last_entry->next = entry->next;
|
|
last_entry->next = entry->next;
|
|
- shm_free(entry->callid.s);
|
|
|
|
- shm_free(entry);
|
|
|
|
|
|
+ rtpengine_hash_table_free_entry(entry);
|
|
|
|
|
|
// update total
|
|
// update total
|
|
rtpengine_hash_table->total--;
|
|
rtpengine_hash_table->total--;
|
|
@@ -256,8 +254,7 @@ int rtpengine_hash_table_remove(str *key) {
|
|
last_entry->next = entry->next;
|
|
last_entry->next = entry->next;
|
|
|
|
|
|
// free current entry; entry points to unknown
|
|
// free current entry; entry points to unknown
|
|
- shm_free(entry->callid.s);
|
|
|
|
- shm_free(entry);
|
|
|
|
|
|
+ rtpengine_hash_table_free_entry(entry);
|
|
|
|
|
|
// set pointers
|
|
// set pointers
|
|
entry = last_entry;
|
|
entry = last_entry;
|
|
@@ -276,7 +273,7 @@ int rtpengine_hash_table_remove(str *key) {
|
|
return 0;
|
|
return 0;
|
|
}
|
|
}
|
|
|
|
|
|
-struct rtpp_node *rtpengine_hash_table_lookup(str *key) {
|
|
|
|
|
|
+struct rtpp_node *rtpengine_hash_table_lookup(str callid, str viabranch) {
|
|
struct rtpengine_hash_entry *entry, *last_entry;
|
|
struct rtpengine_hash_entry *entry, *last_entry;
|
|
unsigned int hash_index;
|
|
unsigned int hash_index;
|
|
struct rtpp_node *node;
|
|
struct rtpp_node *node;
|
|
@@ -294,15 +291,16 @@ struct rtpp_node *rtpengine_hash_table_lookup(str *key) {
|
|
}
|
|
}
|
|
|
|
|
|
// get first entry from entry list; jump over unused list head
|
|
// get first entry from entry list; jump over unused list head
|
|
- hash_index = str_hash(key);
|
|
|
|
|
|
+ hash_index = str_hash(callid);
|
|
entry = rtpengine_hash_table->entry_list[hash_index];
|
|
entry = rtpengine_hash_table->entry_list[hash_index];
|
|
last_entry = entry;
|
|
last_entry = entry;
|
|
|
|
|
|
// lock
|
|
// lock
|
|
lock_get(rtpengine_hash_lock);
|
|
lock_get(rtpengine_hash_lock);
|
|
while (entry) {
|
|
while (entry) {
|
|
- // if key found, return entry
|
|
|
|
- if (str_equal(&entry->callid, (str *)key)) {
|
|
|
|
|
|
+ // if callid found, return entry
|
|
|
|
+ if (str_equal(entry->callid, callid) &&
|
|
|
|
+ str_equal(entry->viabranch, viabranch)) {
|
|
node = entry->node;
|
|
node = entry->node;
|
|
|
|
|
|
// unlock
|
|
// unlock
|
|
@@ -317,8 +315,7 @@ struct rtpp_node *rtpengine_hash_table_lookup(str *key) {
|
|
last_entry->next = entry->next;
|
|
last_entry->next = entry->next;
|
|
|
|
|
|
// free current entry; entry points to unknown
|
|
// free current entry; entry points to unknown
|
|
- shm_free(entry->callid.s);
|
|
|
|
- shm_free(entry);
|
|
|
|
|
|
+ rtpengine_hash_table_free_entry(entry);
|
|
|
|
|
|
// set pointers
|
|
// set pointers
|
|
entry = last_entry;
|
|
entry = last_entry;
|
|
@@ -369,8 +366,7 @@ void rtpengine_hash_table_print() {
|
|
last_entry->next = entry->next;
|
|
last_entry->next = entry->next;
|
|
|
|
|
|
// free current entry; entry points to unknown
|
|
// free current entry; entry points to unknown
|
|
- shm_free(entry->callid.s);
|
|
|
|
- shm_free(entry);
|
|
|
|
|
|
+ rtpengine_hash_table_free_entry(entry);
|
|
|
|
|
|
// set pointers
|
|
// set pointers
|
|
entry = last_entry;
|
|
entry = last_entry;
|
|
@@ -401,3 +397,41 @@ unsigned int rtpengine_hash_table_total() {
|
|
|
|
|
|
return rtpengine_hash_table->total;
|
|
return rtpengine_hash_table->total;
|
|
}
|
|
}
|
|
|
|
+
|
|
|
|
+void rtpengine_hash_table_free_entry(struct rtpengine_hash_entry *entry) {
|
|
|
|
+ if (!entry) {
|
|
|
|
+ return ;
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ // free callid
|
|
|
|
+ if (entry->callid.s) {
|
|
|
|
+ shm_free(entry->callid.s);
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ // free viabranch
|
|
|
|
+ if (entry->viabranch.s) {
|
|
|
|
+ shm_free(entry->viabranch.s);
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ // free entry
|
|
|
|
+ shm_free(entry);
|
|
|
|
+
|
|
|
|
+ return ;
|
|
|
|
+}
|
|
|
|
+
|
|
|
|
+void rtpengine_hash_table_free_entry_list(struct rtpengine_hash_entry *entry_list) {
|
|
|
|
+ struct rtpengine_hash_entry *entry, *last_entry;
|
|
|
|
+
|
|
|
|
+ if (!entry_list) {
|
|
|
|
+ return ;
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ entry = entry_list;
|
|
|
|
+ while (entry) {
|
|
|
|
+ last_entry = entry;
|
|
|
|
+ entry = entry->next;
|
|
|
|
+ rtpengine_hash_table_free_entry(last_entry);
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ return ;
|
|
|
|
+}
|