pespin has uploaded this change for review. (
https://gerrit.osmocom.org/c/libosmo-netif/+/40479?usp=email )
Change subject: stream: Support configuring TCP_USER_TIMEOUT parameter
......................................................................
stream: Support configuring TCP_USER_TIMEOUT parameter
This is set for instance in libosmo-abis, and may affect how keepalive
behaves. See man 7 tcp for more information.
Change-Id: I22c7df92b463cf4ca82854a12ec24337d53e8b20
---
M TODO-RELEASE
M include/osmocom/netif/stream.h
M include/osmocom/netif/stream_private.h
M src/stream.c
M src/stream_cli.c
M src/stream_srv.c
6 files changed, 50 insertions(+), 1 deletion(-)
git pull ssh://gerrit.osmocom.org:29418/libosmo-netif refs/changes/79/40479/1
diff --git a/TODO-RELEASE b/TODO-RELEASE
index e519375..6340cdf 100644
--- a/TODO-RELEASE
+++ b/TODO-RELEASE
@@ -8,3 +8,4 @@
# If any interfaces have been removed or changed since the last public release: c:r:0.
#library what description / commit summary line
stream add OSMO_STREAM_{CLI,SRV,SRV_LINK}_TCP_SOCKOPT_KEEP*,
osmo_stream_srv_set_param()
+stream add OSMO_STREAM_{CLI,SRV,SRV_LINK}_TCP_SOCKOPT_USER_TIMEOUT
diff --git a/include/osmocom/netif/stream.h b/include/osmocom/netif/stream.h
index 7b74e87..8c3fad5 100644
--- a/include/osmocom/netif/stream.h
+++ b/include/osmocom/netif/stream.h
@@ -103,6 +103,7 @@
OSMO_STREAM_SRV_LINK_PAR_TCP_SOCKOPT_KEEPIDLE, /* int: seconds */
OSMO_STREAM_SRV_LINK_PAR_TCP_SOCKOPT_KEEPINTVL, /* int: seconds */
OSMO_STREAM_SRV_LINK_PAR_TCP_SOCKOPT_KEEPCNT, /* int: Number of probes */
+ OSMO_STREAM_SRV_LINK_PAR_TCP_SOCKOPT_USER_TIMEOUT, /* unsigned int: 0 "system
default", >0 see sockopt TCP_USER_TIMEOUT */
};
int osmo_stream_srv_link_set_param(struct osmo_stream_srv_link *link, enum
osmo_stream_srv_link_param par,
@@ -159,6 +160,7 @@
OSMO_STREAM_SRV_PAR_TCP_SOCKOPT_KEEPIDLE, /* int: seconds */
OSMO_STREAM_SRV_PAR_TCP_SOCKOPT_KEEPINTVL, /* int: seconds */
OSMO_STREAM_SRV_PAR_TCP_SOCKOPT_KEEPCNT, /* int: Number of probes */
+ OSMO_STREAM_SRV_PAR_TCP_SOCKOPT_USER_TIMEOUT, /* unsigned int: 0 "system
default", >0 see sockopt TCP_USER_TIMEOUT */
};
int osmo_stream_srv_set_param(struct osmo_stream_srv *conn, enum osmo_stream_srv_param
par,
void *val, size_t val_len);
@@ -274,6 +276,7 @@
OSMO_STREAM_CLI_PAR_TCP_SOCKOPT_KEEPIDLE, /* int: seconds */
OSMO_STREAM_CLI_PAR_TCP_SOCKOPT_KEEPINTVL, /* int: seconds */
OSMO_STREAM_CLI_PAR_TCP_SOCKOPT_KEEPCNT, /* int: Number of probes */
+ OSMO_STREAM_CLI_PAR_TCP_SOCKOPT_USER_TIMEOUT, /* unsigned int: 0 "system
default", >0 see sockopt TCP_USER_TIMEOUT */
};
int osmo_stream_cli_set_param(struct osmo_stream_cli *cli, enum osmo_stream_cli_param
par,
diff --git a/include/osmocom/netif/stream_private.h
b/include/osmocom/netif/stream_private.h
index 7fb0de6..154e7f7 100644
--- a/include/osmocom/netif/stream_private.h
+++ b/include/osmocom/netif/stream_private.h
@@ -46,8 +46,10 @@
struct stream_tcp_pars {
struct stream_tcp_keepalive_pars ka;
- /* Others like TCP_USER_TIMEOUT will be added here in the future. */
+ bool user_timeout_present;
+ unsigned int user_timeout_value;
};
+int stream_setsockopt_tcp_user_timeout(int fd, unsigned int user_timeout);
struct osmo_io_fd;
struct msghdr;
diff --git a/src/stream.c b/src/stream.c
index a1e077a..339dd6a 100644
--- a/src/stream.c
+++ b/src/stream.c
@@ -240,6 +240,17 @@
return 0;
}
+int stream_setsockopt_tcp_user_timeout(int fd, unsigned int user_timeout)
+{
+ int ret = setsockopt(fd, IPPROTO_TCP, TCP_USER_TIMEOUT, &user_timeout,
sizeof(user_timeout));
+ if (ret < 0) {
+ ret = errno;
+ LOGP(DLINP, LOGL_ERROR, "Failed to set TCP_USER_TIMEOUT on fd %d: %s\n", fd,
strerror(ret));
+ return -ret;
+ }
+ return 0;
+}
+
int stream_tcp_keepalive_pars_apply(int fd, const struct stream_tcp_keepalive_pars *tkp)
{
int ret;
diff --git a/src/stream_cli.c b/src/stream_cli.c
index 4b20a61..13a1589 100644
--- a/src/stream_cli.c
+++ b/src/stream_cli.c
@@ -1291,6 +1291,11 @@
ret = stream_tcp_keepalive_pars_apply(fd, &cli->tcp_pars.ka);
if (ret < 0)
goto error_close_socket;
+ if (cli->tcp_pars.user_timeout_present) {
+ ret = stream_setsockopt_tcp_user_timeout(fd, cli->tcp_pars.user_timeout_value);
+ if (ret < 0)
+ goto error_close_socket;
+ }
}
switch (cli->mode) {
@@ -1571,6 +1576,14 @@
if (stream_cli_is_opened(cli))
return stream_setsockopt_tcp_keepcnt(osmo_stream_cli_get_fd(cli),
cli->tcp_pars.ka.probes_value);
break;
+ case OSMO_STREAM_CLI_PAR_TCP_SOCKOPT_USER_TIMEOUT:
+ if (!val || val_len != sizeof(unsigned int))
+ return -EINVAL;
+ cli->tcp_pars.user_timeout_present = true;
+ cli->tcp_pars.user_timeout_value = *(int *)val;
+ if (stream_cli_is_opened(cli))
+ return stream_setsockopt_tcp_user_timeout(osmo_stream_cli_get_fd(cli),
cli->tcp_pars.user_timeout_value);
+ break;
default:
return -ENOENT;
};
diff --git a/src/stream_srv.c b/src/stream_srv.c
index b7bc378..1eebd3a 100644
--- a/src/stream_srv.c
+++ b/src/stream_srv.c
@@ -150,6 +150,9 @@
LOGSLNK(link, LOGL_ERROR, "failed applying TCP keep-alive pars on fd %d\n",
sock_fd);
goto error_close_socket;
}
+ /* tcp_pars.user_timeout (sockopt TCP_USER_TIMEOUT) is
+ * inherited by accept() connected sockets automatically,
+ * no need to re-apply it here. */
break;
case IPPROTO_SCTP:
_setsockopt_nosigpipe(link, sock_fd);
@@ -710,6 +713,15 @@
link->tcp_pars.ka.probes_value = *(int *)val;
/* Will be applied on accepted sockets */
break;
+ case OSMO_STREAM_SRV_LINK_PAR_TCP_SOCKOPT_USER_TIMEOUT:
+ if (!val || val_len != sizeof(unsigned int))
+ return -EINVAL;
+ link->tcp_pars.user_timeout_present = true;
+ link->tcp_pars.user_timeout_value = *(int *)val;
+ /* This value is inherited by accept() connected sockets (hence by child stream_srv):
*/
+ if (osmo_stream_srv_link_is_opened(link))
+ return stream_setsockopt_tcp_user_timeout(osmo_stream_srv_link_get_fd(link),
+ link->tcp_pars.user_timeout_value);
default:
return -ENOENT;
};
@@ -1448,6 +1460,7 @@
{
uint8_t on;
int i;
+ unsigned int u;
OSMO_ASSERT(conn);
switch (par) {
@@ -1472,6 +1485,12 @@
return -EINVAL;
i = *(int *)val;
return stream_setsockopt_tcp_keepcnt(osmo_stream_srv_get_fd(conn), i);
+ case OSMO_STREAM_SRV_PAR_TCP_SOCKOPT_USER_TIMEOUT:
+ if (!val || val_len != sizeof(unsigned int))
+ return -EINVAL;
+ u = *(unsigned int *)val;
+ return stream_setsockopt_tcp_user_timeout(osmo_stream_srv_get_fd(conn), u);
+ break;
default:
return -ENOENT;
};
--
To view, visit
https://gerrit.osmocom.org/c/libosmo-netif/+/40479?usp=email
To unsubscribe, or for help writing mail filters, visit
https://gerrit.osmocom.org/settings?usp=email
Gerrit-MessageType: newchange
Gerrit-Project: libosmo-netif
Gerrit-Branch: master
Gerrit-Change-Id: I22c7df92b463cf4ca82854a12ec24337d53e8b20
Gerrit-Change-Number: 40479
Gerrit-PatchSet: 1
Gerrit-Owner: pespin <pespin(a)sysmocom.de>