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 <pespin(a)sysmocom.de>
Gerrit-Reviewer: Jenkins Builder
Gerrit-Reviewer: laforge <laforge(a)osmocom.org>
Gerrit-Reviewer: osmith <osmith(a)sysmocom.de>
Gerrit-Reviewer: pespin <pespin(a)sysmocom.de>