diff options
author | Holger Hans Peter Freyther <zecke@selfish.org> | 2010-03-29 17:18:42 +0200 |
---|---|---|
committer | Holger Hans Peter Freyther <zecke@selfish.org> | 2010-06-15 20:24:08 +0800 |
commit | 16a6f70834fecfd946ce36583ac738e591a30b10 (patch) | |
tree | bafe775370c8b73bf328c06fbeb27911adeae10b /openbsc/src/nat | |
parent | f8048d9f5c0dbc9a31034289ed8a310a19517520 (diff) |
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.
Diffstat (limited to 'openbsc/src/nat')
-rw-r--r-- | openbsc/src/nat/bsc_nat.c | 4 | ||||
-rw-r--r-- | openbsc/src/nat/bsc_sccp.c | 28 |
2 files changed, 32 insertions, 0 deletions
diff --git a/openbsc/src/nat/bsc_nat.c b/openbsc/src/nat/bsc_nat.c index 65fc10b4e..cafca8352 100644 --- a/openbsc/src/nat/bsc_nat.c +++ b/openbsc/src/nat/bsc_nat.c @@ -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: diff --git a/openbsc/src/nat/bsc_sccp.c b/openbsc/src/nat/bsc_sccp.c index 226e2e0d8..e29dc9b84 100644 --- a/openbsc/src/nat/bsc_sccp.c +++ b/openbsc/src/nat/bsc_sccp.c @@ -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; |