diff --git a/modules/tcpops/doc/functions.xml b/modules/tcpops/doc/functions.xml
index 2bdd261d787..1051b2ae6b1 100644
--- a/modules/tcpops/doc/functions.xml
+++ b/modules/tcpops/doc/functions.xml
@@ -234,14 +234,14 @@ request_route {
tcp_set_closed_event usage
closed_event (int)
- if set to 0, the "tcp:closed" event route will not be called on TCP
- disconnections (unless the "tcp_enable_closed_event()" function enabled
- it explicitly).
+ If set to 0 (gloabbly disabled), the "tcp:closed" event route will never be called on TCP
+ disconnections.
+
+
+ If set to 1 (globally enabled), the "tcp:closed" event route will always be called on TCP
+ disconnections.
+
+
+ If set to 2 ("manual" mode), the "tcp:closed" event route will only be called on TCP
+ connections for which tcp_enable_closed_event() has
+ been applied, when a disconnection occurs.
- Default value is 1 (enabled).
+ Default value is 1 (globally enabled).
diff --git a/modules/tcpops/tcpops.c b/modules/tcpops/tcpops.c
index 7850beca12a..624e8877d41 100644
--- a/modules/tcpops/tcpops.c
+++ b/modules/tcpops/tcpops.c
@@ -35,6 +35,7 @@
#include "../../sr_module.h"
+/* globally enabled by default */
int tcp_closed_event = 1;
/**
@@ -197,11 +198,6 @@ static void tcpops_tcp_closed_run_route(struct tcp_connection *con)
struct run_act_ctx ctx;
sip_msg_t *fmsg;
- /* bypass event route if tcp_closed_event == 0 and the
- * F_CONN_CLOSE_EV flag is not explicitly set */
- if (!(tcp_closed_event || (con->flags & F_CONN_CLOSE_EV)))
- return;
-
LM_DBG("tcp_closed_run_route event_route[tcp:closed]\n");
rt = route_get(&event_rt, "tcp:closed");
@@ -235,7 +231,10 @@ int tcpops_handle_tcp_closed(void *data)
return -1;
}
- tcpops_tcp_closed_run_route(tev->con);
+ /* run event route if tcp_closed_event == 1 or if the
+ * F_CONN_CLOSE_EV flag is explicitly set */
+ if (tcp_closed_event == 1 || (tev->con->flags & F_CONN_CLOSE_EV))
+ tcpops_tcp_closed_run_route(tev->con);
return 0;
}
diff --git a/modules/tcpops/tcpops_mod.c b/modules/tcpops/tcpops_mod.c
index ede05cfe04d..60c7b88db8d 100644
--- a/modules/tcpops/tcpops_mod.c
+++ b/modules/tcpops/tcpops_mod.c
@@ -113,7 +113,14 @@ static int mod_init(void)
{
LM_DBG("TCP keepalive module loaded.\n");
- if (sr_event_register_cb(SREV_TCP_CLOSED, tcpops_handle_tcp_closed) != 0) {
+ if (tcp_closed_event < 0 || tcp_closed_event > 2) {
+ LM_ERR("invalid \"closed_event\" value: %d, must be 0 (disabled), 1 (enabled) or 2 (manual)\n", tcp_closed_event);
+ return -1;
+ }
+
+ if (tcp_closed_event /* register event only if tcp_closed_event != 0 */
+ && (sr_event_register_cb(SREV_TCP_CLOSED, tcpops_handle_tcp_closed) != 0))
+ {
LM_ERR("problem registering tcpops_handle_tcp_closed call-back\n");
return -1;
}
@@ -366,6 +373,12 @@ static int w_tcpops_enable_closed_event0(sip_msg_t* msg, char* foo)
{
struct tcp_connection *s_con;
+ if (unlikely(tcp_closed_event != 2)) {
+ LM_WARN("tcp_enable_closed_event() can only be used if"
+ " the \"closed_event\" modparam is set to 2\n");
+ return -1;
+ }
+
if(unlikely(msg->rcv.proto != PROTO_TCP && msg->rcv.proto != PROTO_TLS && msg->rcv.proto != PROTO_WS && msg->rcv.proto != PROTO_WSS))
{
LM_ERR("the current message does not come from a TCP connection\n");