Attention is currently required from: pespin.
laforge has posted comments on this change. ( https://gerrit.osmocom.org/c/libosmo-sccp/+/34613?usp=email )
Change subject: xua_server: asp: Support removing local addresses
......................................................................
Patch Set 1: Code-Review+1
--
To view, visit https://gerrit.osmocom.org/c/libosmo-sccp/+/34613?usp=email
To unsubscribe, or for help writing mail filters, visit https://gerrit.osmocom.org/settings
Gerrit-Project: libosmo-sccp
Gerrit-Branch: master
Gerrit-Change-Id: I942edff7695efeea7753f22e31c2098c201290ff
Gerrit-Change-Number: 34613
Gerrit-PatchSet: 1
Gerrit-Owner: pespin <pespin(a)sysmocom.de>
Gerrit-Reviewer: Jenkins Builder
Gerrit-Reviewer: laforge <laforge(a)osmocom.org>
Gerrit-Attention: pespin <pespin(a)sysmocom.de>
Gerrit-Comment-Date: Tue, 03 Oct 2023 12:42:49 +0000
Gerrit-HasComments: No
Gerrit-Has-Labels: Yes
Gerrit-MessageType: comment
Attention is currently required from: pespin.
laforge has posted comments on this change. ( https://gerrit.osmocom.org/c/libosmo-sccp/+/34612?usp=email )
Change subject: asp: Support removing local & remote addresses
......................................................................
Patch Set 1: Code-Review+1
--
To view, visit https://gerrit.osmocom.org/c/libosmo-sccp/+/34612?usp=email
To unsubscribe, or for help writing mail filters, visit https://gerrit.osmocom.org/settings
Gerrit-Project: libosmo-sccp
Gerrit-Branch: master
Gerrit-Change-Id: I554aee92285bd72eb90c6daf47b37055cb3067aa
Gerrit-Change-Number: 34612
Gerrit-PatchSet: 1
Gerrit-Owner: pespin <pespin(a)sysmocom.de>
Gerrit-Reviewer: Jenkins Builder
Gerrit-Reviewer: laforge <laforge(a)osmocom.org>
Gerrit-Attention: pespin <pespin(a)sysmocom.de>
Gerrit-Comment-Date: Tue, 03 Oct 2023 12:42:22 +0000
Gerrit-HasComments: No
Gerrit-Has-Labels: Yes
Gerrit-MessageType: comment
pespin has submitted this change. ( https://gerrit.osmocom.org/c/libosmo-sccp/+/34590?usp=email )
Change subject: Split osmo_ss7_as functionalities to its own file
......................................................................
Split osmo_ss7_as functionalities to its own file
Change-Id: I6e39dcb594ffe918ba117fce08cae7b5a6fd2dcc
---
M src/Makefile.am
M src/osmo_ss7.c
A src/osmo_ss7_as.c
M src/ss7_internal.h
4 files changed, 224 insertions(+), 171 deletions(-)
Approvals:
fixeria: Looks good to me, but someone else must approve
Jenkins Builder: Verified
laforge: Looks good to me, approved
diff --git a/src/Makefile.am b/src/Makefile.am
index 2067259..be6442d 100644
--- a/src/Makefile.am
+++ b/src/Makefile.am
@@ -37,6 +37,7 @@
ipa.c \
m3ua.c \
osmo_ss7.c \
+ osmo_ss7_as.c \
osmo_ss7_asp.c \
osmo_ss7_asp_peer.c \
osmo_ss7_hmrt.c \
diff --git a/src/osmo_ss7.c b/src/osmo_ss7.c
index 1e8bcfb..dbbef6b 100644
--- a/src/osmo_ss7.c
+++ b/src/osmo_ss7.c
@@ -69,14 +69,6 @@
{ 0, NULL }
};
-struct value_string osmo_ss7_as_traffic_mode_vals[] = {
- { OSMO_SS7_AS_TMOD_BCAST, "broadcast" },
- { OSMO_SS7_AS_TMOD_LOADSHARE, "loadshare" },
- { OSMO_SS7_AS_TMOD_ROUNDROBIN, "round-robin" },
- { OSMO_SS7_AS_TMOD_OVERRIDE, "override" },
- { 0, NULL }
-};
-
int osmo_ss7_find_free_rctx(struct osmo_ss7_instance *inst)
{
int32_t rctx;
@@ -88,7 +80,7 @@
return -1;
}
-static uint32_t find_free_l_rk_id(struct osmo_ss7_instance *inst)
+uint32_t ss7_find_free_l_rk_id(struct osmo_ss7_instance *inst)
{
uint32_t l_rk_id;
@@ -855,19 +847,6 @@
* SS7 Application Server
***********************************************************************/
-static const struct rate_ctr_desc ss7_as_rcd[] = {
- [SS7_AS_CTR_RX_MSU_TOTAL] = { "rx:msu:total", "Total number of MSU received" },
- [SS7_AS_CTR_TX_MSU_TOTAL] = { "tx:msu:total", "Total number of MSU transmitted" },
-};
-
-static const struct rate_ctr_group_desc ss7_as_rcgd = {
- .group_name_prefix = "sigtran_as",
- .group_description = "SIGTRAN Application Server",
- .num_ctr = ARRAY_SIZE(ss7_as_rcd),
- .ctr_desc = ss7_as_rcd,
-};
-static unsigned int g_ss7_as_rcg_idx;
-
/*! \brief Find Application Server by given name
* \param[in] inst SS7 Instance on which we operate
* \param[in] name Name of AS
@@ -954,37 +933,6 @@
return as_without_asp;
}
-/*! \brief Allocate an Application Server
- * \param[in] inst SS7 Instance on which we operate
- * \param[in] name Name of Application Server
- * \param[in] proto Protocol of Application Server
- * \returns pointer to Application Server on success; NULL otherwise */
-struct osmo_ss7_as *ss7_as_alloc(struct osmo_ss7_instance *inst, const char *name,
- enum osmo_ss7_asp_protocol proto)
-{
- struct osmo_ss7_as *as;
-
- as = talloc_zero(inst, struct osmo_ss7_as);
- if (!as)
- return NULL;
- as->ctrg = rate_ctr_group_alloc(as, &ss7_as_rcgd, g_ss7_as_rcg_idx++);
- if (!as->ctrg) {
- talloc_free(as);
- return NULL;
- }
- rate_ctr_group_set_name(as->ctrg, name);
- as->inst = inst;
- as->cfg.name = talloc_strdup(as, name);
- as->cfg.proto = proto;
- as->cfg.mode = OSMO_SS7_AS_TMOD_OVERRIDE;
- as->cfg.recovery_timeout_msec = 2000;
- as->cfg.routing_key.l_rk_id = find_free_l_rk_id(inst);
- as->fi = xua_as_fsm_start(as, LOGL_DEBUG);
- llist_add_tail(&as->list, &inst->as_list);
-
- return as;
-}
-
/*! \brief Find or Create Application Server
* \param[in] inst SS7 Instance on which we operate
* \param[in] name Name of Application Server
@@ -1012,124 +960,6 @@
return as;
}
-/*! \brief Add given ASP to given AS
- * \param[in] as Application Server to which \ref asp is added
- * \param[in] asp Application Server Process to be added to \ref as
- * \returns 0 on success; negative in case of error */
-int osmo_ss7_as_add_asp(struct osmo_ss7_as *as, const char *asp_name)
-{
- struct osmo_ss7_asp *asp;
- unsigned int i;
-
- OSMO_ASSERT(ss7_initialized);
- asp = osmo_ss7_asp_find_by_name(as->inst, asp_name);
- if (!asp)
- return -ENODEV;
-
- LOGPAS(as, DLSS7, LOGL_INFO, "Adding ASP %s to AS\n", asp->cfg.name);
-
- if (osmo_ss7_as_has_asp(as, asp))
- return 0;
-
- for (i = 0; i < ARRAY_SIZE(as->cfg.asps); i++) {
- if (!as->cfg.asps[i]) {
- as->cfg.asps[i] = asp;
- return 0;
- }
- }
-
- return -ENOSPC;
-}
-
-/*! \brief Delete given ASP from given AS
- * \param[in] as Application Server from which \ref asp is deleted
- * \param[in] asp Application Server Process to delete from \ref as
- * \returns 0 on success; negative in case of error */
-int osmo_ss7_as_del_asp(struct osmo_ss7_as *as, const char *asp_name)
-{
- struct osmo_ss7_asp *asp;
- unsigned int i;
-
- OSMO_ASSERT(ss7_initialized);
- asp = osmo_ss7_asp_find_by_name(as->inst, asp_name);
- if (!asp)
- return -ENODEV;
-
- LOGPAS(as, DLSS7, LOGL_INFO, "Removing ASP %s from AS\n", asp->cfg.name);
-
- for (i = 0; i < ARRAY_SIZE(as->cfg.asps); i++) {
- if (as->cfg.asps[i] == asp) {
- as->cfg.asps[i] = NULL;
- return 0;
- }
- }
-
- return -EINVAL;
-}
-
-/*! \brief Destroy given Application Server
- * \param[in] as Application Server to destroy */
-void osmo_ss7_as_destroy(struct osmo_ss7_as *as)
-{
- struct osmo_ss7_route *rt, *rt2;
-
- OSMO_ASSERT(ss7_initialized);
- LOGPAS(as, DLSS7, LOGL_INFO, "Destroying AS\n");
-
- if (as->fi)
- osmo_fsm_inst_term(as->fi, OSMO_FSM_TERM_REQUEST, NULL);
-
- /* find any routes pointing to this AS and remove them */
- llist_for_each_entry_safe(rt, rt2, &as->inst->rtable_system->routes, list) {
- if (rt->dest.as == as)
- osmo_ss7_route_destroy(rt);
- }
-
- as->inst = NULL;
- llist_del(&as->list);
- rate_ctr_group_free(as->ctrg);
- talloc_free(as);
-}
-
-/*! \brief Determine if given AS contains ASP
- * \param[in] as Application Server in which to look for \ref asp
- * \param[in] asp Application Server Process to look for in \ref as
- * \returns true in case \ref asp is part of \ref as; false otherwise */
-bool osmo_ss7_as_has_asp(const struct osmo_ss7_as *as,
- const struct osmo_ss7_asp *asp)
-{
- unsigned int i;
-
- OSMO_ASSERT(ss7_initialized);
- for (i = 0; i < ARRAY_SIZE(as->cfg.asps); i++) {
- if (as->cfg.asps[i] == asp)
- return true;
- }
- return false;
-}
-
-/*! Determine if given AS is in the active state.
- * \param[in] as Application Server.
- * \returns true in case as is active; false otherwise. */
-bool osmo_ss7_as_active(const struct osmo_ss7_as *as)
-{
- if (!as->fi)
- return false;
- return as->fi->state == XUA_AS_S_ACTIVE;
-}
-
-/*! Determine if given AS is in the down state.
- * \param[in] as Application Server.
- * \returns true in case as is down; false otherwise. */
-bool osmo_ss7_as_down(const struct osmo_ss7_as *as)
-{
- OSMO_ASSERT(as);
-
- if (!as->fi)
- return true;
- return as->fi->state == XUA_AS_S_DOWN;
-}
-
bool ss7_ipv6_sctp_supported(const char *host, bool bind)
{
int rc;
diff --git a/src/osmo_ss7_as.c b/src/osmo_ss7_as.c
new file mode 100644
index 0000000..34baf52
--- /dev/null
+++ b/src/osmo_ss7_as.c
@@ -0,0 +1,211 @@
+/* Core SS7 AS Handling */
+
+/* (C) 2015-2017 by Harald Welte <laforge(a)gnumonks.org>
+ * (C) 2023 by sysmocom s.f.m.c. GmbH <info(a)sysmocom.de>
+ * All Rights Reserved
+ *
+ * SPDX-License-Identifier: GPL-2.0+
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
+ *
+ */
+
+#include <string.h>
+#include <errno.h>
+#include <unistd.h>
+#include <inttypes.h>
+
+#include <osmocom/sigtran/osmo_ss7.h>
+
+#include <osmocom/core/linuxlist.h>
+#include <osmocom/core/utils.h>
+#include <osmocom/core/talloc.h>
+#include <osmocom/core/logging.h>
+
+#include "ss7_internal.h"
+#include "xua_as_fsm.h"
+
+/***********************************************************************
+ * SS7 Application Server
+ ***********************************************************************/
+
+struct value_string osmo_ss7_as_traffic_mode_vals[] = {
+ { OSMO_SS7_AS_TMOD_BCAST, "broadcast" },
+ { OSMO_SS7_AS_TMOD_LOADSHARE, "loadshare" },
+ { OSMO_SS7_AS_TMOD_ROUNDROBIN, "round-robin" },
+ { OSMO_SS7_AS_TMOD_OVERRIDE, "override" },
+ { 0, NULL }
+};
+
+static const struct rate_ctr_desc ss7_as_rcd[] = {
+ [SS7_AS_CTR_RX_MSU_TOTAL] = { "rx:msu:total", "Total number of MSU received" },
+ [SS7_AS_CTR_TX_MSU_TOTAL] = { "tx:msu:total", "Total number of MSU transmitted" },
+};
+
+static const struct rate_ctr_group_desc ss7_as_rcgd = {
+ .group_name_prefix = "sigtran_as",
+ .group_description = "SIGTRAN Application Server",
+ .num_ctr = ARRAY_SIZE(ss7_as_rcd),
+ .ctr_desc = ss7_as_rcd,
+};
+static unsigned int g_ss7_as_rcg_idx;
+
+/*! \brief Allocate an Application Server
+ * \param[in] inst SS7 Instance on which we operate
+ * \param[in] name Name of Application Server
+ * \param[in] proto Protocol of Application Server
+ * \returns pointer to Application Server on success; NULL otherwise */
+struct osmo_ss7_as *ss7_as_alloc(struct osmo_ss7_instance *inst, const char *name,
+ enum osmo_ss7_asp_protocol proto)
+{
+ struct osmo_ss7_as *as;
+
+ as = talloc_zero(inst, struct osmo_ss7_as);
+ if (!as)
+ return NULL;
+ as->ctrg = rate_ctr_group_alloc(as, &ss7_as_rcgd, g_ss7_as_rcg_idx++);
+ if (!as->ctrg) {
+ talloc_free(as);
+ return NULL;
+ }
+ rate_ctr_group_set_name(as->ctrg, name);
+ as->inst = inst;
+ as->cfg.name = talloc_strdup(as, name);
+ as->cfg.proto = proto;
+ as->cfg.mode = OSMO_SS7_AS_TMOD_OVERRIDE;
+ as->cfg.recovery_timeout_msec = 2000;
+ as->cfg.routing_key.l_rk_id = ss7_find_free_l_rk_id(inst);
+ as->fi = xua_as_fsm_start(as, LOGL_DEBUG);
+ llist_add_tail(&as->list, &inst->as_list);
+
+ return as;
+}
+
+/*! \brief Add given ASP to given AS
+ * \param[in] as Application Server to which \ref asp is added
+ * \param[in] asp Application Server Process to be added to \ref as
+ * \returns 0 on success; negative in case of error */
+int osmo_ss7_as_add_asp(struct osmo_ss7_as *as, const char *asp_name)
+{
+ struct osmo_ss7_asp *asp;
+ unsigned int i;
+
+ OSMO_ASSERT(ss7_initialized);
+ asp = osmo_ss7_asp_find_by_name(as->inst, asp_name);
+ if (!asp)
+ return -ENODEV;
+
+ LOGPAS(as, DLSS7, LOGL_INFO, "Adding ASP %s to AS\n", asp->cfg.name);
+
+ if (osmo_ss7_as_has_asp(as, asp))
+ return 0;
+
+ for (i = 0; i < ARRAY_SIZE(as->cfg.asps); i++) {
+ if (!as->cfg.asps[i]) {
+ as->cfg.asps[i] = asp;
+ return 0;
+ }
+ }
+
+ return -ENOSPC;
+}
+
+/*! \brief Delete given ASP from given AS
+ * \param[in] as Application Server from which \ref asp is deleted
+ * \param[in] asp Application Server Process to delete from \ref as
+ * \returns 0 on success; negative in case of error */
+int osmo_ss7_as_del_asp(struct osmo_ss7_as *as, const char *asp_name)
+{
+ struct osmo_ss7_asp *asp;
+ unsigned int i;
+
+ OSMO_ASSERT(ss7_initialized);
+ asp = osmo_ss7_asp_find_by_name(as->inst, asp_name);
+ if (!asp)
+ return -ENODEV;
+
+ LOGPAS(as, DLSS7, LOGL_INFO, "Removing ASP %s from AS\n", asp->cfg.name);
+
+ for (i = 0; i < ARRAY_SIZE(as->cfg.asps); i++) {
+ if (as->cfg.asps[i] == asp) {
+ as->cfg.asps[i] = NULL;
+ return 0;
+ }
+ }
+
+ return -EINVAL;
+}
+
+/*! \brief Destroy given Application Server
+ * \param[in] as Application Server to destroy */
+void osmo_ss7_as_destroy(struct osmo_ss7_as *as)
+{
+ struct osmo_ss7_route *rt, *rt2;
+
+ OSMO_ASSERT(ss7_initialized);
+ LOGPAS(as, DLSS7, LOGL_INFO, "Destroying AS\n");
+
+ if (as->fi)
+ osmo_fsm_inst_term(as->fi, OSMO_FSM_TERM_REQUEST, NULL);
+
+ /* find any routes pointing to this AS and remove them */
+ llist_for_each_entry_safe(rt, rt2, &as->inst->rtable_system->routes, list) {
+ if (rt->dest.as == as)
+ osmo_ss7_route_destroy(rt);
+ }
+
+ as->inst = NULL;
+ llist_del(&as->list);
+ rate_ctr_group_free(as->ctrg);
+ talloc_free(as);
+}
+
+/*! \brief Determine if given AS contains ASP
+ * \param[in] as Application Server in which to look for \ref asp
+ * \param[in] asp Application Server Process to look for in \ref as
+ * \returns true in case \ref asp is part of \ref as; false otherwise */
+bool osmo_ss7_as_has_asp(const struct osmo_ss7_as *as,
+ const struct osmo_ss7_asp *asp)
+{
+ unsigned int i;
+
+ OSMO_ASSERT(ss7_initialized);
+ for (i = 0; i < ARRAY_SIZE(as->cfg.asps); i++) {
+ if (as->cfg.asps[i] == asp)
+ return true;
+ }
+ return false;
+}
+
+/*! Determine if given AS is in the active state.
+ * \param[in] as Application Server.
+ * \returns true in case as is active; false otherwise. */
+bool osmo_ss7_as_active(const struct osmo_ss7_as *as)
+{
+ if (!as->fi)
+ return false;
+ return as->fi->state == XUA_AS_S_ACTIVE;
+}
+
+/*! Determine if given AS is in the down state.
+ * \param[in] as Application Server.
+ * \returns true in case as is down; false otherwise. */
+bool osmo_ss7_as_down(const struct osmo_ss7_as *as)
+{
+ OSMO_ASSERT(as);
+
+ if (!as->fi)
+ return true;
+ return as->fi->state == XUA_AS_S_DOWN;
+}
diff --git a/src/ss7_internal.h b/src/ss7_internal.h
index 4539609..6449c5b 100644
--- a/src/ss7_internal.h
+++ b/src/ss7_internal.h
@@ -3,9 +3,11 @@
/* Internal header used by libosmo-sccp, not available publicly for lib users */
#include <stdbool.h>
+#include <stdint.h>
#include <osmocom/sigtran/osmo_ss7.h>
extern bool ss7_initialized;
+uint32_t ss7_find_free_l_rk_id(struct osmo_ss7_instance *inst);
bool ss7_ipv6_sctp_supported(const char *host, bool bind);
--
To view, visit https://gerrit.osmocom.org/c/libosmo-sccp/+/34590?usp=email
To unsubscribe, or for help writing mail filters, visit https://gerrit.osmocom.org/settings
Gerrit-Project: libosmo-sccp
Gerrit-Branch: master
Gerrit-Change-Id: I6e39dcb594ffe918ba117fce08cae7b5a6fd2dcc
Gerrit-Change-Number: 34590
Gerrit-PatchSet: 1
Gerrit-Owner: pespin <pespin(a)sysmocom.de>
Gerrit-Reviewer: Jenkins Builder
Gerrit-Reviewer: fixeria <vyanitskiy(a)sysmocom.de>
Gerrit-Reviewer: laforge <laforge(a)osmocom.org>
Gerrit-Reviewer: pespin <pespin(a)sysmocom.de>
Gerrit-MessageType: merged
pespin has submitted this change. ( https://gerrit.osmocom.org/c/libosmo-sccp/+/34588?usp=email )
Change subject: Split osmo_ss7_asp_peer functionalities to its own file
......................................................................
Split osmo_ss7_asp_peer functionalities to its own file
Change-Id: I4fe457dc0ee1e904e05423557cfba2505b315a75
---
M src/Makefile.am
M src/osmo_ss7_asp.c
A src/osmo_ss7_asp_peer.c
M src/ss7_internal.h
4 files changed, 247 insertions(+), 190 deletions(-)
Approvals:
Jenkins Builder: Verified
laforge: Looks good to me, approved
fixeria: Looks good to me, but someone else must approve
diff --git a/src/Makefile.am b/src/Makefile.am
index 3c0bdb4..2067259 100644
--- a/src/Makefile.am
+++ b/src/Makefile.am
@@ -38,6 +38,7 @@
m3ua.c \
osmo_ss7.c \
osmo_ss7_asp.c \
+ osmo_ss7_asp_peer.c \
osmo_ss7_hmrt.c \
osmo_ss7_vty.c \
osmo_ss7_xua_srv.c \
diff --git a/src/osmo_ss7_asp.c b/src/osmo_ss7_asp.c
index eab6bc7..6068a9d 100644
--- a/src/osmo_ss7_asp.c
+++ b/src/osmo_ss7_asp.c
@@ -168,196 +168,6 @@
};
static unsigned int g_ss7_asp_rcg_idx;
-void osmo_ss7_asp_peer_init(struct osmo_ss7_asp_peer *peer)
-{
- memset(peer, 0, sizeof(*peer));
- peer->idx_primary = -1;
-}
-
-int osmo_ss7_asp_peer_snprintf(char *buf, size_t buf_len, struct osmo_ss7_asp_peer *peer)
-{
- int len = 0, offset = 0, rem = buf_len;
- int ret, i;
- char *after;
- char *primary;
-
- if (buf_len < 3)
- return -EINVAL;
-
- if (peer->host_cnt > 1) {
- ret = snprintf(buf, rem, "(");
- if (ret < 0)
- return ret;
- OSMO_SNPRINTF_RET(ret, rem, offset, len);
- }
- for (i = 0; i < peer->host_cnt; i++) {
- primary = (peer->idx_primary == i) ? "*" : "";
- if (peer->host_cnt == 1)
- after = "";
- else
- after = (i == (peer->host_cnt - 1)) ? ")" : "|";
- ret = snprintf(buf + offset, rem, "%s%s%s", peer->host[i] ? : "0.0.0.0", primary, after);
- OSMO_SNPRINTF_RET(ret, rem, offset, len);
- }
- ret = snprintf(buf + offset, rem, ":%u", peer->port);
- if (ret < 0)
- return ret;
- OSMO_SNPRINTF_RET(ret, rem, offset, len);
-
- return len;
-}
-
-/*! \brief Set (copy) addresses for a given ASP peer. Previous addresses are freed.
- * \param[in] peer Application Server Process peer whose addresses are to be set.
- * \param[in] talloc_ctx talloc context used to allocate new addresses.
- * \param[in] hosts Array of strings containing IP addresses.
- * \param[in] host_cnt Number of strings in hosts
- * \param[in] idx_primary Index in "hosts" array marking the SCTP Primary Address, -1 if no explicit Primary Address set
- * \returns 0 on success; negative otherwise */
-int osmo_ss7_asp_peer_set_hosts2(struct osmo_ss7_asp_peer *peer, void *talloc_ctx, const char *const*hosts, size_t host_cnt, int idx_primary)
-{
- int i = 0;
-
- if (idx_primary >= (int)host_cnt || idx_primary < -1)
- return -EINVAL;
-
- if (host_cnt > ARRAY_SIZE(peer->host))
- return -EINVAL;
-
- for (; i < host_cnt; i++)
- osmo_talloc_replace_string(talloc_ctx, &peer->host[i], hosts[i]);
- for (; i < peer->host_cnt; i++) {
- talloc_free(peer->host[i]);
- peer->host[i] = NULL;
- }
-
- peer->host_cnt = host_cnt;
- peer->idx_primary = idx_primary;
- return 0;
-}
-
-/*! \brief Set (copy) addresses for a given ASP peer. Previous addresses are freed.
- * \param[in] peer Application Server Process peer whose addresses are to be set.
- * \param[in] talloc_ctx talloc context used to allocate new addresses.
- * \param[in] hosts Array of strings containing IP addresses.
- * \param[in] host_cnt Number of strings in hosts
- * \returns 0 on success; negative otherwise */
-int osmo_ss7_asp_peer_set_hosts(struct osmo_ss7_asp_peer *peer, void *talloc_ctx, const char *const*hosts, size_t host_cnt)
-{
- return osmo_ss7_asp_peer_set_hosts2(peer, talloc_ctx, hosts, host_cnt, -1);
-}
-
-/* Is string formatted IPv4/v6 addr considered IN(6)ADDR_ANY? */
-static inline bool host_is_ip_anyaddr(const char *host, bool is_v6)
-{
- /* NULL addr is resolved as 0.0.0.0 (IPv4) by getaddrinfo(), most
- * probably for backward-compatibility reasons.
- */
- return is_v6 ? (host && !strcmp(host, "::"))
- : (!host || !strcmp(host, "0.0.0.0"));
-}
-
-/*! \brief Append (copy) address to a given ASP peer. Previous addresses are kept.
- * \param[in] peer Application Server Process peer the address is appended to.
- * \param[in] talloc_ctx talloc context used to allocate new address.
- * \param[in] host string containing an IP address.
- * \param[in] is_primary_addr whether this IP address is to be added as SCTP Primary Address
- * \returns 0 on success; negative otherwise */
-int osmo_ss7_asp_peer_add_host2(struct osmo_ss7_asp_peer *peer, void *talloc_ctx,
- const char *host, bool is_primary_addr)
-{
- int i;
- bool new_is_v6 = osmo_ip_str_type(host) == AF_INET6;
- bool new_is_any = host_is_ip_anyaddr(host, new_is_v6);
- struct osmo_sockaddr_str addr_str;
-
- if (osmo_sockaddr_str_from_str(&addr_str, host, 0) < 0)
- return -EINVAL;
-
- if (new_is_any) {
- /* Makes no sense to have INET(6)_ANY many times, or INET(6)_ANY
- * together with specific addresses, be it of same or different
- * IP version: */
- if (peer->host_cnt != 0)
- return -EINVAL;
-
- /* Makes no sense to have INET(6)_ANY as primary: */
- if (is_primary_addr)
- return -EINVAL;
-
- if (peer->host_cnt >= ARRAY_SIZE(peer->host))
- return -EINVAL;
- osmo_talloc_replace_string(talloc_ctx, &peer->host[peer->host_cnt], host);
- peer->host_cnt++;
- return 0;
- }
-
- /* Makes no sense to add specific address to set if INET(6)_ANY
- * is already set, be it from same or different IP version: */
- for (i = 0; i < peer->host_cnt; i++) {
- bool iter_is_v6 = osmo_ip_str_type(peer->host[i]) == AF_INET6;
- if (host_is_ip_anyaddr(peer->host[i], iter_is_v6))
- return -EINVAL;
- }
- /* Reached this point, no INET(6)_ANY address is set nor we are adding an INET(6)_ANY address. */
-
- /* Check if address already exists, and then if primary flags need to be changed: */
- for (i = 0; i < peer->host_cnt; i++) {
- struct osmo_sockaddr_str it_addr_str;
- bool it_is_primary;
- osmo_sockaddr_str_from_str(&it_addr_str, peer->host[i], 0);
-
- if (osmo_sockaddr_str_cmp(&addr_str, &it_addr_str) != 0)
- continue;
- it_is_primary = (peer->idx_primary == i);
- if (is_primary_addr == it_is_primary) {
- /* Nothing to do, return below */
- } else if (is_primary_addr && !it_is_primary) {
- /* Mark it as primary: */
- peer->idx_primary = i;
- } else { /* if (!is_primary_addr && it_is_primary) { */
- /* mark it as non-primary: */
- peer->idx_primary = -1;
- }
- return 0;
- }
-
- if (peer->host_cnt >= ARRAY_SIZE(peer->host))
- return -EINVAL;
-
- osmo_talloc_replace_string(talloc_ctx, &peer->host[peer->host_cnt], host);
- if (is_primary_addr)
- peer->idx_primary = peer->host_cnt;
- peer->host_cnt++;
- return 0;
-}
-
-/*! \brief Append (copy) address to a given ASP peer. Previous addresses are kept.
- * \param[in] peer Application Server Process peer the address is appended to.
- * \param[in] talloc_ctx talloc context used to allocate new address.
- * \param[in] host string containing an IP address.
- * \returns 0 on success; negative otherwise */
-int osmo_ss7_asp_peer_add_host(struct osmo_ss7_asp_peer *peer, void *talloc_ctx,
- const char *host)
-{
- return osmo_ss7_asp_peer_add_host2(peer, talloc_ctx, host, false);
-}
-
-static bool ss7_asp_peer_match_host(const struct osmo_ss7_asp_peer *peer, const char *host, bool host_is_v6)
-{
- unsigned int i;
- for (i = 0; i < peer->host_cnt; i++) {
- bool iter_is_v6 = osmo_ip_str_type(peer->host[i]) == AF_INET6;
- bool iter_is_anyaddr = host_is_ip_anyaddr(peer->host[i], iter_is_v6);
- /* "::" (v6) covers "0.0.0.0" (v4), but not otherwise */
- if ((iter_is_v6 != host_is_v6) && !(iter_is_v6 && iter_is_anyaddr))
- continue;
- if (iter_is_anyaddr || !strcmp(peer->host[i], host))
- return true;
- }
- return false;
-}
-
int ss7_asp_apply_peer_primary_address(const struct osmo_ss7_asp *asp)
{
struct osmo_fd *ofd;
diff --git a/src/osmo_ss7_asp_peer.c b/src/osmo_ss7_asp_peer.c
new file mode 100644
index 0000000..cf591d9
--- /dev/null
+++ b/src/osmo_ss7_asp_peer.c
@@ -0,0 +1,235 @@
+/* SS7 ASP Peer (one endpoint of a conn) */
+
+/* (C) 2015-2017 by Harald Welte <laforge(a)gnumonks.org>
+ * (C) 2023 by sysmocom s.f.m.c. GmbH <info(a)sysmocom.de>
+ * All Rights Reserved
+ *
+ * SPDX-License-Identifier: GPL-2.0+
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
+ *
+ */
+
+#include <string.h>
+#include <errno.h>
+#include <unistd.h>
+#include <inttypes.h>
+#include <netdb.h>
+#include <netinet/in.h>
+#include <netinet/sctp.h>
+
+#include <osmocom/core/utils.h>
+#include <osmocom/core/talloc.h>
+#include <osmocom/core/logging.h>
+#include <osmocom/core/socket.h>
+#include <osmocom/core/sockaddr_str.h>
+
+#include <osmocom/sigtran/osmo_ss7.h>
+
+#include "ss7_internal.h"
+
+
+/***********************************************************************
+ * SS7 Application Server Process peer
+ ***********************************************************************/
+
+void osmo_ss7_asp_peer_init(struct osmo_ss7_asp_peer *peer)
+{
+ memset(peer, 0, sizeof(*peer));
+ peer->idx_primary = -1;
+}
+
+int osmo_ss7_asp_peer_snprintf(char *buf, size_t buf_len, struct osmo_ss7_asp_peer *peer)
+{
+ int len = 0, offset = 0, rem = buf_len;
+ int ret, i;
+ char *after;
+ char *primary;
+
+ if (buf_len < 3)
+ return -EINVAL;
+
+ if (peer->host_cnt > 1) {
+ ret = snprintf(buf, rem, "(");
+ if (ret < 0)
+ return ret;
+ OSMO_SNPRINTF_RET(ret, rem, offset, len);
+ }
+ for (i = 0; i < peer->host_cnt; i++) {
+ primary = (peer->idx_primary == i) ? "*" : "";
+ if (peer->host_cnt == 1)
+ after = "";
+ else
+ after = (i == (peer->host_cnt - 1)) ? ")" : "|";
+ ret = snprintf(buf + offset, rem, "%s%s%s", peer->host[i] ? : "0.0.0.0", primary, after);
+ OSMO_SNPRINTF_RET(ret, rem, offset, len);
+ }
+ ret = snprintf(buf + offset, rem, ":%u", peer->port);
+ if (ret < 0)
+ return ret;
+ OSMO_SNPRINTF_RET(ret, rem, offset, len);
+
+ return len;
+}
+
+/*! \brief Set (copy) addresses for a given ASP peer. Previous addresses are freed.
+ * \param[in] peer Application Server Process peer whose addresses are to be set.
+ * \param[in] talloc_ctx talloc context used to allocate new addresses.
+ * \param[in] hosts Array of strings containing IP addresses.
+ * \param[in] host_cnt Number of strings in hosts
+ * \param[in] idx_primary Index in "hosts" array marking the SCTP Primary Address, -1 if no explicit Primary Address set
+ * \returns 0 on success; negative otherwise */
+int osmo_ss7_asp_peer_set_hosts2(struct osmo_ss7_asp_peer *peer, void *talloc_ctx, const char *const*hosts, size_t host_cnt, int idx_primary)
+{
+ int i = 0;
+
+ if (idx_primary >= (int)host_cnt || idx_primary < -1)
+ return -EINVAL;
+
+ if (host_cnt > ARRAY_SIZE(peer->host))
+ return -EINVAL;
+
+ for (; i < host_cnt; i++)
+ osmo_talloc_replace_string(talloc_ctx, &peer->host[i], hosts[i]);
+ for (; i < peer->host_cnt; i++) {
+ talloc_free(peer->host[i]);
+ peer->host[i] = NULL;
+ }
+
+ peer->host_cnt = host_cnt;
+ peer->idx_primary = idx_primary;
+ return 0;
+}
+
+/*! \brief Set (copy) addresses for a given ASP peer. Previous addresses are freed.
+ * \param[in] peer Application Server Process peer whose addresses are to be set.
+ * \param[in] talloc_ctx talloc context used to allocate new addresses.
+ * \param[in] hosts Array of strings containing IP addresses.
+ * \param[in] host_cnt Number of strings in hosts
+ * \returns 0 on success; negative otherwise */
+int osmo_ss7_asp_peer_set_hosts(struct osmo_ss7_asp_peer *peer, void *talloc_ctx, const char *const*hosts, size_t host_cnt)
+{
+ return osmo_ss7_asp_peer_set_hosts2(peer, talloc_ctx, hosts, host_cnt, -1);
+}
+
+/* Is string formatted IPv4/v6 addr considered IN(6)ADDR_ANY? */
+static inline bool host_is_ip_anyaddr(const char *host, bool is_v6)
+{
+ /* NULL addr is resolved as 0.0.0.0 (IPv4) by getaddrinfo(), most
+ * probably for backward-compatibility reasons.
+ */
+ return is_v6 ? (host && !strcmp(host, "::"))
+ : (!host || !strcmp(host, "0.0.0.0"));
+}
+
+/*! \brief Append (copy) address to a given ASP peer. Previous addresses are kept.
+ * \param[in] peer Application Server Process peer the address is appended to.
+ * \param[in] talloc_ctx talloc context used to allocate new address.
+ * \param[in] host string containing an IP address.
+ * \param[in] is_primary_addr whether this IP address is to be added as SCTP Primary Address
+ * \returns 0 on success; negative otherwise */
+int osmo_ss7_asp_peer_add_host2(struct osmo_ss7_asp_peer *peer, void *talloc_ctx,
+ const char *host, bool is_primary_addr)
+{
+ int i;
+ bool new_is_v6 = osmo_ip_str_type(host) == AF_INET6;
+ bool new_is_any = host_is_ip_anyaddr(host, new_is_v6);
+ struct osmo_sockaddr_str addr_str;
+
+ if (osmo_sockaddr_str_from_str(&addr_str, host, 0) < 0)
+ return -EINVAL;
+
+ if (new_is_any) {
+ /* Makes no sense to have INET(6)_ANY many times, or INET(6)_ANY
+ * together with specific addresses, be it of same or different
+ * IP version: */
+ if (peer->host_cnt != 0)
+ return -EINVAL;
+
+ /* Makes no sense to have INET(6)_ANY as primary: */
+ if (is_primary_addr)
+ return -EINVAL;
+
+ if (peer->host_cnt >= ARRAY_SIZE(peer->host))
+ return -EINVAL;
+ osmo_talloc_replace_string(talloc_ctx, &peer->host[peer->host_cnt], host);
+ peer->host_cnt++;
+ return 0;
+ }
+
+ /* Makes no sense to add specific address to set if INET(6)_ANY
+ * is already set, be it from same or different IP version: */
+ for (i = 0; i < peer->host_cnt; i++) {
+ bool iter_is_v6 = osmo_ip_str_type(peer->host[i]) == AF_INET6;
+ if (host_is_ip_anyaddr(peer->host[i], iter_is_v6))
+ return -EINVAL;
+ }
+ /* Reached this point, no INET(6)_ANY address is set nor we are adding an INET(6)_ANY address. */
+
+ /* Check if address already exists, and then if primary flags need to be changed: */
+ for (i = 0; i < peer->host_cnt; i++) {
+ struct osmo_sockaddr_str it_addr_str;
+ bool it_is_primary;
+ osmo_sockaddr_str_from_str(&it_addr_str, peer->host[i], 0);
+
+ if (osmo_sockaddr_str_cmp(&addr_str, &it_addr_str) != 0)
+ continue;
+ it_is_primary = (peer->idx_primary == i);
+ if (is_primary_addr == it_is_primary) {
+ /* Nothing to do, return below */
+ } else if (is_primary_addr && !it_is_primary) {
+ /* Mark it as primary: */
+ peer->idx_primary = i;
+ } else { /* if (!is_primary_addr && it_is_primary) { */
+ /* mark it as non-primary: */
+ peer->idx_primary = -1;
+ }
+ return 0;
+ }
+
+ if (peer->host_cnt >= ARRAY_SIZE(peer->host))
+ return -EINVAL;
+
+ osmo_talloc_replace_string(talloc_ctx, &peer->host[peer->host_cnt], host);
+ if (is_primary_addr)
+ peer->idx_primary = peer->host_cnt;
+ peer->host_cnt++;
+ return 0;
+}
+
+/*! \brief Append (copy) address to a given ASP peer. Previous addresses are kept.
+ * \param[in] peer Application Server Process peer the address is appended to.
+ * \param[in] talloc_ctx talloc context used to allocate new address.
+ * \param[in] host string containing an IP address.
+ * \returns 0 on success; negative otherwise */
+int osmo_ss7_asp_peer_add_host(struct osmo_ss7_asp_peer *peer, void *talloc_ctx,
+ const char *host)
+{
+ return osmo_ss7_asp_peer_add_host2(peer, talloc_ctx, host, false);
+}
+
+bool ss7_asp_peer_match_host(const struct osmo_ss7_asp_peer *peer, const char *host, bool host_is_v6)
+{
+ unsigned int i;
+ for (i = 0; i < peer->host_cnt; i++) {
+ bool iter_is_v6 = osmo_ip_str_type(peer->host[i]) == AF_INET6;
+ bool iter_is_anyaddr = host_is_ip_anyaddr(peer->host[i], iter_is_v6);
+ /* "::" (v6) covers "0.0.0.0" (v4), but not otherwise */
+ if ((iter_is_v6 != host_is_v6) && !(iter_is_v6 && iter_is_anyaddr))
+ continue;
+ if (iter_is_anyaddr || !strcmp(peer->host[i], host))
+ return true;
+ }
+ return false;
+}
diff --git a/src/ss7_internal.h b/src/ss7_internal.h
index 34378e8..d05b16e 100644
--- a/src/ss7_internal.h
+++ b/src/ss7_internal.h
@@ -21,6 +21,8 @@
int ss7_asp_apply_peer_primary_address(const struct osmo_ss7_asp *asp);
int ss7_asp_apply_primary_address(const struct osmo_ss7_asp *asp);
+bool ss7_asp_peer_match_host(const struct osmo_ss7_asp_peer *peer, const char *host, bool host_is_v6);
+
bool ss7_xua_server_set_default_local_hosts(struct osmo_xua_server *oxs);
enum ss7_as_ctr {
--
To view, visit https://gerrit.osmocom.org/c/libosmo-sccp/+/34588?usp=email
To unsubscribe, or for help writing mail filters, visit https://gerrit.osmocom.org/settings
Gerrit-Project: libosmo-sccp
Gerrit-Branch: master
Gerrit-Change-Id: I4fe457dc0ee1e904e05423557cfba2505b315a75
Gerrit-Change-Number: 34588
Gerrit-PatchSet: 2
Gerrit-Owner: pespin <pespin(a)sysmocom.de>
Gerrit-Reviewer: Jenkins Builder
Gerrit-Reviewer: fixeria <vyanitskiy(a)sysmocom.de>
Gerrit-Reviewer: laforge <laforge(a)osmocom.org>
Gerrit-Reviewer: pespin <pespin(a)sysmocom.de>
Gerrit-MessageType: merged