<p>laforge <strong>submitted</strong> this change.</p><p><a href="https://gerrit.osmocom.org/c/libosmo-sccp/+/15785">View Change</a></p><div style="white-space:pre-wrap">Approvals:
  laforge: Looks good to me, approved
  Jenkins Builder: Verified

</div><pre style="font-family: monospace,monospace; white-space: pre-wrap;">ss7: Support multiple addresses in SCTP connections<br><br>After this patch, Several "local-ip" and "remote-ip" lines are accepted<br>under "listen" and "asp" VTY nodes, allowing to configure an SCTP<br>connection with multiple connections, hence allowing control of SCTP<br>multi-homing features.<br>libosmo-sccp clients such as osmo-bsc and osmo-msc also gain support for<br>this feature with this commit.<br><br>Related: OS#3608<br>Depends: libosmocore.git Ic8681d9e093216c99c6bca4be81c31ef83688ed1<br>Depends: libosmo-netif.git I0fe62f518e195db4e34f3b0ad1762bb57ba9d92a<br>Change-Id: Ibd15de7a4e00dbec78ff2e2dd6a686b0f3af22de<br>---<br>M TODO-RELEASE<br>M include/osmocom/sigtran/osmo_ss7.h<br>M src/osmo_ss7.c<br>M src/osmo_ss7_vty.c<br>M src/sccp_user.c<br>M tests/vty/ss7_asp_test.vty<br>6 files changed, 184 insertions(+), 52 deletions(-)<br><br></pre><pre style="font-family: monospace,monospace; white-space: pre-wrap;"><span>diff --git a/TODO-RELEASE b/TODO-RELEASE</span><br><span>index d0852fc..98b3b88 100644</span><br><span>--- a/TODO-RELEASE</span><br><span>+++ b/TODO-RELEASE</span><br><span>@@ -7,3 +7,4 @@</span><br><span> # If any interfaces have been added since the last public release: c:r:a + 1.</span><br><span> # If any interfaces have been removed or changed since the last public release: c:r:0.</span><br><span> #library   what            description / commit summary line</span><br><span style="color: hsl(120, 100%, 40%);">+libosmo-sigtran osmo_ss7_asp_peer    ABI breakage (host is now an array of strings)</span><br><span>diff --git a/include/osmocom/sigtran/osmo_ss7.h b/include/osmocom/sigtran/osmo_ss7.h</span><br><span>index 9e8f2b3..12aeea4 100644</span><br><span>--- a/include/osmocom/sigtran/osmo_ss7.h</span><br><span>+++ b/include/osmocom/sigtran/osmo_ss7.h</span><br><span>@@ -8,6 +8,7 @@</span><br><span> #include <osmocom/core/fsm.h></span><br><span> #include <osmocom/core/msgb.h></span><br><span> #include <osmocom/core/prim.h></span><br><span style="color: hsl(120, 100%, 40%);">+#include <osmocom/core/socket.h></span><br><span> </span><br><span> extern struct llist_head osmo_ss7_instances;</span><br><span> </span><br><span>@@ -348,7 +349,8 @@</span><br><span>  ***********************************************************************/</span><br><span> </span><br><span> struct osmo_ss7_asp_peer {</span><br><span style="color: hsl(0, 100%, 40%);">-       char *host;</span><br><span style="color: hsl(120, 100%, 40%);">+   char *host[OSMO_SOCK_MAX_ADDRS];</span><br><span style="color: hsl(120, 100%, 40%);">+      size_t host_cnt;</span><br><span>     uint16_t port;</span><br><span> };</span><br><span> </span><br><span>@@ -409,6 +411,8 @@</span><br><span>       } cfg;</span><br><span> };</span><br><span> </span><br><span style="color: hsl(120, 100%, 40%);">+int osmo_ss7_asp_peer_snprintf(char* buf, size_t buf_len, struct osmo_ss7_asp_peer *peer);</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span> struct osmo_ss7_asp *</span><br><span> osmo_ss7_asp_find_by_name(struct osmo_ss7_instance *inst, const char *name);</span><br><span> struct osmo_ss7_asp</span><br><span>@@ -480,7 +484,9 @@</span><br><span> </span><br><span> int</span><br><span> osmo_ss7_xua_server_set_local_host(struct osmo_xua_server *xs, const char *local_host);</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(120, 100%, 40%);">+int</span><br><span style="color: hsl(120, 100%, 40%);">+osmo_ss7_xua_server_set_local_hosts(struct osmo_xua_server *xs, const char **local_hosts, size_t local_host_cnt);</span><br><span style="color: hsl(120, 100%, 40%);">+int osmo_ss7_xua_server_add_local_host(struct osmo_xua_server *xs, const char *local_host);</span><br><span> void osmo_ss7_xua_server_destroy(struct osmo_xua_server *xs);</span><br><span> </span><br><span> struct osmo_sccp_instance *</span><br><span>diff --git a/src/osmo_ss7.c b/src/osmo_ss7.c</span><br><span>index 9b51c29..a0b931e 100644</span><br><span>--- a/src/osmo_ss7.c</span><br><span>+++ b/src/osmo_ss7.c</span><br><span>@@ -1065,6 +1065,37 @@</span><br><span>  * SS7 Application Server Process</span><br><span>  ***********************************************************************/</span><br><span> </span><br><span style="color: hsl(120, 100%, 40%);">+int osmo_ss7_asp_peer_snprintf(char* buf, size_t buf_len, struct osmo_ss7_asp_peer *peer)</span><br><span style="color: hsl(120, 100%, 40%);">+{</span><br><span style="color: hsl(120, 100%, 40%);">+ int len = 0, offset = 0, rem = buf_len;</span><br><span style="color: hsl(120, 100%, 40%);">+       int ret, i;</span><br><span style="color: hsl(120, 100%, 40%);">+   char *after;</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+        if (buf_len < 3)</span><br><span style="color: hsl(120, 100%, 40%);">+           return -EINVAL;</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+     if (peer->host_cnt != 1) {</span><br><span style="color: hsl(120, 100%, 40%);">+         ret = snprintf(buf, rem, "(");</span><br><span style="color: hsl(120, 100%, 40%);">+              if (ret < 0)</span><br><span style="color: hsl(120, 100%, 40%);">+                       return ret;</span><br><span style="color: hsl(120, 100%, 40%);">+           OSMO_SNPRINTF_RET(ret, rem, offset, len);</span><br><span style="color: hsl(120, 100%, 40%);">+     }</span><br><span style="color: hsl(120, 100%, 40%);">+     for (i = 0; i < peer->host_cnt; i++) {</span><br><span style="color: hsl(120, 100%, 40%);">+          if (peer->host_cnt == 1)</span><br><span style="color: hsl(120, 100%, 40%);">+                   after = "";</span><br><span style="color: hsl(120, 100%, 40%);">+         else</span><br><span style="color: hsl(120, 100%, 40%);">+                  after = (i == (peer->host_cnt - 1)) ? ")" : "|";</span><br><span style="color: hsl(120, 100%, 40%);">+               ret = snprintf(buf + offset, rem, "%s%s", peer->host[i] ? : "0.0.0.0", after);</span><br><span style="color: hsl(120, 100%, 40%);">+         OSMO_SNPRINTF_RET(ret, rem, offset, len);</span><br><span style="color: hsl(120, 100%, 40%);">+     }</span><br><span style="color: hsl(120, 100%, 40%);">+     ret = snprintf(buf + offset, rem, ":%u", peer->port);</span><br><span style="color: hsl(120, 100%, 40%);">+    if (ret < 0)</span><br><span style="color: hsl(120, 100%, 40%);">+               return ret;</span><br><span style="color: hsl(120, 100%, 40%);">+   OSMO_SNPRINTF_RET(ret, rem, offset, len);</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+   return len;</span><br><span style="color: hsl(120, 100%, 40%);">+}</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span> struct osmo_ss7_asp *</span><br><span> osmo_ss7_asp_find_by_name(struct osmo_ss7_instance *inst, const char *name)</span><br><span> {</span><br><span>@@ -1103,6 +1134,7 @@</span><br><span>        char hostbuf_l[64], hostbuf_r[64];</span><br><span>   uint16_t local_port, remote_port;</span><br><span>    int rc;</span><br><span style="color: hsl(120, 100%, 40%);">+       int i;</span><br><span> </span><br><span>   OSMO_ASSERT(ss7_initialized);</span><br><span>        /* convert local and remote IP to string */</span><br><span>@@ -1129,11 +1161,26 @@</span><br><span>        llist_for_each_entry(inst, &osmo_ss7_instances, list) {</span><br><span>          struct osmo_ss7_asp *asp;</span><br><span>            llist_for_each_entry(asp, &inst->asp_list, list) {</span><br><span style="color: hsl(0, 100%, 40%);">-                       if (asp->cfg.local.port == local_port &&</span><br><span style="color: hsl(0, 100%, 40%);">-                         (!asp->cfg.remote.port ||asp->cfg.remote.port == remote_port) &&</span><br><span style="color: hsl(0, 100%, 40%);">-                          (!asp->cfg.local.host || !strcmp(asp->cfg.local.host, hostbuf_l)) &&</span><br><span style="color: hsl(0, 100%, 40%);">-                      (!asp->cfg.remote.host || !strcmp(asp->cfg.remote.host, hostbuf_r)))</span><br><span style="color: hsl(0, 100%, 40%);">-                          return asp;</span><br><span style="color: hsl(120, 100%, 40%);">+                   if (asp->cfg.local.port != local_port)</span><br><span style="color: hsl(120, 100%, 40%);">+                             continue;</span><br><span style="color: hsl(120, 100%, 40%);">+                     if (asp->cfg.remote.port && asp->cfg.remote.port != remote_port)</span><br><span style="color: hsl(120, 100%, 40%);">+                                continue;</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+                   for (i = 0; i < asp->cfg.local.host_cnt; i++) {</span><br><span style="color: hsl(120, 100%, 40%);">+                         if (!asp->cfg.local.host[i] || !strcmp(asp->cfg.local.host[i], hostbuf_l))</span><br><span style="color: hsl(120, 100%, 40%);">+                                      break;</span><br><span style="color: hsl(120, 100%, 40%);">+                        }</span><br><span style="color: hsl(120, 100%, 40%);">+                     if (i == asp->cfg.local.host_cnt)</span><br><span style="color: hsl(120, 100%, 40%);">+                          continue; /* didn't match any local.host */</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+                     for (i = 0; i < asp->cfg.remote.host_cnt; i++) {</span><br><span style="color: hsl(120, 100%, 40%);">+                                if (!asp->cfg.remote.host[i] || !strcmp(asp->cfg.remote.host[i], hostbuf_r))</span><br><span style="color: hsl(120, 100%, 40%);">+                                    break;</span><br><span style="color: hsl(120, 100%, 40%);">+                        }</span><br><span style="color: hsl(120, 100%, 40%);">+                     if (i == asp->cfg.remote.host_cnt)</span><br><span style="color: hsl(120, 100%, 40%);">+                         continue; /* didn't match any remote.host */</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+                    return asp;</span><br><span>          }</span><br><span>    }</span><br><span> </span><br><span>@@ -1250,9 +1297,9 @@</span><br><span>                        return -1;</span><br><span>           }</span><br><span>            osmo_stream_cli_set_nodelay(asp->client, true);</span><br><span style="color: hsl(0, 100%, 40%);">-              osmo_stream_cli_set_addr(asp->client, asp->cfg.remote.host);</span><br><span style="color: hsl(120, 100%, 40%);">+            osmo_stream_cli_set_addrs(asp->client, (const char**)asp->cfg.remote.host, asp->cfg.remote.host_cnt);</span><br><span>               osmo_stream_cli_set_port(asp->client, asp->cfg.remote.port);</span><br><span style="color: hsl(0, 100%, 40%);">-              osmo_stream_cli_set_local_addr(asp->client, asp->cfg.local.host);</span><br><span style="color: hsl(120, 100%, 40%);">+               osmo_stream_cli_set_local_addrs(asp->client, (const char**)asp->cfg.local.host, asp->cfg.local.host_cnt);</span><br><span>           osmo_stream_cli_set_local_port(asp->client, asp->cfg.local.port);</span><br><span>              osmo_stream_cli_set_proto(asp->client, asp_proto_to_ip_proto(asp->cfg.proto));</span><br><span>                 osmo_stream_cli_set_reconnect_timeout(asp->client, 5);</span><br><span>@@ -1699,8 +1746,11 @@</span><br><span>                           LOGP(DLSS7, LOGL_INFO, "%s: created dynamicASP %s\n",</span><br><span>                                      sock_name, asp->cfg.name);</span><br><span>                                asp->cfg.is_server = true;</span><br><span style="color: hsl(120, 100%, 40%);">+                         asp->cfg.local.host[0] = NULL;</span><br><span style="color: hsl(120, 100%, 40%);">+                             asp->cfg.remote.host_cnt = 1;</span><br><span>                             asp->cfg.remote.port = atoi(portbuf);</span><br><span style="color: hsl(0, 100%, 40%);">-                                asp->cfg.remote.host = talloc_strdup(asp, hostbuf);</span><br><span style="color: hsl(120, 100%, 40%);">+                                asp->cfg.remote.host[0] = talloc_strdup(asp, hostbuf);</span><br><span style="color: hsl(120, 100%, 40%);">+                             asp->cfg.remote.host_cnt = 1;</span><br><span>                             asp->dyn_allocated = true;</span><br><span>                                asp->server = srv;</span><br><span>                                osmo_ss7_asp_restart(asp);</span><br><span>@@ -1832,17 +1882,17 @@</span><br><span> </span><br><span>     oxs->cfg.proto = proto;</span><br><span>   oxs->cfg.local.port = local_port;</span><br><span style="color: hsl(0, 100%, 40%);">-    oxs->cfg.local.host = talloc_strdup(oxs, local_host);</span><br><span> </span><br><span>         oxs->server = osmo_stream_srv_link_create(oxs);</span><br><span>   osmo_stream_srv_link_set_data(oxs->server, oxs);</span><br><span>  osmo_stream_srv_link_set_accept_cb(oxs->server, xua_accept_cb);</span><br><span> </span><br><span>       osmo_stream_srv_link_set_nodelay(oxs->server, true);</span><br><span style="color: hsl(0, 100%, 40%);">- osmo_stream_srv_link_set_addr(oxs->server, oxs->cfg.local.host);</span><br><span>       osmo_stream_srv_link_set_port(oxs->server, oxs->cfg.local.port);</span><br><span>       osmo_stream_srv_link_set_proto(oxs->server, asp_proto_to_ip_proto(proto));</span><br><span> </span><br><span style="color: hsl(120, 100%, 40%);">+     osmo_ss7_xua_server_set_local_host(oxs, local_host);</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span>       LOGP(DLSS7, LOGL_INFO, "Created %s server on %s:%" PRIu16 "\n",</span><br><span>          get_value_string(osmo_ss7_asp_protocol_vals, proto), local_host, local_port);</span><br><span> </span><br><span>@@ -1863,20 +1913,74 @@</span><br><span> int</span><br><span> osmo_ss7_xua_server_bind(struct osmo_xua_server *xs)</span><br><span> {</span><br><span style="color: hsl(0, 100%, 40%);">- LOGP(DLSS7, LOGL_INFO, "(Re)binding %s Server to %s:%u\n",</span><br><span style="color: hsl(0, 100%, 40%);">-            get_value_string(osmo_ss7_asp_protocol_vals, xs->cfg.proto),</span><br><span style="color: hsl(0, 100%, 40%);">-         xs->cfg.local.host, xs->cfg.local.port);</span><br><span style="color: hsl(120, 100%, 40%);">+        char buf[512];</span><br><span style="color: hsl(120, 100%, 40%);">+        int rc;</span><br><span style="color: hsl(120, 100%, 40%);">+       const char *proto = get_value_string(osmo_ss7_asp_protocol_vals, xs->cfg.proto);</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+ rc = osmo_ss7_asp_peer_snprintf(buf, sizeof(buf), &xs->cfg.local);</span><br><span style="color: hsl(120, 100%, 40%);">+     if (rc < 0) {</span><br><span style="color: hsl(120, 100%, 40%);">+              LOGP(DLSS7, LOGL_INFO, "Failed parsing %s Server osmo_ss7_asp_peer\n", proto);</span><br><span style="color: hsl(120, 100%, 40%);">+      } else {</span><br><span style="color: hsl(120, 100%, 40%);">+              LOGP(DLSS7, LOGL_INFO, "(Re)binding %s Server to %s\n",</span><br><span style="color: hsl(120, 100%, 40%);">+                  proto, buf);</span><br><span style="color: hsl(120, 100%, 40%);">+     }</span><br><span>    return osmo_stream_srv_link_open(xs->server);</span><br><span> }</span><br><span> </span><br><span> int</span><br><span> osmo_ss7_xua_server_set_local_host(struct osmo_xua_server *xs, const char *local_host)</span><br><span> {</span><br><span style="color: hsl(120, 100%, 40%);">+       osmo_ss7_xua_server_set_local_hosts(xs, &local_host, 1);</span><br><span style="color: hsl(120, 100%, 40%);">+  return 0;</span><br><span style="color: hsl(120, 100%, 40%);">+}</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+int</span><br><span style="color: hsl(120, 100%, 40%);">+osmo_ss7_xua_server_set_local_hosts(struct osmo_xua_server *xs, const char **local_hosts, size_t local_host_cnt)</span><br><span style="color: hsl(120, 100%, 40%);">+{</span><br><span style="color: hsl(120, 100%, 40%);">+      int i = 0;</span><br><span>   OSMO_ASSERT(ss7_initialized);</span><br><span style="color: hsl(0, 100%, 40%);">-   osmo_talloc_replace_string(xs, &xs->cfg.local.host, local_host);</span><br><span> </span><br><span style="color: hsl(0, 100%, 40%);">-     osmo_stream_srv_link_set_addr(xs->server, xs->cfg.local.host);</span><br><span style="color: hsl(120, 100%, 40%);">+  if (local_host_cnt > ARRAY_SIZE(xs->cfg.local.host))</span><br><span style="color: hsl(120, 100%, 40%);">+            return -EINVAL;</span><br><span> </span><br><span style="color: hsl(120, 100%, 40%);">+   for (; i < local_host_cnt; i++)</span><br><span style="color: hsl(120, 100%, 40%);">+            osmo_talloc_replace_string(xs, &xs->cfg.local.host[i], local_hosts[i]);</span><br><span style="color: hsl(120, 100%, 40%);">+        for (; i < xs->cfg.local.host_cnt; i++) {</span><br><span style="color: hsl(120, 100%, 40%);">+                       talloc_free(xs->cfg.local.host[i]);</span><br><span style="color: hsl(120, 100%, 40%);">+                        xs->cfg.local.host[i] = NULL;</span><br><span style="color: hsl(120, 100%, 40%);">+      }</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+   xs->cfg.local.host_cnt = local_host_cnt;</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+ osmo_stream_srv_link_set_addrs(xs->server, (const char **)xs->cfg.local.host, xs->cfg.local.host_cnt);</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+     return 0;</span><br><span style="color: hsl(120, 100%, 40%);">+}</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+int</span><br><span style="color: hsl(120, 100%, 40%);">+osmo_ss7_xua_server_add_local_host(struct osmo_xua_server *xs, const char *local_host)</span><br><span style="color: hsl(120, 100%, 40%);">+{</span><br><span style="color: hsl(120, 100%, 40%);">+        int i;</span><br><span style="color: hsl(120, 100%, 40%);">+        bool new_is_any = !local_host || !strcmp(local_host, "0.0.0.0");</span><br><span style="color: hsl(120, 100%, 40%);">+    bool iter_is_any;</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+   /* Makes no sense to have INET_ANY and specific addresses in the set */</span><br><span style="color: hsl(120, 100%, 40%);">+       for (i = 0; i < xs->cfg.local.host_cnt; i++) {</span><br><span style="color: hsl(120, 100%, 40%);">+                  iter_is_any = !xs->cfg.local.host[i] ||</span><br><span style="color: hsl(120, 100%, 40%);">+                                  !strcmp(xs->cfg.local.host[i], "0.0.0.0");</span><br><span style="color: hsl(120, 100%, 40%);">+                 if (new_is_any && iter_is_any)</span><br><span style="color: hsl(120, 100%, 40%);">+                                return -EINVAL;</span><br><span style="color: hsl(120, 100%, 40%);">+                       if (!new_is_any && iter_is_any)</span><br><span style="color: hsl(120, 100%, 40%);">+                               return -EINVAL;</span><br><span style="color: hsl(120, 100%, 40%);">+       }</span><br><span style="color: hsl(120, 100%, 40%);">+     /* Makes no sense to have INET_ANY many times */</span><br><span style="color: hsl(120, 100%, 40%);">+      if (new_is_any && xs->cfg.local.host_cnt)</span><br><span style="color: hsl(120, 100%, 40%);">+          return -EINVAL;</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+     osmo_talloc_replace_string(xs, &xs->cfg.local.host[xs->cfg.local.host_cnt], local_host);</span><br><span style="color: hsl(120, 100%, 40%);">+    xs->cfg.local.host_cnt++;</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+        osmo_stream_srv_link_set_addrs(xs->server, (const char **)xs->cfg.local.host, xs->cfg.local.host_cnt);</span><br><span>      return 0;</span><br><span> }</span><br><span> </span><br><span>diff --git a/src/osmo_ss7_vty.c b/src/osmo_ss7_vty.c</span><br><span>index 85cc695..8169aaf 100644</span><br><span>--- a/src/osmo_ss7_vty.c</span><br><span>+++ b/src/osmo_ss7_vty.c</span><br><span>@@ -436,6 +436,8 @@</span><br><span>                xs = osmo_ss7_xua_server_create(inst, proto, port, NULL);</span><br><span>            if (!xs)</span><br><span>                     return CMD_SUCCESS;</span><br><span style="color: hsl(120, 100%, 40%);">+           /* Drop first dummy address created automatically by _create(): */</span><br><span style="color: hsl(120, 100%, 40%);">+            osmo_ss7_xua_server_set_local_hosts(xs, NULL, 0);</span><br><span>    }</span><br><span> </span><br><span>        vty->node = L_CS7_XUA_NODE;</span><br><span>@@ -469,7 +471,7 @@</span><br><span> {</span><br><span>    struct osmo_xua_server *xs = vty->index;</span><br><span> </span><br><span style="color: hsl(0, 100%, 40%);">- osmo_ss7_xua_server_set_local_host(xs, argv[0]);</span><br><span style="color: hsl(120, 100%, 40%);">+      osmo_ss7_xua_server_add_local_host(xs, argv[0]);</span><br><span> </span><br><span>         return CMD_SUCCESS;</span><br><span> }</span><br><span>@@ -492,21 +494,26 @@</span><br><span> </span><br><span> static void write_one_xua(struct vty *vty, struct osmo_xua_server *xs)</span><br><span> {</span><br><span style="color: hsl(120, 100%, 40%);">+   int i;</span><br><span>       vty_out(vty, " listen %s %u%s",</span><br><span>            get_value_string(osmo_ss7_asp_protocol_vals, xs->cfg.proto),</span><br><span>              xs->cfg.local.port, VTY_NEWLINE);</span><br><span style="color: hsl(0, 100%, 40%);">-    if (xs->cfg.local.host)</span><br><span style="color: hsl(0, 100%, 40%);">-              vty_out(vty, "  local-ip %s%s", xs->cfg.local.host, VTY_NEWLINE);</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+      for (i = 0; i < xs->cfg.local.host_cnt; i++) {</span><br><span style="color: hsl(120, 100%, 40%);">+          if (xs->cfg.local.host)</span><br><span style="color: hsl(120, 100%, 40%);">+                    vty_out(vty, "  local-ip %s%s", xs->cfg.local.host[i], VTY_NEWLINE);</span><br><span style="color: hsl(120, 100%, 40%);">+     }</span><br><span>    if (xs->cfg.accept_dyn_reg)</span><br><span>               vty_out(vty, "  accept-asp-connections dynamic-permitted%s", VTY_NEWLINE);</span><br><span> }</span><br><span> </span><br><span> static void vty_dump_xua_server(struct vty *vty, struct osmo_xua_server *xs)</span><br><span> {</span><br><span style="color: hsl(0, 100%, 40%);">-      vty_out(vty, "xUA server for %s on %s:%u%s",</span><br><span style="color: hsl(0, 100%, 40%);">-          get_value_string(osmo_ss7_asp_protocol_vals, xs->cfg.proto),</span><br><span style="color: hsl(0, 100%, 40%);">-         xs->cfg.local.host ? xs->cfg.local.host : "0.0.0.0",</span><br><span style="color: hsl(0, 100%, 40%);">-            xs->cfg.local.port, VTY_NEWLINE);</span><br><span style="color: hsl(120, 100%, 40%);">+  char buf[512];</span><br><span style="color: hsl(120, 100%, 40%);">+        const char *proto = get_value_string(osmo_ss7_asp_protocol_vals, xs->cfg.proto);</span><br><span style="color: hsl(120, 100%, 40%);">+   if (osmo_ss7_asp_peer_snprintf(buf, sizeof(buf), &xs->cfg.local) < 0)</span><br><span style="color: hsl(120, 100%, 40%);">+               snprintf(buf, sizeof(buf), "<error>");</span><br><span style="color: hsl(120, 100%, 40%);">+        vty_out(vty, "xUA server for %s on %s%s", proto, buf, VTY_NEWLINE);</span><br><span> }</span><br><span> </span><br><span> DEFUN(show_cs7_xua, show_cs7_xua_cmd,</span><br><span>@@ -604,7 +611,8 @@</span><br><span>        "Local IP Address from which to contact of ASP\n")</span><br><span> {</span><br><span>    struct osmo_ss7_asp *asp = vty->index;</span><br><span style="color: hsl(0, 100%, 40%);">-       osmo_talloc_replace_string(asp, &asp->cfg.local.host, argv[0]);</span><br><span style="color: hsl(120, 100%, 40%);">+        osmo_talloc_replace_string(asp, &asp->cfg.local.host[asp->cfg.local.host_cnt], argv[0]);</span><br><span style="color: hsl(120, 100%, 40%);">+    asp->cfg.local.host_cnt++;</span><br><span>        return CMD_SUCCESS;</span><br><span> }</span><br><span> </span><br><span>@@ -614,7 +622,8 @@</span><br><span>   "Remote IP Address of ASP\n")</span><br><span> {</span><br><span>         struct osmo_ss7_asp *asp = vty->index;</span><br><span style="color: hsl(0, 100%, 40%);">-       osmo_talloc_replace_string(asp, &asp->cfg.remote.host, argv[0]);</span><br><span style="color: hsl(120, 100%, 40%);">+       osmo_talloc_replace_string(asp, &asp->cfg.remote.host[asp->cfg.remote.host_cnt], argv[0]);</span><br><span style="color: hsl(120, 100%, 40%);">+  asp->cfg.remote.host_cnt++;</span><br><span>       return CMD_SUCCESS;</span><br><span> }</span><br><span> </span><br><span>@@ -652,6 +661,7 @@</span><br><span> {</span><br><span>      struct osmo_ss7_instance *inst;</span><br><span>      struct osmo_ss7_asp *asp;</span><br><span style="color: hsl(120, 100%, 40%);">+     char buf[512];</span><br><span>       int id = atoi(argv[0]);</span><br><span> </span><br><span>  inst = osmo_ss7_instance_find(id);</span><br><span>@@ -661,21 +671,23 @@</span><br><span>   }</span><br><span> </span><br><span>        vty_out(vty, "                                                          Effect Primary%s", VTY_NEWLINE);</span><br><span style="color: hsl(0, 100%, 40%);">-      vty_out(vty, "ASP Name      AS Name       State          Type  Rmt Port Remote IP Addr  SCTP%s", VTY_NEWLINE);</span><br><span style="color: hsl(0, 100%, 40%);">-        vty_out(vty, "------------  ------------  -------------  ----  -------- --------------- ----------%s", VTY_NEWLINE);</span><br><span style="color: hsl(120, 100%, 40%);">+        vty_out(vty, "ASP Name      AS Name       State          Type Remote IP Addr:Rmt Port SCTP%s", VTY_NEWLINE);</span><br><span style="color: hsl(120, 100%, 40%);">+        vty_out(vty, "------------  ------------  -------------  ---- ----------------------- ----------%s", VTY_NEWLINE);</span><br><span> </span><br><span>     llist_for_each_entry(asp, &inst->asp_list, list) {</span><br><span style="color: hsl(0, 100%, 40%);">-               vty_out(vty, "%-12s  %-12s  %-13s  %-4s  %-8u %-15s %-10s%s",</span><br><span style="color: hsl(120, 100%, 40%);">+               osmo_ss7_asp_peer_snprintf(buf, sizeof(buf), &asp->cfg.remote);</span><br><span style="color: hsl(120, 100%, 40%);">+                vty_out(vty, "%-12s  %-12s  %-13s  %-4s  %-14s  %-10s%s",</span><br><span>                  asp->cfg.name, "?",</span><br><span>                     asp->fi? osmo_fsm_inst_state_name(asp->fi) : "uninitialized",</span><br><span>                        get_value_string(osmo_ss7_asp_protocol_vals, asp->cfg.proto),</span><br><span style="color: hsl(0, 100%, 40%);">-                        asp->cfg.remote.port, asp->cfg.remote.host, "", VTY_NEWLINE);</span><br><span style="color: hsl(120, 100%, 40%);">+                 buf, "", VTY_NEWLINE);</span><br><span>     }</span><br><span>    return CMD_SUCCESS;</span><br><span> }</span><br><span> </span><br><span> static void write_one_asp(struct vty *vty, struct osmo_ss7_asp *asp)</span><br><span> {</span><br><span style="color: hsl(120, 100%, 40%);">+     int i;</span><br><span>       /* skip any dynamically created ASPs (e.g. auto-created at connect time) */</span><br><span>  if (asp->dyn_allocated || asp->simple_client_allocated)</span><br><span>                return;</span><br><span>@@ -685,10 +697,14 @@</span><br><span>              osmo_ss7_asp_protocol_name(asp->cfg.proto), VTY_NEWLINE);</span><br><span>         if (asp->cfg.description)</span><br><span>                 vty_out(vty, "  description %s%s", asp->cfg.description, VTY_NEWLINE);</span><br><span style="color: hsl(0, 100%, 40%);">-     if (asp->cfg.local.host)</span><br><span style="color: hsl(0, 100%, 40%);">-             vty_out(vty, "  local-ip %s%s", asp->cfg.local.host, VTY_NEWLINE);</span><br><span style="color: hsl(0, 100%, 40%);">- if (asp->cfg.remote.host)</span><br><span style="color: hsl(0, 100%, 40%);">-            vty_out(vty, "  remote-ip %s%s", asp->cfg.remote.host, VTY_NEWLINE);</span><br><span style="color: hsl(120, 100%, 40%);">+     for (i = 0; i < asp->cfg.local.host_cnt; i++) {</span><br><span style="color: hsl(120, 100%, 40%);">+         if (asp->cfg.local.host)</span><br><span style="color: hsl(120, 100%, 40%);">+                   vty_out(vty, "  local-ip %s%s", asp->cfg.local.host[i], VTY_NEWLINE);</span><br><span style="color: hsl(120, 100%, 40%);">+    }</span><br><span style="color: hsl(120, 100%, 40%);">+     for (i = 0; i < asp->cfg.remote.host_cnt; i++) {</span><br><span style="color: hsl(120, 100%, 40%);">+                if (asp->cfg.remote.host)</span><br><span style="color: hsl(120, 100%, 40%);">+                  vty_out(vty, "  remote-ip %s%s", asp->cfg.remote.host[i], VTY_NEWLINE);</span><br><span style="color: hsl(120, 100%, 40%);">+  }</span><br><span>    if (asp->cfg.qos_class)</span><br><span>           vty_out(vty, "  qos-class %u%s", asp->cfg.qos_class, VTY_NEWLINE);</span><br><span> }</span><br><span>@@ -1722,6 +1738,9 @@</span><br><span>                 break;</span><br><span>       case L_CS7_XUA_NODE:</span><br><span>                 oxs = vty->index;</span><br><span style="color: hsl(120, 100%, 40%);">+          /* If no local addr was set, or erased after _create(): */</span><br><span style="color: hsl(120, 100%, 40%);">+            if (!oxs->cfg.local.host_cnt)</span><br><span style="color: hsl(120, 100%, 40%);">+                      osmo_ss7_xua_server_set_local_host(oxs, NULL);</span><br><span>               if (osmo_ss7_xua_server_bind(oxs) < 0)</span><br><span>                    vty_out(vty, "%% Unable to bind xUA server to IP(s)%s", VTY_NEWLINE);</span><br><span>              vty->node = L_CS7_NODE;</span><br><span>diff --git a/src/sccp_user.c b/src/sccp_user.c</span><br><span>index a1302d9..4e4144e 100644</span><br><span>--- a/src/sccp_user.c</span><br><span>+++ b/src/sccp_user.c</span><br><span>@@ -566,16 +566,18 @@</span><br><span>                          goto out_rt;</span><br><span>                         asp_created = true;</span><br><span> </span><br><span style="color: hsl(0, 100%, 40%);">-                 asp->cfg.local.host = NULL;</span><br><span style="color: hsl(0, 100%, 40%);">-                  asp->cfg.remote.host = NULL;</span><br><span style="color: hsl(120, 100%, 40%);">+                       asp->cfg.local.host[0] = NULL;</span><br><span style="color: hsl(120, 100%, 40%);">+                     asp->cfg.remote.host[0] = NULL;</span><br><span>                   if (default_local_ip) {</span><br><span style="color: hsl(0, 100%, 40%);">-                         asp->cfg.local.host =</span><br><span style="color: hsl(120, 100%, 40%);">+                              asp->cfg.local.host[0] =</span><br><span>                              talloc_strdup(asp, default_local_ip);</span><br><span>                    }</span><br><span>                    if (default_remote_ip) {</span><br><span style="color: hsl(0, 100%, 40%);">-                                asp->cfg.remote.host =</span><br><span style="color: hsl(120, 100%, 40%);">+                             asp->cfg.remote.host[0] =</span><br><span>                                     talloc_strdup(asp, default_remote_ip);</span><br><span>                   }</span><br><span style="color: hsl(120, 100%, 40%);">+                     asp->cfg.local.host_cnt = 1;</span><br><span style="color: hsl(120, 100%, 40%);">+                       asp->cfg.remote.host_cnt = 1;</span><br><span>                     asp->simple_client_allocated = true;</span><br><span>              } else</span><br><span>                       talloc_free(asp_name);</span><br><span>diff --git a/tests/vty/ss7_asp_test.vty b/tests/vty/ss7_asp_test.vty</span><br><span>index 1aa954a..b502367 100644</span><br><span>--- a/tests/vty/ss7_asp_test.vty</span><br><span>+++ b/tests/vty/ss7_asp_test.vty</span><br><span>@@ -231,9 +231,9 @@</span><br><span> ss7_asp_vty_test(config-cs7-asp)# local-ip 127.0.0.100</span><br><span> ss7_asp_vty_test(config-cs7-asp)# do show cs7 instance 0 asp</span><br><span>                                                           Effect Primary</span><br><span style="color: hsl(0, 100%, 40%);">-ASP Name      AS Name       State          Type  Rmt Port Remote IP Addr  SCTP</span><br><span>-------------  ------------  -------------  ----  -------- --------------- ----------</span><br><span style="color: hsl(0, 100%, 40%);">-my-asp        ?             uninitialized  m3ua  12345    127.0.0.200               </span><br><span style="color: hsl(120, 100%, 40%);">+ASP Name      AS Name       State          Type Remote IP Addr:Rmt Port SCTP</span><br><span style="color: hsl(120, 100%, 40%);">+------------  ------------  -------------  ---- ----------------------- ----------</span><br><span style="color: hsl(120, 100%, 40%);">+my-asp        ?             uninitialized  m3ua  127.0.0.200:12345            </span><br><span> ss7_asp_vty_test(config-cs7-asp)# exit</span><br><span> </span><br><span> ss7_asp_vty_test(config-cs7)# as my-ass m3ua</span><br><span>@@ -294,25 +294,25 @@</span><br><span> </span><br><span> ss7_asp_vty_test(config-cs7-as)# do show cs7 instance 0 asp</span><br><span>                                                           Effect Primary</span><br><span style="color: hsl(0, 100%, 40%);">-ASP Name      AS Name       State          Type  Rmt Port Remote IP Addr  SCTP</span><br><span>-------------  ------------  -------------  ----  -------- --------------- ----------</span><br><span style="color: hsl(0, 100%, 40%);">-my-asp        ?             ASP_DOWN       m3ua  12345    127.0.0.200               </span><br><span style="color: hsl(120, 100%, 40%);">+ASP Name      AS Name       State          Type Remote IP Addr:Rmt Port SCTP</span><br><span style="color: hsl(120, 100%, 40%);">+------------  ------------  -------------  ---- ----------------------- ----------</span><br><span style="color: hsl(120, 100%, 40%);">+my-asp        ?             ASP_DOWN       m3ua  127.0.0.200:12345            </span><br><span> </span><br><span> ss7_asp_vty_test(config-cs7-as)# exit</span><br><span> ss7_asp_vty_test(config-cs7)# do show cs7 instance 0 asp</span><br><span>                                                           Effect Primary</span><br><span style="color: hsl(0, 100%, 40%);">-ASP Name      AS Name       State          Type  Rmt Port Remote IP Addr  SCTP</span><br><span>-------------  ------------  -------------  ----  -------- --------------- ----------</span><br><span style="color: hsl(0, 100%, 40%);">-my-asp        ?             ASP_DOWN       m3ua  12345    127.0.0.200               </span><br><span style="color: hsl(120, 100%, 40%);">+ASP Name      AS Name       State          Type Remote IP Addr:Rmt Port SCTP</span><br><span style="color: hsl(120, 100%, 40%);">+------------  ------------  -------------  ---- ----------------------- ----------</span><br><span style="color: hsl(120, 100%, 40%);">+my-asp        ?             ASP_DOWN       m3ua  127.0.0.200:12345            </span><br><span> </span><br><span> ss7_asp_vty_test(config-cs7)# exit</span><br><span> </span><br><span> </span><br><span> ss7_asp_vty_test(config)# do show cs7 instance 0 asp</span><br><span>                                                           Effect Primary</span><br><span style="color: hsl(0, 100%, 40%);">-ASP Name      AS Name       State          Type  Rmt Port Remote IP Addr  SCTP</span><br><span>-------------  ------------  -------------  ----  -------- --------------- ----------</span><br><span style="color: hsl(0, 100%, 40%);">-my-asp        ?             ASP_DOWN       m3ua  12345    127.0.0.200               </span><br><span style="color: hsl(120, 100%, 40%);">+ASP Name      AS Name       State          Type Remote IP Addr:Rmt Port SCTP</span><br><span style="color: hsl(120, 100%, 40%);">+------------  ------------  -------------  ---- ----------------------- ----------</span><br><span style="color: hsl(120, 100%, 40%);">+my-asp        ?             ASP_DOWN       m3ua  127.0.0.200:12345            </span><br><span> </span><br><span> ss7_asp_vty_test(config)# do show cs7 instance 0 as all</span><br><span>                           Routing    Routing Key                          Cic   Cic</span><br><span>@@ -352,8 +352,8 @@</span><br><span> </span><br><span> ss7_asp_vty_test(config-cs7)# do show cs7 instance 0 asp</span><br><span>                                                           Effect Primary</span><br><span style="color: hsl(0, 100%, 40%);">-ASP Name      AS Name       State          Type  Rmt Port Remote IP Addr  SCTP</span><br><span>-------------  ------------  -------------  ----  -------- --------------- ----------</span><br><span style="color: hsl(120, 100%, 40%);">+ASP Name      AS Name       State          Type Remote IP Addr:Rmt Port SCTP</span><br><span style="color: hsl(120, 100%, 40%);">+------------  ------------  -------------  ---- ----------------------- ----------</span><br><span> </span><br><span> ss7_asp_vty_test(config-cs7)# do show cs7 instance 0 as all</span><br><span>                           Routing    Routing Key                          Cic   Cic</span><br><span></span><br></pre><p>To view, visit <a href="https://gerrit.osmocom.org/c/libosmo-sccp/+/15785">change 15785</a>. To unsubscribe, or for help writing mail filters, visit <a href="https://gerrit.osmocom.org/settings">settings</a>.</p><div itemscope itemtype="http://schema.org/EmailMessage"><div itemscope itemprop="action" itemtype="http://schema.org/ViewAction"><link itemprop="url" href="https://gerrit.osmocom.org/c/libosmo-sccp/+/15785"/><meta itemprop="name" content="View Change"/></div></div>

<div style="display:none"> Gerrit-Project: libosmo-sccp </div>
<div style="display:none"> Gerrit-Branch: master </div>
<div style="display:none"> Gerrit-Change-Id: Ibd15de7a4e00dbec78ff2e2dd6a686b0f3af22de </div>
<div style="display:none"> Gerrit-Change-Number: 15785 </div>
<div style="display:none"> Gerrit-PatchSet: 5 </div>
<div style="display:none"> Gerrit-Owner: pespin <pespin@sysmocom.de> </div>
<div style="display:none"> Gerrit-Reviewer: Jenkins Builder </div>
<div style="display:none"> Gerrit-Reviewer: daniel <daniel@totalueberwachung.de> </div>
<div style="display:none"> Gerrit-Reviewer: laforge <laforge@osmocom.org> </div>
<div style="display:none"> Gerrit-Reviewer: neels <nhofmeyr@sysmocom.de> </div>
<div style="display:none"> Gerrit-Reviewer: pespin <pespin@sysmocom.de> </div>
<div style="display:none"> Gerrit-MessageType: merged </div>