pespin has uploaded this change for review. ( https://gerrit.osmocom.org/c/libosmo-netif/+/34347?usp=email )
Change subject: stream: Introduce API to set several transport parameters ......................................................................
stream: Introduce API to set several transport parameters
This will allow extending capabilitites to set different parameters at the lower layers as we need them.
This commit changes the behavior of osmo_stream_{cli,srv_link}: It now doesn't enable by default SCTP AUTH/ASCONF features using setsockopt. It is left up to the user of the API (libosmo-sccp in this case) to set it. Since this unilateral use of setsockopt() has only been added recently and we didn't release yet, it's fine changing it. libosmo-sccp will be changed to unconditionally set its using setsockopt. It is left up to the user of the API (libosmo-sccp in this case) to set it.
Related: SYS#6501 Related: SYS#6558 Change-Id: I2607c1c926a625986cd851adc65dd8b4de83d6ab --- M TODO-RELEASE M include/osmocom/netif/stream.h M src/stream_cli.c M src/stream_srv.c 4 files changed, 107 insertions(+), 34 deletions(-)
git pull ssh://gerrit.osmocom.org:29418/libosmo-netif refs/changes/47/34347/1
diff --git a/TODO-RELEASE b/TODO-RELEASE index 830e77b..084ca67 100644 --- a/TODO-RELEASE +++ b/TODO-RELEASE @@ -8,4 +8,5 @@ # If any interfaces have been removed or changed since the last public release: c:r:0. #library what description / commit summary line libosmocore >1.8.0 osmo_iofd, osmo_sock_init2_multiaddr2() -stream NEW API osmo_stream_srv_link_set_name(), osmo_stream_srv_set_name(), osmo_stream_cli_set_name() \ No newline at end of file +stream NEW API osmo_stream_srv_link_set_name(), osmo_stream_srv_set_name(), osmo_stream_cli_set_name() +stream NEW API osmo_stream_srv_link_set_param(), osmo_stream_cli_set_param() diff --git a/include/osmocom/netif/stream.h b/include/osmocom/netif/stream.h index 6240205..f78df8a 100644 --- a/include/osmocom/netif/stream.h +++ b/include/osmocom/netif/stream.h @@ -2,6 +2,7 @@
#include <stdbool.h> #include <stdint.h> +#include <unistd.h>
#include <osmocom/core/msgb.h>
@@ -41,6 +42,14 @@ int osmo_stream_srv_link_open(struct osmo_stream_srv_link *link); void osmo_stream_srv_link_close(struct osmo_stream_srv_link *link);
+enum osmo_stream_srv_link_param { + OSMO_STREAM_SRV_LINK_PAR_SCTP_SOCKOPT_AUTH_SUPPORTED, /* uint8_t: 0 disable, 1 enable, 2 force disable, 3 force enable */ + OSMO_STREAM_SRV_LINK_PAR_SCTP_SOCKOPT_ASCONF_SUPPORTED, /* uint8_t: 0 disable, 1 enable, 2 force disable, 3 force enable */ +}; + +int osmo_stream_srv_link_set_param(struct osmo_stream_srv_link *link, enum osmo_stream_srv_link_param par, + void *val, size_t val_len); + /*! \brief Osmocom Stream Server: Single connection accept()ed via \ref * osmo_stream_srv_link */ struct osmo_stream_srv; @@ -105,4 +114,12 @@
void osmo_stream_cli_clear_tx_queue(struct osmo_stream_cli *cli);
+enum osmo_stream_cli_param { + OSMO_STREAM_CLI_PAR_SCTP_SOCKOPT_AUTH_SUPPORTED, /* uint8_t: 0 disable, 1 enable, 2 force disable, 3 force enable */ + OSMO_STREAM_CLI_PAR_SCTP_SOCKOPT_ASCONF_SUPPORTED, /* uint8_t: 0 disable, 1 enable, 2 force disable, 3 force enable */ +}; + +int osmo_stream_cli_set_param(struct osmo_stream_cli *cli, enum osmo_stream_cli_param par, + void *val, size_t val_len); + /*! @} */ diff --git a/src/stream_cli.c b/src/stream_cli.c index 8f18bfb..16d033e 100644 --- a/src/stream_cli.c +++ b/src/stream_cli.c @@ -122,6 +122,7 @@ void *data; int flags; int reconnect_timeout; + struct osmo_sock_init2_multiaddr_pars ma_pars; };
void osmo_stream_cli_close(struct osmo_stream_cli *cli); @@ -420,6 +421,8 @@ cli->reconnect_timeout = 5; /* default is 5 seconds. */ INIT_LLIST_HEAD(&cli->tx_queue);
+ cli->ma_pars.sctp.version = 0; + return cli; }
@@ -733,9 +736,6 @@ */ int osmo_stream_cli_open2(struct osmo_stream_cli *cli, int reconnect) { -#ifdef HAVE_LIBSCTP - struct osmo_sock_init2_multiaddr_pars ma_pars; -#endif int ret;
/* we are reconfiguring this socket, close existing first. */ @@ -747,18 +747,11 @@ switch (cli->proto) { #ifdef HAVE_LIBSCTP case IPPROTO_SCTP: - ma_pars = (struct osmo_sock_init2_multiaddr_pars){ - .sctp = { - .version = 0, - .sockopt_auth_supported = {.set = true, .abort_on_failure = false, .value = 1 }, - .sockopt_asconf_supported = {.set = true, .abort_on_failure = false, .value = 1 }, - } - }; ret = osmo_sock_init2_multiaddr2(AF_UNSPEC, SOCK_STREAM, cli->proto, (const char **)cli->local_addr, cli->local_addrcnt, cli->local_port, (const char **)cli->addr, cli->addrcnt, cli->port, OSMO_SOCK_F_CONNECT|OSMO_SOCK_F_BIND|OSMO_SOCK_F_NONBLOCK, - &ma_pars); + &cli->ma_pars); break; #endif default: @@ -816,9 +809,6 @@ * \return negative on error, 0 on success */ int osmo_stream_cli_open(struct osmo_stream_cli *cli) { -#ifdef HAVE_LIBSCTP - struct osmo_sock_init2_multiaddr_pars ma_pars; -#endif int ret, fd = -1;
/* we are reconfiguring this socket, close existing first. */ @@ -837,18 +827,11 @@ switch (cli->proto) { #ifdef HAVE_LIBSCTP case IPPROTO_SCTP: - ma_pars = (struct osmo_sock_init2_multiaddr_pars){ - .sctp = { - .version = 0, - .sockopt_auth_supported = {.set = true, .abort_on_failure = false, .value = 1 }, - .sockopt_asconf_supported = {.set = true, .abort_on_failure = false, .value = 1 }, - } - }; ret = osmo_sock_init2_multiaddr2(cli->sk_domain, cli->sk_type, cli->proto, (const char **)cli->local_addr, cli->local_addrcnt, cli->local_port, (const char **)cli->addr, cli->addrcnt, cli->port, OSMO_SOCK_F_CONNECT|OSMO_SOCK_F_BIND|OSMO_SOCK_F_NONBLOCK, - &ma_pars); + &cli->ma_pars); break; #endif default: @@ -1018,4 +1001,32 @@ } }
+int osmo_stream_cli_set_param(struct osmo_stream_cli *cli, enum osmo_stream_cli_param par, void *val, size_t val_len) +{ + OSMO_ASSERT(cli); + uint8_t val8; + + switch (par) { + case OSMO_STREAM_CLI_PAR_SCTP_SOCKOPT_AUTH_SUPPORTED: + if (!val || val_len != sizeof(uint8_t)) + return -EINVAL; + val8 = *(uint8_t *)val; + cli->ma_pars.sctp.sockopt_auth_supported.set = true; + cli->ma_pars.sctp.sockopt_auth_supported.abort_on_failure = val8 > 1; + cli->ma_pars.sctp.sockopt_auth_supported.value = (val8 == 1 || val8 == 3) ? 1 : 0; + break; + case OSMO_STREAM_CLI_PAR_SCTP_SOCKOPT_ASCONF_SUPPORTED: + if (!val || val_len != sizeof(uint8_t)) + return -EINVAL; + val8 = *(uint8_t *)val; + cli->ma_pars.sctp.sockopt_asconf_supported.set = true; + cli->ma_pars.sctp.sockopt_asconf_supported.abort_on_failure = val8 > 1; + cli->ma_pars.sctp.sockopt_asconf_supported.value = (val8 == 1 || val8 == 3) ? 1 : 0; + break; + default: + return -ENOENT; + }; + return 0; +} + /*! @} */ diff --git a/src/stream_srv.c b/src/stream_srv.c index 9818864..e64142e 100644 --- a/src/stream_srv.c +++ b/src/stream_srv.c @@ -95,6 +95,7 @@ int (*accept_cb)(struct osmo_stream_srv_link *srv, int fd); void *data; int flags; + struct osmo_sock_init2_multiaddr_pars ma_pars; };
static int _setsockopt_nosigpipe(struct osmo_stream_srv_link *link, int new_fd) @@ -191,6 +192,8 @@ link->proto = IPPROTO_TCP; osmo_fd_setup(&link->ofd, -1, OSMO_FD_READ | OSMO_FD_WRITE, osmo_stream_srv_link_ofd_cb, link, 0);
+ link->ma_pars.sctp.version = 0; + return link; }
@@ -387,9 +390,6 @@ * \return negative on error, 0 on success */ int osmo_stream_srv_link_open(struct osmo_stream_srv_link *link) { -#ifdef HAVE_LIBSCTP - struct osmo_sock_init2_multiaddr_pars ma_pars; -#endif int ret;
if (link->ofd.fd >= 0) { @@ -412,16 +412,9 @@ switch (link->proto) { #ifdef HAVE_LIBSCTP case IPPROTO_SCTP: - ma_pars = (struct osmo_sock_init2_multiaddr_pars){ - .sctp = { - .version = 0, - .sockopt_auth_supported = {.set = true, .abort_on_failure = false, .value = 1 }, - .sockopt_asconf_supported = {.set = true, .abort_on_failure = false, .value = 1 }, - } - }; ret = osmo_sock_init2_multiaddr2(link->sk_domain, link->sk_type, link->proto, (const char **)link->addr, link->addrcnt, link->port, - NULL, 0, 0, OSMO_SOCK_F_BIND, &ma_pars); + NULL, 0, 0, OSMO_SOCK_F_BIND, &link->ma_pars); break; #endif default: @@ -472,6 +465,35 @@ link->ofd.fd = -1; }
+int osmo_stream_srv_link_set_param(struct osmo_stream_srv_link *link, enum osmo_stream_srv_link_param par, + void *val, size_t val_len) +{ + OSMO_ASSERT(link); + uint8_t val8; + + switch (par) { + case OSMO_STREAM_CLI_PAR_SCTP_SOCKOPT_AUTH_SUPPORTED: + if (!val || val_len != sizeof(uint8_t)) + return -EINVAL; + val8 = *(uint8_t *)val; + link->ma_pars.sctp.sockopt_auth_supported.set = true; + link->ma_pars.sctp.sockopt_auth_supported.abort_on_failure = val8 > 1; + link->ma_pars.sctp.sockopt_auth_supported.value = (val8 == 1 || val8 == 3) ? 1 : 0; + break; + case OSMO_STREAM_CLI_PAR_SCTP_SOCKOPT_ASCONF_SUPPORTED: + if (!val || val_len != sizeof(uint8_t)) + return -EINVAL; + val8 = *(uint8_t *)val; + link->ma_pars.sctp.sockopt_asconf_supported.set = true; + link->ma_pars.sctp.sockopt_asconf_supported.abort_on_failure = val8 > 1; + link->ma_pars.sctp.sockopt_asconf_supported.value = (val8 == 1 || val8 == 3) ? 1 : 0; + break; + default: + return -ENOENT; + }; + return 0; +} + #define OSMO_STREAM_SRV_F_FLUSH_DESTROY (1 << 0)
struct osmo_stream_srv {