pespin has submitted this change. ( 
https://gerrit.osmocom.org/c/libosmo-abis/+/40537?usp=email )

Change subject: ipaccess: Use osmo_stream APIs to set TCP keepalive pars
......................................................................

ipaccess: Use osmo_stream APIs to set TCP keepalive pars

This way osmo_stream takes care of applying the sockopts when needed.

Related: OS#6637
Change-Id: I91deef49563bcec51e1e1eaceec6c1eedc708529
---
M TODO-RELEASE
M src/input/ipaccess.c
2 files changed, 108 insertions(+), 41 deletions(-)

Approvals:
  laforge: Looks good to me, but someone else must approve
  Jenkins Builder: Verified
  pespin: Looks good to me, approved
  osmith: Looks good to me, but someone else must approve




diff --git a/TODO-RELEASE b/TODO-RELEASE
index 0ed7189..32849fa 100644
--- a/TODO-RELEASE
+++ b/TODO-RELEASE
@@ -7,3 +7,4 @@
 # If any interfaces have been added since the last public release: c:r:a + 1.
 # If any interfaces have been removed or changed since the last public 
release: c:r:0.
 #library       what                    description / commit summary line
+libosmo-netif >1.6.0  stream OSMO_STREAM_{CLI,SRV}_TCP_SOCKOPT_*
diff --git a/src/input/ipaccess.c b/src/input/ipaccess.c
index 10dec22..6eddba0 100644
--- a/src/input/ipaccess.c
+++ b/src/input/ipaccess.c
@@ -619,51 +619,115 @@
        return 0;
 }
 
-static void update_fd_settings(struct e1inp_line *line, int fd)
+struct keepalive_pars {
+       int idle_val;
+       int interval_val;
+       int retry_count_val;
+       unsigned int user_timeout_val;
+};
+
+static void line_get_keepalive_pars(const struct e1inp_line *line, struct 
keepalive_pars *pars)
 {
-       int ret;
-       int val, idle_val, interval_val, retry_count_val, user_timeout_val;
+       pars->idle_val = line->keepalive_idle_timeout > 0 ?
+                       line->keepalive_idle_timeout :
+                       DEFAULT_TCP_KEEPALIVE_IDLE_TIMEOUT;
+       pars->interval_val = line->keepalive_probe_interval > -1 ?
+                       line->keepalive_probe_interval :
+                       DEFAULT_TCP_KEEPALIVE_INTERVAL;
+       pars->retry_count_val = line->keepalive_num_probes > 0 ?
+                       line->keepalive_num_probes :
+                       DEFAULT_TCP_KEEPALIVE_RETRY_COUNT;
+       pars->user_timeout_val = 1000 * pars->retry_count_val * 
(pars->interval_val + pars->idle_val);
+}
+
+static void cli_apply_tcp_pars(struct e1inp_line *line, struct osmo_stream_cli 
*cli)
+{
+       struct keepalive_pars pars;
+       int rc;
+       uint8_t on = 1;

        if (line->keepalive_num_probes == 0)
                return;

-       /* Enable TCP keepalive to find out if the connection is gone */
-       val = 1;
-       ret = setsockopt(fd, SOL_SOCKET, SO_KEEPALIVE, &val, sizeof(val));
-       if (ret < 0)
-               LOGPIL(line, DLINP, LOGL_ERROR, "Failed to enable TCP 
keepalive: %s\n", strerror(errno));
-       else
-               LOGPIL(line, DLINP, LOGL_NOTICE, "TCP Keepalive is enabled\n");
+       line_get_keepalive_pars(line, &pars);

-       idle_val = line->keepalive_idle_timeout > 0 ?
-                       line->keepalive_idle_timeout :
-                       DEFAULT_TCP_KEEPALIVE_IDLE_TIMEOUT;
-       interval_val = line->keepalive_probe_interval > -1 ?
-                       line->keepalive_probe_interval :
-                       DEFAULT_TCP_KEEPALIVE_INTERVAL;
-       retry_count_val = line->keepalive_num_probes > 0 ?
-                       line->keepalive_num_probes :
-                       DEFAULT_TCP_KEEPALIVE_RETRY_COUNT;
-       user_timeout_val = 1000 * retry_count_val * (interval_val + idle_val);
-       LOGPIL(line, DLINP, LOGL_NOTICE, "TCP keepalive idle_timeout=%us, 
interval=%us, retry_count=%u "
-               "user_timeout=%ums\n", idle_val, interval_val, retry_count_val, 
user_timeout_val);
-       /* The following options are not portable! */
-       ret = setsockopt(fd, IPPROTO_TCP, TCP_KEEPIDLE, &idle_val, 
sizeof(idle_val));
-       if (ret < 0) {
+       LOGPIL(line, DLINP, LOGL_INFO,
+              "TCP keepalive idle_timeout=%us, interval=%us, retry_count=%u 
user_timeout=%ums\n",
+              pars.idle_val, pars.interval_val, pars.retry_count_val, 
pars.user_timeout_val);
+
+       rc = osmo_stream_cli_set_param(cli, 
OSMO_STREAM_CLI_PAR_TCP_SOCKOPT_KEEPALIVE,
+                                      &on, sizeof(on));
+       if (rc < 0)
+               LOGPIL(line, DLINP, LOGL_ERROR, "Failed to enable TCP 
keepalive: %s\n", strerror(-rc));
+
+       rc = osmo_stream_cli_set_param(cli, 
OSMO_STREAM_CLI_PAR_TCP_SOCKOPT_KEEPIDLE,
+                                      &pars.idle_val, sizeof(pars.idle_val));
+       if (rc < 0)
                LOGPIL(line, DLINP, LOGL_ERROR, "Failed to set TCP keepalive 
idle time: %s\n",
-                      strerror(errno));
-       }
-       ret = setsockopt(fd, IPPROTO_TCP, TCP_KEEPINTVL, &interval_val, 
sizeof(interval_val));
-       if (ret < 0) {
+                      strerror(-rc));
+
+       rc = osmo_stream_cli_set_param(cli, 
OSMO_STREAM_CLI_PAR_TCP_SOCKOPT_KEEPINTVL,
+                                      &pars.interval_val, 
sizeof(pars.interval_val));
+       if (rc < 0)
                LOGPIL(line, DLINP, LOGL_ERROR, "Failed to set TCP keepalive 
interval: %s\n",
-                      strerror(errno));
-       }
-       ret = setsockopt(fd, IPPROTO_TCP, TCP_KEEPCNT, &retry_count_val, 
sizeof(retry_count_val));
-       if (ret < 0)
-               LOGPIL(line, DLINP, LOGL_ERROR, "Failed to set TCP keepalive 
count: %s\n", strerror(errno));
-       ret = setsockopt(fd, IPPROTO_TCP, TCP_USER_TIMEOUT, &user_timeout_val, 
sizeof(user_timeout_val));
-       if (ret < 0)
-               LOGPIL(line, DLINP, LOGL_ERROR, "Failed to set TCP user 
timeout: %s\n", strerror(errno));
+                      strerror(-rc));
+
+       rc = osmo_stream_cli_set_param(cli, 
OSMO_STREAM_CLI_PAR_TCP_SOCKOPT_KEEPCNT,
+                                      &pars.retry_count_val, 
sizeof(pars.retry_count_val));
+       if (rc < 0)
+               LOGPIL(line, DLINP, LOGL_ERROR, "Failed to set TCP keepalive 
count: %s\n",
+                      strerror(-rc));
+
+       rc = osmo_stream_cli_set_param(cli, 
OSMO_STREAM_CLI_PAR_TCP_SOCKOPT_USER_TIMEOUT,
+                                       &pars.user_timeout_val, 
sizeof(pars.user_timeout_val));
+       if (rc < 0)
+               LOGPIL(line, DLINP, LOGL_ERROR, "Failed to set TCP user 
timeout: %s\n",
+                      strerror(-rc));
+}
+
+static void srv_apply_tcp_pars(struct e1inp_line *line, struct osmo_stream_srv 
*conn)
+{
+       struct keepalive_pars pars;
+       int rc;
+       uint8_t on = 1;
+
+       if (line->keepalive_num_probes == 0)
+               return;
+
+       line_get_keepalive_pars(line, &pars);
+
+       LOGPIL(line, DLINP, LOGL_INFO,
+              "TCP keepalive idle_timeout=%us, interval=%us, retry_count=%u 
user_timeout=%ums\n",
+              pars.idle_val, pars.interval_val, pars.retry_count_val, 
pars.user_timeout_val);
+
+       rc = osmo_stream_srv_set_param(conn, 
OSMO_STREAM_SRV_PAR_TCP_SOCKOPT_KEEPALIVE,
+                                      &on, sizeof(on));
+       if (rc < 0)
+               LOGPIL(line, DLINP, LOGL_ERROR, "Failed to enable TCP 
keepalive: %s\n", strerror(-rc));
+
+       rc = osmo_stream_srv_set_param(conn, 
OSMO_STREAM_SRV_PAR_TCP_SOCKOPT_KEEPIDLE,
+                                      &pars.idle_val, sizeof(pars.idle_val));
+       if (rc < 0)
+               LOGPIL(line, DLINP, LOGL_ERROR, "Failed to set TCP keepalive 
idle time: %s\n",
+                      strerror(-rc));
+
+       rc = osmo_stream_srv_set_param(conn, 
OSMO_STREAM_SRV_PAR_TCP_SOCKOPT_KEEPINTVL,
+                                      &pars.interval_val, 
sizeof(pars.interval_val));
+       if (rc < 0)
+               LOGPIL(line, DLINP, LOGL_ERROR, "Failed to set TCP keepalive 
interval: %s\n",
+                      strerror(-rc));
+
+       rc = osmo_stream_srv_set_param(conn, 
OSMO_STREAM_SRV_PAR_TCP_SOCKOPT_KEEPCNT,
+                                      &pars.retry_count_val, 
sizeof(pars.retry_count_val));
+       if (rc < 0)
+               LOGPIL(line, DLINP, LOGL_ERROR, "Failed to set TCP keepalive 
count: %s\n",
+                      strerror(-rc));
+
+       rc = osmo_stream_srv_set_param(conn, 
OSMO_STREAM_SRV_PAR_TCP_SOCKOPT_USER_TIMEOUT,
+                                       &pars.user_timeout_val, 
sizeof(pars.user_timeout_val));
+       if (rc < 0)
+               LOGPIL(line, DLINP, LOGL_ERROR, "Failed to set TCP user 
timeout: %s\n",
+                      strerror(-rc));
 }

 /* callback of the OML listening filedescriptor */
@@ -701,14 +765,13 @@
        osmo_stream_srv_set_read_cb(conn, ipaccess_bsc_conn_read_cb);
        osmo_stream_srv_set_closed_cb(conn, ipaccess_bsc_conn_closed_cb);
        osmo_stream_srv_set_segmentation_cb(conn, osmo_ipa_segmentation_cb);
+       srv_apply_tcp_pars(line, conn);

        /* We use bfd->fd in here for osmo_stats_tcp, and bfd->data to access 
osmo_stream_srv from e1i_ts. */
        bfd = &e1i_ts->driver.ipaccess.fd;
        osmo_fd_setup(bfd, fd, 0, NULL, conn, E1INP_SIGN_OML);
        osmo_stats_tcp_osmo_fd_register(bfd, "ipa-oml");

-       update_fd_settings(line, fd);
-
        /* Request ID. FIXME: request LOCATION, HW/SW VErsion, Unit Name, Serno 
*/
        ret = ipa_ccm_send_id_req(fd);
        if (ret < 0) {
@@ -756,6 +819,7 @@
        osmo_stream_srv_set_read_cb(conn, ipaccess_bsc_conn_read_cb);
        osmo_stream_srv_set_closed_cb(conn, ipaccess_bsc_conn_closed_cb);
        osmo_stream_srv_set_segmentation_cb(conn, osmo_ipa_segmentation_cb);
+       srv_apply_tcp_pars(line, conn);

        /* We use bfd->fd in here for osmo_stats_tcp, and bfd->data to access 
osmo_stream_srv from e1i_ts. */
        bfd = &e1i_ts->driver.ipaccess.fd;
@@ -768,7 +832,6 @@
                LOGPITS(e1i_ts, DLINP, LOGL_ERROR, "could not send ID REQ. 
Reason: %s\n", strerror(errno));
                goto err_socket;
        }
-       update_fd_settings(line, fd);
        return 0;

 err_socket:
@@ -928,7 +991,6 @@
        struct e1inp_line *line = e1i_ts->line;
        struct osmo_ipa_ka_fsm_inst *ka_fsm = e1i_ts->driver.ipaccess.ka_fsm;

-       update_fd_settings(line, osmo_stream_cli_get_fd(cli));
        if (ka_fsm && line->ipa_kap)
                osmo_ipa_ka_fsm_start(ka_fsm);
        return 0;
@@ -1048,6 +1110,8 @@
                osmo_stream_cli_set_disconnect_cb(cli, 
ipaccess_bts_disconnect_cb);
                osmo_stream_cli_set_read_cb2(cli, ipaccess_bts_read_cb);

+               cli_apply_tcp_pars(line, cli);
+
                if (osmo_stream_cli_open(cli)) {
                        LOGPITS(e1i_ts, DLINP, LOGL_ERROR, "cannot open OML BTS 
link: %s\n", strerror(errno));
                        osmo_stream_cli_destroy(cli);
@@ -1126,6 +1190,8 @@
        osmo_stream_cli_set_disconnect_cb(cli, ipaccess_bts_disconnect_cb);
        osmo_stream_cli_set_read_cb2(cli, ipaccess_bts_read_cb);

+       cli_apply_tcp_pars(line, cli);
+
        if (osmo_stream_cli_open(cli)) {
                LOGPITS(e1i_ts, DLINP, LOGL_ERROR, "cannot open RSL BTS link: 
%s\n", strerror(errno));
                osmo_stream_cli_destroy(cli);

--
To view, visit https://gerrit.osmocom.org/c/libosmo-abis/+/40537?usp=email
To unsubscribe, or for help writing mail filters, visit 
https://gerrit.osmocom.org/settings?usp=email

Gerrit-MessageType: merged
Gerrit-Project: libosmo-abis
Gerrit-Branch: master
Gerrit-Change-Id: I91deef49563bcec51e1e1eaceec6c1eedc708529
Gerrit-Change-Number: 40537
Gerrit-PatchSet: 2
Gerrit-Owner: pespin <[email protected]>
Gerrit-Reviewer: Jenkins Builder
Gerrit-Reviewer: laforge <[email protected]>
Gerrit-Reviewer: osmith <[email protected]>
Gerrit-Reviewer: pespin <[email protected]>

Reply via email to