Hoernchen has uploaded this change for review. ( 
https://gerrit.osmocom.org/c/osmo-hlr/+/14741


Change subject: add keepalive for gsup client/server, osmo-hlr
......................................................................

add keepalive for gsup client/server, osmo-hlr

Change-Id: I01654d4a023e76a2b9245817a0096148c8bd44c1
Depends: (libosmo-abis) Ie453fdee8bfd7fc1a3f1ed67ef0331f0abb1d59b
---
M doc/manuals/vty/hlr_vty_reference.xml
M include/osmocom/gsupclient/gsup_client.h
M src/gsup_server.c
M src/gsup_server.h
M src/gsupclient/gsup_client.c
M src/gsupclient/gsup_test_client.c
M src/hlr.c
M src/hlr.h
M src/hlr_vty.c
M src/osmo-euse-demo.c
10 files changed, 109 insertions(+), 60 deletions(-)



  git pull ssh://gerrit.osmocom.org:29418/osmo-hlr refs/changes/41/14741/1

diff --git a/doc/manuals/vty/hlr_vty_reference.xml 
b/doc/manuals/vty/hlr_vty_reference.xml
index e5fd0f2..b1ce7d9 100644
--- a/doc/manuals/vty/hlr_vty_reference.xml
+++ b/doc/manuals/vty/hlr_vty_reference.xml
@@ -1408,6 +1408,13 @@
         <param name='A.B.C.D' doc='IPv4 Address to bind the GSUP interface to' 
/>
       </params>
     </command>
+    <command id='keepalive <0-300> <1-300>'>
+      <params>
+        <param name='keepalive' doc='Enable keepalive probing' />
+        <param name='<0-300>' doc='Idle interval in seconds before probes are 
sent, 0 disables keepalive' />
+        <param name='<1-300>' doc='Timeout waiting for PONG response' />
+      </params>
+    </command>
   </node>
   <node id='config-hlr-euse'>
     <name>config-hlr-euse</name>
diff --git a/include/osmocom/gsupclient/gsup_client.h 
b/include/osmocom/gsupclient/gsup_client.h
index 154e3e0..a05511f 100644
--- a/include/osmocom/gsupclient/gsup_client.h
+++ b/include/osmocom/gsupclient/gsup_client.h
@@ -35,6 +35,7 @@
 struct msgb;
 struct ipa_client_conn;
 struct osmo_gsup_client;
+struct ipa_keepalive_params;

 /* Expects message in msg->l2h */
 typedef int (*osmo_gsup_client_read_cb_t)(struct osmo_gsup_client *gsupc, 
struct msgb *msg);
@@ -48,12 +49,11 @@

        struct osmo_oap_client_state oap_state;

-       struct osmo_timer_list ping_timer;
        struct osmo_timer_list connect_timer;
        int is_connected;
-       int got_ipa_pong;

        struct ipaccess_unit *ipa_dev; /* identification information sent to 
IPA server */
+       struct osmo_fsm_inst* ka_fsm;
 };

 struct osmo_gsup_client *osmo_gsup_client_create2(void *talloc_ctx,
@@ -61,13 +61,15 @@
                                                  const char *ip_addr,
                                                  unsigned int tcp_port,
                                                  osmo_gsup_client_read_cb_t 
read_cb,
-                                                 struct osmo_oap_client_config 
*oapc_config);
+                                                 struct osmo_oap_client_config 
*oapc_config,
+                                               struct ipa_keepalive_params * 
params);
 struct osmo_gsup_client *osmo_gsup_client_create(void *talloc_ctx,
                                                 const char *unit_name,
                                                 const char *ip_addr,
                                                 unsigned int tcp_port,
                                                 osmo_gsup_client_read_cb_t 
read_cb,
-                                                struct osmo_oap_client_config 
*oapc_config);
+                                                struct osmo_oap_client_config 
*oapc_config,
+                                               struct ipa_keepalive_params * 
params);

 void osmo_gsup_client_destroy(struct osmo_gsup_client *gsupc);
 int osmo_gsup_client_send(struct osmo_gsup_client *gsupc, struct msgb *msg);
diff --git a/src/gsup_server.c b/src/gsup_server.c
index e75bbd7..5a4031c 100644
--- a/src/gsup_server.c
+++ b/src/gsup_server.c
@@ -30,6 +30,8 @@
 #include "gsup_server.h"
 #include "gsup_router.h"

+static int osmo_gsup_server_closed_cb(struct ipa_server_conn *conn);
+
 static void osmo_gsup_server_send(struct osmo_gsup_conn *conn,
                             int proto_ext, struct msgb *msg_tx)
 {
@@ -79,11 +81,17 @@
        msg->l2h = &hh->data[0];

        if (hh->proto == IPAC_PROTO_IPACCESS) {
+               uint8_t msg_type = *(msg->l2h);
                rc = ipa_server_conn_ccm(conn, msg);
                if (rc < 0) {
                        /* conn is already invalid here! */
                        return -1;
                }
+
+               /* peek the pong for out keepalive fsm */
+               if(clnt->ka_fsm && msg_type == IPAC_MSGT_PONG)
+                       ipa_keepalive_fsm_pong_received(clnt->ka_fsm);
+
                msgb_free(msg);
                return 0;
        }
@@ -171,6 +179,12 @@
        return TLVP_LEN(&clnt->ccm, tag);
 }

+static int osmo_gsup_server_ka_timeout_cb(struct osmo_fsm_inst *fi, void 
*conn){
+       ipa_server_conn_destroy(conn);
+       /* we're dead, our talloc context was conn, which was freed */
+       return 0;
+}
+
 static int osmo_gsup_server_ccm_cb(struct ipa_server_conn *conn,
                                   struct msgb *msg, struct tlv_parsed *tlvp,
                                   struct ipaccess_unit *unit)
@@ -196,6 +210,18 @@
        }

        gsup_route_add(clnt, addr, addr_len);
+
+       if(clnt->ka_fsm)
+               osmo_fsm_inst_free(clnt->ka_fsm);
+
+       if(clnt->server->ka_params){
+               clnt->ka_fsm = ipa_server_conn_alloc_keepalive_fsm(conn, 
clnt->server->ka_params, "gsup_server");
+               if(clnt->ka_fsm){
+                       ipa_keepalive_fsm_set_timeout_cb(clnt->ka_fsm, 
osmo_gsup_server_ka_timeout_cb);
+                       ipa_keepalive_fsm_start(clnt->ka_fsm);
+               }
+       }
+
        return 0;
 }

@@ -206,6 +232,11 @@
        LOGP(DLGSUP, LOGL_INFO, "Lost GSUP client %s:%d\n",
                conn->addr, conn->port);

+       if(clnt->ka_fsm){
+               osmo_fsm_inst_free(clnt->ka_fsm);
+               clnt->ka_fsm = NULL;
+       }
+
        gsup_route_del_conn(clnt);
        llist_del(&clnt->list);
        talloc_free(clnt);
@@ -292,7 +323,7 @@
 struct osmo_gsup_server *
 osmo_gsup_server_create(void *ctx, const char *ip_addr, uint16_t tcp_port,
                        osmo_gsup_read_cb_t read_cb,
-                       struct llist_head *lu_op_lst, void *priv)
+                       struct llist_head *lu_op_lst, struct 
ipa_keepalive_params * params, void *priv)
 {
        struct osmo_gsup_server *gsups;
        int rc;
@@ -313,6 +344,7 @@

        gsups->read_cb = read_cb;
        gsups->priv = priv;
+       gsups->ka_params = params;

        rc = ipa_server_link_open(gsups->link);
        if (rc < 0)
diff --git a/src/gsup_server.h b/src/gsup_server.h
index 9c4d483..406ecf8 100644
--- a/src/gsup_server.h
+++ b/src/gsup_server.h
@@ -28,6 +28,7 @@
        struct ipa_server_link *link;
        osmo_gsup_read_cb_t read_cb;
        struct llist_head routes;
+       struct ipa_keepalive_params* ka_params;
 };


@@ -45,6 +46,7 @@
        /* Set when Location Update is received: */
        bool supports_cs; /* client supports OSMO_GSUP_CN_DOMAIN_CS */
        bool supports_ps; /* client supports OSMO_GSUP_CN_DOMAIN_PS */
+       struct osmo_fsm_inst* ka_fsm;
 };


@@ -57,6 +59,7 @@
                                                 uint16_t tcp_port,
                                                 osmo_gsup_read_cb_t read_cb,
                                                 struct llist_head *lu_op_lst,
+                                                struct ipa_keepalive_params * 
params,
                                                 void *priv);

 void osmo_gsup_server_destroy(struct osmo_gsup_server *gsups);
diff --git a/src/gsupclient/gsup_client.c b/src/gsupclient/gsup_client.c
index c8408fd..5fe9740 100644
--- a/src/gsupclient/gsup_client.c
+++ b/src/gsupclient/gsup_client.c
@@ -32,18 +32,6 @@
 #include <errno.h>
 #include <string.h>

-static void start_test_procedure(struct osmo_gsup_client *gsupc);
-
-static void gsup_client_send_ping(struct osmo_gsup_client *gsupc)
-{
-       struct msgb *msg = osmo_gsup_client_msgb_alloc();
-
-       msg->l2h = msgb_put(msg, 1);
-       msg->l2h[0] = IPAC_MSGT_PING;
-       ipa_msg_push_header(msg, IPAC_PROTO_IPACCESS);
-       ipa_client_conn_send(gsupc->link, msg);
-}
-
 static int gsup_client_connect(struct osmo_gsup_client *gsupc)
 {
        int rc;
@@ -57,12 +45,6 @@
                osmo_timer_del(&gsupc->connect_timer);
        }

-       if (osmo_timer_pending(&gsupc->ping_timer)) {
-               LOGP(DLGSUP, LOGL_DEBUG,
-                    "GSUP connect: ping timer already running\n");
-               osmo_timer_del(&gsupc->ping_timer);
-       }
-
        if (ipa_client_conn_clear_queue(gsupc->link) > 0)
                LOGP(DLGSUP, LOGL_DEBUG, "GSUP connect: discarded stored 
messages\n");

@@ -71,6 +53,10 @@
        if (rc >= 0) {
                LOGP(DLGSUP, LOGL_NOTICE, "GSUP connecting to %s:%d\n",
                     gsupc->link->addr, gsupc->link->port);
+
+               if(gsupc->ka_fsm)
+                       ipa_keepalive_fsm_start(gsupc->ka_fsm);
+
                return 0;
        }

@@ -133,14 +119,16 @@
        gsupc->is_connected = up;

        if (up) {
-               start_test_procedure(gsupc);
+               if(gsupc->ka_fsm)
+                       ipa_keepalive_fsm_start(gsupc->ka_fsm);

                if (gsupc->oap_state.state == OSMO_OAP_INITIALIZED)
                        gsup_client_oap_register(gsupc);

                osmo_timer_del(&gsupc->connect_timer);
        } else {
-               osmo_timer_del(&gsupc->ping_timer);
+               if(gsupc->ka_fsm)
+                       ipa_keepalive_fsm_stop(gsupc->ka_fsm);

                osmo_timer_schedule(&gsupc->connect_timer,
                                    OSMO_GSUP_CLIENT_RECONNECT_INTERVAL, 0);
@@ -189,11 +177,10 @@

        if (rc == 1) {
                uint8_t msg_type = *(msg->l2h);
-               /* CCM message */
-               if (msg_type == IPAC_MSGT_PONG) {
-                       LOGP(DLGSUP, LOGL_DEBUG, "GSUP receiving PONG\n");
-                       gsupc->got_ipa_pong = 1;
-               }
+
+               /* peek the pong for out keepalive fsm */
+               if(gsupc->ka_fsm && msg_type == IPAC_MSGT_PONG)
+                       ipa_keepalive_fsm_pong_received(gsupc->ka_fsm);

                msgb_free(msg);
                return 0;
@@ -228,34 +215,20 @@
        return -1;
 }

-static void ping_timer_cb(void *gsupc_)
-{
-       struct osmo_gsup_client *gsupc = gsupc_;
+static int osmo_gsup_client_ka_timeout_cb(struct osmo_fsm_inst *fi, void 
*data){
+       struct ipa_client_conn* cc = (struct ipa_client_conn*) data;
+       struct osmo_gsup_client* gsupc = (struct osmo_gsup_client *)cc->data;

-       LOGP(DLGSUP, LOGL_INFO, "GSUP ping callback (%s, %s PONG)\n",
-            gsupc->is_connected ? "connected" : "not connected",
-            gsupc->got_ipa_pong ? "got" : "didn't get");
+       ipa_keepalive_fsm_stop(gsupc->ka_fsm);

-       if (gsupc->got_ipa_pong) {
-               start_test_procedure(gsupc);
-               return;
-       }
-
-       LOGP(DLGSUP, LOGL_NOTICE, "GSUP ping timed out, reconnecting\n");
        ipa_client_conn_close(gsupc->link);
        gsupc->is_connected = 0;

-       gsup_client_connect(gsupc);
-}
+       osmo_timer_schedule(&gsupc->connect_timer,
+                                               
OSMO_GSUP_CLIENT_RECONNECT_INTERVAL, 0);

-static void start_test_procedure(struct osmo_gsup_client *gsupc)
-{
-       osmo_timer_setup(&gsupc->ping_timer, ping_timer_cb, gsupc);
-
-       gsupc->got_ipa_pong = 0;
-       osmo_timer_schedule(&gsupc->ping_timer, OSMO_GSUP_CLIENT_PING_INTERVAL, 
0);
-       LOGP(DLGSUP, LOGL_DEBUG, "GSUP sending PING\n");
-       gsup_client_send_ping(gsupc);
+       /* do not terminate */
+       return 0;
 }

 /*!
@@ -276,7 +249,8 @@
                                                  const char *ip_addr,
                                                  unsigned int tcp_port,
                                                  osmo_gsup_client_read_cb_t 
read_cb,
-                                                 struct osmo_oap_client_config 
*oapc_config)
+                                                 struct osmo_oap_client_config 
*oapc_config,
+                                                 struct ipa_keepalive_params * 
params)
 {
        struct osmo_gsup_client *gsupc;
        int rc;
@@ -302,6 +276,12 @@
        if (!gsupc->link)
                goto failed;

+       if(params){
+               gsupc->ka_fsm = 
ipa_client_conn_alloc_keepalive_fsm(gsupc->link, params, "gsup_client");
+               if(gsupc->ka_fsm)
+                       ipa_keepalive_fsm_set_timeout_cb(gsupc->ka_fsm, 
osmo_gsup_client_ka_timeout_cb);
+       }
+
        osmo_timer_setup(&gsupc->connect_timer, connect_timer_cb, gsupc);

        rc = gsup_client_connect(gsupc);
@@ -327,17 +307,17 @@
                                                 const char *ip_addr,
                                                 unsigned int tcp_port,
                                                 osmo_gsup_client_read_cb_t 
read_cb,
-                                                struct osmo_oap_client_config 
*oapc_config)
+                                                struct osmo_oap_client_config 
*oapc_config,
+                                                struct ipa_keepalive_params * 
params)
 {
        struct ipaccess_unit *ipa_dev = talloc_zero(talloc_ctx, struct 
ipaccess_unit);
        ipa_dev->unit_name = talloc_strdup(ipa_dev, unit_name);
-       return osmo_gsup_client_create2(talloc_ctx, ipa_dev, ip_addr, tcp_port, 
read_cb, oapc_config);
+       return osmo_gsup_client_create2(talloc_ctx, ipa_dev, ip_addr, tcp_port, 
read_cb, oapc_config, params);
 }

 void osmo_gsup_client_destroy(struct osmo_gsup_client *gsupc)
 {
        osmo_timer_del(&gsupc->connect_timer);
-       osmo_timer_del(&gsupc->ping_timer);

        if (gsupc->link) {
                ipa_client_conn_close(gsupc->link);
diff --git a/src/gsupclient/gsup_test_client.c 
b/src/gsupclient/gsup_test_client.c
index b0362ad..cb293c9 100644
--- a/src/gsupclient/gsup_test_client.c
+++ b/src/gsupclient/gsup_test_client.c
@@ -10,6 +10,7 @@
 #include <osmocom/core/utils.h>
 #include <osmocom/core/logging.h>
 #include <osmocom/gsm/gsup.h>
+#include <osmocom/abis/ipa.h>

 #include <osmocom/gsupclient/gsup_client.h>

@@ -289,12 +290,12 @@
        unsigned long long i;
        char *server_host = "127.0.0.1";
        uint16_t server_port = OSMO_GSUP_PORT;
+       struct ipa_keepalive_params kap = {.interval = 10, .wait_for_resp = 5};
        void *ctx = talloc_named_const(NULL, 0, "gsup_test_client");
-
        osmo_init_logging2(ctx, &gsup_test_client_log_info);

        g_gc = osmo_gsup_client_create(ctx, "GSUPTEST", server_host, 
server_port,
-                                       gsupc_read_cb, NULL);
+                                       gsupc_read_cb, NULL, &kap);


        signal(SIGINT, sig_cb);
diff --git a/src/hlr.c b/src/hlr.c
index 90cbac4..5237012 100644
--- a/src/hlr.c
+++ b/src/hlr.c
@@ -880,7 +880,7 @@
        }

        g_hlr->gs = osmo_gsup_server_create(hlr_ctx, g_hlr->gsup_bind_addr, 
OSMO_GSUP_PORT,
-                                           read_cb, &g_lu_ops, g_hlr);
+                                        read_cb, &g_lu_ops, g_hlr->ka_params, 
g_hlr);
        if (!g_hlr->gs) {
                LOGP(DMAIN, LOGL_FATAL, "Error starting GSUP server\n");
                exit(1);
diff --git a/src/hlr.h b/src/hlr.h
index 18c4a1d..97b49bc 100644
--- a/src/hlr.h
+++ b/src/hlr.h
@@ -61,6 +61,7 @@
        /* Bitmask of DB_SUBSCR_FLAG_* */
        uint8_t subscr_create_on_demand_flags;
        unsigned int subscr_create_on_demand_rand_msisdn_len;
+       struct ipa_keepalive_params* ka_params;
 };

 extern struct hlr *g_hlr;
diff --git a/src/hlr_vty.c b/src/hlr_vty.c
index e6567cc..c975c7f 100644
--- a/src/hlr_vty.c
+++ b/src/hlr_vty.c
@@ -102,6 +102,9 @@
        vty_out(vty, " gsup%s", VTY_NEWLINE);
        if (g_hlr->gsup_bind_addr)
                vty_out(vty, "  bind ip %s%s", g_hlr->gsup_bind_addr, 
VTY_NEWLINE);
+       if (g_hlr->ka_params)
+               vty_out(vty, "  keepalive %d %d%s", g_hlr->ka_params->interval,
+                               g_hlr->ka_params->wait_for_resp, VTY_NEWLINE);
        return CMD_SUCCESS;
 }
 
@@ -146,6 +149,22 @@
        return CMD_SUCCESS;
 }

+DEFUN(cfg_hlr_gsup_keepalive,
+      cfg_hlr_gsup_keepalive_cmd,
+      "keepalive <0-300> <1-300>",
+      "Enable keepalive probing\n"
+      "Idle interval in seconds before probes are sent, 0 disables keepalive\n"
+      "Timeout waiting for PONG response\n")
+{
+       if(atoi(argv[0]) > 0){
+               g_hlr->ka_params = talloc_zero(g_hlr, struct 
ipa_keepalive_params);
+               g_hlr->ka_params->interval = atoi(argv[0]);
+               g_hlr->ka_params->wait_for_resp = atoi(argv[1]);
+       }
+
+    return CMD_SUCCESS;
+}
+
 /***********************************************************************
  * USSD Entity
  ***********************************************************************/
@@ -444,6 +463,7 @@
        install_node(&gsup_node, config_write_hlr_gsup);

        install_element(GSUP_NODE, &cfg_hlr_gsup_bind_ip_cmd);
+       install_element(GSUP_NODE, &cfg_hlr_gsup_keepalive_cmd);

        install_element(HLR_NODE, &cfg_database_cmd);

diff --git a/src/osmo-euse-demo.c b/src/osmo-euse-demo.c
index 4e4ef78..5cb5c40 100644
--- a/src/osmo-euse-demo.c
+++ b/src/osmo-euse-demo.c
@@ -44,6 +44,8 @@

 #include <osmocom/gsupclient/gsup_client.h>

+#include <osmocom/abis/ipa.h>
+
 #include "logging.h"

 static struct osmo_gsup_client *g_gc;
@@ -212,6 +214,7 @@
 {
        char *server_host = "127.0.0.1";
        uint16_t server_port = OSMO_GSUP_PORT;
+       struct ipa_keepalive_params kap = {.interval = 10, .wait_for_resp = 5};
        void *ctx = talloc_named_const(NULL, 0, "demo-euse");

        osmo_init_logging2(ctx, &gsup_log_info);
@@ -228,7 +231,7 @@
        if (argc > 2)
                server_port = atoi(argv[2]);

-       g_gc = osmo_gsup_client_create(ctx, "EUSE-foobar", server_host, 
server_port, gsupc_read_cb, NULL);
+       g_gc = osmo_gsup_client_create(ctx, "EUSE-foobar", server_host, 
server_port, gsupc_read_cb, NULL, &kap);

        while (1) {
                osmo_select_main(0);

--
To view, visit https://gerrit.osmocom.org/c/osmo-hlr/+/14741
To unsubscribe, or for help writing mail filters, visit 
https://gerrit.osmocom.org/settings

Gerrit-Project: osmo-hlr
Gerrit-Branch: master
Gerrit-Change-Id: I01654d4a023e76a2b9245817a0096148c8bd44c1
Gerrit-Change-Number: 14741
Gerrit-PatchSet: 1
Gerrit-Owner: Hoernchen <[email protected]>
Gerrit-MessageType: newchange

Reply via email to