Просмотр исходного кода

tcpops: per-connection control over tcp:closed

for enhancement #461
Camille Oudot 9 лет назад
Родитель
Сommit
8357543007

+ 43 - 0
modules/tcpops/doc/functions.xml

@@ -211,4 +211,47 @@ request_route {
                         ]]></programlisting>
                         ]]></programlisting>
                 </example>
                 </example>
         </section>
         </section>
+
+        <section id="tcpops.f.tcp_enable_closed_event">
+                <title>
+                        <function>tcp_enable_closed_event([conid])</function>
+                </title>
+                <para>
+                                Explicitly enables the "tcp:closed" event route
+                                on a TCP connection.
+                </para>
+                <para>Meaning of the parameters is as follows:</para>
+                <itemizedlist>
+                        <listitem>
+                                <para><emphasis>conid</emphasis> (optionnal): the kamailio internal
+                                connection id. If no parameter
+                                is given, it will be enabled on the current message source connection.
+                                </para>
+                        </listitem>
+                </itemizedlist>
+                <para>Retuns 1 on success, -1 on failure.</para>
+                <example>
+                        <title><function>tcp_set_closed_event</function> usage</title>
+                        <programlisting><![CDATA[
+...
+# "tcp:closed" event route is globally disabled
+modparam("tcpops", "closed_event", 0)
+...
+
+request_route {
+	...
+	if (is_method("REGISTER") && pv_www_authenticate("$td", "xxx", "0")) {
+		# but it will be enabled on this specific connection
+		tcp_enable_closed_event();
+	}
+	...
+
+}
+
+event_route[tcp:closed] {
+	xlog("connection $conid was closed");
+}
+]]></programlisting>
+                </example>
+        </section>
 </section>
 </section>

+ 21 - 0
modules/tcpops/doc/params.xml

@@ -7,6 +7,27 @@
     </sectioninfo>
     </sectioninfo>
 
 
     <title>Parameters</title>
     <title>Parameters</title>
+		<section>
+		<title><varname>closed_event</varname> (int)</title>
+		<para>
+			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).
+		</para>
+		<para>
+		<emphasis>
+			Default value is 1 (enabled).
+		</emphasis>
+		</para>
+		<example>
+		<title>Set <varname>closed_event</varname> parameter</title>
+		<programlisting format="linespecific">
+...
+modparam("tcpops", "closed_event", 0)
+...
+</programlisting>
+		</example>
+	</section>
 
 
 
 
 
 

+ 9 - 0
modules/tcpops/tcpops.c

@@ -34,6 +34,9 @@
 #include "../../fmsg.h"
 #include "../../fmsg.h"
 #include "../../sr_module.h"
 #include "../../sr_module.h"
 
 
+
+int tcp_closed_event = 1;
+
 /**
 /**
  * gets the fd of the current message source connection
  * gets the fd of the current message source connection
  *
  *
@@ -193,6 +196,12 @@ static void tcpops_tcp_closed_run_route(struct tcp_connection *con)
 	int rt, backup_rt;
 	int rt, backup_rt;
 	struct run_act_ctx ctx;
 	struct run_act_ctx ctx;
 	sip_msg_t *fmsg;
 	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");
 	LM_DBG("tcp_closed_run_route event_route[tcp:closed]\n");
 
 
 	rt = route_get(&event_rt, "tcp:closed");
 	rt = route_get(&event_rt, "tcp:closed");

+ 2 - 0
modules/tcpops/tcpops.h

@@ -27,6 +27,8 @@
 #include "../../tcp_conn.h"
 #include "../../tcp_conn.h"
 #include "../../events.h"
 #include "../../events.h"
 
 
+extern int tcp_closed_event;
+
 int tcpops_get_current_fd(int conid, int *fd);
 int tcpops_get_current_fd(int conid, int *fd);
 int tcpops_acquire_fd_from_tcpmain(int conid, int *fd);
 int tcpops_acquire_fd_from_tcpmain(int conid, int *fd);
 int tcpops_keepalive_enable(int fd, int idle, int count, int interval, int closefd);
 int tcpops_keepalive_enable(int fd, int idle, int count, int interval, int closefd);

+ 48 - 1
modules/tcpops/tcpops_mod.c

@@ -50,6 +50,8 @@ static int w_tcp_keepalive_disable1(sip_msg_t* msg, char* con);
 static int w_tcp_keepalive_disable0(sip_msg_t* msg);
 static int w_tcp_keepalive_disable0(sip_msg_t* msg);
 static int w_tcpops_set_connection_lifetime2(sip_msg_t* msg, char* con, char* time);
 static int w_tcpops_set_connection_lifetime2(sip_msg_t* msg, char* con, char* time);
 static int w_tcpops_set_connection_lifetime1(sip_msg_t* msg, char* time);
 static int w_tcpops_set_connection_lifetime1(sip_msg_t* msg, char* time);
+static int w_tcpops_enable_closed_event1(sip_msg_t* msg, char* con, char* foo);
+static int w_tcpops_enable_closed_event0(sip_msg_t* msg, char* foo);
 static int w_tcp_conid_state(sip_msg_t* msg, char* con, char *p2);
 static int w_tcp_conid_state(sip_msg_t* msg, char* con, char *p2);
 static int w_tcp_conid_alive(sip_msg_t* msg, char* con, char *p2);
 static int w_tcp_conid_alive(sip_msg_t* msg, char* con, char *p2);
 
 
@@ -69,6 +71,10 @@ static cmd_export_t cmds[]={
 		0, ANY_ROUTE},
 		0, ANY_ROUTE},
 	{"tcp_set_connection_lifetime", (cmd_function)w_tcpops_set_connection_lifetime1, 1, fixup_numpv,
 	{"tcp_set_connection_lifetime", (cmd_function)w_tcpops_set_connection_lifetime1, 1, fixup_numpv,
 		0, REQUEST_ROUTE|ONREPLY_ROUTE},
 		0, REQUEST_ROUTE|ONREPLY_ROUTE},
+	{"tcp_enable_closed_event", (cmd_function)w_tcpops_enable_closed_event1, 1, fixup_numpv,
+		0, ANY_ROUTE},
+	{"tcp_enable_closed_event", (cmd_function)w_tcpops_enable_closed_event0, 0, 0,
+		0, REQUEST_ROUTE|ONREPLY_ROUTE},
 	{"tcp_conid_state", (cmd_function)w_tcp_conid_state, 1, fixup_numpv,
 	{"tcp_conid_state", (cmd_function)w_tcp_conid_state, 1, fixup_numpv,
 		0, ANY_ROUTE},
 		0, ANY_ROUTE},
 	{"tcp_conid_alive", (cmd_function)w_tcp_conid_alive, 1, fixup_numpv,
 	{"tcp_conid_alive", (cmd_function)w_tcp_conid_alive, 1, fixup_numpv,
@@ -76,13 +82,18 @@ static cmd_export_t cmds[]={
 	{0, 0, 0, 0, 0, 0}
 	{0, 0, 0, 0, 0, 0}
 };
 };
 
 
+static param_export_t params[] = {
+	{"closed_event",    PARAM_INT,    &tcp_closed_event},
+	{0, 0, 0}
+};
+
 
 
 
 
 struct module_exports exports = {
 struct module_exports exports = {
 	"tcpops",
 	"tcpops",
 	DEFAULT_DLFLAGS, /* dlopen flags */
 	DEFAULT_DLFLAGS, /* dlopen flags */
 	cmds,            /* exported functions to config */
 	cmds,            /* exported functions to config */
-	0,          /* exported parameters to config */
+	params,          /* exported parameters to config */
 	0,               /* exported statistics */
 	0,               /* exported statistics */
 	0,              /* exported MI functions */
 	0,              /* exported MI functions */
 	0,        /* exported pseudo-variables */
 	0,        /* exported pseudo-variables */
@@ -334,6 +345,42 @@ static int w_tcpops_set_connection_lifetime1(sip_msg_t* msg, char* time)
 	return ret;
 	return ret;
 }
 }
 
 
+static int w_tcpops_enable_closed_event1(sip_msg_t* msg, char* conid, char* foo)
+{
+	struct tcp_connection *s_con;
+
+	_IVALUE (conid)
+
+	if (unlikely((s_con = tcpconn_get(i_conid, 0, 0, 0, 0)) == NULL)) {
+		LM_ERR("invalid connection id %d, (must be a TCP conid)\n", i_conid);
+		return 0;
+	} else {
+		s_con->flags |= F_CONN_CLOSE_EV;
+		tcpconn_put(s_con);
+	}
+	return 1;
+}
+
+
+static int w_tcpops_enable_closed_event0(sip_msg_t* msg, char* foo)
+{
+	struct tcp_connection *s_con;
+
+	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");
+		return -1;
+	}
+
+	if (unlikely((s_con = tcpconn_get(msg->rcv.proto_reserved1, 0, 0, 0, 0)) == NULL)) {
+		return -1;
+	} else {
+		s_con->flags |= F_CONN_CLOSE_EV;
+		tcpconn_put(s_con);
+	}
+	return 1;
+}
+
 /**
 /**
  *
  *
  */
  */