summaryrefslogtreecommitdiffstats
path: root/openbsc
diff options
context:
space:
mode:
authorPau Espin Pedrol <pespin@sysmocom.de>2019-05-01 22:30:26 +0200
committerPau Espin Pedrol <pespin@sysmocom.de>2019-05-16 17:19:42 +0200
commitc44cbbf839dcff3f7b83ca3a051854e52fe88e40 (patch)
tree5ec3794a6ddaaf8bc52ef6c0d031a38fc4098740 /openbsc
parent7ab9a9eb50076e98cae0c978622d7be99d9d1b02 (diff)
nat: Allocate bsc_nat_parsed on the stack instead of heap
There's no real need to allocate it using talloc. Allocating it on the stack simplifies the code, avoids mem leaks and makes it faster. Change-Id: I66c44890952339f15131081e2f629a2824b6d3ba
Diffstat (limited to 'openbsc')
-rw-r--r--openbsc/include/openbsc/bsc_nat.h5
-rw-r--r--openbsc/src/osmo-bsc_nat/bsc_filter.c26
-rw-r--r--openbsc/src/osmo-bsc_nat/bsc_nat.c102
-rw-r--r--openbsc/src/osmo-bsc_nat/bsc_nat_rewrite.c2
-rw-r--r--openbsc/src/osmo-bsc_nat/bsc_ussd.c11
-rw-r--r--openbsc/tests/bsc-nat/bsc_nat_test.c164
6 files changed, 136 insertions, 174 deletions
diff --git a/openbsc/include/openbsc/bsc_nat.h b/openbsc/include/openbsc/bsc_nat.h
index 3eba70d65..86134bec7 100644
--- a/openbsc/include/openbsc/bsc_nat.h
+++ b/openbsc/include/openbsc/bsc_nat.h
@@ -356,10 +356,7 @@ void bsc_close_connection(struct bsc_connection *);
const char *bsc_con_type_to_string(int type);
-/**
- * parse the given message into the above structure
- */
-struct bsc_nat_parsed *bsc_nat_parse(struct msgb *msg);
+int bsc_nat_parse(struct msgb *msg, struct bsc_nat_parsed *parsed);
/**
* filter based on IP Access header in both directions
diff --git a/openbsc/src/osmo-bsc_nat/bsc_filter.c b/openbsc/src/osmo-bsc_nat/bsc_filter.c
index 432529e15..a8786829d 100644
--- a/openbsc/src/osmo-bsc_nat/bsc_filter.c
+++ b/openbsc/src/osmo-bsc_nat/bsc_filter.c
@@ -72,19 +72,24 @@ static struct bsc_pkt_filter white_list[] = {
{ IPAC_PROTO_MGCP_OLD, ALLOW_ANY, ALLOW_ANY, ALLOW_ANY, FILTER_TO_BOTH },
};
-struct bsc_nat_parsed *bsc_nat_parse(struct msgb *msg)
+ /*! Parse the given message into the parsed structure.
+ * \param[in] msg the IPA message to parse
+ * \param[out] parsed the structure to fill with parsed values
+ * \returns 0 on success, negative on error
+ */
+int bsc_nat_parse(struct msgb *msg, struct bsc_nat_parsed *parsed)
{
struct sccp_parse_result result;
- struct bsc_nat_parsed *parsed;
struct ipaccess_head *hh;
/* quick fail */
if (msg->len < 4)
- return NULL;
+ return -1;
- parsed = talloc_zero(msg, struct bsc_nat_parsed);
if (!parsed)
- return NULL;
+ return -1;
+
+ memset(parsed, 0, sizeof(*parsed));
/* more init */
parsed->ipa_proto = parsed->called_ssn = parsed->calling_ssn = -1;
@@ -99,22 +104,19 @@ struct bsc_nat_parsed *bsc_nat_parse(struct msgb *msg)
/* do a size check on the input */
if (ntohs(hh->len) != msgb_l2len(msg)) {
LOGP(DLINP, LOGL_ERROR, "Wrong input length?\n");
- talloc_free(parsed);
- return NULL;
+ return -1;
}
/* analyze sccp down here */
if (parsed->ipa_proto == IPAC_PROTO_SCCP) {
memset(&result, 0, sizeof(result));
if (sccp_parse_header(msg, &result) != 0) {
- talloc_free(parsed);
- return 0;
+ return -1;
}
if (msg->l3h && msgb_l3len(msg) < 3) {
LOGP(DNAT, LOGL_ERROR, "Not enough space or GSM payload\n");
- talloc_free(parsed);
- return 0;
+ return -1;
}
parsed->sccp_type = sccp_determine_msg_type(msg);
@@ -132,7 +134,7 @@ struct bsc_nat_parsed *bsc_nat_parse(struct msgb *msg)
}
}
- return parsed;
+ return 0;
}
/* Returns 0 if message is whitelisted (has to beforwarded by bsc-nat), 1 if
diff --git a/openbsc/src/osmo-bsc_nat/bsc_nat.c b/openbsc/src/osmo-bsc_nat/bsc_nat.c
index 30e4b3423..2e2eac04d 100644
--- a/openbsc/src/osmo-bsc_nat/bsc_nat.c
+++ b/openbsc/src/osmo-bsc_nat/bsc_nat.c
@@ -696,24 +696,23 @@ static int forward_sccp_to_bts(struct bsc_msc_connection *msc_con, struct msgb *
{
struct nat_sccp_connection *con = NULL;
struct bsc_connection *bsc;
- struct bsc_nat_parsed *parsed;
+ struct bsc_nat_parsed parsed;
int proto;
/* filter, drop, patch the message? */
- parsed = bsc_nat_parse(msg);
- if (!parsed) {
+ if (bsc_nat_parse(msg, &parsed) < 0) {
LOGP(DNAT, LOGL_ERROR, "Can not parse msg from BSC.\n");
return -1;
}
- if (bsc_nat_filter_ipa(DIR_BSC, msg, parsed))
+ if (bsc_nat_filter_ipa(DIR_BSC, msg, &parsed))
goto exit;
- proto = parsed->ipa_proto;
+ proto = parsed.ipa_proto;
/* Route and modify the SCCP packet */
if (proto == IPAC_PROTO_SCCP) {
- switch (parsed->sccp_type) {
+ switch (parsed.sccp_type) {
case SCCP_MSG_TYPE_UDT:
/* forward UDT messages to every BSC */
goto send_to_all;
@@ -722,8 +721,8 @@ static int forward_sccp_to_bts(struct bsc_msc_connection *msc_con, struct msgb *
case SCCP_MSG_TYPE_CREF:
case SCCP_MSG_TYPE_DT1:
case SCCP_MSG_TYPE_IT:
- con = patch_sccp_src_ref_to_bsc(msg, parsed, nat);
- if (parsed->gsm_type == BSS_MAP_MSG_ASSIGMENT_RQST) {
+ con = patch_sccp_src_ref_to_bsc(msg, &parsed, nat);
+ if (parsed.gsm_type == BSS_MAP_MSG_ASSIGMENT_RQST) {
osmo_counter_inc(nat->stats.sccp.calls);
if (con) {
@@ -735,14 +734,14 @@ static int forward_sccp_to_bts(struct bsc_msc_connection *msc_con, struct msgb *
} else
LOGP(DNAT, LOGL_ERROR, "Assignment command but no BSC.\n");
} else if (con && con->con_local == NAT_CON_END_USSD &&
- parsed->gsm_type == BSS_MAP_MSG_CLEAR_CMD) {
+ parsed.gsm_type == BSS_MAP_MSG_CLEAR_CMD) {
LOGP(DNAT, LOGL_NOTICE, "Clear Command for USSD Connection. Ignoring.\n");
con = NULL;
}
break;
case SCCP_MSG_TYPE_CC:
- con = patch_sccp_src_ref_to_bsc(msg, parsed, nat);
- if (!con || update_sccp_src_ref(con, parsed) != 0)
+ con = patch_sccp_src_ref_to_bsc(msg, &parsed, nat);
+ if (!con || update_sccp_src_ref(con, &parsed) != 0)
goto exit;
break;
case SCCP_MSG_TYPE_RLC:
@@ -755,27 +754,24 @@ static int forward_sccp_to_bts(struct bsc_msc_connection *msc_con, struct msgb *
goto exit;
}
- if (!con && parsed->sccp_type == SCCP_MSG_TYPE_RLSD) {
+ if (!con && parsed.sccp_type == SCCP_MSG_TYPE_RLSD) {
LOGP(DNAT, LOGL_NOTICE, "Sending fake RLC on RLSD message to network.\n");
/* Exchange src/dest for the reply */
- nat_send_rlc(msc_con, &parsed->original_dest_ref,
- parsed->src_local_ref);
+ nat_send_rlc(msc_con, &parsed.original_dest_ref,
+ parsed.src_local_ref);
} else if (!con)
- LOGP(DNAT, LOGL_ERROR, "Unknown connection for msg type: 0x%x from the MSC.\n", parsed->sccp_type);
+ LOGP(DNAT, LOGL_ERROR, "Unknown connection for msg type: 0x%x from the MSC.\n", parsed.sccp_type);
}
- if (!con) {
- talloc_free(parsed);
+ if (!con)
return -1;
- }
+
if (!con->bsc->authenticated) {
- talloc_free(parsed);
LOGP(DNAT, LOGL_ERROR, "Selected BSC not authenticated.\n");
return -1;
}
- update_con_authorize(con, parsed, msg);
- talloc_free(parsed);
+ update_con_authorize(con, &parsed, msg);
bsc_send_data(con->bsc, msg->l2h, msgb_l2len(msg), proto);
return 0;
@@ -786,7 +782,7 @@ send_to_all:
* Command to every BSC in our network. We will analys the PAGING
* message and then send it to the authenticated messages...
*/
- if (parsed->ipa_proto == IPAC_PROTO_SCCP && parsed->gsm_type == BSS_MAP_MSG_PAGING) {
+ if (parsed.ipa_proto == IPAC_PROTO_SCCP && parsed.gsm_type == BSS_MAP_MSG_PAGING) {
bsc_nat_handle_paging(nat, msg);
goto exit;
}
@@ -795,11 +791,10 @@ send_to_all:
if (!bsc->authenticated)
continue;
- bsc_send_data(bsc, msg->l2h, msgb_l2len(msg), parsed->ipa_proto);
+ bsc_send_data(bsc, msg->l2h, msgb_l2len(msg), parsed.ipa_proto);
}
exit:
- talloc_free(parsed);
return 0;
}
@@ -1130,19 +1125,19 @@ static int forward_sccp_to_msc(struct bsc_connection *bsc, struct msgb *msg, boo
struct bsc_msc_connection *con_msc = NULL;
struct bsc_connection *con_bsc = NULL;
int con_type;
- struct bsc_nat_parsed *parsed;
+ struct bsc_nat_parsed parsed;
struct bsc_filter_reject_cause cause;
*bsc_conn_closed = false;
/* Parse and filter messages */
- parsed = bsc_nat_parse(msg);
- if (!parsed) {
+ bool parsed_ok = bsc_nat_parse(msg, &parsed) == 0;
+ if (!parsed_ok) {
LOGP(DNAT, LOGL_ERROR, "Can not parse msg from BSC.\n");
msgb_free(msg);
return -1;
}
- if (bsc_nat_filter_ipa(DIR_MSC, msg, parsed))
+ if (bsc_nat_filter_ipa(DIR_MSC, msg, &parsed))
goto exit;
/*
@@ -1157,32 +1152,32 @@ static int forward_sccp_to_msc(struct bsc_connection *bsc, struct msgb *msg, boo
/* modify the SCCP entries */
- if (parsed->ipa_proto == IPAC_PROTO_SCCP) {
+ if (parsed.ipa_proto == IPAC_PROTO_SCCP) {
int filter;
struct nat_sccp_connection *con;
- switch (parsed->sccp_type) {
+ switch (parsed.sccp_type) {
case SCCP_MSG_TYPE_CR:
memset(&cause, 0, sizeof(cause));
- filter = bsc_nat_filter_sccp_cr(bsc, msg, parsed,
+ filter = bsc_nat_filter_sccp_cr(bsc, msg, &parsed,
&con_type, &imsi, &cause);
if (filter < 0) {
if (imsi)
bsc_nat_inform_reject(bsc, imsi);
bsc_stat_reject(filter, bsc, 0);
/* send a SCCP Connection Refused */
- bsc_send_con_refuse(bsc, parsed, con_type, &cause);
+ bsc_send_con_refuse(bsc, &parsed, con_type, &cause);
goto exit2;
}
- if (!create_sccp_src_ref(bsc, parsed))
+ if (!create_sccp_src_ref(bsc, &parsed))
goto exit2;
- con = patch_sccp_src_ref_to_msc(msg, parsed, bsc);
+ con = patch_sccp_src_ref_to_msc(msg, &parsed, bsc);
OSMO_ASSERT(con);
con->msc_con = bsc->nat->msc_con;
con_msc = con->msc_con;
con->filter_state.con_type = con_type;
con->filter_state.imsi_checked = filter;
- bsc_nat_extract_lac(bsc, con, parsed, msg);
+ bsc_nat_extract_lac(bsc, con, &parsed, msg);
if (imsi)
con->filter_state.imsi = talloc_steal(con, imsi);
imsi = NULL;
@@ -1194,13 +1189,13 @@ static int forward_sccp_to_msc(struct bsc_connection *bsc, struct msgb *msg, boo
case SCCP_MSG_TYPE_DT1:
case SCCP_MSG_TYPE_CC:
case SCCP_MSG_TYPE_IT:
- con = patch_sccp_src_ref_to_msc(msg, parsed, bsc);
+ con = patch_sccp_src_ref_to_msc(msg, &parsed, bsc);
if (con) {
/* only filter non local connections */
if (!con->con_local) {
memset(&cause, 0, sizeof(cause));
filter = bsc_nat_filter_dt(bsc, msg,
- con, parsed, &cause);
+ con, &parsed, &cause);
if (filter < 0) {
if (con->filter_state.imsi)
bsc_nat_inform_reject(bsc,
@@ -1212,20 +1207,19 @@ static int forward_sccp_to_msc(struct bsc_connection *bsc, struct msgb *msg, boo
}
/* hand data to a side channel */
- if (bsc_ussd_check(con, parsed, msg) == 1)
+ if (bsc_ussd_check(con, &parsed, msg) == 1)
con->con_local = NAT_CON_END_USSD;
/*
* Optionally rewrite setup message. This can
- * replace the msg and the parsed structure becomes
- * invalid.
+ * replace the msg and hence data in struct parsed
+ * becomes invalid.
*/
- msg = bsc_nat_rewrite_msg(bsc->nat, msg, parsed,
+ msg = bsc_nat_rewrite_msg(bsc->nat, msg, &parsed,
con->filter_state.imsi);
- talloc_free(parsed);
- parsed = NULL;
+ parsed_ok = false;
} else if (con->con_local == NAT_CON_END_USSD) {
- bsc_ussd_check(con, parsed, msg);
+ bsc_ussd_check(con, &parsed, msg);
}
con_bsc = con->bsc;
@@ -1235,13 +1229,13 @@ static int forward_sccp_to_msc(struct bsc_connection *bsc, struct msgb *msg, boo
break;
case SCCP_MSG_TYPE_RLC:
- con = patch_sccp_src_ref_to_msc(msg, parsed, bsc);
+ con = patch_sccp_src_ref_to_msc(msg, &parsed, bsc);
if (con) {
con_bsc = con->bsc;
con_msc = con->msc_con;
con_filter = con->con_local;
}
- remove_sccp_src_ref(bsc, msg, parsed);
+ remove_sccp_src_ref(bsc, msg, &parsed);
*bsc_conn_closed = bsc_maybe_close(bsc);
break;
case SCCP_MSG_TYPE_UDT:
@@ -1249,16 +1243,16 @@ static int forward_sccp_to_msc(struct bsc_connection *bsc, struct msgb *msg, boo
con = NULL;
break;
default:
- LOGP(DNAT, LOGL_ERROR, "Not forwarding to msc sccp type: 0x%x\n", parsed->sccp_type);
+ LOGP(DNAT, LOGL_ERROR, "Not forwarding to msc sccp type: 0x%x\n", parsed.sccp_type);
con = NULL;
goto exit2;
break;
}
- } else if (parsed->ipa_proto == IPAC_PROTO_MGCP_OLD) {
+ } else if (parsed.ipa_proto == IPAC_PROTO_MGCP_OLD) {
bsc_mgcp_forward(bsc, msg);
goto exit2;
} else {
- LOGP(DNAT, LOGL_ERROR, "Not forwarding unknown stream id: 0x%x\n", parsed->ipa_proto);
+ LOGP(DNAT, LOGL_ERROR, "Not forwarding unknown stream id: 0x%x\n", parsed.ipa_proto);
goto exit2;
}
@@ -1275,22 +1269,21 @@ static int forward_sccp_to_msc(struct bsc_connection *bsc, struct msgb *msg, boo
if (!con_msc) {
LOGP(DNAT, LOGL_ERROR, "Not forwarding data bsc_nr: %d ipa: %d type: 0x%x\n",
bsc->cfg->nr,
- parsed ? parsed->ipa_proto : -1,
- parsed ? parsed->sccp_type : -1);
+ parsed_ok ? parsed.ipa_proto : -1,
+ parsed_ok ? parsed.sccp_type : -1);
goto exit2;
}
/* send the non-filtered but maybe modified msg */
- talloc_free(parsed);
queue_for_msc(con_msc, msg);
return 0;
exit:
/* if we filter out the reset send an ack to the BSC */
- if (parsed->bssap == 0 && parsed->gsm_type == BSS_MAP_MSG_RESET) {
+ if (parsed.bssap == 0 && parsed.gsm_type == BSS_MAP_MSG_RESET) {
send_reset_ack(bsc);
- } else if (parsed->ipa_proto == IPAC_PROTO_IPACCESS) {
+ } else if (parsed.ipa_proto == IPAC_PROTO_IPACCESS) {
/* do we know who is handling this? */
if (msg->l2h[0] == IPAC_MSGT_ID_RESP && msgb_l2len(msg) > 2) {
struct tlv_parsed tvp;
@@ -1315,7 +1308,6 @@ exit:
exit2:
if (imsi)
talloc_free(imsi);
- talloc_free(parsed);
msgb_free(msg);
return -1;
}
diff --git a/openbsc/src/osmo-bsc_nat/bsc_nat_rewrite.c b/openbsc/src/osmo-bsc_nat/bsc_nat_rewrite.c
index e7c387c22..1dd2ada0f 100644
--- a/openbsc/src/osmo-bsc_nat/bsc_nat_rewrite.c
+++ b/openbsc/src/osmo-bsc_nat/bsc_nat_rewrite.c
@@ -618,8 +618,6 @@ struct msgb *bsc_nat_rewrite_msg(struct bsc_nat *nat, struct msgb *msg, struct b
ipa_prepend_header(sccp, IPAC_PROTO_SCCP);
- /* the parsed hangs off from msg but it needs to survive */
- talloc_steal(sccp, parsed);
msgb_free(msg);
return sccp;
}
diff --git a/openbsc/src/osmo-bsc_nat/bsc_ussd.c b/openbsc/src/osmo-bsc_nat/bsc_ussd.c
index dea18073f..d44b1b2fe 100644
--- a/openbsc/src/osmo-bsc_nat/bsc_ussd.c
+++ b/openbsc/src/osmo-bsc_nat/bsc_ussd.c
@@ -90,30 +90,27 @@ static void ussd_pong(struct bsc_nat_ussd_con *conn)
static int forward_sccp(struct bsc_nat *nat, struct msgb *msg)
{
struct nat_sccp_connection *con;
- struct bsc_nat_parsed *parsed;
+ struct bsc_nat_parsed parsed;
-
- parsed = bsc_nat_parse(msg);
- if (!parsed) {
+ if (bsc_nat_parse(msg, &parsed) < 0) {
LOGP(DNAT, LOGL_ERROR, "Can not parse msg from USSD.\n");
msgb_free(msg);
return -1;
}
- if (!parsed->dest_local_ref) {
+ if (!parsed.dest_local_ref) {
LOGP(DNAT, LOGL_ERROR, "No destination local reference.\n");
msgb_free(msg);
return -1;
}
- con = bsc_nat_find_con_by_bsc(nat, parsed->dest_local_ref);
+ con = bsc_nat_find_con_by_bsc(nat, parsed.dest_local_ref);
if (!con || !con->bsc) {
LOGP(DNAT, LOGL_ERROR, "No active connection found.\n");
msgb_free(msg);
return -1;
}
- talloc_free(parsed);
bsc_write_msg(&con->bsc->write_queue, msg);
return 0;
}
diff --git a/openbsc/tests/bsc-nat/bsc_nat_test.c b/openbsc/tests/bsc-nat/bsc_nat_test.c
index e0d0051ba..4bee60d8c 100644
--- a/openbsc/tests/bsc-nat/bsc_nat_test.c
+++ b/openbsc/tests/bsc-nat/bsc_nat_test.c
@@ -235,20 +235,19 @@ static void test_filter(void)
printf("Testing BSS Filtering.\n");
for (i = 0; i < ARRAY_SIZE(results); ++i) {
int result;
- struct bsc_nat_parsed *parsed;
+ struct bsc_nat_parsed parsed;
struct msgb *msg = msgb_alloc(4096, "test-message");
printf("Going to test item: %d\n", i);
memcpy(msg->data, results[i].data, results[i].length);
msg->l2h = msgb_put(msg, results[i].length);
- parsed = bsc_nat_parse(msg);
- if (!parsed) {
+ if (bsc_nat_parse(msg, &parsed) < 0) {
printf("FAIL: Failed to parse the message\n");
continue;
}
- result = bsc_nat_filter_ipa(results[i].dir, msg, parsed);
+ result = bsc_nat_filter_ipa(results[i].dir, msg, &parsed);
if (result != results[i].result) {
printf("FAIL: Not the expected result got: %d wanted: %d\n",
result, results[i].result);
@@ -310,7 +309,7 @@ static void test_contrack()
struct bsc_connection *con;
struct nat_sccp_connection *con_found;
struct nat_sccp_connection *rc_con;
- struct bsc_nat_parsed *parsed;
+ struct bsc_nat_parsed parsed;
struct msgb *msg;
printf("Testing connection tracking.\n");
@@ -326,19 +325,19 @@ static void test_contrack()
/* 1.) create a connection */
copy_to_msg(msg, bsc_cr, sizeof(bsc_cr));
- parsed = bsc_nat_parse(msg);
- con_found = patch_sccp_src_ref_to_msc(msg, parsed, con);
+ OSMO_ASSERT(bsc_nat_parse(msg, &parsed) == 0);
+ con_found = patch_sccp_src_ref_to_msc(msg, &parsed, con);
if (con_found != NULL) {
printf("Con should not exist realref(%u)\n",
sccp_src_ref_to_int(&con_found->real_ref));
abort();
}
- rc_con = create_sccp_src_ref(con, parsed);
+ rc_con = create_sccp_src_ref(con, &parsed);
if (!rc_con) {
printf("Failed to create a ref\n");
abort();
}
- con_found = patch_sccp_src_ref_to_msc(msg, parsed, con);
+ con_found = patch_sccp_src_ref_to_msc(msg, &parsed, con);
if (!con_found) {
printf("Failed to find connection.\n");
abort();
@@ -356,40 +355,39 @@ static void test_contrack()
printf("Failed to patch the BSC CR msg.\n");
abort();
}
- talloc_free(parsed);
/* 2.) get the cc */
copy_to_msg(msg, msc_cc, sizeof(msc_cc));
- parsed = bsc_nat_parse(msg);
- con_found = patch_sccp_src_ref_to_bsc(msg, parsed, nat);
+ OSMO_ASSERT(bsc_nat_parse(msg, &parsed) == 0);
+ con_found = patch_sccp_src_ref_to_bsc(msg, &parsed, nat);
VERIFY(con_found, con, msg, msc_cc_patched, "MSC CC");
- if (update_sccp_src_ref(con_found, parsed) != 0) {
+ if (update_sccp_src_ref(con_found, &parsed) != 0) {
printf("Failed to update the SCCP con.\n");
abort();
}
/* 3.) send some data */
copy_to_msg(msg, bsc_dtap, sizeof(bsc_dtap));
- parsed = bsc_nat_parse(msg);
- con_found = patch_sccp_src_ref_to_msc(msg, parsed, con);
+ OSMO_ASSERT(bsc_nat_parse(msg, &parsed) == 0);
+ con_found = patch_sccp_src_ref_to_msc(msg, &parsed, con);
VERIFY(con_found, con, msg, bsc_dtap_patched, "BSC DTAP");
/* 4.) receive some data */
copy_to_msg(msg, msc_dtap, sizeof(msc_dtap));
- parsed = bsc_nat_parse(msg);
- con_found = patch_sccp_src_ref_to_bsc(msg, parsed, nat);
+ OSMO_ASSERT(bsc_nat_parse(msg, &parsed) == 0);
+ con_found = patch_sccp_src_ref_to_bsc(msg, &parsed, nat);
VERIFY(con_found, con, msg, msc_dtap_patched, "MSC DTAP");
/* 5.) close the connection */
copy_to_msg(msg, msc_rlsd, sizeof(msc_rlsd));
- parsed = bsc_nat_parse(msg);
- con_found = patch_sccp_src_ref_to_bsc(msg, parsed, nat);
+ OSMO_ASSERT(bsc_nat_parse(msg, &parsed) == 0);
+ con_found = patch_sccp_src_ref_to_bsc(msg, &parsed, nat);
VERIFY(con_found, con, msg, msc_rlsd_patched, "MSC RLSD");
/* 6.) confirm the connection close */
copy_to_msg(msg, bsc_rlc, sizeof(bsc_rlc));
- parsed = bsc_nat_parse(msg);
- con_found = patch_sccp_src_ref_to_msc(msg, parsed, con);
+ OSMO_ASSERT(bsc_nat_parse(msg, &parsed) == 0);
+ con_found = patch_sccp_src_ref_to_msc(msg, &parsed, con);
if (!con_found) {
printf("Failed to find connection.\n");
abort();
@@ -403,12 +401,11 @@ static void test_contrack()
printf("Failed to patch the BSC CR msg.\n");
abort();
}
- remove_sccp_src_ref(con, msg, parsed);
- talloc_free(parsed);
+ remove_sccp_src_ref(con, msg, &parsed);
copy_to_msg(msg, bsc_rlc, sizeof(bsc_rlc));
- parsed = bsc_nat_parse(msg);
- con_found = patch_sccp_src_ref_to_msc(msg, parsed, con);
+ OSMO_ASSERT(bsc_nat_parse(msg, &parsed) == 0);
+ con_found = patch_sccp_src_ref_to_msc(msg, &parsed, con);
/* verify that it is gone */
if (con_found != NULL) {
@@ -416,8 +413,6 @@ static void test_contrack()
sccp_src_ref_to_int(&con_found->real_ref));
abort();
}
- talloc_free(parsed);
-
bsc_config_free(con->cfg);
bsc_nat_free(nat);
@@ -507,7 +502,7 @@ static void test_mgcp_ass_tracking(void)
struct bsc_connection *bsc;
struct bsc_nat *nat;
struct nat_sccp_connection con;
- struct bsc_nat_parsed *parsed;
+ struct bsc_nat_parsed parsed;
struct msgb *msg;
printf("Testing MGCP.\n");
@@ -529,7 +524,7 @@ static void test_mgcp_ass_tracking(void)
msg = msgb_alloc(4096, "foo");
copy_to_msg(msg, ass_cmd, sizeof(ass_cmd));
- parsed = bsc_nat_parse(msg);
+ OSMO_ASSERT(bsc_nat_parse(msg, &parsed) == 0);
if (msg->l2h[16] != 0 ||
msg->l2h[17] != 0x1) {
@@ -568,8 +563,6 @@ static void test_mgcp_ass_tracking(void)
abort();
}
- talloc_free(parsed);
-
bsc_mgcp_dlcx(&con);
if (con.bsc_endp != -1 || con.msc_endp != -1 ||
con.bsc->_endpoint_status[1] != 0 || con.bsc->last_endpoint != 0x1) {
@@ -867,7 +860,7 @@ static void test_cr_filter()
{
int i, res, contype;
struct msgb *msg = msgb_alloc(4096, "test_cr_filter");
- struct bsc_nat_parsed *parsed;
+ struct bsc_nat_parsed parsed;
struct bsc_msg_acc_lst *nat_lst, *bsc_lst;
struct bsc_msg_acc_lst_entry *nat_entry, *bsc_entry;
struct bsc_filter_reject_cause cause;
@@ -912,14 +905,13 @@ static void test_cr_filter()
&cr_filter[i].bsc_imsi_deny) != 0)
abort();
- parsed = bsc_nat_parse(msg);
- if (!parsed) {
+ if (bsc_nat_parse(msg, &parsed) < 0) {
printf("FAIL: Failed to parse the message\n");
abort();
}
memset(&cause, 0, sizeof(cause));
- res = bsc_nat_filter_sccp_cr(bsc, msg, parsed, &contype, &imsi, &cause);
+ res = bsc_nat_filter_sccp_cr(bsc, msg, &parsed, &contype, &imsi, &cause);
if (res != cr_filter[i].result) {
printf("FAIL: Wrong result %d for test %d.\n", res, i);
abort();
@@ -934,8 +926,7 @@ static void test_cr_filter()
abort();
}
- talloc_steal(parsed, imsi);
- talloc_free(parsed);
+ talloc_free(imsi);
}
msgb_free(msg);
@@ -946,7 +937,7 @@ static void test_dt_filter()
{
int i;
struct msgb *msg = msgb_alloc(4096, "test_dt_filter");
- struct bsc_nat_parsed *parsed;
+ struct bsc_nat_parsed parsed;
struct bsc_filter_reject_cause cause;
struct bsc_nat *nat = bsc_nat_alloc();
@@ -960,26 +951,25 @@ static void test_dt_filter()
msgb_reset(msg);
copy_to_msg(msg, id_resp, ARRAY_SIZE(id_resp));
- parsed = bsc_nat_parse(msg);
- if (!parsed) {
+ if (bsc_nat_parse(msg, &parsed) < 0) {
printf("FAIL: Could not parse ID resp\n");
abort();
}
- if (parsed->bssap != BSSAP_MSG_DTAP) {
+ if (parsed.bssap != BSSAP_MSG_DTAP) {
printf("FAIL: It should be dtap\n");
abort();
}
/* gsm_type is actually the size of the dtap */
- if (parsed->gsm_type < msgb_l3len(msg) - 3) {
+ if (parsed.gsm_type < msgb_l3len(msg) - 3) {
printf("FAIL: Not enough space for the content\n");
abort();
}
memset(&cause, 0, sizeof(cause));
OSMO_ASSERT(!con->filter_state.imsi);
- if (bsc_nat_filter_dt(bsc, msg, con, parsed, &cause) != 1) {
+ if (bsc_nat_filter_dt(bsc, msg, con, &parsed, &cause) != 1) {
printf("FAIL: Should have passed..\n");
abort();
}
@@ -991,13 +981,13 @@ static void test_dt_filter()
msgb_reset(msg);
copy_to_msg(msg, id_resp, ARRAY_SIZE(id_resp));
- parsed = bsc_nat_parse(msg);
- if (!parsed)
+ if (bsc_nat_parse(msg, &parsed) < 0)
continue;
+
con->filter_state.imsi_checked = 0;
memset(&cause, 0, sizeof(cause));
- bsc_nat_filter_dt(bsc, msg, con, parsed, &cause);
+ bsc_nat_filter_dt(bsc, msg, con, &parsed, &cause);
}
msgb_free(msg);
@@ -1008,7 +998,7 @@ static void test_setup_rewrite()
{
struct msgb *msg = msgb_alloc(4096, "test_dt_filter");
struct msgb *out;
- struct bsc_nat_parsed *parsed;
+ struct bsc_nat_parsed parsed;
const char *imsi = "27408000001234";
struct bsc_nat *nat = bsc_nat_alloc();
@@ -1028,31 +1018,28 @@ static void test_setup_rewrite()
/* verify that nothing changed */
msgb_reset(msg);
copy_to_msg(msg, cc_setup_international, ARRAY_SIZE(cc_setup_international));
- parsed = bsc_nat_parse(msg);
- if (!parsed) {
+ if (bsc_nat_parse(msg, &parsed) < 0) {
printf("FAIL: Could not parse ID resp\n");
abort();
}
- out = bsc_nat_rewrite_msg(nat, msg, parsed, imsi);
+ out = bsc_nat_rewrite_msg(nat, msg, &parsed, imsi);
if (msg != out) {
printf("FAIL: The message should not have been changed\n");
abort();
}
verify_msg(out, cc_setup_international, ARRAY_SIZE(cc_setup_international));
- talloc_free(parsed);
/* verify that something in the message changes */
msgb_reset(msg);
copy_to_msg(msg, cc_setup_national, ARRAY_SIZE(cc_setup_national));
- parsed = bsc_nat_parse(msg);
- if (!parsed) {
+ if (bsc_nat_parse(msg, &parsed) < 0) {
printf("FAIL: Could not parse ID resp\n");
abort();
}
- out = bsc_nat_rewrite_msg(nat, msg, parsed, imsi);
+ out = bsc_nat_rewrite_msg(nat, msg, &parsed, imsi);
if (!out) {
printf("FAIL: A new message should be created.\n");
abort();
@@ -1071,13 +1058,12 @@ static void test_setup_rewrite()
bsc_nat_num_rewr_entry_adapt(nat, &nat->num_rewr, &entries);
msg = msgb_alloc(4096, "test_dt_filter");
copy_to_msg(msg, cc_setup_national, ARRAY_SIZE(cc_setup_national));
- parsed = bsc_nat_parse(msg);
- if (!parsed) {
+ if (bsc_nat_parse(msg, &parsed) < 0) {
printf("FAIL: Could not parse ID resp\n");
abort();
}
- out = bsc_nat_rewrite_msg(nat, msg, parsed, imsi);
+ out = bsc_nat_rewrite_msg(nat, msg, &parsed, imsi);
if (!out) {
printf("FAIL: A new message should be created.\n");
abort();
@@ -1096,13 +1082,12 @@ static void test_setup_rewrite()
bsc_nat_num_rewr_entry_adapt(nat, &nat->num_rewr, &entries);
msg = msgb_alloc(4096, "test_dt_filter");
copy_to_msg(msg, cc_setup_national, ARRAY_SIZE(cc_setup_national));
- parsed = bsc_nat_parse(msg);
- if (!parsed) {
+ if (bsc_nat_parse(msg, &parsed) < 0) {
printf("FAIL: Could not parse ID resp\n");
abort();
}
- out = bsc_nat_rewrite_msg(nat, msg, parsed, imsi);
+ out = bsc_nat_rewrite_msg(nat, msg, &parsed, imsi);
if (out != msg) {
printf("FAIL: The message should be unchanged.\n");
abort();
@@ -1118,13 +1103,12 @@ static void test_setup_rewrite()
bsc_nat_num_rewr_entry_adapt(nat, &nat->num_rewr, &entries);
msg = msgb_alloc(4096, "test_dt_filter");
copy_to_msg(msg, cc_setup_national_patched, ARRAY_SIZE(cc_setup_national_patched));
- parsed = bsc_nat_parse(msg);
- if (!parsed) {
+ if (bsc_nat_parse(msg, &parsed) < 0) {
printf("FAIL: Could not parse ID resp %d\n", __LINE__);
abort();
}
- out = bsc_nat_rewrite_msg(nat, msg, parsed, imsi);
+ out = bsc_nat_rewrite_msg(nat, msg, &parsed, imsi);
if (!out) {
printf("FAIL: A new message should be created %d.\n", __LINE__);
abort();
@@ -1146,13 +1130,12 @@ static void test_setup_rewrite()
bsc_nat_num_rewr_entry_adapt(nat, &nat->num_rewr, &entries);
msg = msgb_alloc(4096, "test_dt_filter");
copy_to_msg(msg, cc_setup_national_patched, ARRAY_SIZE(cc_setup_national_patched));
- parsed = bsc_nat_parse(msg);
- if (!parsed) {
+ if (bsc_nat_parse(msg, &parsed) < 0) {
printf("FAIL: Could not parse ID resp %d\n", __LINE__);
abort();
}
- out = bsc_nat_rewrite_msg(nat, msg, parsed, imsi);
+ out = bsc_nat_rewrite_msg(nat, msg, &parsed, imsi);
if (!out) {
printf("FAIL: A new message should be created %d.\n", __LINE__);
abort();
@@ -1174,7 +1157,7 @@ static void test_setup_rewrite_prefix(void)
{
struct msgb *msg = msgb_alloc(4096, "test_dt_filter");
struct msgb *out;
- struct bsc_nat_parsed *parsed;
+ struct bsc_nat_parsed parsed;
const char *imsi = "27408000001234";
struct bsc_nat *nat = bsc_nat_alloc();
@@ -1195,13 +1178,12 @@ static void test_setup_rewrite_prefix(void)
msgb_reset(msg);
copy_to_msg(msg, cc_setup_national, ARRAY_SIZE(cc_setup_national));
- parsed = bsc_nat_parse(msg);
- if (!parsed) {
+ if (bsc_nat_parse(msg, &parsed) < 0) {
printf("FAIL: Could not parse ID resp\n");
abort();
}
- out = bsc_nat_rewrite_msg(nat, msg, parsed, imsi);
+ out = bsc_nat_rewrite_msg(nat, msg, &parsed, imsi);
if (!out) {
printf("FAIL: A new message should be created.\n");
abort();
@@ -1223,7 +1205,7 @@ static void test_setup_rewrite_post(void)
{
struct msgb *msg = msgb_alloc(4096, "test_dt_filter");
struct msgb *out;
- struct bsc_nat_parsed *parsed;
+ struct bsc_nat_parsed parsed;
const char *imsi = "27408000001234";
struct bsc_nat *nat = bsc_nat_alloc();
@@ -1255,13 +1237,12 @@ static void test_setup_rewrite_post(void)
msgb_reset(msg);
copy_to_msg(msg, cc_setup_national, ARRAY_SIZE(cc_setup_national));
- parsed = bsc_nat_parse(msg);
- if (!parsed) {
+ if (bsc_nat_parse(msg, &parsed) < 0) {
printf("FAIL: Could not parse ID resp\n");
abort();
}
- out = bsc_nat_rewrite_msg(nat, msg, parsed, imsi);
+ out = bsc_nat_rewrite_msg(nat, msg, &parsed, imsi);
if (!out) {
printf("FAIL: A new message should be created.\n");
abort();
@@ -1281,7 +1262,7 @@ static void test_setup_rewrite_post(void)
static void test_sms_smsc_rewrite()
{
struct msgb *msg = msgb_alloc(4096, "SMSC rewrite"), *out;
- struct bsc_nat_parsed *parsed;
+ struct bsc_nat_parsed parsed;
const char *imsi = "515039900406700";
struct bsc_nat *nat = bsc_nat_alloc();
@@ -1317,13 +1298,12 @@ static void test_sms_smsc_rewrite()
* Check if the SMSC address is changed
*/
copy_to_msg(msg, smsc_rewrite, ARRAY_SIZE(smsc_rewrite));
- parsed = bsc_nat_parse(msg);
- if (!parsed) {
+ if (bsc_nat_parse(msg, &parsed) < 0) {
printf("FAIL: Could not parse SMS\n");
abort();
}
- out = bsc_nat_rewrite_msg(nat, msg, parsed, imsi);
+ out = bsc_nat_rewrite_msg(nat, msg, &parsed, imsi);
if (out == msg) {
printf("FAIL: This should have changed.\n");
abort();
@@ -1337,13 +1317,12 @@ static void test_sms_smsc_rewrite()
bsc_nat_num_rewr_entry_adapt(nat, &nat->smsc_rewr, NULL);
msg = msgb_alloc(4096, "SMSC rewrite");
copy_to_msg(msg, smsc_rewrite, ARRAY_SIZE(smsc_rewrite));
- parsed = bsc_nat_parse(msg);
- if (!parsed) {
+ if (bsc_nat_parse(msg, &parsed) < 0) {
printf("FAIL: Could not parse SMS\n");
abort();
}
- out = bsc_nat_rewrite_msg(nat, msg, parsed, imsi);
+ out = bsc_nat_rewrite_msg(nat, msg, &parsed, imsi);
if (out == msg) {
printf("FAIL: This should have changed.\n");
abort();
@@ -1357,13 +1336,12 @@ static void test_sms_smsc_rewrite()
bsc_nat_num_rewr_entry_adapt(nat, &nat->sms_clear_tp_srr, NULL);
msg = msgb_alloc(4096, "SMSC rewrite");
copy_to_msg(msg, smsc_rewrite, ARRAY_SIZE(smsc_rewrite));
- parsed = bsc_nat_parse(msg);
- if (!parsed) {
+ if (bsc_nat_parse(msg, &parsed) < 0) {
printf("FAIL: Could not parse SMS\n");
abort();
}
- out = bsc_nat_rewrite_msg(nat, msg, parsed, imsi);
+ out = bsc_nat_rewrite_msg(nat, msg, &parsed, imsi);
if (out != msg) {
printf("FAIL: This should not have changed.\n");
abort();
@@ -1377,7 +1355,7 @@ static void test_sms_smsc_rewrite()
static void test_sms_number_rewrite(void)
{
struct msgb *msg, *out;
- struct bsc_nat_parsed *parsed;
+ struct bsc_nat_parsed parsed;
const char *imsi = "515039900406700";
struct bsc_nat *nat = bsc_nat_alloc();
@@ -1401,13 +1379,12 @@ static void test_sms_number_rewrite(void)
*/
msg = msgb_alloc(4096, "SMSC rewrite");
copy_to_msg(msg, smsc_rewrite, ARRAY_SIZE(smsc_rewrite));
- parsed = bsc_nat_parse(msg);
- if (!parsed) {
+ if (bsc_nat_parse(msg, &parsed) < 0) {
printf("FAIL: Could not parse SMS\n");
abort();
}
- out = bsc_nat_rewrite_msg(nat, msg, parsed, imsi);
+ out = bsc_nat_rewrite_msg(nat, msg, &parsed, imsi);
if (out == msg) {
printf("FAIL: This should have changed.\n");
abort();
@@ -1429,13 +1406,12 @@ static void test_sms_number_rewrite(void)
msg = msgb_alloc(4096, "SMSC rewrite");
copy_to_msg(msg, smsc_rewrite, ARRAY_SIZE(smsc_rewrite));
- parsed = bsc_nat_parse(msg);
- if (!parsed) {
+ if (bsc_nat_parse(msg, &parsed) < 0) {
printf("FAIL: Could not parse SMS\n");
abort();
}
- out = bsc_nat_rewrite_msg(nat, msg, parsed, imsi);
+ out = bsc_nat_rewrite_msg(nat, msg, &parsed, imsi);
if (out == msg) {
printf("FAIL: This should have changed.\n");
abort();
@@ -1520,7 +1496,7 @@ static void test_nat_extract_lac()
struct bsc_connection *bsc;
struct bsc_nat *nat;
struct nat_sccp_connection con;
- struct bsc_nat_parsed *parsed;
+ struct bsc_nat_parsed parsed;
struct msgb *msg = msgb_alloc(4096, "test-message");
printf("Testing LAC extraction from SCCP CR\n");
@@ -1538,8 +1514,8 @@ static void test_nat_extract_lac()
memcpy(msg->l2h, bssmap_cr, ARRAY_SIZE(bssmap_cr));
/* parse it and pass it on */
- parsed = bsc_nat_parse(msg);
- res = bsc_nat_extract_lac(bsc, &con, parsed, msg);
+ OSMO_ASSERT(bsc_nat_parse(msg, &parsed) == 0);
+ res = bsc_nat_extract_lac(bsc, &con, &parsed, msg);
OSMO_ASSERT(res == 0);
/* verify the LAC */