From 09c5e6069aaeed472d1d4e4088d14551d90f90a9 Mon Sep 17 00:00:00 2001 From: "Olle E. Johansson" Date: Thu, 1 Oct 2015 22:05:53 +0300 Subject: [PATCH] tcpops Add tcp_conid_state function to check connection state --- modules/tcpops/README | 84 ++++++++++++++++++++++++-------- modules/tcpops/doc/functions.xml | 35 +++++++++++++ modules/tcpops/doc/tcpops.xml | 14 +++++- modules/tcpops/tcpops_mod.c | 44 ++++++++++++++++- 4 files changed, 154 insertions(+), 23 deletions(-) diff --git a/modules/tcpops/README b/modules/tcpops/README index d05b80008fa..9fdf43399e9 100644 --- a/modules/tcpops/README +++ b/modules/tcpops/README @@ -4,7 +4,13 @@ Camille Oudot Orange - Copyright © 2015 Orange +Olle E. Johansson + + Edvina AB + + Copyright © 2015 Orange + + Copyright © 2015 Edvina AB, Sollentuna, Sweden __________________________________________________________________ Table of Contents @@ -15,15 +21,17 @@ Camille Oudot 2. Parameters 3. Functions - 3.1. tcp_keepalive_enable([conid], idle, count, interval) - 3.2. tcp_keepalive_disable([conid]) - 3.3. tcp_set_connection_lifetime([conid], lifetime) + 3.1. tcp_conid_state(conid) + 3.2. tcp_keepalive_enable([conid], idle, count, interval) + 3.3. tcp_keepalive_disable([conid]) + 3.4. tcp_set_connection_lifetime([conid], lifetime) List of Examples - 1.1. tcp_keepalive_enable usage - 1.2. tcp_keepalive_disable usage - 1.3. tcp_set_connection_lifetime usage + 1.1. tcp_conid_state usage + 1.2. tcp_keepalive_enable usage + 1.3. tcp_keepalive_disable usage + 1.4. tcp_set_connection_lifetime usage Chapter 1. Admin Guide @@ -33,14 +41,16 @@ Chapter 1. Admin Guide 2. Parameters 3. Functions - 3.1. tcp_keepalive_enable([conid], idle, count, interval) - 3.2. tcp_keepalive_disable([conid]) - 3.3. tcp_set_connection_lifetime([conid], lifetime) + 3.1. tcp_conid_state(conid) + 3.2. tcp_keepalive_enable([conid], idle, count, interval) + 3.3. tcp_keepalive_disable([conid]) + 3.4. tcp_set_connection_lifetime([conid], lifetime) 1. Overview - This modules allows kamailio to control the TCP options (such as the - keepalive mechanism), on demand, and on a per-socket basis. + This modules allows Kamailio to control the TCP connection options + (such as the keepalive mechanism), on demand, and on a per-socket + basis. Note: the keepalive functions only work on systems with the HAVE_TCP_KEEPIDLE, HAVE_TCP_KEEPCNT and HAVE_TCP_KEEPINTVL macros @@ -50,11 +60,43 @@ Chapter 1. Admin Guide 3. Functions - 3.1. tcp_keepalive_enable([conid], idle, count, interval) - 3.2. tcp_keepalive_disable([conid]) - 3.3. tcp_set_connection_lifetime([conid], lifetime) + 3.1. tcp_conid_state(conid) + 3.2. tcp_keepalive_enable([conid], idle, count, interval) + 3.3. tcp_keepalive_disable([conid]) + 3.4. tcp_set_connection_lifetime([conid], lifetime) + +3.1. tcp_conid_state(conid) + + Check the state of a TCP or WS connection ID + + Meaning of the parameters is as follows: + * conid (optionnal): the Kamailio internal connection id (as in the + $conid pseudovariable). + + Retuns values: + + 1: Connection is OK + + 2: Socket is accepting incoming connections + + 3: Socket is setting up outgoing connection + + -1: Connection does not exist (or was closed) + + -2: Socket has reached EOF + + -3: Socket error has occured. Connection will likely close. + + -4: Socket is in unknow bad state. Connection will likely close. + + Example 1.1. tcp_conid_state usage +... + if(!tcp_conid_state($var(conid))) { + xlog("L_ERR", "Connection $conid is closed or malfunctional\n"); + } +... -3.1. tcp_keepalive_enable([conid], idle, count, interval) +3.2. tcp_keepalive_enable([conid], idle, count, interval) Enables keepalive on a TCP connection. @@ -70,7 +112,7 @@ Chapter 1. Admin Guide Retuns 1 on success, -1 on failure. - Example 1.1. tcp_keepalive_enable usage + Example 1.2. tcp_keepalive_enable usage request_route { if (is_method("INVITE")) { $avp(caller_conid) = $conid; @@ -89,7 +131,7 @@ onreply_route[foo] { ... } -3.2. tcp_keepalive_disable([conid]) +3.3. tcp_keepalive_disable([conid]) Disables keepalive on a TCP connection. @@ -101,7 +143,7 @@ onreply_route[foo] { Retuns 1 on success, -1 on failure. - Example 1.2. tcp_keepalive_disable usage + Example 1.3. tcp_keepalive_disable usage request_route { ... if (is_method("BYE")) { @@ -120,7 +162,7 @@ onreply_route[foo] { ... } -3.3. tcp_set_connection_lifetime([conid], lifetime) +3.4. tcp_set_connection_lifetime([conid], lifetime) Sets the connection lifetime of a connection (TCP). @@ -132,7 +174,7 @@ onreply_route[foo] { Retuns 1 on success, -1 on failure. - Example 1.3. tcp_set_connection_lifetime usage + Example 1.4. tcp_set_connection_lifetime usage ... # use 10s as default lifetime tcp_connection_lifetime=10 diff --git a/modules/tcpops/doc/functions.xml b/modules/tcpops/doc/functions.xml index 16f1b869a53..7053e385e21 100644 --- a/modules/tcpops/doc/functions.xml +++ b/modules/tcpops/doc/functions.xml @@ -8,6 +8,41 @@ Functions +
+ + <function>tcp_conid_state(conid)</function> + + + Check the state of a TCP or WS connection ID + + Meaning of the parameters is as follows: + + + conid (optionnal): the Kamailio internal + connection id (as in the $conid pseudovariable). + + + + Retuns values: + 1: Connection is OK + 2: Socket is accepting incoming connections + 3: Socket is setting up outgoing connection + -1: Connection does not exist (or was closed) + -2: Socket has reached EOF + -3: Socket error has occured. Connection will likely close. + -4: Socket is in unknow bad state. Connection will likely close. + + <function>tcp_conid_state</function> usage + + +
+
<function>tcp_keepalive_enable([conid], idle, count, interval)</function> diff --git a/modules/tcpops/doc/tcpops.xml b/modules/tcpops/doc/tcpops.xml index 1c3a30542f5..f142b7d5396 100644 --- a/modules/tcpops/doc/tcpops.xml +++ b/modules/tcpops/doc/tcpops.xml @@ -14,11 +14,23 @@ <email>camille.oudot@orange.com</email> </address> </author> + <author> + <firstname>Olle E.</firstname> + <surname>Johansson</surname> + <affiliation><orgname>Edvina AB</orgname></affiliation> + <address> + <email>oej@edvina.net</email> + </address> + </author> </authorgroup> <copyright> <year>2015</year> <holder>Orange</holder> </copyright> + <copyright> + <year>2015</year> + <holder>Edvina AB, Sollentuna, Sweden</holder> + </copyright> </bookinfo> <toc></toc> @@ -27,7 +39,7 @@ <section id="tcpops.overview"> <title>Overview - This modules allows kamailio to control the TCP options (such as the keepalive + This modules allows Kamailio to control the TCP connection options (such as the keepalive mechanism), on demand, and on a per-socket basis. diff --git a/modules/tcpops/tcpops_mod.c b/modules/tcpops/tcpops_mod.c index fb565dece78..c088d1a5452 100644 --- a/modules/tcpops/tcpops_mod.c +++ b/modules/tcpops/tcpops_mod.c @@ -2,6 +2,9 @@ * Copyright 2015 (C) Orange * * + * Copyright 2015 (C) Edvina AB + * + * * This file is part of Kamailio, a free SIP server. * * This file is free software; you can redistribute it and/or modify @@ -46,6 +49,7 @@ 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_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_tcp_is_conid_alive(sip_msg_t* msg, char* con); static int fixup_numpv(void** param, int param_no); @@ -63,6 +67,8 @@ static cmd_export_t cmds[]={ 0, ANY_ROUTE}, {"tcp_set_connection_lifetime", (cmd_function)w_tcpops_set_connection_lifetime1, 1, fixup_numpv, 0, REQUEST_ROUTE|ONREPLY_ROUTE}, + {"tcp_conid_state", (cmd_function)w_tcp_conid_state, 1, fixup_numpv, + 0, ANY_ROUTE}, {0, 0, 0, 0, 0, 0} }; @@ -216,6 +222,42 @@ static int w_tcp_keepalive_disable0(sip_msg_t* msg) return tcpops_keepalive_disable(fd, 0); } +static int w_tcp_conid_state(sip_msg_t* msg, char* conid) +{ + struct tcp_connection *s_con; + int ret = -1; + + _IVALUE (conid) + + if (unlikely((s_con = tcpconn_get(i_conid, 0, 0, 0, 0)) == NULL)) { + LM_DBG("Connection id %d does not exist.\n", i_conid); + return -1; + } + /* Connection structure exists, now check what Kamailio thinks of it */ + if (s_con->state == S_CONN_OK) { + /* All is fine, return happily */ + return 1; + } + if (s_con->state == S_CONN_EOF) { /* Socket closed or about to close under our feet */ + return -2; + } + if (s_con->state == S_CONN_ERROR) { /* Error on read/write - will close soon */ + return -3; + } + if (s_con->state == S_CONN_BAD) { /* Unknown state */ + return -4; + } + if (s_con->state == S_CONN_ACCEPT) { /* Incoming connection to be set up */ + return 2; + } + if (s_con->state == S_CONN_CONNECT) { /* Outbound connection moving to S_CONN_OK */ + return 3; + } + /* Wonder what state we're in here */ + LM_DBG("Connection id %d is in state %d - go figure. I will treat is a good. If not, file a bug report please.\n", i_conid, s_con->flags); + + return 1; /* Good connection */ +} static int w_tcpops_set_connection_lifetime2(sip_msg_t* msg, char* conid, char* time) { @@ -226,7 +268,7 @@ static int w_tcpops_set_connection_lifetime2(sip_msg_t* msg, char* conid, char* _IVALUE (time) if (unlikely((s_con = tcpconn_get(i_conid, 0, 0, 0, 0)) == NULL)) { - LM_ERR("invalid connection id %d, (must be a TCP connid)\n", i_conid); + LM_ERR("invalid connection id %d, (must be a TCP conid)\n", i_conid); return 0; } else { ret = tcpops_set_connection_lifetime(s_con, i_time);