dgsm Proxy Cache design WIP

Change-Id: Ifa322e84fadd3b04943c8c7024c0e2de4935bed0
diff --git a/include/osmocom/hlr/Makefile.am b/include/osmocom/hlr/Makefile.am
index aceda4a..23ace45 100644
--- a/include/osmocom/hlr/Makefile.am
+++ b/include/osmocom/hlr/Makefile.am
@@ -14,6 +14,8 @@
 	mslookup_server.h \
 	mslookup_server_mdns.h \
 	proxy.h \
+	proxy_mm.h \
+	proxy_db.h \
 	rand.h \
 	remote_hlr.h \
 	timestamp.h \
diff --git a/include/osmocom/hlr/proxy.h b/include/osmocom/hlr/proxy.h
index 92ed30a..76d9d99 100644
--- a/include/osmocom/hlr/proxy.h
+++ b/include/osmocom/hlr/proxy.h
@@ -20,8 +20,11 @@
 #pragma once
 
 #include <time.h>
-#include <osmocom/gsm/protocol/gsm_23_003.h>
 #include <osmocom/core/sockaddr_str.h>
+#include <osmocom/core/linuxlist.h>
+#include <osmocom/core/timer.h>
+#include <osmocom/gsm/protocol/gsm_23_003.h>
+#include <osmocom/gsm/gsup.h>
 #include <osmocom/gsupclient/gsup_peer_id.h>
 #include <osmocom/hlr/timestamp.h>
 
@@ -65,6 +68,8 @@
 	char msisdn[GSM23003_MSISDN_MAX_DIGITS+1];
 	struct osmo_sockaddr_str remote_hlr_addr;
 	struct proxy_subscr_domain_state cs, ps;
+	struct osmo_fsm_inst *mm_fi;
+	struct osmo_fsm_inst *to_home_fi;
 };
 
 void proxy_init(struct osmo_gsup_server *gsup_server_to_vlr);
diff --git a/include/osmocom/hlr/proxy_broken_link_cache.h b/include/osmocom/hlr/proxy_broken_link_cache.h
new file mode 100644
index 0000000..9467a9b
--- /dev/null
+++ b/include/osmocom/hlr/proxy_broken_link_cache.h
@@ -0,0 +1,37 @@
+/* Copyright 2020 by sysmocom s.f.m.c. GmbH <info@sysmocom.de>
+ *
+ * Author: Neels Hofmeyr <neels@hofmeyr.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/>.
+ *
+ */
+
+/* If a subscriber from a remote site has successfully attached at this local site, and the link to the subscriber's
+ * home HLR has succeeded, this will try to bridge the time of temporary link failure to that home HLR.
+ * Tasks to take over from the unreachable home HLR:
+ * - Resend known auth tuples on OSMO_GSUP_MSGT_SEND_AUTH_INFO_REQUEST.
+ * - ...?
+ *
+ *
+ */
+
+/* Data stored per subscriber */
+struct proxy_broken_link_cache {
+	struct osmo_auth_vector auth_vectors[OSMO_GSUP_MAX_NUM_AUTH_INFO];
+	size_t num_auth_vectors;
+
+	timestamp_t last_update;
+};
diff --git a/include/osmocom/hlr/proxy_mm.h b/include/osmocom/hlr/proxy_mm.h
new file mode 100644
index 0000000..de68f60
--- /dev/null
+++ b/include/osmocom/hlr/proxy_mm.h
@@ -0,0 +1,54 @@
+#pragma once
+
+#include <osmocom/core/linuxlist.h>
+#include <osmocom/hlr/proxy.h>
+
+enum proxy_mm_fsm_event {
+	PROXY_MM_EV_SUBSCR_INVALID,
+	PROXY_MM_EV_RX_GSUP_LU,
+	PROXY_MM_EV_RX_GSUP_SAI,
+	PROXY_MM_EV_RX_SUBSCR_DATA,
+	PROXY_MM_EV_RX_GSUP_ISD_RESULT,
+	PROXY_MM_EV_RX_AUTH_TUPLES,
+};
+
+enum proxy_to_home_fsm_event {
+	PROXY_TO_HOME_EV_HOME_HLR_RESOLVED,
+	PROXY_TO_HOME_EV_RX_INSERT_SUBSCRIBER_DATA_REQ,
+	PROXY_TO_HOME_EV_RX_UPDATE_LOCATION_RESULT,
+	PROXY_TO_HOME_EV_RX_SEND_AUTH_INFO_RESULT,
+	PROXY_TO_HOME_EV_CHECK_TUPLES,
+	PROXY_TO_HOME_EV_CONFIRM_LU,
+};
+
+extern struct llist_head proxy_mm_list;
+
+struct proxy_mm_auth_cache {
+	struct llist_head entry;
+	uint64_t db_id;
+	struct osmo_auth_vector	auth_vectors[OSMO_GSUP_MAX_NUM_AUTH_INFO];
+	size_t num_auth_vectors;
+	unsigned int sent_to_vlr_count;
+};
+
+struct proxy_mm {
+	struct llist_head entry;
+	struct osmo_gsup_peer_id vlr_name;
+	char imsi[GSM23003_IMSI_MAX_DIGITS+1];
+	bool is_ps;
+	struct osmo_fsm_inst *mm_fi;
+	struct osmo_fsm_inst *to_home_fi;
+	struct llist_head auth_cache;
+};
+
+struct proxy_mm *proxy_mm_alloc(const struct osmo_gsup_peer_id *vlr_name,
+				bool is_ps,
+				const char *imsi);
+
+void proxy_mm_add_auth_vectors(struct proxy_mm *proxy_mm,
+			       const struct osmo_auth_vector *auth_vectors, size_t num_auth_vectors);
+struct proxy_mm_auth_cache *proxy_mm_get_auth_vectors(struct proxy_mm *proxy_mm);
+void proxy_mm_use_auth_vectors(struct proxy_mm *proxy_mm, struct proxy_mm_auth_cache *ac);
+void proxy_mm_discard_auth_vectors(struct proxy_mm *proxy_mm, struct proxy_mm_auth_cache *ac);
+
+bool proxy_mm_subscriber_data_known(const struct proxy_mm *proxy_mm);