mirror of https://github.com/sipwise/kamailio.git
parent
b303b8c8a8
commit
d041b0fba0
@ -1,29 +0,0 @@
|
|||||||
From ee692ab89f1321ccfb24316c30fce5a90e6a9764 Mon Sep 17 00:00:00 2001
|
|
||||||
From: Daniel-Constantin Mierla <miconda@gmail.com>
|
|
||||||
Date: Mon, 28 Apr 2014 09:51:42 +0200
|
|
||||||
Subject: [PATCH] pipelimit: run timer at 1000ms
|
|
||||||
|
|
||||||
- proper execution on timer_interval
|
|
||||||
- reported by Julia <juliabo@gmail.com>
|
|
||||||
|
|
||||||
(cherry picked from commit f9d95734ba7c04a0188077914161395c2e94f3eb)
|
|
||||||
---
|
|
||||||
modules/pipelimit/pipelimit.c | 2 +-
|
|
||||||
1 file changed, 1 insertion(+), 1 deletion(-)
|
|
||||||
|
|
||||||
diff --git a/modules/pipelimit/pipelimit.c b/modules/pipelimit/pipelimit.c
|
|
||||||
index 77d2796..5aeb071 100644
|
|
||||||
--- a/modules/pipelimit/pipelimit.c
|
|
||||||
+++ b/modules/pipelimit/pipelimit.c
|
|
||||||
@@ -308,7 +308,7 @@ static int mod_init(void)
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
timer_init(pl_timer, pl_timer_handle, 0, F_TIMER_FAST);
|
|
||||||
- timer_add(pl_timer, MS_TO_TICKS(1500)); /* Start it after 1500ms */
|
|
||||||
+ timer_add(pl_timer, MS_TO_TICKS(1000)); /* Start it after 1000ms */
|
|
||||||
|
|
||||||
/* bind the SL API */
|
|
||||||
if (sl_load_api(&slb)!=0) {
|
|
||||||
--
|
|
||||||
2.0.0.rc0
|
|
||||||
|
|
||||||
@ -0,0 +1,28 @@
|
|||||||
|
From c24508f80449a01165e65d4592cf77303054c36a Mon Sep 17 00:00:00 2001
|
||||||
|
From: Victor Seva <linuxmaniac@torreviejawireless.org>
|
||||||
|
Date: Sat, 14 Jun 2014 18:20:06 +0200
|
||||||
|
Subject: [PATCH] app_java: Use generic libgcj
|
||||||
|
|
||||||
|
(cherry picked from commit 00d2c27cbd0c36fd8979d5b92a3f860a5e657c60)
|
||||||
|
---
|
||||||
|
modules/app_java/Makefile | 4 ++--
|
||||||
|
1 file changed, 2 insertions(+), 2 deletions(-)
|
||||||
|
|
||||||
|
diff --git a/modules/app_java/Makefile b/modules/app_java/Makefile
|
||||||
|
index 792a116..ca854ed 100644
|
||||||
|
--- a/modules/app_java/Makefile
|
||||||
|
+++ b/modules/app_java/Makefile
|
||||||
|
@@ -17,8 +17,8 @@ LIBS += $(shell pkg-config libgcj-4.4 --cflags) -L$(JVM_PATH) -ljvm
|
||||||
|
else
|
||||||
|
# try to detect JAVA_HOME
|
||||||
|
JAVA_HOME ?= $(shell readlink -f /usr/bin/javac | sed "s:bin/javac::")
|
||||||
|
-DEFS += $(shell pkg-config libgcj12 --cflags) -I$(JAVA_HOME)/include
|
||||||
|
-LIBS += $(shell pkg-config libgcj12 --libs) -L$(JAVA_HOME)/lib -ljvm
|
||||||
|
+DEFS += $(shell pkg-config libgcj --cflags) -I$(JAVA_HOME)/include
|
||||||
|
+LIBS += $(shell pkg-config libgcj --libs) -L$(JAVA_HOME)/lib -ljvm
|
||||||
|
|
||||||
|
# On Debian 7.5 there is a bug with JAVA_HOME detection.
|
||||||
|
# $(shell readlink -f /usr/bin/javac | sed "s:bin/javac::") points to perl wrapper script (/usr/bin/gcj-wrapper-4.7)
|
||||||
|
--
|
||||||
|
2.0.0
|
||||||
|
|
||||||
@ -1,26 +0,0 @@
|
|||||||
From a9a3cebc7688dcaea7539c067c4b1bf3463040ce Mon Sep 17 00:00:00 2001
|
|
||||||
From: Daniel-Constantin Mierla <miconda@gmail.com>
|
|
||||||
Date: Thu, 24 Apr 2014 18:02:34 +0200
|
|
||||||
Subject: [PATCH] drouting: removed old contraint on route index
|
|
||||||
|
|
||||||
(cherry picked from commit c3386295d7607a58d37a65b6822bf5f98b3fefa0)
|
|
||||||
---
|
|
||||||
modules/drouting/drouting.c | 2 +-
|
|
||||||
1 file changed, 1 insertion(+), 1 deletion(-)
|
|
||||||
|
|
||||||
diff --git a/modules/drouting/drouting.c b/modules/drouting/drouting.c
|
|
||||||
index 60006b1..4322a7e 100644
|
|
||||||
--- a/modules/drouting/drouting.c
|
|
||||||
+++ b/modules/drouting/drouting.c
|
|
||||||
@@ -754,7 +754,7 @@ again:
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
- if (rt_info->route_idx>0 && rt_info->route_idx<RT_NO) {
|
|
||||||
+ if (rt_info->route_idx>0 && main_rt.rlist[rt_info->route_idx]!=NULL) {
|
|
||||||
ret = run_top_route(main_rt.rlist[rt_info->route_idx], msg, 0);
|
|
||||||
if (ret<1) {
|
|
||||||
/* drop the action */
|
|
||||||
--
|
|
||||||
2.0.0.rc0
|
|
||||||
|
|
||||||
@ -1,44 +0,0 @@
|
|||||||
From 70f1b7479f80ca4f5e3a45fcf772785c110d0b57 Mon Sep 17 00:00:00 2001
|
|
||||||
From: Daniel-Constantin Mierla <miconda@gmail.com>
|
|
||||||
Date: Wed, 30 Apr 2014 21:46:55 +0200
|
|
||||||
Subject: [PATCH] core: compute the len for dns srv name
|
|
||||||
|
|
||||||
- fixes dns srv for cache, reported by Rob Eijgenraam, FS#426
|
|
||||||
|
|
||||||
(cherry picked from commit b834cde74f8a4b41ec24ceb8332adff8bb3922bb)
|
|
||||||
---
|
|
||||||
dns_cache.c | 4 +---
|
|
||||||
1 file changed, 1 insertion(+), 3 deletions(-)
|
|
||||||
|
|
||||||
diff --git a/dns_cache.c b/dns_cache.c
|
|
||||||
index 7465c83..029b445 100644
|
|
||||||
--- a/dns_cache.c
|
|
||||||
+++ b/dns_cache.c
|
|
||||||
@@ -2656,7 +2656,6 @@ struct hostent* dns_srv_sip_resolvehost(str* name, unsigned short* port,
|
|
||||||
struct hostent* he;
|
|
||||||
struct ip_addr* ip;
|
|
||||||
static char tmp[MAX_DNS_NAME]; /* tmp. buff. for SRV lookups */
|
|
||||||
- int len;
|
|
||||||
str srv_name;
|
|
||||||
char srv_proto;
|
|
||||||
|
|
||||||
@@ -2664,7 +2663,6 @@ struct hostent* dns_srv_sip_resolvehost(str* name, unsigned short* port,
|
|
||||||
/* not init or off => use normal, non-cached version */
|
|
||||||
return _sip_resolvehost(name, port, proto);
|
|
||||||
}
|
|
||||||
- len=0;
|
|
||||||
if (proto){ /* makes sure we have a protocol set*/
|
|
||||||
if (*proto==0)
|
|
||||||
*proto=srv_proto=PROTO_UDP; /* default */
|
|
||||||
@@ -2708,7 +2706,7 @@ struct hostent* dns_srv_sip_resolvehost(str* name, unsigned short* port,
|
|
||||||
}
|
|
||||||
|
|
||||||
srv_name.s=tmp;
|
|
||||||
- srv_name.len=len;
|
|
||||||
+ srv_name.len=strlen(tmp);
|
|
||||||
if ((he=dns_srv_get_he(&srv_name, port, dns_flags))!=0)
|
|
||||||
return he;
|
|
||||||
}
|
|
||||||
--
|
|
||||||
2.0.0.rc0
|
|
||||||
|
|
||||||
@ -1,30 +0,0 @@
|
|||||||
From 4455a13e8d31416dc44af455710fd7a7ff37ec11 Mon Sep 17 00:00:00 2001
|
|
||||||
From: Daniel-Constantin Mierla <miconda@gmail.com>
|
|
||||||
Date: Mon, 28 Apr 2014 13:51:56 +0200
|
|
||||||
Subject: [PATCH] acc: no request is needed for setting end time on dialog
|
|
||||||
termination
|
|
||||||
|
|
||||||
- callback function cdr_on_end() doesn't use it at all
|
|
||||||
- reported by Eduardo Lejarreta, FS#256
|
|
||||||
|
|
||||||
(cherry picked from commit 8fcdd23aaa49cb6c1ecb34c4c6b4a88078a860f7)
|
|
||||||
---
|
|
||||||
modules/acc/acc_cdr.c | 2 +-
|
|
||||||
1 file changed, 1 insertion(+), 1 deletion(-)
|
|
||||||
|
|
||||||
diff --git a/modules/acc/acc_cdr.c b/modules/acc/acc_cdr.c
|
|
||||||
index 68792e9..3cab762 100644
|
|
||||||
--- a/modules/acc/acc_cdr.c
|
|
||||||
+++ b/modules/acc/acc_cdr.c
|
|
||||||
@@ -569,7 +569,7 @@ static void cdr_on_end( struct dlg_cell* dialog,
|
|
||||||
int type,
|
|
||||||
struct dlg_cb_params* params)
|
|
||||||
{
|
|
||||||
- if( !dialog || !params || !params->req)
|
|
||||||
+ if( !dialog || !params)
|
|
||||||
{
|
|
||||||
LM_ERR("invalid values\n!");
|
|
||||||
return;
|
|
||||||
--
|
|
||||||
2.0.0.rc0
|
|
||||||
|
|
||||||
@ -0,0 +1,27 @@
|
|||||||
|
From 77019552cf3e1d88b98620eedad2ce7fb4bbb469 Mon Sep 17 00:00:00 2001
|
||||||
|
From: Hugh Waite <hugh.waite@acision.com>
|
||||||
|
Date: Mon, 16 Jun 2014 11:53:11 +0100
|
||||||
|
Subject: [PATCH] registrar: Add check for contact header before checking
|
||||||
|
outbound support
|
||||||
|
|
||||||
|
- Fixes crash when processing REGISTER without a contact
|
||||||
|
(cherry picked from commit c9301c99d3c9acb663023cf02393d0e7ed74c133)
|
||||||
|
---
|
||||||
|
modules/registrar/save.c | 1 +
|
||||||
|
1 file changed, 1 insertion(+)
|
||||||
|
|
||||||
|
diff --git a/modules/registrar/save.c b/modules/registrar/save.c
|
||||||
|
index 18e6758..70b868b 100644
|
||||||
|
--- a/modules/registrar/save.c
|
||||||
|
+++ b/modules/registrar/save.c
|
||||||
|
@@ -910,6 +910,7 @@ int save(struct sip_msg* _m, udomain_t* _d, int _cflags, str *_uri)
|
||||||
|
}
|
||||||
|
|
||||||
|
if (reg_outbound_mode != REG_OUTBOUND_NONE
|
||||||
|
+ && _m->contact && _m->contact->parsed
|
||||||
|
&& !(parse_headers(_m, HDR_VIA2_F, 0) == -1 || _m->via2 == 0
|
||||||
|
|| _m->via2->error != PARSE_OK)) {
|
||||||
|
/* Outbound supported on server, and more than one Via: - not the first hop */
|
||||||
|
--
|
||||||
|
2.0.0
|
||||||
|
|
||||||
@ -1,42 +0,0 @@
|
|||||||
From c5781b28cd92360cf163a84312fa72c08c4737b5 Mon Sep 17 00:00:00 2001
|
|
||||||
From: Daniel-Constantin Mierla <miconda@gmail.com>
|
|
||||||
Date: Tue, 29 Apr 2014 20:02:19 +0200
|
|
||||||
Subject: [PATCH] rtmier: reset avps and xavp lists after route blocks
|
|
||||||
execution
|
|
||||||
|
|
||||||
- avoid leaks if someone is using avp/xavp with rtimer - there is a fake
|
|
||||||
message used there, thus not the normal sip message routing that
|
|
||||||
resets avps/xavps
|
|
||||||
|
|
||||||
(cherry picked from commit 159978cf2a98748f3225155d8946bcbd768b51e3)
|
|
||||||
---
|
|
||||||
modules/rtimer/rtimer_mod.c | 6 ++++++
|
|
||||||
1 file changed, 6 insertions(+)
|
|
||||||
|
|
||||||
diff --git a/modules/rtimer/rtimer_mod.c b/modules/rtimer/rtimer_mod.c
|
|
||||||
index 03a002d..271b888 100644
|
|
||||||
--- a/modules/rtimer/rtimer_mod.c
|
|
||||||
+++ b/modules/rtimer/rtimer_mod.c
|
|
||||||
@@ -37,6 +37,8 @@
|
|
||||||
#include "../../socket_info.h"
|
|
||||||
#include "../../dset.h"
|
|
||||||
#include "../../pt.h"
|
|
||||||
+#include "../../usr_avp.h"
|
|
||||||
+#include "../../xavp.h"
|
|
||||||
#include "../../timer_proc.h"
|
|
||||||
#include "../../script_cb.h"
|
|
||||||
#include "../../parser/parse_param.h"
|
|
||||||
@@ -190,6 +192,10 @@ void stm_timer_exec(unsigned int ticks, void *param)
|
|
||||||
set_route_type(REQUEST_ROUTE);
|
|
||||||
run_top_route(main_rt.rlist[rt->route], fmsg, 0);
|
|
||||||
exec_post_script_cb(fmsg, REQUEST_CB_TYPE);
|
|
||||||
+ reset_avps();
|
|
||||||
+#ifdef WITH_XAVP
|
|
||||||
+ xavp_reset_list();
|
|
||||||
+#endif
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
--
|
|
||||||
2.0.0.rc0
|
|
||||||
|
|
||||||
@ -1,60 +0,0 @@
|
|||||||
From b76eb77a36a5e751d792cb7e0d60f4750976e322 Mon Sep 17 00:00:00 2001
|
|
||||||
From: Daniel-Constantin Mierla <miconda@gmail.com>
|
|
||||||
Date: Fri, 2 May 2014 21:50:14 +0200
|
|
||||||
Subject: [PATCH] dialog: copy dlg var value locally on get operation
|
|
||||||
|
|
||||||
- reference to shared memory exposes risk on accessing an invalid
|
|
||||||
pointer if anothe process updates it
|
|
||||||
- reported by Dragos Oancea
|
|
||||||
|
|
||||||
(cherry picked from commit bb3eed8aabea9f63c9922f71714aea242771db02)
|
|
||||||
---
|
|
||||||
modules/dialog/dlg_var.c | 18 ++++++++++++++++--
|
|
||||||
1 file changed, 16 insertions(+), 2 deletions(-)
|
|
||||||
|
|
||||||
diff --git a/modules/dialog/dlg_var.c b/modules/dialog/dlg_var.c
|
|
||||||
index 111dcd8..4b2ca89 100644
|
|
||||||
--- a/modules/dialog/dlg_var.c
|
|
||||||
+++ b/modules/dialog/dlg_var.c
|
|
||||||
@@ -284,6 +284,7 @@ int pv_get_dlg_variable(struct sip_msg *msg, pv_param_t *param, pv_value_t *res)
|
|
||||||
{
|
|
||||||
dlg_cell_t *dlg;
|
|
||||||
str * value;
|
|
||||||
+ str spv;
|
|
||||||
|
|
||||||
if (param==NULL || param->pvn.type!=PV_NAME_INTSTR
|
|
||||||
|| param->pvn.u.isname.type!=AVP_NAME_STR
|
|
||||||
@@ -306,6 +307,19 @@ int pv_get_dlg_variable(struct sip_msg *msg, pv_param_t *param, pv_value_t *res)
|
|
||||||
/* dcm: todo - the value should be cloned for safe usage */
|
|
||||||
value = get_dlg_variable_unsafe(dlg, ¶m->pvn.u.isname.name.s);
|
|
||||||
|
|
||||||
+ spv.s = NULL;
|
|
||||||
+ if(value) {
|
|
||||||
+ spv.len = pv_get_buffer_size();
|
|
||||||
+ if(spv.len<value->len+1) {
|
|
||||||
+ LM_ERR("pv buffer too small (%d) - needed %d\n", spv.len, value->len);
|
|
||||||
+ } else {
|
|
||||||
+ spv.s = pv_get_buffer();
|
|
||||||
+ strncpy(spv.s, value->s, value->len);
|
|
||||||
+ spv.len = value->len;
|
|
||||||
+ spv.s[spv.len] = '\0';
|
|
||||||
+ }
|
|
||||||
+ }
|
|
||||||
+
|
|
||||||
print_lists(dlg);
|
|
||||||
|
|
||||||
/* unlock dialog */
|
|
||||||
@@ -314,8 +328,8 @@ int pv_get_dlg_variable(struct sip_msg *msg, pv_param_t *param, pv_value_t *res)
|
|
||||||
dlg_release(dlg);
|
|
||||||
}
|
|
||||||
|
|
||||||
- if (value)
|
|
||||||
- return pv_get_strval(msg, param, res, value);
|
|
||||||
+ if (spv.s)
|
|
||||||
+ return pv_get_strval(msg, param, res, &spv);
|
|
||||||
|
|
||||||
|
|
||||||
return pv_get_null(msg, param, res);
|
|
||||||
--
|
|
||||||
2.0.0.rc0
|
|
||||||
|
|
||||||
@ -1,39 +0,0 @@
|
|||||||
From cc4a7c67f24d105a119ea492ce53f017369af296 Mon Sep 17 00:00:00 2001
|
|
||||||
From: Daniel-Constantin Mierla <miconda@gmail.com>
|
|
||||||
Date: Thu, 8 May 2014 08:40:28 +0200
|
|
||||||
Subject: [PATCH] presence_dialoginfo: interetate through all 'dialog' nodes of
|
|
||||||
xml document
|
|
||||||
|
|
||||||
- PUBLISH request can carry info for many dialogs
|
|
||||||
- reported and patch by Klaus Feichtinger
|
|
||||||
|
|
||||||
(cherry picked from commit 7a827a612f93b9dd938f9b78c0de3ac2d98a0c77)
|
|
||||||
---
|
|
||||||
modules/presence_dialoginfo/notify_body.c | 4 +++-
|
|
||||||
1 file changed, 3 insertions(+), 1 deletion(-)
|
|
||||||
|
|
||||||
diff --git a/modules/presence_dialoginfo/notify_body.c b/modules/presence_dialoginfo/notify_body.c
|
|
||||||
index 7f74b1f..db8834b 100644
|
|
||||||
--- a/modules/presence_dialoginfo/notify_body.c
|
|
||||||
+++ b/modules/presence_dialoginfo/notify_body.c
|
|
||||||
@@ -111,6 +111,7 @@ str* agregate_xmls(str* pres_user, str* pres_domain, str** body_array, int n)
|
|
||||||
xmlNodePtr confirmed_node = NULL;
|
|
||||||
xmlNodePtr proceed_node = NULL;
|
|
||||||
xmlNodePtr trying_node = NULL;
|
|
||||||
+ xmlNodePtr next_node = NULL;
|
|
||||||
|
|
||||||
|
|
||||||
char *state = NULL;
|
|
||||||
@@ -214,7 +215,8 @@ str* agregate_xmls(str* pres_user, str* pres_domain, str** body_array, int n)
|
|
||||||
goto error;
|
|
||||||
}
|
|
||||||
if (p_root->children) {
|
|
||||||
- for (node = p_root->children; node; node = node->next) {
|
|
||||||
+ for (node = p_root->children; node; node = next_node) {
|
|
||||||
+ next_node = node->next;
|
|
||||||
if (node->type == XML_ELEMENT_NODE) {
|
|
||||||
LM_DBG("node type: Element, name: %s\n", node->name);
|
|
||||||
/* we do not copy the node, but unlink it and then add it ot the new node
|
|
||||||
--
|
|
||||||
2.0.0.rc0
|
|
||||||
|
|
||||||
@ -1,740 +0,0 @@
|
|||||||
From 74c1bd884ec2a3418dee3cbf358ab8bb7e899d7a Mon Sep 17 00:00:00 2001
|
|
||||||
From: Vitaliy Aleksandrov <vitalik.voip@gmail.com>
|
|
||||||
Date: Thu, 8 May 2014 15:01:02 +0100
|
|
||||||
Subject: [PATCH] websocket: Fix crash in websocket module
|
|
||||||
|
|
||||||
- Avoid race condition by maintaining a connection reference count
|
|
||||||
- Fixes FS#406
|
|
||||||
---
|
|
||||||
modules/websocket/ws_conn.c | 180 ++++++++++++++++++++++++++++++++++----
|
|
||||||
modules/websocket/ws_conn.h | 8 ++
|
|
||||||
modules/websocket/ws_frame.c | 182 ++++++++++++++++++++++++++-------------
|
|
||||||
modules/websocket/ws_handshake.c | 4 +-
|
|
||||||
4 files changed, 295 insertions(+), 79 deletions(-)
|
|
||||||
|
|
||||||
diff --git a/modules/websocket/ws_conn.c b/modules/websocket/ws_conn.c
|
|
||||||
index 9f2b672..62a1b61 100644
|
|
||||||
--- a/modules/websocket/ws_conn.c
|
|
||||||
+++ b/modules/websocket/ws_conn.c
|
|
||||||
@@ -47,6 +47,9 @@ gen_lock_t *wsconn_lock = NULL;
|
|
||||||
#define WSCONN_LOCK lock_get(wsconn_lock)
|
|
||||||
#define WSCONN_UNLOCK lock_release(wsconn_lock)
|
|
||||||
|
|
||||||
+#define wsconn_ref(c) atomic_inc(&((c)->refcnt))
|
|
||||||
+#define wsconn_unref(c) atomic_dec_and_test(&((c)->refcnt))
|
|
||||||
+
|
|
||||||
gen_lock_t *wsstat_lock = NULL;
|
|
||||||
|
|
||||||
ws_connection_used_list_t *wsconn_used_list = NULL;
|
|
||||||
@@ -197,6 +200,8 @@ int wsconn_add(struct receive_info rcv, unsigned int sub_protocol)
|
|
||||||
int id_hash = tcp_id_hash(id);
|
|
||||||
ws_connection_t *wsc;
|
|
||||||
|
|
||||||
+ LM_DBG("wsconn_add id [%d]\n", id);
|
|
||||||
+
|
|
||||||
/* Allocate and fill in new WebSocket connection */
|
|
||||||
wsc = shm_malloc(sizeof(ws_connection_t));
|
|
||||||
if (wsc == NULL)
|
|
||||||
@@ -210,6 +215,10 @@ int wsconn_add(struct receive_info rcv, unsigned int sub_protocol)
|
|
||||||
wsc->state = WS_S_OPEN;
|
|
||||||
wsc->rcv = rcv;
|
|
||||||
wsc->sub_protocol = sub_protocol;
|
|
||||||
+ wsc->run_event = 0;
|
|
||||||
+ atomic_set(&wsc->refcnt, 0);
|
|
||||||
+
|
|
||||||
+ LM_DBG("wsconn_add new wsc => [%p], ref => [%d]\n", wsc, atomic_get(&wsc->refcnt));
|
|
||||||
|
|
||||||
WSCONN_LOCK;
|
|
||||||
/* Add to WebSocket connection table */
|
|
||||||
@@ -225,8 +234,12 @@ int wsconn_add(struct receive_info rcv, unsigned int sub_protocol)
|
|
||||||
wsconn_used_list->tail->used_next = wsc;
|
|
||||||
wsconn_used_list->tail = wsc;
|
|
||||||
}
|
|
||||||
+ wsconn_ref(wsc);
|
|
||||||
+
|
|
||||||
WSCONN_UNLOCK;
|
|
||||||
|
|
||||||
+ LM_DBG("wsconn_add added to conn_table wsc => [%p], ref => [%d]\n", wsc, atomic_get(&wsc->refcnt));
|
|
||||||
+
|
|
||||||
/* Update connection statistics */
|
|
||||||
lock_get(wsstat_lock);
|
|
||||||
|
|
||||||
@@ -290,32 +303,29 @@ static void wsconn_run_route(ws_connection_t *wsc)
|
|
||||||
set_route_type(backup_rt);
|
|
||||||
}
|
|
||||||
|
|
||||||
-int wsconn_rm(ws_connection_t *wsc, ws_conn_eventroute_t run_event_route)
|
|
||||||
+static void wsconn_dtor(ws_connection_t *wsc)
|
|
||||||
{
|
|
||||||
if (!wsc)
|
|
||||||
- {
|
|
||||||
- LM_ERR("wsconn_rm: null pointer\n");
|
|
||||||
- return -1;
|
|
||||||
- }
|
|
||||||
+ return;
|
|
||||||
|
|
||||||
- if (run_event_route == WSCONN_EVENTROUTE_YES)
|
|
||||||
+ LM_DBG("wsconn_dtor for [%p] refcnt [%d]\n", wsc, atomic_get(&wsc->refcnt));
|
|
||||||
+
|
|
||||||
+ if (wsc->run_event)
|
|
||||||
wsconn_run_route(wsc);
|
|
||||||
|
|
||||||
- WSCONN_LOCK;
|
|
||||||
- /* Remove from the WebSocket used list */
|
|
||||||
- if (wsconn_used_list->head == wsc)
|
|
||||||
- wsconn_used_list->head = wsc->used_next;
|
|
||||||
- if (wsconn_used_list->tail == wsc)
|
|
||||||
- wsconn_used_list->tail = wsc->used_prev;
|
|
||||||
- if (wsc->used_prev)
|
|
||||||
- wsc->used_prev->used_next = wsc->used_next;
|
|
||||||
- if (wsc->used_next)
|
|
||||||
- wsc->used_next->used_prev = wsc->used_prev;
|
|
||||||
+ shm_free(wsc);
|
|
||||||
|
|
||||||
- _wsconn_rm(wsc);
|
|
||||||
- WSCONN_UNLOCK;
|
|
||||||
+ LM_DBG("wsconn_dtor for [%p] destroyed\n", wsc);
|
|
||||||
+}
|
|
||||||
|
|
||||||
- return 0;
|
|
||||||
+int wsconn_rm(ws_connection_t *wsc, ws_conn_eventroute_t run_event_route)
|
|
||||||
+{
|
|
||||||
+ LM_DBG("wsconn_rm for [%p] refcnt [%d]\n", wsc, atomic_get(&wsc->refcnt));
|
|
||||||
+
|
|
||||||
+ if (run_event_route == WSCONN_EVENTROUTE_YES)
|
|
||||||
+ wsc->run_event = 1;
|
|
||||||
+
|
|
||||||
+ return wsconn_put(wsc);
|
|
||||||
}
|
|
||||||
|
|
||||||
int wsconn_update(ws_connection_t *wsc)
|
|
||||||
@@ -366,17 +376,70 @@ void wsconn_close_now(ws_connection_t *wsc)
|
|
||||||
con->timeout = get_ticks_raw();
|
|
||||||
}
|
|
||||||
|
|
||||||
+/* must be called with unlocked WSCONN_LOCK */
|
|
||||||
+int wsconn_put(ws_connection_t *wsc)
|
|
||||||
+{
|
|
||||||
+ int destroy = 0;
|
|
||||||
+
|
|
||||||
+ LM_DBG("wsconn_put start for [%p] refcnt [%d]\n", wsc, atomic_get(&wsc->refcnt));
|
|
||||||
+
|
|
||||||
+ if (!wsc)
|
|
||||||
+ return -1;
|
|
||||||
+
|
|
||||||
+ WSCONN_LOCK;
|
|
||||||
+ /* refcnt == 0*/
|
|
||||||
+ if (wsconn_unref(wsc))
|
|
||||||
+ {
|
|
||||||
+ /* Remove from the WebSocket used list */
|
|
||||||
+ if (wsconn_used_list->head == wsc)
|
|
||||||
+ wsconn_used_list->head = wsc->used_next;
|
|
||||||
+ if (wsconn_used_list->tail == wsc)
|
|
||||||
+ wsconn_used_list->tail = wsc->used_prev;
|
|
||||||
+ if (wsc->used_prev)
|
|
||||||
+ wsc->used_prev->used_next = wsc->used_next;
|
|
||||||
+ if (wsc->used_next)
|
|
||||||
+ wsc->used_next->used_prev = wsc->used_prev;
|
|
||||||
+
|
|
||||||
+ /* remove from wsconn_id_hash */
|
|
||||||
+ wsconn_listrm(wsconn_id_hash[wsc->id_hash], wsc, id_next, id_prev);
|
|
||||||
+
|
|
||||||
+ /* stat */
|
|
||||||
+ update_stat(ws_current_connections, -1);
|
|
||||||
+ if (wsc->sub_protocol == SUB_PROTOCOL_SIP)
|
|
||||||
+ update_stat(ws_sip_current_connections, -1);
|
|
||||||
+ else if (wsc->sub_protocol == SUB_PROTOCOL_MSRP)
|
|
||||||
+ update_stat(ws_msrp_current_connections, -1);
|
|
||||||
+
|
|
||||||
+ destroy = 1;
|
|
||||||
+ }
|
|
||||||
+ WSCONN_UNLOCK;
|
|
||||||
+
|
|
||||||
+ LM_DBG("wsconn_put end for [%p] refcnt [%d]\n", wsc, atomic_get(&wsc->refcnt));
|
|
||||||
+
|
|
||||||
+ /* wsc is removed from all lists and can be destroyed safely */
|
|
||||||
+ if (destroy)
|
|
||||||
+ wsconn_dtor(wsc);
|
|
||||||
+
|
|
||||||
+ return 0;
|
|
||||||
+}
|
|
||||||
+
|
|
||||||
ws_connection_t *wsconn_get(int id)
|
|
||||||
{
|
|
||||||
int id_hash = tcp_id_hash(id);
|
|
||||||
ws_connection_t *wsc;
|
|
||||||
|
|
||||||
+ LM_DBG("wsconn_get for id [%d]\n", id);
|
|
||||||
+
|
|
||||||
WSCONN_LOCK;
|
|
||||||
for (wsc = wsconn_id_hash[id_hash]; wsc; wsc = wsc->id_next)
|
|
||||||
{
|
|
||||||
if (wsc->id == id)
|
|
||||||
{
|
|
||||||
+ wsconn_ref(wsc);
|
|
||||||
+ LM_DBG("wsconn_get returns wsc [%p] refcnt [%d]\n", wsc, atomic_get(&wsc->refcnt));
|
|
||||||
+
|
|
||||||
WSCONN_UNLOCK;
|
|
||||||
+
|
|
||||||
return wsc;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -385,6 +448,85 @@ ws_connection_t *wsconn_get(int id)
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
+ws_connection_t **wsconn_get_list(void)
|
|
||||||
+{
|
|
||||||
+ ws_connection_t **list = NULL;
|
|
||||||
+ ws_connection_t *wsc = NULL;
|
|
||||||
+ size_t list_size = 0;
|
|
||||||
+ size_t list_len = 0;
|
|
||||||
+ size_t i = 0;
|
|
||||||
+
|
|
||||||
+ LM_DBG("wsconn_get_list\n");
|
|
||||||
+
|
|
||||||
+ WSCONN_LOCK;
|
|
||||||
+
|
|
||||||
+ /* get the number of used connections */
|
|
||||||
+ wsc = wsconn_used_list->head;
|
|
||||||
+ while (wsc)
|
|
||||||
+ {
|
|
||||||
+ LM_DBG("counter wsc [%p] prev => [%p] next => [%p]\n", wsc, wsc->used_prev, wsc->used_next);
|
|
||||||
+ list_len++;
|
|
||||||
+ wsc = wsc->used_next;
|
|
||||||
+ }
|
|
||||||
+
|
|
||||||
+ if (!list_len)
|
|
||||||
+ goto end;
|
|
||||||
+
|
|
||||||
+ /* allocate a NULL terminated list of wsconn pointers */
|
|
||||||
+ list_size = (list_len + 1) * sizeof(ws_connection_t *);
|
|
||||||
+ list = pkg_malloc(list_size);
|
|
||||||
+ if (!list)
|
|
||||||
+ goto end;
|
|
||||||
+
|
|
||||||
+ memset(list, 0, list_size);
|
|
||||||
+
|
|
||||||
+ /* copy */
|
|
||||||
+ wsc = wsconn_used_list->head;
|
|
||||||
+ for(i = 0; i < list_len; i++)
|
|
||||||
+ {
|
|
||||||
+ if (!wsc) {
|
|
||||||
+ LM_ERR("Wrong list length\n");
|
|
||||||
+ }
|
|
||||||
+
|
|
||||||
+ list[i] = wsc;
|
|
||||||
+ wsconn_ref(wsc);
|
|
||||||
+ LM_DBG("wsc [%p] id [%d] ref++\n", wsc, wsc->id);
|
|
||||||
+
|
|
||||||
+ wsc = wsc->used_next;
|
|
||||||
+ }
|
|
||||||
+ list[list_len] = NULL; /* explicit NULL termination */
|
|
||||||
+
|
|
||||||
+end:
|
|
||||||
+ WSCONN_UNLOCK;
|
|
||||||
+
|
|
||||||
+ LM_DBG("wsconn_get_list returns list [%p] with [%d] members\n", list, (int)list_len);
|
|
||||||
+
|
|
||||||
+ return list;
|
|
||||||
+}
|
|
||||||
+
|
|
||||||
+int wsconn_put_list(ws_connection_t **list_head)
|
|
||||||
+{
|
|
||||||
+ ws_connection_t **list = NULL;
|
|
||||||
+ ws_connection_t *wsc = NULL;
|
|
||||||
+
|
|
||||||
+ LM_DBG("wsconn_put_list [%p]\n", list_head);
|
|
||||||
+
|
|
||||||
+ if (!list_head)
|
|
||||||
+ return -1;
|
|
||||||
+
|
|
||||||
+ list = list_head;
|
|
||||||
+ wsc = *list_head;
|
|
||||||
+ while (wsc)
|
|
||||||
+ {
|
|
||||||
+ wsconn_put(wsc);
|
|
||||||
+ wsc = *(++list);
|
|
||||||
+ }
|
|
||||||
+
|
|
||||||
+ pkg_free(list_head);
|
|
||||||
+
|
|
||||||
+ return 0;
|
|
||||||
+}
|
|
||||||
+
|
|
||||||
static int add_node(struct mi_root *tree, ws_connection_t *wsc)
|
|
||||||
{
|
|
||||||
int interval;
|
|
||||||
diff --git a/modules/websocket/ws_conn.h b/modules/websocket/ws_conn.h
|
|
||||||
index 0c7d639..27ba5ee 100644
|
|
||||||
--- a/modules/websocket/ws_conn.h
|
|
||||||
+++ b/modules/websocket/ws_conn.h
|
|
||||||
@@ -29,6 +29,8 @@
|
|
||||||
#ifndef _WS_CONN_H
|
|
||||||
#define _WS_CONN_H
|
|
||||||
|
|
||||||
+#include "../../atomic_ops.h"
|
|
||||||
+
|
|
||||||
#include "../../lib/kcore/kstats_wrapper.h"
|
|
||||||
#include "../../lib/kmi/tree.h"
|
|
||||||
|
|
||||||
@@ -57,6 +59,9 @@ typedef struct ws_connection
|
|
||||||
struct receive_info rcv;
|
|
||||||
|
|
||||||
unsigned int sub_protocol;
|
|
||||||
+
|
|
||||||
+ atomic_t refcnt;
|
|
||||||
+ int run_event;
|
|
||||||
} ws_connection_t;
|
|
||||||
|
|
||||||
typedef struct
|
|
||||||
@@ -89,6 +94,9 @@ int wsconn_rm(ws_connection_t *wsc, ws_conn_eventroute_t run_event_route);
|
|
||||||
int wsconn_update(ws_connection_t *wsc);
|
|
||||||
void wsconn_close_now(ws_connection_t *wsc);
|
|
||||||
ws_connection_t *wsconn_get(int id);
|
|
||||||
+int wsconn_put(ws_connection_t *wsc);
|
|
||||||
+ws_connection_t **wsconn_get_list(void);
|
|
||||||
+int wsconn_put_list(ws_connection_t **list);
|
|
||||||
struct mi_root *ws_mi_dump(struct mi_root *cmd, void *param);
|
|
||||||
|
|
||||||
#endif /* _WS_CONN_H */
|
|
||||||
diff --git a/modules/websocket/ws_frame.c b/modules/websocket/ws_frame.c
|
|
||||||
index ba0713b..7dc2669 100644
|
|
||||||
--- a/modules/websocket/ws_frame.c
|
|
||||||
+++ b/modules/websocket/ws_frame.c
|
|
||||||
@@ -240,7 +240,6 @@ static int encode_and_send_ws_frame(ws_frame_t *frame, conn_close_t conn_close)
|
|
||||||
pkg_free(send_buf);
|
|
||||||
if (wsconn_rm(frame->wsc, WSCONN_EVENTROUTE_YES) < 0)
|
|
||||||
LM_ERR("removing WebSocket connection\n");
|
|
||||||
- frame->wsc = NULL;
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
init_dst_from_rcv(&dst, &con->rcv);
|
|
||||||
@@ -252,10 +251,8 @@ static int encode_and_send_ws_frame(ws_frame_t *frame, conn_close_t conn_close)
|
|
||||||
LM_ERR("removing WebSocket connection\n");
|
|
||||||
tcpconn_put(con);
|
|
||||||
pkg_free(send_buf);
|
|
||||||
- frame->wsc = NULL;
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
- frame->wsc = NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (dst.proto == PROTO_WS)
|
|
||||||
@@ -308,7 +305,6 @@ static int encode_and_send_ws_frame(ws_frame_t *frame, conn_close_t conn_close)
|
|
||||||
update_stat(ws_msrp_failed_connections, 1);
|
|
||||||
if (wsconn_rm(frame->wsc, WSCONN_EVENTROUTE_YES) < 0)
|
|
||||||
LM_ERR("removing WebSocket connection\n");
|
|
||||||
- frame->wsc = NULL;
|
|
||||||
tcpconn_put(con);
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
@@ -394,20 +390,19 @@ static int close_connection(ws_connection_t **p_wsc, ws_close_type_t type,
|
|
||||||
else if (sub_proto == SUB_PROTOCOL_MSRP)
|
|
||||||
update_stat(ws_msrp_remote_closed_connections,
|
|
||||||
1);
|
|
||||||
- *p_wsc = NULL;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else /* if (frame->wsc->state == WS_S_CLOSING) */
|
|
||||||
{
|
|
||||||
wsconn_close_now(wsc);
|
|
||||||
- *p_wsc = NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
static int decode_and_validate_ws_frame(ws_frame_t *frame,
|
|
||||||
- tcp_event_info_t *tcpinfo)
|
|
||||||
+ tcp_event_info_t *tcpinfo,
|
|
||||||
+ short *err_code, str *err_text)
|
|
||||||
{
|
|
||||||
unsigned int i, len = tcpinfo->len;
|
|
||||||
int mask_start, j;
|
|
||||||
@@ -415,21 +410,14 @@ static int decode_and_validate_ws_frame(ws_frame_t *frame,
|
|
||||||
|
|
||||||
LM_DBG("decoding WebSocket frame\n");
|
|
||||||
|
|
||||||
- if ((frame->wsc = wsconn_get(tcpinfo->con->id)) == NULL)
|
|
||||||
- {
|
|
||||||
- LM_ERR("WebSocket connection not found\n");
|
|
||||||
- return -1;
|
|
||||||
- }
|
|
||||||
-
|
|
||||||
wsconn_update(frame->wsc);
|
|
||||||
|
|
||||||
/* Decode and validate first 9 bits */
|
|
||||||
if (len < 2)
|
|
||||||
{
|
|
||||||
LM_WARN("message is too short\n");
|
|
||||||
- if (close_connection(&frame->wsc, LOCAL_CLOSE, 1002,
|
|
||||||
- str_status_protocol_error) < 0)
|
|
||||||
- LM_ERR("closing connection\n");
|
|
||||||
+ *err_code = 1002;
|
|
||||||
+ *err_text = str_status_protocol_error;
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
frame->fin = (buf[0] & 0xff) & BYTE0_MASK_FIN;
|
|
||||||
@@ -443,18 +431,16 @@ static int decode_and_validate_ws_frame(ws_frame_t *frame,
|
|
||||||
{
|
|
||||||
LM_WARN("WebSocket fragmentation not supported in the sip "
|
|
||||||
"sub-protocol\n");
|
|
||||||
- if (close_connection(&frame->wsc, LOCAL_CLOSE, 1002,
|
|
||||||
- str_status_protocol_error) < 0)
|
|
||||||
- LM_ERR("closing connection\n");
|
|
||||||
+ *err_code = 1002;
|
|
||||||
+ *err_text = str_status_protocol_error;
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (frame->rsv1 || frame->rsv2 || frame->rsv3)
|
|
||||||
{
|
|
||||||
LM_WARN("WebSocket reserved fields with non-zero values\n");
|
|
||||||
- if (close_connection(&frame->wsc, LOCAL_CLOSE, 1002,
|
|
||||||
- str_status_protocol_error) < 0)
|
|
||||||
- LM_ERR("closing connection\n");
|
|
||||||
+ *err_code = 1002;
|
|
||||||
+ *err_text = str_status_protocol_error;
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
|
|
||||||
@@ -476,9 +462,8 @@ static int decode_and_validate_ws_frame(ws_frame_t *frame,
|
|
||||||
default:
|
|
||||||
LM_WARN("unsupported opcode: 0x%x\n",
|
|
||||||
(unsigned char) frame->opcode);
|
|
||||||
- if (close_connection(&frame->wsc, LOCAL_CLOSE, 1008,
|
|
||||||
- str_status_unsupported_opcode) < 0)
|
|
||||||
- LM_ERR("closing connection\n");
|
|
||||||
+ *err_code = 1008;
|
|
||||||
+ *err_text = str_status_unsupported_opcode;
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
|
|
||||||
@@ -486,9 +471,8 @@ static int decode_and_validate_ws_frame(ws_frame_t *frame,
|
|
||||||
{
|
|
||||||
LM_WARN("this is a server - all received messages must be "
|
|
||||||
"masked\n");
|
|
||||||
- if (close_connection(&frame->wsc, LOCAL_CLOSE, 1002,
|
|
||||||
- str_status_protocol_error) < 0)
|
|
||||||
- LM_ERR("closing connection\n");
|
|
||||||
+ *err_code = 1002;
|
|
||||||
+ *err_text = str_status_protocol_error;
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
|
|
||||||
@@ -499,9 +483,8 @@ static int decode_and_validate_ws_frame(ws_frame_t *frame,
|
|
||||||
if (len < 4)
|
|
||||||
{
|
|
||||||
LM_WARN("message is too short\n");
|
|
||||||
- if (close_connection(&frame->wsc, LOCAL_CLOSE, 1002,
|
|
||||||
- str_status_protocol_error) < 0)
|
|
||||||
- LM_ERR("closing connection\n");
|
|
||||||
+ *err_code = 1002;
|
|
||||||
+ *err_text = str_status_protocol_error;
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
mask_start = 4;
|
|
||||||
@@ -514,9 +497,8 @@ static int decode_and_validate_ws_frame(ws_frame_t *frame,
|
|
||||||
if (len < 10)
|
|
||||||
{
|
|
||||||
LM_WARN("message is too short\n");
|
|
||||||
- if (close_connection(&frame->wsc, LOCAL_CLOSE, 1002,
|
|
||||||
- str_status_protocol_error) < 0)
|
|
||||||
- LM_ERR("closing connection\n");
|
|
||||||
+ *err_code = 1002;
|
|
||||||
+ *err_text = str_status_protocol_error;
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
mask_start = 10;
|
|
||||||
@@ -525,9 +507,8 @@ static int decode_and_validate_ws_frame(ws_frame_t *frame,
|
|
||||||
|| (buf[4] & 0xff) != 0 || (buf[5] & 0xff) != 0)
|
|
||||||
{
|
|
||||||
LM_WARN("message is too long\n");
|
|
||||||
- if (close_connection(&frame->wsc, LOCAL_CLOSE, 1009,
|
|
||||||
- str_status_message_too_big) < 0)
|
|
||||||
- LM_ERR("closing connection\n");
|
|
||||||
+ *err_code = 1009;
|
|
||||||
+ *err_text = str_status_message_too_big;
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
|
|
||||||
@@ -553,9 +534,8 @@ static int decode_and_validate_ws_frame(ws_frame_t *frame,
|
|
||||||
{
|
|
||||||
LM_WARN("message not complete frame size %u but received %u\n",
|
|
||||||
frame->payload_len + mask_start + 4, len);
|
|
||||||
- if (close_connection(&frame->wsc, LOCAL_CLOSE, 1002,
|
|
||||||
- str_status_protocol_error) < 0)
|
|
||||||
- LM_ERR("closing connection\n");
|
|
||||||
+ *err_code = 1002;
|
|
||||||
+ *err_text = str_status_protocol_error;
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
frame->payload_data = &buf[mask_start + 4];
|
|
||||||
@@ -632,6 +612,11 @@ int ws_frame_receive(void *data)
|
|
||||||
ws_frame_t frame;
|
|
||||||
tcp_event_info_t *tcpinfo = (tcp_event_info_t *) data;
|
|
||||||
|
|
||||||
+ int opcode = -1;
|
|
||||||
+ int ret = 0;
|
|
||||||
+ short err_code = 0;
|
|
||||||
+ str err_text = {NULL, 0};
|
|
||||||
+
|
|
||||||
update_stat(ws_received_frames, 1);
|
|
||||||
|
|
||||||
if (tcpinfo == NULL || tcpinfo->buf == NULL || tcpinfo->len <= 0)
|
|
||||||
@@ -640,7 +625,26 @@ int ws_frame_receive(void *data)
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
|
|
||||||
- switch(decode_and_validate_ws_frame(&frame, tcpinfo))
|
|
||||||
+ /* wsc refcnt++ */
|
|
||||||
+ frame.wsc = wsconn_get(tcpinfo->con->id);
|
|
||||||
+ if (frame.wsc == NULL)
|
|
||||||
+ {
|
|
||||||
+ LM_ERR("WebSocket connection not found\n");
|
|
||||||
+ return -1;
|
|
||||||
+ }
|
|
||||||
+
|
|
||||||
+ opcode = decode_and_validate_ws_frame(&frame, tcpinfo, &err_code, &err_text);
|
|
||||||
+ if (opcode < 0)
|
|
||||||
+ {
|
|
||||||
+ if (close_connection(&frame.wsc, LOCAL_CLOSE, err_code, err_text) < 0)
|
|
||||||
+ LM_ERR("closing connection\n");
|
|
||||||
+
|
|
||||||
+ wsconn_put(frame.wsc);
|
|
||||||
+
|
|
||||||
+ return -1;
|
|
||||||
+ }
|
|
||||||
+
|
|
||||||
+ switch(opcode)
|
|
||||||
{
|
|
||||||
case OPCODE_TEXT_FRAME:
|
|
||||||
case OPCODE_BINARY_FRAME:
|
|
||||||
@@ -649,6 +653,9 @@ int ws_frame_receive(void *data)
|
|
||||||
LM_DBG("Rx SIP message:\n%.*s\n", frame.payload_len,
|
|
||||||
frame.payload_data);
|
|
||||||
update_stat(ws_sip_received_frames, 1);
|
|
||||||
+
|
|
||||||
+ wsconn_put(frame.wsc);
|
|
||||||
+
|
|
||||||
return receive_msg(frame.payload_data,
|
|
||||||
frame.payload_len,
|
|
||||||
tcpinfo->rcv);
|
|
||||||
@@ -667,30 +674,46 @@ int ws_frame_receive(void *data)
|
|
||||||
tev.len = frame.payload_len;
|
|
||||||
tev.rcv = tcpinfo->rcv;
|
|
||||||
tev.con = tcpinfo->con;
|
|
||||||
+
|
|
||||||
+ wsconn_put(frame.wsc);
|
|
||||||
+
|
|
||||||
return sr_event_exec(SREV_TCP_MSRP_FRAME,
|
|
||||||
(void *) &tev);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
- LM_ERR("no callback registerd for MSRP\n");
|
|
||||||
+ LM_ERR("no callback registered for MSRP\n");
|
|
||||||
+
|
|
||||||
+ wsconn_put(frame.wsc);
|
|
||||||
+
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
case OPCODE_CLOSE:
|
|
||||||
- return handle_close(&frame);
|
|
||||||
+ ret = handle_close(&frame);
|
|
||||||
+ if (frame.wsc) wsconn_put(frame.wsc);
|
|
||||||
+ return ret;
|
|
||||||
|
|
||||||
case OPCODE_PING:
|
|
||||||
- return handle_ping(&frame);
|
|
||||||
+ ret = handle_ping(&frame);
|
|
||||||
+ if (frame.wsc) wsconn_put(frame.wsc);
|
|
||||||
+ return ret;
|
|
||||||
|
|
||||||
case OPCODE_PONG:
|
|
||||||
- return handle_pong(&frame);
|
|
||||||
+ ret = handle_pong(&frame);
|
|
||||||
+ if (frame.wsc) wsconn_put(frame.wsc);
|
|
||||||
+ return ret;
|
|
||||||
|
|
||||||
default:
|
|
||||||
LM_WARN("received bad frame\n");
|
|
||||||
+ wsconn_put(frame.wsc);
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
|
|
||||||
+ /* how can we get here ? */
|
|
||||||
+ wsconn_put(frame.wsc);
|
|
||||||
+
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
@@ -715,9 +738,14 @@ int ws_frame_transmit(void *data)
|
|
||||||
if (encode_and_send_ws_frame(&frame, CONN_CLOSE_DONT) < 0)
|
|
||||||
{
|
|
||||||
LM_ERR("sending message\n");
|
|
||||||
+
|
|
||||||
+ wsconn_put(frame.wsc);
|
|
||||||
+
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
|
|
||||||
+ wsconn_put(frame.wsc);
|
|
||||||
+
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
@@ -783,8 +811,11 @@ struct mi_root *ws_mi_close(struct mi_root *cmd, void *param)
|
|
||||||
str_status_bad_param.len);
|
|
||||||
}
|
|
||||||
|
|
||||||
- if (close_connection(&wsc, LOCAL_CLOSE, 1000,
|
|
||||||
- str_status_normal_closure) < 0)
|
|
||||||
+ int ret = close_connection(&wsc, LOCAL_CLOSE, 1000, str_status_normal_closure);
|
|
||||||
+
|
|
||||||
+ wsconn_put(wsc);
|
|
||||||
+
|
|
||||||
+ if (ret < 0)
|
|
||||||
{
|
|
||||||
LM_WARN("closing connection\n");
|
|
||||||
return init_mi_tree(500, str_status_error_closing.s,
|
|
||||||
@@ -834,7 +865,11 @@ static struct mi_root *mi_ping_pong(struct mi_root *cmd, void *param,
|
|
||||||
str_status_bad_param.len);
|
|
||||||
}
|
|
||||||
|
|
||||||
- if (ping_pong(wsc, opcode) < 0)
|
|
||||||
+ int ret = ping_pong(wsc, opcode);
|
|
||||||
+
|
|
||||||
+ wsconn_put(wsc);
|
|
||||||
+
|
|
||||||
+ if (ret < 0)
|
|
||||||
{
|
|
||||||
LM_WARN("sending %s\n", OPCODE_PING ? "Ping" : "Pong");
|
|
||||||
return init_mi_tree(500, str_status_error_sending.s,
|
|
||||||
@@ -858,36 +893,55 @@ void ws_keepalive(unsigned int ticks, void *param)
|
|
||||||
{
|
|
||||||
int check_time = (int) time(NULL)
|
|
||||||
- cfg_get(websocket, ws_cfg, keepalive_timeout);
|
|
||||||
- ws_connection_t *wsc = wsconn_used_list->head;
|
|
||||||
|
|
||||||
+ ws_connection_t **list = NULL,
|
|
||||||
+ **list_head = NULL;
|
|
||||||
+ ws_connection_t *wsc = NULL;
|
|
||||||
+
|
|
||||||
+ /* get an array of pointer to all ws connection */
|
|
||||||
+ list_head = wsconn_get_list();
|
|
||||||
+ if (!list_head)
|
|
||||||
+ return;
|
|
||||||
+
|
|
||||||
+ list = list_head;
|
|
||||||
+ wsc = *list_head;
|
|
||||||
while (wsc && wsc->last_used < check_time)
|
|
||||||
{
|
|
||||||
- if (wsc->state == WS_S_CLOSING
|
|
||||||
- || wsc->awaiting_pong)
|
|
||||||
+ if (wsc->state == WS_S_CLOSING || wsc->awaiting_pong)
|
|
||||||
{
|
|
||||||
LM_WARN("forcibly closing connection\n");
|
|
||||||
wsconn_close_now(wsc);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
- ping_pong(wsconn_used_list->head,
|
|
||||||
- ws_keepalive_mechanism == KEEPALIVE_MECHANISM_PING
|
|
||||||
- ? OPCODE_PING : OPCODE_PONG);
|
|
||||||
- wsc = wsconn_used_list->head;
|
|
||||||
+ {
|
|
||||||
+ int opcode = (ws_keepalive_mechanism == KEEPALIVE_MECHANISM_PING)
|
|
||||||
+ ? OPCODE_PING
|
|
||||||
+ : OPCODE_PONG;
|
|
||||||
+ ping_pong(wsc, opcode);
|
|
||||||
+ }
|
|
||||||
+
|
|
||||||
+ wsc = *(++list);
|
|
||||||
}
|
|
||||||
-
|
|
||||||
+
|
|
||||||
+ wsconn_put_list(list_head);
|
|
||||||
}
|
|
||||||
|
|
||||||
int ws_close(sip_msg_t *msg)
|
|
||||||
{
|
|
||||||
ws_connection_t *wsc;
|
|
||||||
+ int ret;
|
|
||||||
|
|
||||||
if ((wsc = wsconn_get(msg->rcv.proto_reserved1)) == NULL) {
|
|
||||||
LM_ERR("failed to retrieve WebSocket connection\n");
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
|
|
||||||
- return (close_connection(&wsc, LOCAL_CLOSE, 1000,
|
|
||||||
+ ret = (close_connection(&wsc, LOCAL_CLOSE, 1000,
|
|
||||||
str_status_normal_closure) == 0) ? 1: 0;
|
|
||||||
+
|
|
||||||
+ wsconn_put(wsc);
|
|
||||||
+
|
|
||||||
+ return ret;
|
|
||||||
}
|
|
||||||
|
|
||||||
int ws_close2(sip_msg_t *msg, char *_status, char *_reason)
|
|
||||||
@@ -895,6 +949,7 @@ int ws_close2(sip_msg_t *msg, char *_status, char *_reason)
|
|
||||||
int status;
|
|
||||||
str reason;
|
|
||||||
ws_connection_t *wsc;
|
|
||||||
+ int ret;
|
|
||||||
|
|
||||||
if (get_int_fparam(&status, msg, (fparam_t *) _status) < 0) {
|
|
||||||
LM_ERR("failed to get status code\n");
|
|
||||||
@@ -911,7 +966,11 @@ int ws_close2(sip_msg_t *msg, char *_status, char *_reason)
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
|
|
||||||
- return (close_connection(&wsc, LOCAL_CLOSE, status, reason) == 0) ? 1: 0;
|
|
||||||
+ ret = (close_connection(&wsc, LOCAL_CLOSE, status, reason) == 0) ? 1: 0;
|
|
||||||
+
|
|
||||||
+ wsconn_put(wsc);
|
|
||||||
+
|
|
||||||
+ return ret;
|
|
||||||
}
|
|
||||||
|
|
||||||
int ws_close3(sip_msg_t *msg, char *_status, char *_reason, char *_con)
|
|
||||||
@@ -920,6 +979,7 @@ int ws_close3(sip_msg_t *msg, char *_status, char *_reason, char *_con)
|
|
||||||
str reason;
|
|
||||||
int con;
|
|
||||||
ws_connection_t *wsc;
|
|
||||||
+ int ret;
|
|
||||||
|
|
||||||
if (get_int_fparam(&status, msg, (fparam_t *) _status) < 0) {
|
|
||||||
LM_ERR("failed to get status code\n");
|
|
||||||
@@ -941,5 +1001,9 @@ int ws_close3(sip_msg_t *msg, char *_status, char *_reason, char *_con)
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
|
|
||||||
- return (close_connection(&wsc, LOCAL_CLOSE, status, reason) == 0) ? 1: 0;
|
|
||||||
+ ret = (close_connection(&wsc, LOCAL_CLOSE, status, reason) == 0) ? 1: 0;
|
|
||||||
+
|
|
||||||
+ wsconn_put(wsc);
|
|
||||||
+
|
|
||||||
+ return ret;
|
|
||||||
}
|
|
||||||
diff --git a/modules/websocket/ws_handshake.c b/modules/websocket/ws_handshake.c
|
|
||||||
index 05332e4..e89fda1 100644
|
|
||||||
--- a/modules/websocket/ws_handshake.c
|
|
||||||
+++ b/modules/websocket/ws_handshake.c
|
|
||||||
@@ -427,8 +427,10 @@ int ws_handle_handshake(struct sip_msg *msg)
|
|
||||||
&headers) < 0)
|
|
||||||
{
|
|
||||||
if ((wsc = wsconn_get(msg->rcv.proto_reserved1)) != NULL)
|
|
||||||
+ {
|
|
||||||
wsconn_rm(wsc, WSCONN_EVENTROUTE_NO);
|
|
||||||
-
|
|
||||||
+ wsconn_put(wsc);
|
|
||||||
+ }
|
|
||||||
goto end;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
--
|
|
||||||
2.0.0.rc0
|
|
||||||
|
|
||||||
@ -1,58 +0,0 @@
|
|||||||
From 402e2122d1aa353ee8c10321aa1eb9315a81cd81 Mon Sep 17 00:00:00 2001
|
|
||||||
From: Daniel-Constantin Mierla <miconda@gmail.com>
|
|
||||||
Date: Wed, 16 Apr 2014 19:43:45 +0200
|
|
||||||
Subject: [PATCH] db_mysql: properly free db result structure if
|
|
||||||
db_mysql_convert_result() fails
|
|
||||||
|
|
||||||
- reported by Torrey Searle, FS#420
|
|
||||||
|
|
||||||
(cherry picked from commit 37983c9f57536c57c5d34ce2d8a1c8f411e61e39)
|
|
||||||
---
|
|
||||||
modules/db_mysql/km_dbase.c | 8 ++++----
|
|
||||||
modules/db_mysql/km_res.c | 2 ++
|
|
||||||
2 files changed, 6 insertions(+), 4 deletions(-)
|
|
||||||
|
|
||||||
diff --git a/modules/db_mysql/km_dbase.c b/modules/db_mysql/km_dbase.c
|
|
||||||
index f644dea..a1e7ac7 100644
|
|
||||||
--- a/modules/db_mysql/km_dbase.c
|
|
||||||
+++ b/modules/db_mysql/km_dbase.c
|
|
||||||
@@ -190,12 +190,12 @@ static int db_mysql_store_result(const db1_con_t* _h, db1_res_t** _r)
|
|
||||||
if (db_mysql_convert_result(_h, *_r) < 0) {
|
|
||||||
LM_ERR("error while converting result\n");
|
|
||||||
LM_DBG("freeing result set at %p\n", _r);
|
|
||||||
- pkg_free(*_r);
|
|
||||||
- *_r = 0;
|
|
||||||
/* all mem on Kamailio API side is already freed by
|
|
||||||
* db_mysql_convert_result in case of error, but we also need
|
|
||||||
- * to free the mem from the mysql lib side */
|
|
||||||
- mysql_free_result(RES_RESULT(*_r));
|
|
||||||
+ * to free the mem from the mysql lib side, internal pkg for it
|
|
||||||
+ * and *_r */
|
|
||||||
+ db_mysql_free_result(_h, *_r);
|
|
||||||
+ *_r = 0;
|
|
||||||
#if (MYSQL_VERSION_ID >= 40100)
|
|
||||||
while( mysql_more_results(CON_CONNECTION(_h)) && mysql_next_result(CON_CONNECTION(_h)) > 0 ) {
|
|
||||||
MYSQL_RES *res = mysql_store_result( CON_CONNECTION(_h) );
|
|
||||||
diff --git a/modules/db_mysql/km_res.c b/modules/db_mysql/km_res.c
|
|
||||||
index 965e6dc..3f1ca26 100644
|
|
||||||
--- a/modules/db_mysql/km_res.c
|
|
||||||
+++ b/modules/db_mysql/km_res.c
|
|
||||||
@@ -69,6 +69,7 @@ int db_mysql_get_columns(const db1_con_t* _h, db1_res_t* _r)
|
|
||||||
}
|
|
||||||
|
|
||||||
if (db_allocate_columns(_r, RES_COL_N(_r)) != 0) {
|
|
||||||
+ RES_COL_N(_r) = 0;
|
|
||||||
LM_ERR("could not allocate columns\n");
|
|
||||||
return -3;
|
|
||||||
}
|
|
||||||
@@ -173,6 +174,7 @@ static inline int db_mysql_convert_rows(const db1_con_t* _h, db1_res_t* _r)
|
|
||||||
|
|
||||||
if (db_allocate_rows(_r) < 0) {
|
|
||||||
LM_ERR("could not allocate rows");
|
|
||||||
+ RES_ROW_N(_r) = 0;
|
|
||||||
return -2;
|
|
||||||
}
|
|
||||||
|
|
||||||
--
|
|
||||||
2.0.0.rc0
|
|
||||||
|
|
||||||
@ -1,30 +0,0 @@
|
|||||||
From 9c15e8444e99f33ca2f0c920d3cbb846d407f596 Mon Sep 17 00:00:00 2001
|
|
||||||
From: Daniel-Constantin Mierla <miconda@gmail.com>
|
|
||||||
Date: Wed, 14 May 2014 09:58:50 +0200
|
|
||||||
Subject: [PATCH] presence_dialoginfo: get rid of unused variables warning
|
|
||||||
|
|
||||||
- priority and winning_priority are used in an alternative winning node
|
|
||||||
selection which is disabled now
|
|
||||||
- reported by Jua Heinanen
|
|
||||||
|
|
||||||
(cherry picked from commit 4f4641ea2a4018a72558c40d4878e9af7053be2d)
|
|
||||||
---
|
|
||||||
modules/presence_dialoginfo/notify_body.c | 2 +-
|
|
||||||
1 file changed, 1 insertion(+), 1 deletion(-)
|
|
||||||
|
|
||||||
diff --git a/modules/presence_dialoginfo/notify_body.c b/modules/presence_dialoginfo/notify_body.c
|
|
||||||
index db8834b..92ece0a 100644
|
|
||||||
--- a/modules/presence_dialoginfo/notify_body.c
|
|
||||||
+++ b/modules/presence_dialoginfo/notify_body.c
|
|
||||||
@@ -101,7 +101,7 @@ str* agregate_xmls(str* pres_user, str* pres_domain, str** body_array, int n)
|
|
||||||
xmlDocPtr doc = NULL;
|
|
||||||
xmlNodePtr root_node = NULL;
|
|
||||||
xmlNsPtr namespace = NULL;
|
|
||||||
- int winner_priority = -1, priority;
|
|
||||||
+ /*int winner_priority = -1, priority;*/
|
|
||||||
|
|
||||||
xmlNodePtr p_root= NULL;
|
|
||||||
xmlDocPtr* xml_array ;
|
|
||||||
--
|
|
||||||
2.0.0.rc0
|
|
||||||
|
|
||||||
@ -1,29 +0,0 @@
|
|||||||
From f44415eee52d5c17a9b6c5e16175bd84455e9867 Mon Sep 17 00:00:00 2001
|
|
||||||
From: Daniel-Constantin Mierla <miconda@gmail.com>
|
|
||||||
Date: Thu, 15 May 2014 13:59:03 +0200
|
|
||||||
Subject: [PATCH] siputils: allocate enough space to hold ending zero for tel
|
|
||||||
uri in tel2sip()
|
|
||||||
|
|
||||||
- reported by Juha Heinanen
|
|
||||||
|
|
||||||
(cherry picked from commit 7992a2b8d42bb7e8bcf1738cf042013ed126a47a)
|
|
||||||
---
|
|
||||||
modules/siputils/checks.c | 2 +-
|
|
||||||
1 file changed, 1 insertion(+), 1 deletion(-)
|
|
||||||
|
|
||||||
diff --git a/modules/siputils/checks.c b/modules/siputils/checks.c
|
|
||||||
index a1a9344..7f50cfc 100644
|
|
||||||
--- a/modules/siputils/checks.c
|
|
||||||
+++ b/modules/siputils/checks.c
|
|
||||||
@@ -354,7 +354,7 @@ int tel2sip(struct sip_msg* _msg, char* _uri, char* _hostpart, char* _res)
|
|
||||||
if (strncasecmp(uri.s, "tel:", 4) != 0) return 1;
|
|
||||||
|
|
||||||
/* reserve memory for clean tel uri */
|
|
||||||
- tel_uri.s = pkg_malloc(uri.len);
|
|
||||||
+ tel_uri.s = pkg_malloc(uri.len+1);
|
|
||||||
if (tel_uri.s == 0) {
|
|
||||||
LM_ERR("no more pkg memory\n");
|
|
||||||
return -1;
|
|
||||||
--
|
|
||||||
2.0.0.rc0
|
|
||||||
|
|
||||||
@ -1,50 +0,0 @@
|
|||||||
From 47a00936695c46176c3c047e0ab141b4127d08dc Mon Sep 17 00:00:00 2001
|
|
||||||
From: Daniel-Constantin Mierla <miconda@gmail.com>
|
|
||||||
Date: Sun, 18 May 2014 19:07:38 +0200
|
|
||||||
Subject: [PATCH] mtree: replace tree structure even there are no records in db
|
|
||||||
table
|
|
||||||
|
|
||||||
- reload didn't replaced old tree if no records in db table
|
|
||||||
- reported by Juha Heinanen
|
|
||||||
|
|
||||||
(cherry picked from commit c36f326d3c7372b149592d438df75f3d7b0a0233)
|
|
||||||
---
|
|
||||||
modules/mtree/mtree_mod.c | 8 ++++----
|
|
||||||
1 file changed, 4 insertions(+), 4 deletions(-)
|
|
||||||
|
|
||||||
diff --git a/modules/mtree/mtree_mod.c b/modules/mtree/mtree_mod.c
|
|
||||||
index 4e32dfa..96e6479 100644
|
|
||||||
--- a/modules/mtree/mtree_mod.c
|
|
||||||
+++ b/modules/mtree/mtree_mod.c
|
|
||||||
@@ -550,8 +550,7 @@ static int mt_load_db(m_tree_t *pt)
|
|
||||||
} else {
|
|
||||||
if(RES_ROW_N(db_res)==0)
|
|
||||||
{
|
|
||||||
- mt_dbf.free_result(db_con, db_res);
|
|
||||||
- return 0;
|
|
||||||
+ goto dbreloaded;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
@@ -561,8 +560,7 @@ static int mt_load_db(m_tree_t *pt)
|
|
||||||
{
|
|
||||||
if(ret==0)
|
|
||||||
{
|
|
||||||
- mt_dbf.free_result(db_con, db_res);
|
|
||||||
- return 0;
|
|
||||||
+ goto dbreloaded;
|
|
||||||
} else {
|
|
||||||
goto error;
|
|
||||||
}
|
|
||||||
@@ -617,6 +615,8 @@ static int mt_load_db(m_tree_t *pt)
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
} while(RES_ROW_N(db_res)>0);
|
|
||||||
+
|
|
||||||
+dbreloaded:
|
|
||||||
mt_dbf.free_result(db_con, db_res);
|
|
||||||
|
|
||||||
|
|
||||||
--
|
|
||||||
2.0.0.rc0
|
|
||||||
|
|
||||||
Loading…
Reference in new issue