aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorPau Espin Pedrol <pespin@sysmocom.de>2019-10-11 16:17:45 +0200
committerPau Espin Pedrol <pespin@sysmocom.de>2019-10-15 13:11:54 +0200
commitc3a6c75cea96932b5a34c0d6a61f8da02aeac6a2 (patch)
tree954c6d404d94ccbb7b788c8366cbf25029ac2178
parentf254ef80f2143997f40c946641ead475a5fc0b4c (diff)
stream: osmo_stream_cli: Support setting multiple addr
This API will be later used to set multiple addresses for SCTP sockets. Depends: libosmocore.git Ic8681d9e093216c99c6bca4be81c31ef83688ed1 Related: OS#3608 Change-Id: I09f0d989f2309abdeb304fe570355abed2cd107b
-rw-r--r--include/osmocom/netif/stream.h2
-rw-r--r--src/stream.c95
2 files changed, 85 insertions, 12 deletions
diff --git a/include/osmocom/netif/stream.h b/include/osmocom/netif/stream.h
index 8fe2578..331dec1 100644
--- a/include/osmocom/netif/stream.h
+++ b/include/osmocom/netif/stream.h
@@ -55,9 +55,11 @@ struct osmo_stream_cli;
void osmo_stream_cli_set_nodelay(struct osmo_stream_cli *cli, bool nodelay);
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);
void osmo_stream_cli_set_proto(struct osmo_stream_cli *cli, uint16_t proto);
void osmo_stream_cli_set_local_addr(struct osmo_stream_cli *cli, const char *addr);
+int osmo_stream_cli_set_local_addrs(struct osmo_stream_cli *cli, const char **addr, size_t addrcnt);
void osmo_stream_cli_set_local_port(struct osmo_stream_cli *cli, uint16_t port);
void osmo_stream_cli_set_data(struct osmo_stream_cli *cli, void *data);
void osmo_stream_cli_set_reconnect_timeout(struct osmo_stream_cli *cli, int timeout);
diff --git a/src/stream.c b/src/stream.c
index 0027537..b7e5c3c 100644
--- a/src/stream.c
+++ b/src/stream.c
@@ -148,9 +148,11 @@ struct osmo_stream_cli {
struct llist_head tx_queue;
struct osmo_timer_list timer;
enum osmo_stream_cli_state state;
- char *addr;
+ char *addr[OSMO_SOCK_MAX_ADDRS];
+ uint8_t addrcnt;
uint16_t port;
- char *local_addr;
+ char *local_addr[OSMO_SOCK_MAX_ADDRS];
+ uint8_t local_addrcnt;
uint16_t local_port;
uint16_t proto;
int (*connect_cb)(struct osmo_stream_cli *srv);
@@ -354,8 +356,32 @@ struct osmo_stream_cli *osmo_stream_cli_create(void *ctx)
void
osmo_stream_cli_set_addr(struct osmo_stream_cli *cli, const char *addr)
{
- osmo_talloc_replace_string(cli, &cli->addr, addr);
+ osmo_stream_cli_set_addrs(cli, &addr, 1);
+}
+
+/*! \brief Set the remote address set to which we connect.
+ * Useful for protocols allowing connecting to more than one address (such as SCTP)
+ * \param[in] cli Stream Client to modify
+ * \param[in] addr Remote IP address set
+ * \return negative on error, 0 on success
+ */
+int osmo_stream_cli_set_addrs(struct osmo_stream_cli *cli, const char **addr, size_t addrcnt)
+{
+ int i = 0;
+
+ if (addrcnt > OSMO_SOCK_MAX_ADDRS)
+ return -EINVAL;
+
+ for (; i < addrcnt; i++)
+ osmo_talloc_replace_string(cli, &cli->addr[i], addr[i]);
+ for (; i < cli->addrcnt; i++) {
+ talloc_free(cli->addr[i]);
+ cli->addr[i] = NULL;
+ }
+
+ cli->addrcnt = addrcnt;
cli->flags |= OSMO_STREAM_CLI_F_RECONF;
+ return 0;
}
/*! \brief Set the remote port number to which we connect
@@ -387,8 +413,32 @@ osmo_stream_cli_set_local_port(struct osmo_stream_cli *cli, uint16_t port)
void
osmo_stream_cli_set_local_addr(struct osmo_stream_cli *cli, const char *addr)
{
- osmo_talloc_replace_string(cli, &cli->local_addr, addr);
+ osmo_stream_cli_set_local_addrs(cli, &addr, 1);
+}
+
+/*! \brief Set the local address set to which we connect.
+ * Useful for protocols allowing bind to more than one address (such as SCTP)
+ * \param[in] cli Stream Client to modify
+ * \param[in] addr Local IP address set
+ * \return negative on error, 0 on success
+ */
+int osmo_stream_cli_set_local_addrs(struct osmo_stream_cli *cli, const char **addr, size_t addrcnt)
+{
+ int i = 0;
+
+ if (addrcnt > OSMO_SOCK_MAX_ADDRS)
+ return -EINVAL;
+
+ for (; i < addrcnt; i++)
+ osmo_talloc_replace_string(cli, &cli->local_addr[i], addr[i]);
+ for (; i < cli->local_addrcnt; i++) {
+ talloc_free(cli->local_addr[i]);
+ cli->local_addr[i] = NULL;
+ }
+
+ cli->local_addrcnt = addrcnt;
cli->flags |= OSMO_STREAM_CLI_F_RECONF;
+ return 0;
}
/*! \brief Set the protocol for the stream client socket
@@ -503,10 +553,20 @@ int osmo_stream_cli_open2(struct osmo_stream_cli *cli, int reconnect)
cli->flags &= ~OSMO_STREAM_CLI_F_RECONF;
- ret = osmo_sock_init2(AF_INET, SOCK_STREAM, cli->proto,
- cli->local_addr, cli->local_port,
- cli->addr, cli->port,
- OSMO_SOCK_F_CONNECT|OSMO_SOCK_F_BIND|OSMO_SOCK_F_NONBLOCK);
+ switch (cli->proto) {
+ case IPPROTO_SCTP:
+ ret = osmo_sock_init2_multiaddr(AF_INET, 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);
+ break;
+ default:
+ ret = osmo_sock_init2(AF_INET, 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);
+ }
+
if (ret < 0) {
if (reconnect)
osmo_stream_cli_reconnect(cli);
@@ -561,10 +621,21 @@ int osmo_stream_cli_open(struct osmo_stream_cli *cli)
cli->flags &= ~OSMO_STREAM_CLI_F_RECONF;
- ret = osmo_sock_init2(AF_INET, SOCK_STREAM, cli->proto,
- cli->local_addr, cli->local_port,
- cli->addr, cli->port,
- OSMO_SOCK_F_CONNECT|OSMO_SOCK_F_BIND|OSMO_SOCK_F_NONBLOCK);
+
+ switch (cli->proto) {
+ case IPPROTO_SCTP:
+ ret = osmo_sock_init2_multiaddr(AF_INET, 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);
+ break;
+ default:
+ ret = osmo_sock_init2(AF_INET, 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);
+ }
+
if (ret < 0) {
osmo_stream_cli_reconnect(cli);
return ret;