[nat] Implement token based identification.
Based on the token the NAT/MUX is capable of figuring out
which LAC this BSC is supposed to satisfy. This will be
needed for messages like paging that can be done by LAC.
diff --git a/openbsc/include/openbsc/bsc_nat.h b/openbsc/include/openbsc/bsc_nat.h
index 66acde5..1da58bc 100644
--- a/openbsc/include/openbsc/bsc_nat.h
+++ b/openbsc/include/openbsc/bsc_nat.h
@@ -32,6 +32,8 @@
#define DIR_BSC 1
#define DIR_MSC 2
+struct bsc_nat;
+
/*
* For the NAT we will need to analyze and later patch
* the received message. This would require us to parse
@@ -82,6 +84,9 @@
/* a timeout node */
struct timer_list id_timeout;
+
+ /* a back pointer */
+ struct bsc_nat *nat;
};
/*
diff --git a/openbsc/src/nat/bsc_nat.c b/openbsc/src/nat/bsc_nat.c
index aee0095..8466876 100644
--- a/openbsc/src/nat/bsc_nat.c
+++ b/openbsc/src/nat/bsc_nat.c
@@ -379,8 +379,12 @@
{
struct sccp_connections *sccp_patch, *tmp;
bsc_unregister_fd(&connection->bsc_fd);
+ close(connection->bsc_fd.fd);
llist_del(&connection->list_entry);
+ /* stop the timeout timer */
+ bsc_del_timer(&connection->id_timeout);
+
/* remove all SCCP connections */
llist_for_each_entry_safe(sccp_patch, tmp, &nat->sccp_connections, list_entry) {
if (sccp_patch->bsc != connection)
@@ -393,6 +397,29 @@
talloc_free(connection);
}
+static void ipaccess_close_bsc(void *data)
+{
+ struct bsc_connection *conn = data;
+
+ LOGP(DNAT, LOGL_ERROR, "BSC didn't respond to identity request. Closing.\n");
+ remove_bsc_connection(conn);
+}
+
+static void ipaccess_auth_bsc(struct tlv_parsed *tvp, struct bsc_connection *bsc)
+{
+ struct bsc_config *conf;
+ const char* token = (const char *) TLVP_VAL(tvp, IPAC_IDTAG_UNITNAME);
+
+ llist_for_each_entry(conf, &bsc->nat->bsc_configs, entry) {
+ if (strcmp(conf->token, token) == 0) {
+ bsc->authenticated = 1;
+ bsc->lac = conf->lac;
+ bsc_del_timer(&bsc->id_timeout);
+ break;
+ }
+ }
+}
+
static int forward_sccp_to_msc(struct bsc_fd *bfd, struct msgb *msg)
{
struct bsc_connection *bsc;
@@ -459,6 +486,18 @@
if (parsed->bssap == 0 && parsed->gsm_type == BSS_MAP_MSG_RESET) {
send_reset_ack(bfd);
send_reset_ack(bfd);
+ } else if (parsed->ipa_proto == IPAC_PROTO_IPACCESS) {
+ /* do we know who is handling this? */
+ if (msg->l2h[0] == IPAC_MSGT_ID_RESP) {
+ struct tlv_parsed tvp;
+ ipaccess_idtag_parse(&tvp,
+ (unsigned char *) msg->l2h + 2,
+ msgb_l2len(msg) - 2);
+ if (TLVP_PRESENT(&tvp, IPAC_IDTAG_UNITNAME))
+ ipaccess_auth_bsc(&tvp, bsc);
+ }
+
+ goto exit2;
}
exit2:
@@ -521,6 +560,7 @@
return -1;
}
+ bsc->nat = nat;
bsc->bsc_fd.data = bsc;
bsc->bsc_fd.fd = ret;
bsc->bsc_fd.cb = ipaccess_bsc_cb;
@@ -534,7 +574,15 @@
LOGP(DNAT, LOGL_INFO, "Registered new BSC\n");
llist_add(&bsc->list_entry, &nat->bsc_connections);
- ipaccess_send_id_ack(ret);
+ ipaccess_send_id_ack(bsc->bsc_fd.fd);
+ ipaccess_send_id_req(ret);
+
+ /*
+ * start the hangup timer
+ */
+ bsc->id_timeout.data = bsc;
+ bsc->id_timeout.cb = ipaccess_close_bsc;
+ bsc_schedule_timer(&bsc->id_timeout, 2, 0);
return 0;
}