nat: Keep track of both sides of the connection

On a CC message we will need to remeber where the source local
reference of the network belonged so we can properly identify
the connection when receiving UDT messages.
This commit is contained in:
Holger Hans Peter Freyther 2010-03-29 17:18:42 +02:00
parent f8048d9f5c
commit 16a6f70834
3 changed files with 34 additions and 0 deletions

View File

@ -102,6 +102,7 @@ struct sccp_connections {
struct sccp_source_reference real_ref;
struct sccp_source_reference patched_ref;
struct sccp_source_reference remote_ref;
};
/**
@ -154,6 +155,7 @@ int bsc_nat_vty_init(struct bsc_nat *nat);
* SCCP patching and handling
*/
int create_sccp_src_ref(struct bsc_connection *bsc, struct msgb *msg, struct bsc_nat_parsed *parsed);
int update_sccp_src_ref(struct bsc_connection *bsc, struct msgb *msg, struct bsc_nat_parsed *parsed);
void remove_sccp_src_ref(struct bsc_connection *bsc, struct msgb *msg, struct bsc_nat_parsed *parsed);
struct bsc_connection *patch_sccp_src_ref_to_bsc(struct msgb *, struct bsc_nat_parsed *, struct bsc_nat *);
struct bsc_connection *patch_sccp_src_ref_to_msc(struct msgb *, struct bsc_nat_parsed *, struct bsc_nat *);

View File

@ -191,7 +191,11 @@ static int forward_sccp_to_bts(struct msgb *msg)
case SCCP_MSG_TYPE_RLSD:
case SCCP_MSG_TYPE_CREF:
case SCCP_MSG_TYPE_DT1:
bsc = patch_sccp_src_ref_to_bsc(msg, parsed, nat);
break;
case SCCP_MSG_TYPE_CC:
if (update_sccp_src_ref(bsc, msg, parsed) != 0)
goto exit;
bsc = patch_sccp_src_ref_to_bsc(msg, parsed, nat);
break;
case SCCP_MSG_TYPE_RLC:

View File

@ -103,6 +103,34 @@ int create_sccp_src_ref(struct bsc_connection *bsc, struct msgb *msg, struct bsc
return 0;
}
int update_sccp_src_ref(struct bsc_connection *bsc, struct msgb *msg, struct bsc_nat_parsed *parsed)
{
struct sccp_connections *conn;
if (!parsed->dest_local_ref || !parsed->src_local_ref) {
LOGP(DNAT, LOGL_ERROR, "CC MSG should contain both local and dest address.\n");
return -1;
}
llist_for_each_entry(conn, &bsc->nat->sccp_connections, list_entry) {
if (conn->bsc != bsc)
continue;
if (memcmp(parsed->dest_local_ref,
&conn->patched_ref, sizeof(conn->patched_ref)) != 0)
continue;
conn->remote_ref = *parsed->src_local_ref;
LOGP(DNAT, LOGL_DEBUG, "Updating 0x%x to remote 0x%x on 0x%p\n",
sccp_src_ref_to_int(&conn->patched_ref),
sccp_src_ref_to_int(&conn->remote_ref), bsc);
return 0;
}
LOGP(DNAT, LOGL_ERROR, "Referenced connection not found on BSC: 0x%p\n", bsc);
return -1;
}
void remove_sccp_src_ref(struct bsc_connection *bsc, struct msgb *msg, struct bsc_nat_parsed *parsed)
{
struct sccp_connections *conn;