pespin has uploaded this change for review. ( https://gerrit.osmocom.org/c/libosmo-netif/+/38827?usp=email )
Change subject: stream_cli: Add osmo_stream_cli_set_{ip_dscp,priority}() APIs ......................................................................
stream_cli: Add osmo_stream_cli_set_{ip_dscp,priority}() APIs
Change-Id: Ie5954fcf7eb1276210a99baf1e445c7ad54e0bb4 --- M include/osmocom/netif/stream.h M src/stream_cli.c 2 files changed, 75 insertions(+), 4 deletions(-)
git pull ssh://gerrit.osmocom.org:29418/libosmo-netif refs/changes/27/38827/1
diff --git a/include/osmocom/netif/stream.h b/include/osmocom/netif/stream.h index 3c4ec7e..96d8bbf 100644 --- a/include/osmocom/netif/stream.h +++ b/include/osmocom/netif/stream.h @@ -192,6 +192,8 @@ void osmo_stream_cli_set_name(struct osmo_stream_cli *cli, const char *name); const char *osmo_stream_cli_get_name(const struct osmo_stream_cli *cli); void osmo_stream_cli_set_nodelay(struct osmo_stream_cli *cli, bool nodelay); +int osmo_stream_cli_set_priority(struct osmo_stream_cli *cli, int sk_prio); +int osmo_stream_cli_set_ip_dscp(struct osmo_stream_cli *cli, uint8_t ip_dscp); void osmo_stream_cli_set_addr(struct osmo_stream_cli *cli, const char *addr); int osmo_stream_cli_set_addrs(struct osmo_stream_cli *cli, const char **addr, size_t addrcnt); void osmo_stream_cli_set_port(struct osmo_stream_cli *cli, uint16_t port); diff --git a/src/stream_cli.c b/src/stream_cli.c index 5d8a2c2..19b3862 100644 --- a/src/stream_cli.c +++ b/src/stream_cli.c @@ -102,7 +102,9 @@ uint16_t local_port; int sk_domain; int sk_type; + int sk_prio; /* socket priority, SO_PRIORITY, default=0=unset */ uint16_t proto; + uint8_t ip_dscp; /* IP Differentiated services, 0..63, default=0=unset */ osmo_stream_cli_connect_cb_t connect_cb; osmo_stream_cli_disconnect_cb_t disconnect_cb; osmo_stream_cli_read_cb_t read_cb; @@ -883,7 +885,8 @@ 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, + OSMO_SOCK_F_CONNECT | OSMO_SOCK_F_BIND | OSMO_SOCK_F_NONBLOCK | + OSMO_SOCK_F_DSCP(cli->ip_dscp) | OSMO_SOCK_F_PRIO(cli->sk_prio), &cli->ma_pars); break; #endif @@ -891,7 +894,8 @@ ret = osmo_sock_init2(AF_UNSPEC, SOCK_STREAM, cli->proto, cli->local_addr[0], cli->local_port, cli->addr[0], cli->port, - OSMO_SOCK_F_CONNECT|OSMO_SOCK_F_BIND|OSMO_SOCK_F_NONBLOCK); + OSMO_SOCK_F_CONNECT | OSMO_SOCK_F_BIND | OSMO_SOCK_F_NONBLOCK | + OSMO_SOCK_F_DSCP(cli->ip_dscp) | OSMO_SOCK_F_PRIO(cli->sk_prio)); }
if (ret < 0) { @@ -947,6 +951,69 @@ nodelay, errno); }
+/*! Set the priority value of the stream socket. + * Setting this will automatically set the socket priority + * option on any socket established via \ref osmo_stream_cli_open + * or any re-connect. This can be set either before or after opening the + * socket. + * \param[in] cli Stream client whose sockets are to be configured + * \param[in] sk_prio priority value. Values outside 0..6 require CAP_NET_ADMIN. + * \return negative on error, 0 on success + */ +int osmo_stream_cli_set_priority(struct osmo_stream_cli *cli, int sk_prio) +{ + int rc; + int fd; + + if (cli->sk_prio == sk_prio) + return 0; /* No change needed */ + + cli->sk_prio = sk_prio; + + if (!stream_cli_is_opened(cli)) + return 0; /* Config will be applied upon open() time */ + + if ((fd = osmo_stream_cli_get_fd(cli)) < 0) { /* Shouldn't happen... */ + LOGSCLI(cli, LOGL_ERROR, "set_priority(%u): failed obtaining socket\n", cli->sk_prio); + return -EBADFD; + } + if ((rc = osmo_sock_set_priority(fd, cli->sk_prio)) < 0) + LOGSCLI(cli, LOGL_ERROR, "set_priority(%u): failed setsockopt err=%d\n", + cli->sk_prio, errno); + return rc; +} + +/*! Set the DSCP (differentiated services code point) of the stream socket. + * Setting this will automatically set the IP DSCP option on any socket established + * via \ref osmo_stream_cli_open or any re-connect. This can be set either before or + * after opening the socket. + * \param[in] cli Stream client whose sockets are to be configured + * \param[in] ip_dscp DSCP value. Value range 0..63. + * \return negative on error, 0 on success + */ +int osmo_stream_cli_set_ip_dscp(struct osmo_stream_cli *cli, uint8_t ip_dscp) +{ + int rc; + int fd; + + if (cli->ip_dscp == ip_dscp) + return 0; /* No change needed */ + + cli->ip_dscp = ip_dscp; + + if (!stream_cli_is_opened(cli)) + return 0; /* Config will be applied upon open() time */ + + if ((fd = osmo_stream_cli_get_fd(cli)) < 0) { /* Shouldn't happen... */ + LOGSCLI(cli, LOGL_ERROR, "set_ip_dscp(%u): failed obtaining socket\n", cli->ip_dscp); + return -EBADFD; + } + if ((rc = osmo_sock_set_dscp(fd, cli->ip_dscp)) < 0) + LOGSCLI(cli, LOGL_ERROR, "set_ip_dscp(%u): failed setsockopt err=%d\n", + cli->ip_dscp, errno); + return rc; +} + /*! Open connection of an Osmocom stream client. * This will initiate an non-blocking outbound connect to the configured destination (server) address. * By default the client will automatically attempt to reconnect after default timeout. @@ -976,7 +1043,8 @@ #ifdef HAVE_LIBSCTP case IPPROTO_SCTP: local_addrcnt = cli->local_addrcnt; - flags = OSMO_SOCK_F_CONNECT|OSMO_SOCK_F_NONBLOCK; + flags = OSMO_SOCK_F_CONNECT | OSMO_SOCK_F_NONBLOCK | + OSMO_SOCK_F_DSCP(cli->ip_dscp) | OSMO_SOCK_F_PRIO(cli->sk_prio); if (cli->local_addrcnt > 0 || cli->local_port > 0) { /* explicit bind required? */ flags |= OSMO_SOCK_F_BIND; /* If no local addr configured, use local_addr[0]=NULL by default when creating the socket. */ @@ -993,7 +1061,8 @@ ret = osmo_sock_init2(cli->sk_domain, cli->sk_type, cli->proto, cli->local_addr[0], cli->local_port, cli->addr[0], cli->port, - OSMO_SOCK_F_CONNECT|OSMO_SOCK_F_BIND|OSMO_SOCK_F_NONBLOCK); + OSMO_SOCK_F_CONNECT | OSMO_SOCK_F_BIND | OSMO_SOCK_F_NONBLOCK | + OSMO_SOCK_F_DSCP(cli->ip_dscp) | OSMO_SOCK_F_PRIO(cli->sk_prio)); } break; default: