[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.
This commit is contained in:
Holger Hans Peter Freyther 2010-06-15 18:46:19 +08:00
parent 3f37b8fba3
commit aa6982445f
2 changed files with 54 additions and 1 deletions

View File

@ -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 @@ struct bsc_connection {
/* a timeout node */
struct timer_list id_timeout;
/* a back pointer */
struct bsc_nat *nat;
};
/*

View File

@ -379,8 +379,12 @@ static void remove_bsc_connection(struct bsc_connection *connection)
{
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 @@ static void remove_bsc_connection(struct bsc_connection *connection)
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 @@ exit:
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 @@ static int ipaccess_listen_bsc_cb(struct bsc_fd *bfd, unsigned int what)
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 @@ static int ipaccess_listen_bsc_cb(struct bsc_fd *bfd, unsigned int what)
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;
}