diff options
Diffstat (limited to 'include/osmocom')
-rw-r--r-- | include/osmocom/hlr/Makefile.am | 3 | ||||
-rw-r--r-- | include/osmocom/hlr/dgsm.h | 46 | ||||
-rw-r--r-- | include/osmocom/hlr/gsup_server.h | 5 | ||||
-rw-r--r-- | include/osmocom/hlr/hlr.h | 25 | ||||
-rw-r--r-- | include/osmocom/hlr/hlr_vty.h | 1 | ||||
-rw-r--r-- | include/osmocom/hlr/logging.h | 1 | ||||
-rw-r--r-- | include/osmocom/hlr/mslookup_server.h | 4 | ||||
-rw-r--r-- | include/osmocom/hlr/proxy.h | 95 | ||||
-rw-r--r-- | include/osmocom/hlr/remote_hlr.h | 59 |
9 files changed, 239 insertions, 0 deletions
diff --git a/include/osmocom/hlr/Makefile.am b/include/osmocom/hlr/Makefile.am index b24f084..aceda4a 100644 --- a/include/osmocom/hlr/Makefile.am +++ b/include/osmocom/hlr/Makefile.am @@ -2,6 +2,7 @@ noinst_HEADERS = \ auc.h \ ctrl.h \ db.h \ + dgsm.h \ gsup_router.h \ gsup_server.h \ hlr.h \ @@ -12,6 +13,8 @@ noinst_HEADERS = \ lu_fsm.h \ mslookup_server.h \ mslookup_server_mdns.h \ + proxy.h \ rand.h \ + remote_hlr.h \ timestamp.h \ $(NULL) diff --git a/include/osmocom/hlr/dgsm.h b/include/osmocom/hlr/dgsm.h new file mode 100644 index 0000000..cc8f3d2 --- /dev/null +++ b/include/osmocom/hlr/dgsm.h @@ -0,0 +1,46 @@ +/* Copyright 2019 by sysmocom s.f.m.c. GmbH <info@sysmocom.de> + * + * All Rights Reserved + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU Affero General Public License as published by + * the Free Software Foundation; either version 3 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 Affero General Public License for more details. + * + * You should have received a copy of the GNU Affero General Public License + * along with this program. If not, see <http://www.gnu.org/licenses/>. + * + */ + +#pragma once + +#include <osmocom/mslookup/mslookup.h> +#include <osmocom/hlr/gsup_server.h> +#include <osmocom/hlr/logging.h> +#include <osmocom/gsupclient/cni_peer_id.h> +#include <osmocom/gsupclient/gsup_req.h> + +#define LOG_DGSM(imsi, level, fmt, args...) \ + LOGP(DDGSM, level, "(IMSI-%s) " fmt, imsi, ##args) + +struct vty; +struct remote_hlr; +struct hlr_subscriber; + +extern void *dgsm_ctx; + +void dgsm_init(void *ctx); +void dgsm_start(void *ctx); +void dgsm_stop(); + +bool dgsm_check_forward_gsup_msg(struct osmo_gsup_req *req); + +void dgsm_vty_init(); +void dgsm_mdns_client_config_apply(void); + +bool hlr_subscr_lu_age(const struct hlr_subscriber *subscr, uint32_t *age_p); diff --git a/include/osmocom/hlr/gsup_server.h b/include/osmocom/hlr/gsup_server.h index 774f750..ce7556e 100644 --- a/include/osmocom/hlr/gsup_server.h +++ b/include/osmocom/hlr/gsup_server.h @@ -27,6 +27,9 @@ struct osmo_gsup_server { struct ipa_server_link *link; osmo_gsup_read_cb_t read_cb; struct llist_head routes; + + /* Proxy requests from this server's clients to remote GSUP servers. */ + struct proxy *proxy; }; @@ -71,3 +74,5 @@ int osmo_gsup_create_insert_subscriber_data_msg(struct osmo_gsup_message *gsup, uint8_t *msisdn_enc, size_t msisdn_enc_size, uint8_t *apn_buf, size_t apn_buf_size, enum osmo_gsup_cn_domain cn_domain); +int osmo_gsup_forward_to_local_peer(struct osmo_gsup_server *server, const struct osmo_cni_peer_id *to_peer, + struct osmo_gsup_req *req, struct osmo_gsup_message *modified_gsup); diff --git a/include/osmocom/hlr/hlr.h b/include/osmocom/hlr/hlr.h index 8f26704..e8df5cd 100644 --- a/include/osmocom/hlr/hlr.h +++ b/include/osmocom/hlr/hlr.h @@ -28,6 +28,8 @@ #include <osmocom/core/tdef.h> #include <osmocom/core/sockaddr_str.h> +#include <osmocom/hlr/dgsm.h> + #define HLR_DEFAULT_DB_FILE_PATH "hlr.db" struct hlr_euse; @@ -85,6 +87,29 @@ struct hlr { struct osmo_mslookup_server_mdns *running; } mdns; } server; + + /* The mslookup client in osmo-hlr is used to find out which remote HLRs service a locally unknown IMSI. + * (It may also be used to resolve recipients for SMS-over-GSUP in the future.) */ + struct { + /* Whether to proxy/forward to remote HLRs */ + bool enable; + + /* If this is set, all GSUP for unknown IMSIs is forwarded directly to this GSUP address, + * unconditionally. */ + struct osmo_sockaddr_str gsup_gateway_proxy; + + /* mslookup client request handling */ + unsigned int result_timeout_milliseconds; + + struct osmo_mslookup_client *client; + struct { + /* Whether to use mDNS for IMSI MS Lookup */ + bool enable; + struct osmo_sockaddr_str query_addr; + char *domain_suffix; + struct osmo_mslookup_client_method *running; + } mdns; + } client; } mslookup; }; diff --git a/include/osmocom/hlr/hlr_vty.h b/include/osmocom/hlr/hlr_vty.h index 0ba9821..c026d91 100644 --- a/include/osmocom/hlr/hlr_vty.h +++ b/include/osmocom/hlr/hlr_vty.h @@ -34,6 +34,7 @@ enum hlr_vty_node { MSLOOKUP_NODE, MSLOOKUP_SERVER_NODE, MSLOOKUP_SERVER_MSC_NODE, + MSLOOKUP_CLIENT_NODE, }; int hlr_vty_is_config_node(struct vty *vty, int node); diff --git a/include/osmocom/hlr/logging.h b/include/osmocom/hlr/logging.h index 4e0a25c..a8081af 100644 --- a/include/osmocom/hlr/logging.h +++ b/include/osmocom/hlr/logging.h @@ -10,6 +10,7 @@ enum { DSS, DMSLOOKUP, DLU, + DDGSM, }; extern const struct log_info hlr_log_info; diff --git a/include/osmocom/hlr/mslookup_server.h b/include/osmocom/hlr/mslookup_server.h index 440c451..7c80f2a 100644 --- a/include/osmocom/hlr/mslookup_server.h +++ b/include/osmocom/hlr/mslookup_server.h @@ -66,3 +66,7 @@ struct mslookup_server_msc_cfg *mslookup_server_msc_get(const struct osmo_ipa_na const struct mslookup_service_host *mslookup_server_get_local_gsup_addr(); void mslookup_server_rx(const struct osmo_mslookup_query *query, struct osmo_mslookup_result *result); + +bool subscriber_has_done_lu_here(const struct osmo_mslookup_query *query, + uint32_t *lu_age_p, struct osmo_ipa_name *local_msc_name, + char *ret_imsi, size_t ret_imsi_len); diff --git a/include/osmocom/hlr/proxy.h b/include/osmocom/hlr/proxy.h new file mode 100644 index 0000000..0169038 --- /dev/null +++ b/include/osmocom/hlr/proxy.h @@ -0,0 +1,95 @@ +/* Copyright 2019 by sysmocom s.f.m.c. GmbH <info@sysmocom.de> + * + * All Rights Reserved + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU Affero General Public License as published by + * the Free Software Foundation; either version 3 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 Affero General Public License for more details. + * + * You should have received a copy of the GNU Affero General Public License + * along with this program. If not, see <http://www.gnu.org/licenses/>. + * + */ + +#pragma once + +#include <time.h> +#include <osmocom/gsm/protocol/gsm_23_003.h> +#include <osmocom/core/sockaddr_str.h> +#include <osmocom/gsupclient/cni_peer_id.h> +#include <osmocom/hlr/timestamp.h> + +struct osmo_gsup_req; +struct remote_hlr; + +struct proxy { + struct llist_head subscr_list; + struct llist_head pending_gsup_reqs; + + /* When messages arrive back from a remote HLR that this is the proxy for, reach the VLR to forward the response + * to via this osmo_gsup_server. */ + struct osmo_gsup_server *gsup_server_to_vlr; + + /* How long to keep proxy entries without a refresh, in seconds. */ + uint32_t fresh_time; + + /* How often to garbage collect the proxy cache, period in seconds. + * To change this and take effect immediately, rather use proxy_set_gc_period(). */ + uint32_t gc_period; + + struct osmo_timer_list gc_timer; +}; + +struct proxy_subscr_domain_state { + struct osmo_ipa_name vlr_name; + timestamp_t last_lu; + + /* The name from which an Update Location Request was received. Copied to vlr_name as soon as the LU is + * completed successfully. */ + struct osmo_ipa_name vlr_name_preliminary; + + /* Set if this is a middle proxy, i.e. a proxy behind another proxy. + * That is mostly to know whether the MS is attached at a local MSC/SGSN or further away. + * It could be a boolean, but store the full name for logging. Set only at successful LU acceptance. */ + struct osmo_ipa_name vlr_via_proxy; +}; + +struct proxy_subscr { + char imsi[GSM23003_IMSI_MAX_DIGITS+1]; + char msisdn[GSM23003_MSISDN_MAX_DIGITS+1]; + struct osmo_sockaddr_str remote_hlr_addr; + struct proxy_subscr_domain_state cs, ps; +}; + +void proxy_init(struct osmo_gsup_server *gsup_server_to_vlr); +void proxy_del(struct proxy *proxy); +void proxy_set_gc_period(struct proxy *proxy, uint32_t gc_period); + +/* The API to access / modify proxy entries keeps the implementation opaque, to make sure that we can easily move proxy + * storage to SQLite db. */ +int proxy_subscr_get_by_imsi(struct proxy_subscr *dst, struct proxy *proxy, const char *imsi); +int proxy_subscr_get_by_msisdn(struct proxy_subscr *dst, struct proxy *proxy, const char *msisdn); +void proxy_subscrs_get_by_remote_hlr(struct proxy *proxy, const struct osmo_sockaddr_str *remote_hlr_addr, + bool (*yield)(struct proxy *proxy, const struct proxy_subscr *subscr, void *data), + void *data); +int proxy_subscr_create_or_update(struct proxy *proxy, const struct proxy_subscr *proxy_subscr); +int proxy_subscr_del(struct proxy *proxy, const char *imsi); + +int proxy_subscr_forward_to_remote_hlr(struct proxy *proxy, const struct proxy_subscr *proxy_subscr, + struct osmo_gsup_req *req); +void proxy_subscr_forward_to_remote_hlr_resolved(struct proxy *proxy, const struct proxy_subscr *proxy_subscr, + struct remote_hlr *remote_hlr, struct osmo_gsup_req *req); + +int proxy_subscr_forward_to_vlr(struct proxy *proxy, const struct proxy_subscr *proxy_subscr, + const struct osmo_gsup_message *gsup, struct remote_hlr *from_remote_hlr); + +void proxy_subscr_remote_hlr_resolved(struct proxy *proxy, const struct proxy_subscr *proxy_subscr, + const struct osmo_sockaddr_str *remote_hlr_addr); +void proxy_subscr_remote_hlr_up(struct proxy *proxy, const struct proxy_subscr *proxy_subscr, + struct remote_hlr *remote_hlr); diff --git a/include/osmocom/hlr/remote_hlr.h b/include/osmocom/hlr/remote_hlr.h new file mode 100644 index 0000000..6a4e8a1 --- /dev/null +++ b/include/osmocom/hlr/remote_hlr.h @@ -0,0 +1,59 @@ +/* Copyright 2019 by sysmocom s.f.m.c. GmbH <info@sysmocom.de> + * + * All Rights Reserved + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU Affero General Public License as published by + * the Free Software Foundation; either version 3 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 Affero General Public License for more details. + * + * You should have received a copy of the GNU Affero General Public License + * along with this program. If not, see <http://www.gnu.org/licenses/>. + * + */ + +#pragma once + +#include <stdbool.h> +#include <osmocom/core/linuxlist.h> +#include <osmocom/core/sockaddr_str.h> + +struct osmo_gsup_client; +struct osmo_gsup_message; +struct osmo_gsup_req; +struct msgb; + +#define LOG_REMOTE_HLR(remote_hlr, level, fmt, args...) \ + LOGP(DDGSM, level, "(Proxy HLR-" OSMO_SOCKADDR_STR_FMT ") " fmt, \ + OSMO_SOCKADDR_STR_FMT_ARGS((remote_hlr) ? &(remote_hlr)->addr : NULL), ##args) + +#define LOG_REMOTE_HLR_MSG(remote_hlr, gsup_msg, level, fmt, args...) \ + LOG_REMOTE_HLR(remote_hlr, level, "%s: " fmt, osmo_gsup_message_type_name((gsup_msg)->message_type), ##args) + +/* GSUP client link for proxying to a remote HLR. */ +struct remote_hlr { + struct llist_head entry; + struct osmo_sockaddr_str addr; + struct osmo_gsup_client *gsupc; + struct llist_head pending_up_callbacks; +}; + +/*! Receive a remote_hlr address when connecting succeeded, or remote_hlr == NULL on error. + * \param addr GSUP IP address and port for which the connection was requested. + * \param remote_hlr The connected remote_hlr ready for sending, or NULL if connecting failed. + * \param data Same a passed to remote_hlr_get_or_connect(). */ +typedef void (*remote_hlr_connect_result_cb_t)(const struct osmo_sockaddr_str *addr, struct remote_hlr *remote_hlr, void *data); + +struct remote_hlr *remote_hlr_get_or_connect(const struct osmo_sockaddr_str *addr, bool connect, + remote_hlr_connect_result_cb_t connect_result_cb, void *data); +void remote_hlr_destroy(struct remote_hlr *remote_hlr); +int remote_hlr_msgb_send(struct remote_hlr *remote_hlr, struct msgb *msg); +void remote_hlr_gsup_forward_to_remote_hlr(struct remote_hlr *remote_hlr, struct osmo_gsup_req *req, + struct osmo_gsup_message *modified_gsup); + +bool remote_hlr_is_up(struct remote_hlr *remote_hlr); |