/* 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/>.
 *
 */

#include <string.h>
#include <talloc.h>
#include <errno.h>
#include <inttypes.h>

#include <osmocom/core/timer.h>
#include <osmocom/gsm/gsup.h>
#include <osmocom/gsm/gsm23003.h>
#include <osmocom/gsm/gsm48_ie.h>
#include <osmocom/gsupclient/gsup_client.h>
#include <osmocom/gsupclient/gsup_req.h>

#include <osmocom/hlr/logging.h>
#include <osmocom/hlr/proxy.h>
#include <osmocom/hlr/remote_hlr.h>
#include <osmocom/hlr/gsup_server.h>
#include <osmocom/hlr/gsup_router.h>

#define LOG_PROXY_SUBSCR(proxy_subscr, level, fmt, args...) \
	LOGP(DDGSM, level, "(Proxy IMSI-%s MSISDN-%s HLR-" OSMO_SOCKADDR_STR_FMT ") " fmt, \
	     ((proxy_subscr) && *(proxy_subscr)->imsi)? (proxy_subscr)->imsi : "?", \
	     ((proxy_subscr) && *(proxy_subscr)->msisdn)? (proxy_subscr)->msisdn : "?", \
	     OSMO_SOCKADDR_STR_FMT_ARGS((proxy_subscr)? &(proxy_subscr)->remote_hlr_addr : NULL), \
	     ##args)

#define LOG_PROXY_SUBSCR_MSG(proxy_subscr, gsup_msg, level, fmt, args...) \
		     LOG_PROXY_SUBSCR(proxy_subscr, level, "%s: " fmt, \
				      (gsup_msg) ? osmo_gsup_message_type_name((gsup_msg)->message_type) : "NULL", \
				      ##args)

/* The proxy subscriber database.
 * Why have a separate struct to add an llist_head entry?
 * This is to keep the option open to store the proxy data in the database instead, without any visible effect outside
 * of proxy.c. */
struct proxy_subscr_listentry {
	struct llist_head entry;
	timestamp_t last_update;
	struct proxy_subscr data;
};

struct proxy_pending_gsup_req {
	struct llist_head entry;
	struct osmo_gsup_req *req;
	timestamp_t received_at;
};

/* Defer a GSUP message until we know a remote HLR to proxy to.
 * Where to send this GSUP message is indicated by its IMSI: as soon as an MS lookup has yielded the IMSI's home HLR,
 * that's where the message should go. */
static void proxy_deferred_gsup_req_add(struct proxy *proxy, struct osmo_gsup_req *req)
{
	struct proxy_pending_gsup_req *m;

	m = talloc_zero(proxy, struct proxy_pending_gsup_req);
	OSMO_ASSERT(m);
	m->req = req;
	timestamp_update(&m->received_at);
	llist_add_tail(&m->entry, &proxy->pending_gsup_reqs);
}

static void proxy_pending_req_remote_hlr_connect_result(struct osmo_gsup_req *req, struct remote_hlr *remote_hlr)
{
	if (!remote_hlr || !remote_hlr_is_up(remote_hlr)) {
		osmo_gsup_req_respond_err(req, GMM_CAUSE_IMSI_UNKNOWN, "Proxy: Failed to connect to home HLR");
		return;
	}

	remote_hlr_gsup_forward_to_remote_hlr(remote_hlr, req, NULL);
}

static bool proxy_deferred_gsup_req_waiting(struct proxy *proxy, const char *imsi)
{
	struct proxy_pending_gsup_req *p;
	OSMO_ASSERT(imsi);

	llist_for_each_entry(p, &proxy->pending_gsup_reqs, entry) {
		if (strcmp(p->req->gsup.imsi, imsi))
			continue;
		return true;
	}
	return false;
}

/* Result of looking for remote HLR. If it failed, pass remote_hlr as NULL. On failure, the remote_hlr may be passed
 * NULL. */
static void proxy_deferred_gsup_req_pop(struct proxy *proxy, const char *imsi, struct remote_hlr *remote_hlr)
{
	struct proxy_pending_gsup_req *p, *n;
	OSMO_ASSERT(imsi);

	llist_for_each_entry_safe(p, n, &proxy->pending_gsup_reqs, entry) {
		if (strcmp(p->req->gsup.imsi, imsi))
			continue;

		proxy_pending_req_remote_hlr_connect_result(p->req, remote_hlr);
		p->req = NULL;
		llist_del(&p->entry);
		talloc_free(p);
	}
}

static bool proxy_subscr_matches_imsi(const struct proxy_subscr *proxy_subscr, const char *imsi)
{
	if (!proxy_subscr || !imsi)
		return false;
	return strcmp(proxy_subscr->imsi, imsi) == 0;
}

static bool proxy_subscr_matches_msisdn(const struct proxy_subscr *proxy_subscr, const char *msisdn)
{
	if (!proxy_subscr || !msisdn)
		return false;
	return strcmp(proxy_subscr->msisdn, msisdn) == 0;
}

static struct proxy_subscr_listentry *_proxy_get_by_imsi(struct proxy *proxy, const char *imsi)
{
	struct proxy_subscr_listentry *e;
	if (!proxy)
		return NULL;
	llist_for_each_entry(e, &proxy->subscr_list, entry) {
		if (proxy_subscr_matches_imsi(&e->data, imsi))
			return e;
	}
	return NULL;
}

static struct proxy_subscr_listentry *_proxy_get_by_msisdn(struct proxy *proxy, const char *msisdn)
{
	struct proxy_subscr_listentry *e;
	if (!proxy)
		return NULL;
	llist_for_each_entry(e, &proxy->subscr_list, entry) {
		if (proxy_subscr_matches_msisdn(&e->data, msisdn))
			return e;
	}
	return NULL;
}

int proxy_subscr_get_by_imsi(struct proxy_subscr *dst, struct proxy *proxy, const char *imsi)
{
	struct proxy_subscr_listentry *e = _proxy_get_by_imsi(proxy, imsi);
	if (!e)
		return -ENOENT;
	*dst = e->data;
	return 0;
}

int proxy_subscr_get_by_msisdn(struct proxy_subscr *dst, struct proxy *proxy, const char *msisdn)
{
	struct proxy_subscr_listentry *e = _proxy_get_by_msisdn(proxy, msisdn);
	if (!e)
		return -ENOENT;
	*dst = e->data;
	return 0;
}

int proxy_subscr_create_or_update(struct proxy *proxy, const struct proxy_subscr *proxy_subscr)
{
	struct proxy_subscr_listentry *e = _proxy_get_by_imsi(proxy, proxy_subscr->imsi);
	if (!e) {
		/* Does not exist yet */
		e = talloc_zero(proxy, struct proxy_subscr_listentry);
		llist_add(&e->entry, &proxy->subscr_list);
	}
	e->data = *proxy_subscr;
	timestamp_update(&e->last_update);
	return 0;
}

int _proxy_subscr_del(struct proxy_subscr_listentry *e)
{
	llist_del(&e->entry);
	talloc_free(e);
	return 0;
}

int proxy_subscr_del(struct proxy *proxy, const char *imsi)
{
	struct proxy_subscr_listentry *e;
	proxy_deferred_gsup_req_pop(proxy, imsi, NULL);
	e = _proxy_get_by_imsi(proxy, imsi);
	if (!e)
		return -ENOENT;
	return _proxy_subscr_del(e);
}

/* Discard stale proxy entries. */
static void proxy_cleanup(void *proxy_v)
{
	struct proxy *proxy = proxy_v;
	struct proxy_subscr_listentry *e, *n;
	uint32_t age;
	llist_for_each_entry_safe(e, n, &proxy->subscr_list, entry) {
		if (!timestamp_age(&e->last_update, &age))
			LOGP(DDGSM, LOGL_ERROR, "Invalid timestamp, deleting proxy entry\n");
		else if (age <= proxy->fresh_time)
			continue;
		LOG_PROXY_SUBSCR(&e->data, LOGL_INFO, "proxy entry timed out, deleting\n");
		_proxy_subscr_del(e);
	}
	if (proxy->gc_period)
		osmo_timer_schedule(&proxy->gc_timer, proxy->gc_period, 0);
	else
		LOGP(DDGSM, LOGL_NOTICE, "Proxy cleanup is switched off (gc_period == 0)\n");
}

void proxy_set_gc_period(struct proxy *proxy, uint32_t gc_period)
{
	proxy->gc_period = gc_period;
	proxy_cleanup(proxy);
}

void proxy_init(struct osmo_gsup_server *gsup_server_to_vlr)
{
	OSMO_ASSERT(!gsup_server_to_vlr->proxy);
	struct proxy *proxy = talloc_zero(gsup_server_to_vlr, struct proxy);
	*proxy = (struct proxy){
		.gsup_server_to_vlr = gsup_server_to_vlr,
		.fresh_time = 60*60,
		.gc_period = 60,
	};
	INIT_LLIST_HEAD(&proxy->subscr_list);
	INIT_LLIST_HEAD(&proxy->pending_gsup_reqs);

	osmo_timer_setup(&proxy->gc_timer, proxy_cleanup, proxy);
	/* Invoke to trigger the first timer schedule */
	proxy_set_gc_period(proxy, proxy->gc_period);
	gsup_server_to_vlr->proxy = proxy;
}

void proxy_del(struct proxy *proxy)
{
	osmo_timer_del(&proxy->gc_timer);
	talloc_free(proxy);
}

/* All GSUP messages sent to the remote HLR pass through this function, to modify the subscriber state or disallow
 * sending the message. Return 0 to allow sending the message. */
static int proxy_acknowledge_gsup_to_remote_hlr(struct proxy *proxy, const struct proxy_subscr *proxy_subscr,
						const struct osmo_gsup_req *req)
{
	struct proxy_subscr proxy_subscr_new = *proxy_subscr;
	bool ps;
	bool cs;
	int rc;

	if (req->source_name.type != OSMO_CNI_PEER_ID_IPA_NAME) {
		LOG_PROXY_SUBSCR_MSG(proxy_subscr, &req->gsup, LOGL_ERROR,
				     "Unsupported GSUP peer id type: %s\n",
				     osmo_cni_peer_id_type_name(req->source_name.type));
		return -ENOTSUP;
	}

	switch (req->gsup.message_type) {

	case OSMO_GSUP_MSGT_UPDATE_LOCATION_REQUEST:
		/* Store the CS and PS VLR name in vlr_name_preliminary to later update the right {cs,ps} LU timestamp
		 * when receiving an OSMO_GSUP_MSGT_UPDATE_LOCATION_RESULT. Store in vlr_name_preliminary so that in
		 * case the LU fails, we keep the vlr_name intact. */
		switch (req->gsup.cn_domain) {
		case OSMO_GSUP_CN_DOMAIN_CS:
			proxy_subscr_new.cs.vlr_name_preliminary = req->source_name.ipa_name;
			break;
		case OSMO_GSUP_CN_DOMAIN_PS:
			proxy_subscr_new.ps.vlr_name_preliminary = req->source_name.ipa_name;
			break;
		default:
			break;
		}

		ps = cs = false;
		if (osmo_ipa_name_cmp(&proxy_subscr_new.cs.vlr_name_preliminary, &proxy_subscr->cs.vlr_name_preliminary))
			cs = true;
		if (osmo_ipa_name_cmp(&proxy_subscr_new.ps.vlr_name_preliminary, &proxy_subscr->ps.vlr_name_preliminary))
			ps = true;

		if (!(cs || ps)) {
			LOG_PROXY_SUBSCR_MSG(proxy_subscr, &req->gsup, LOGL_DEBUG, "VLR names remain unchanged\n");
			break;
		}

		rc = proxy_subscr_create_or_update(proxy, &proxy_subscr_new);
		LOG_PROXY_SUBSCR_MSG(proxy_subscr, &req->gsup, rc ? LOGL_ERROR : LOGL_INFO,
				     "%s: preliminary VLR name for%s%s to %s\n",
				     rc ? "failed to update" : "updated",
				     cs ? " CS" : "", ps ? " PS" : "",
				     osmo_cni_peer_id_to_str(&req->source_name));
		break;
	/* TODO: delete proxy entry in case of a Purge Request? */
	default:
		break;
	}
	return 0;
}

/* All GSUP messages received from the remote HLR to be sent to a local MSC pass through this function, to modify the
 * subscriber state or disallow sending the message. Return 0 to allow sending the message.
 * The local MSC shall be indicated by gsup.destination_name. */
static int proxy_acknowledge_gsup_from_remote_hlr(struct proxy *proxy, const struct proxy_subscr *proxy_subscr,
						  const struct osmo_gsup_message *gsup,
						  struct remote_hlr *from_remote_hlr,
						  const struct osmo_ipa_name *destination,
						  const struct osmo_ipa_name *via_peer)
{
	struct proxy_subscr proxy_subscr_new = *proxy_subscr;
	bool ps;
	bool cs;
	bool vlr_name_changed_cs = false;
	bool vlr_name_changed_ps = false;
	int rc;
	struct osmo_ipa_name via_proxy = {};
	if (osmo_ipa_name_cmp(via_peer, destination))
		via_proxy = *via_peer;

	switch (gsup->message_type) {
	case OSMO_GSUP_MSGT_INSERT_DATA_REQUEST:
		/* Remember the MSISDN of the subscriber. This does not need to be a preliminary record, because when
		 * the HLR tells us about subscriber data, it is definitive info and there is no ambiguity (like there
		 * would be with failed LU attempts from various sources). */
		if (!gsup->msisdn_enc_len)
			LOG_PROXY_SUBSCR_MSG(proxy_subscr, gsup, LOGL_DEBUG, "No MSISDN in this Insert Data Request\n");
		else if (gsm48_decode_bcd_number2(proxy_subscr_new.msisdn, sizeof(proxy_subscr_new.msisdn),
						  gsup->msisdn_enc, gsup->msisdn_enc_len, 0))
			LOG_PROXY_SUBSCR_MSG(proxy_subscr, gsup, LOGL_ERROR, "Failed to decode MSISDN\n");
		else if (!osmo_msisdn_str_valid(proxy_subscr_new.msisdn))
			LOG_PROXY_SUBSCR_MSG(proxy_subscr, gsup, LOGL_ERROR, "invalid MSISDN: %s\n",
					     osmo_quote_str_c(OTC_SELECT, proxy_subscr_new.msisdn, -1));
		else if (!strcmp(proxy_subscr->msisdn, proxy_subscr_new.msisdn))
			LOG_PROXY_SUBSCR_MSG(proxy_subscr, gsup, LOGL_DEBUG, "already have MSISDN = %s\n",
					     proxy_subscr_new.msisdn);
		else if (proxy_subscr_create_or_update(proxy, &proxy_subscr_new))
			LOG_PROXY_SUBSCR_MSG(proxy_subscr, gsup, LOGL_ERROR, "failed to update MSISDN to %s\n",
					     proxy_subscr_new.msisdn);
		else
			LOG_PROXY_SUBSCR_MSG(proxy_subscr, gsup, LOGL_INFO, "stored MSISDN=%s\n",
					     proxy_subscr_new.msisdn);
		break;

	case OSMO_GSUP_MSGT_UPDATE_LOCATION_RESULT:
		/* Update the Location Updating timestamp */
		cs = ps = false;
		if (!osmo_ipa_name_cmp(destination, &proxy_subscr->cs.vlr_name_preliminary)) {
			timestamp_update(&proxy_subscr_new.cs.last_lu);
			proxy_subscr_new.cs.vlr_name_preliminary = (struct osmo_ipa_name){};
			vlr_name_changed_cs =
				osmo_ipa_name_cmp(&proxy_subscr->cs.vlr_name, destination)
				|| osmo_ipa_name_cmp(&proxy_subscr->cs.vlr_via_proxy, &via_proxy);
			proxy_subscr_new.cs.vlr_name = *destination;
			proxy_subscr_new.cs.vlr_via_proxy = via_proxy;
			cs = true;
		}
		if (!osmo_ipa_name_cmp(destination, &proxy_subscr->ps.vlr_name_preliminary)) {
			timestamp_update(&proxy_subscr_new.ps.last_lu);
			proxy_subscr_new.ps.vlr_name_preliminary = (struct osmo_ipa_name){};
			proxy_subscr_new.ps.vlr_name = *destination;
			vlr_name_changed_ps =
				osmo_ipa_name_cmp(&proxy_subscr->ps.vlr_name, destination)
				|| osmo_ipa_name_cmp(&proxy_subscr->ps.vlr_via_proxy, &via_proxy);
			proxy_subscr_new.ps.vlr_via_proxy = via_proxy;
			ps = true;
		}
		if (!(cs || ps)) {
			LOG_PROXY_SUBSCR_MSG(proxy_subscr, gsup, LOGL_ERROR,
					     "destination is neither CS nor PS VLR: %s\n",
					     osmo_ipa_name_to_str(destination));
			return GMM_CAUSE_PROTO_ERR_UNSPEC;
		}
		rc = proxy_subscr_create_or_update(proxy, &proxy_subscr_new);

		LOG_PROXY_SUBSCR_MSG(proxy_subscr, gsup, rc ? LOGL_ERROR : LOGL_INFO,
				     "%s LU: timestamp for%s%s%s%s%s%s%s%s%s%s\n",
				     rc ? "failed to update" : "updated",
				     cs ? " CS" : "", ps ? " PS" : "",
				     vlr_name_changed_cs? ", CS VLR=" : "",
				     vlr_name_changed_cs? osmo_ipa_name_to_str(&proxy_subscr_new.cs.vlr_name) : "",
				     proxy_subscr_new.cs.vlr_via_proxy.len ? " via proxy " : "",
				     proxy_subscr_new.cs.vlr_via_proxy.len ?
					     osmo_ipa_name_to_str(&proxy_subscr_new.cs.vlr_via_proxy) : "",
				     vlr_name_changed_ps? ", PS VLR=" : "",
				     vlr_name_changed_ps? osmo_ipa_name_to_str(&proxy_subscr_new.ps.vlr_name) : "",
				     proxy_subscr_new.ps.vlr_via_proxy.len ? " via proxy " : "",
				     proxy_subscr_new.ps.vlr_via_proxy.len ?
					     osmo_ipa_name_to_str(&proxy_subscr_new.ps.vlr_via_proxy) : ""
				    );
		break;

	default:
		break;
	}

	return 0;
}

static void proxy_remote_hlr_connect_result_cb(const struct osmo_sockaddr_str *addr, struct remote_hlr *remote_hlr,
					       void *data)
{
	struct proxy *proxy = data;
	struct proxy_subscr_listentry *e;
	if (!proxy)
		return;
	llist_for_each_entry(e, &proxy->subscr_list, entry) {
		if (!osmo_sockaddr_str_cmp(addr, &e->data.remote_hlr_addr)) {
			proxy_deferred_gsup_req_pop(proxy, e->data.imsi, remote_hlr);
		}
	}
}

/* Store the remote HLR's GSUP address for this proxy subscriber.
 * This can be set before the remote_hlr is connected, or after.
 * And, this can be set before the gsup_req has been queued for this HLR, or after.
 */
void proxy_subscr_remote_hlr_resolved(struct proxy *proxy, const struct proxy_subscr *proxy_subscr,
				      const struct osmo_sockaddr_str *remote_hlr_addr)
{
	struct proxy_subscr proxy_subscr_new;

	if (osmo_sockaddr_str_is_nonzero(&proxy_subscr->remote_hlr_addr)) {
		if (!osmo_sockaddr_str_cmp(remote_hlr_addr, &proxy_subscr->remote_hlr_addr)) {
			/* Already have this remote address */
			return;
		} else {
			LOG_PROXY_SUBSCR(proxy_subscr, LOGL_NOTICE,
					 "Remote HLR address changes to " OSMO_SOCKADDR_STR_FMT "\n",
					 OSMO_SOCKADDR_STR_FMT_ARGS(remote_hlr_addr));
		}
	}

	/* Store the address. Make a copy to modify. */
	proxy_subscr_new = *proxy_subscr;
	proxy_subscr = &proxy_subscr_new;
	proxy_subscr_new.remote_hlr_addr = *remote_hlr_addr;

	if (proxy_subscr_create_or_update(proxy, proxy_subscr)) {
		LOG_PROXY_SUBSCR(proxy_subscr, LOGL_ERROR, "Failed to store proxy entry for remote HLR\n");
		/* If no remote HLR is known for the IMSI, the proxy entry is pointless. */
		proxy_subscr_del(proxy, proxy_subscr->imsi);
		return;
	}
	LOG_PROXY_SUBSCR(proxy_subscr, LOGL_DEBUG, "Remote HLR resolved, stored address\n");

	/* If any messages for this HLR are already spooled, connect now. Otherwise wait for
	 * proxy_subscr_forward_to_remote_hlr() to connect then. */
	if (proxy_deferred_gsup_req_waiting(proxy, proxy_subscr->imsi))
		remote_hlr_get_or_connect(&proxy_subscr->remote_hlr_addr, true,
					  proxy_remote_hlr_connect_result_cb, proxy);
}

int proxy_subscr_forward_to_remote_hlr(struct proxy *proxy, const struct proxy_subscr *proxy_subscr, struct osmo_gsup_req *req)
{
	struct remote_hlr *remote_hlr;
	int rc;

	rc = proxy_acknowledge_gsup_to_remote_hlr(proxy, proxy_subscr, req);
	if (rc) {
		osmo_gsup_req_respond_err(req, GMM_CAUSE_PROTO_ERR_UNSPEC, "Proxy does not allow this message");
		return rc;
	}

	if (!osmo_sockaddr_str_is_nonzero(&proxy_subscr->remote_hlr_addr)) {
		/* We don't know the remote target yet. Still waiting for an MS lookup response, which will end up
		 * calling proxy_subscr_remote_hlr_resolved(). See dgsm.c. */
		LOG_PROXY_SUBSCR_MSG(proxy_subscr, &req->gsup, LOGL_DEBUG, "deferring until remote HLR is known\n");
		proxy_deferred_gsup_req_add(proxy, req);
		return 0;
	}

	if (!osmo_cni_peer_id_is_empty(&req->via_proxy)) {
		LOG_PROXY_SUBSCR_MSG(proxy_subscr, &req->gsup, LOGL_INFO, "VLR->HLR: forwarding from %s via proxy %s\n",
				     osmo_cni_peer_id_to_str(&req->source_name),
				     osmo_cni_peer_id_to_str(&req->via_proxy));
	} else {
		LOG_PROXY_SUBSCR_MSG(proxy_subscr, &req->gsup, LOGL_INFO, "VLR->HLR: forwarding from %s\n",
				     osmo_cni_peer_id_to_str(&req->source_name));
	}

	/* We could always store in the defer queue and empty the queue if the connection is already up.
	 * Slight optimisation: if the remote_hlr is already up and running, skip the defer queue.
	 * First ask for an existing remote_hlr. */
	remote_hlr = remote_hlr_get_or_connect(&proxy_subscr->remote_hlr_addr, false, NULL, NULL);
	if (remote_hlr && remote_hlr_is_up(remote_hlr)) {
		proxy_pending_req_remote_hlr_connect_result(req, remote_hlr);
		return 0;
	}

	/* Not existing or not up. Defer req and ask to be notified when it is up.
	 * If the remote_hlr exists but is not connected yet, there should actually already be a pending
	 * proxy_remote_hlr_connect_result_cb queued, but it doesn't hurt to do that more often. */
	proxy_deferred_gsup_req_add(proxy, req);
	remote_hlr_get_or_connect(&proxy_subscr->remote_hlr_addr, true,
				  proxy_remote_hlr_connect_result_cb, proxy);
	return 0;
}

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)
{
	struct osmo_ipa_name destination;
	struct osmo_gsup_conn *vlr_conn;
	struct msgb *msg;

	if (osmo_ipa_name_set(&destination, gsup->destination_name, gsup->destination_name_len)) {
		LOG_PROXY_SUBSCR_MSG(proxy_subscr, gsup, LOGL_ERROR,
				     "no valid Destination Name IE, cannot route to VLR.\n");
		return GMM_CAUSE_INV_MAND_INFO;
	}

	/* Route to MSC/SGSN that we're proxying for */
	vlr_conn = gsup_route_find_by_ipa_name(proxy->gsup_server_to_vlr, &destination);
	if (!vlr_conn) {
		LOG_PROXY_SUBSCR_MSG(proxy_subscr, gsup, LOGL_ERROR,
				     "Destination VLR unreachable: %s\n", osmo_ipa_name_to_str(&destination));
		return GMM_CAUSE_MSC_TEMP_NOTREACH;
	}

	if (proxy_acknowledge_gsup_from_remote_hlr(proxy, proxy_subscr, gsup, from_remote_hlr, &destination,
						   &vlr_conn->peer_name)) {
		LOG_PROXY_SUBSCR_MSG(proxy_subscr, gsup, LOGL_ERROR,
				     "Proxy does not allow forwarding this message\n");
		return GMM_CAUSE_PROTO_ERR_UNSPEC;
	}

	msg = osmo_gsup_msgb_alloc("GSUP proxy to VLR");
	if (osmo_gsup_encode(msg, gsup)) {
		LOG_PROXY_SUBSCR_MSG(proxy_subscr, gsup, LOGL_ERROR,
				     "Failed to re-encode GSUP message, cannot forward\n");
		return GMM_CAUSE_INV_MAND_INFO;
	}

	LOG_PROXY_SUBSCR_MSG(proxy_subscr, gsup, LOGL_INFO, "VLR<-HLR: forwarding to %s%s%s\n",
			     osmo_ipa_name_to_str(&destination),
			     osmo_ipa_name_cmp(&destination, &vlr_conn->peer_name) ? " via " : "",
			     osmo_ipa_name_cmp(&destination, &vlr_conn->peer_name) ?
						       osmo_ipa_name_to_str(&vlr_conn->peer_name) : "");
	return osmo_gsup_conn_send(vlr_conn, msg);
}
