bring libosm-tcap more in line with libasn1c's use of talloc
libasn1c expects all data structures to be heap-allocated, whereas we used to allocate some of them on the stack, which causes problems at free() time. As a side-effect, we had to remove the 'struct tcap_component' and replace its list_head in tcap_dialogue with a 'struct ComponentPortion'
This commit is contained in:
parent
5a7afc24a7
commit
a764e40c80
|
@ -77,7 +77,6 @@ int tcap_cha_tc_invoke_req(struct tcap_dialogue *td, uint8_t op_class, int8_t in
|
|||
{
|
||||
/* allocate new Invocation State Machine, link it with dialogue */
|
||||
struct tcap_invocation *ti = tcap_ism_alloc(td, inv_id);
|
||||
struct tcap_component *tcomp;
|
||||
struct Component *comp;
|
||||
struct Invoke *inv;
|
||||
|
||||
|
@ -94,10 +93,9 @@ int tcap_cha_tc_invoke_req(struct tcap_dialogue *td, uint8_t op_class, int8_t in
|
|||
ti->op_class = op_class;
|
||||
|
||||
/* Allocate a new component structure */
|
||||
tcomp = talloc_zero(td, struct tcap_component);
|
||||
if (!tcomp)
|
||||
comp = talloc_zero(td, struct Component);
|
||||
if (!comp)
|
||||
return -ENOMEM;
|
||||
comp = &tcomp->comp;
|
||||
comp->present = Component_PR_invoke;
|
||||
|
||||
/* Assemble INV component */
|
||||
|
@ -110,10 +108,10 @@ int tcap_cha_tc_invoke_req(struct tcap_dialogue *td, uint8_t op_class, int8_t in
|
|||
}
|
||||
memcpy(&inv->opCode, op, sizeof(inv->opCode));
|
||||
if (param && param_len)
|
||||
inv->parameter = gen_param(tcomp, param, param_len);
|
||||
inv->parameter = gen_param(comp, param, param_len);
|
||||
|
||||
/* Make component available for this Dialogue ID */
|
||||
llist_add_tail(&tcomp->list, &td->pend_comp_list);
|
||||
asn_sequence_add(&td->pend_comp->list, comp);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
@ -140,7 +138,6 @@ int tcap_cha_tc_result_req(struct tcap_dialogue *td, int8_t inv_id, int last,
|
|||
struct OPERATION *op, uint8_t *param, uint32_t param_len)
|
||||
{
|
||||
struct tcap_invocation *ti = tcap_ism_lookup(td, inv_id);
|
||||
struct tcap_component *tcomp;
|
||||
struct Component *comp;
|
||||
struct ReturnResult *res;
|
||||
struct resultretres *retres;
|
||||
|
@ -149,10 +146,9 @@ int tcap_cha_tc_result_req(struct tcap_dialogue *td, int8_t inv_id, int last,
|
|||
return -ENOENT;
|
||||
|
||||
/* Allocate a new component structure */
|
||||
tcomp = talloc_zero(td, struct tcap_component);
|
||||
if (!tcomp)
|
||||
comp = talloc_zero(td, struct Component);
|
||||
if (!comp)
|
||||
return -ENOMEM;
|
||||
comp = &tcomp->comp;
|
||||
|
||||
/* Assemble requested component */
|
||||
if (last) {
|
||||
|
@ -167,10 +163,10 @@ int tcap_cha_tc_result_req(struct tcap_dialogue *td, int8_t inv_id, int last,
|
|||
res->resultretres = retres;
|
||||
memcpy(&retres->opCode, op, sizeof(retres->opCode));
|
||||
if (param && param_len)
|
||||
retres->parameter = gen_param(tcomp, param, param_len);
|
||||
retres->parameter = gen_param(comp, param, param_len);
|
||||
|
||||
/* Mark component available for this dialogue ID */
|
||||
llist_add_tail(&tcomp->list, &td->pend_comp_list);
|
||||
asn_sequence_add(&td->pend_comp->list, comp);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
|
|
@ -43,33 +43,6 @@ static BIT_STRING_t dial_version1 = {
|
|||
.bits_unused = 7,
|
||||
};
|
||||
|
||||
/* Assemble the list (sequence) of pending components for a dialogue */
|
||||
static ComponentPortion_t *assemble_components(ComponentPortion_t *cp, struct tcap_dialogue *td)
|
||||
{
|
||||
struct tcap_component *tcomp;
|
||||
unsigned int comp_count = 0;
|
||||
|
||||
memset(cp, 0, sizeof(*cp));
|
||||
llist_for_each_entry(tcomp, &td->pend_comp_list, list) {
|
||||
ASN_SEQUENCE_ADD(&cp->list, &tcomp->comp);
|
||||
comp_count++;
|
||||
}
|
||||
if (comp_count)
|
||||
return cp;
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
static void release_components(struct tcap_dialogue *td)
|
||||
{
|
||||
struct tcap_component *tcomp, *tcomp2;
|
||||
|
||||
llist_for_each_entry_safe(tcomp, tcomp2, &td->pend_comp_list, list) {
|
||||
llist_del(&tcomp->list);
|
||||
talloc_free(tcomp);
|
||||
}
|
||||
}
|
||||
|
||||
/* Extract the Application Context Name and User Info from a DialoguePDU */
|
||||
static int extract_appctx_uinfo(OBJECT_IDENTIFIER_t **app_ctx_name, struct user_information **user_info,
|
||||
struct DialoguePDU *dial_pdu)
|
||||
|
@ -129,7 +102,9 @@ int tcap_csl_tc_uni_req(struct tcap_dialogue *td, OBJECT_IDENTIFIER_t *app_ctx,
|
|||
/* Request components to CHA */
|
||||
/* Process components */
|
||||
/* Assemble TSL user data */
|
||||
assemble_components(&tcm.choice.unidirectional.components, td);
|
||||
memcpy(&tcm.choice.unidirectional.components, td->pend_comp, sizeof(*td->pend_comp));
|
||||
talloc_free(td->pend_comp);
|
||||
td->pend_comp = talloc_zero(td, struct ComponentPortion);
|
||||
|
||||
/* TR-UNI-REQ to TSL */
|
||||
rc = tcap_tco_tr_uni_req(&td->trans, &tcm);
|
||||
|
@ -148,7 +123,6 @@ int tcap_csl_tc_begin_req(struct tcap_dialogue *td, OBJECT_IDENTIFIER_t *app_ctx
|
|||
struct ComponentPortion cp;
|
||||
ExternalPDU_t ext;
|
||||
DialoguePDU_t dial;
|
||||
ANY_t any;
|
||||
struct tcap_invocation *ti;
|
||||
uint32_t trans_id;
|
||||
int rc;
|
||||
|
@ -158,6 +132,7 @@ int tcap_csl_tc_begin_req(struct tcap_dialogue *td, OBJECT_IDENTIFIER_t *app_ctx
|
|||
|
||||
if (app_ctx) {
|
||||
AARQ_apdu_t *aarq;
|
||||
ANY_t *any;
|
||||
|
||||
memset(&dial, 0, sizeof(dial));
|
||||
dial.present = DialoguePDU_PR_dialogueRequest;
|
||||
|
@ -178,16 +153,14 @@ int tcap_csl_tc_begin_req(struct tcap_dialogue *td, OBJECT_IDENTIFIER_t *app_ctx
|
|||
rc = ANY_fromType((ANY_t *) &ext.dialog, &asn_DEF_DialoguePDU, &dial);
|
||||
if (rc < 0)
|
||||
fprintf(stderr, "Error encoding DialoguePDU portion\n");
|
||||
memset(&any, 0, sizeof(any));
|
||||
rc = ANY_fromType(&any, &asn_DEF_ExternalPDU, &ext);
|
||||
if (rc < 0)
|
||||
fprintf(stderr, "Error encoding ExternalPDU portion\n");
|
||||
tcm.choice.begin.dialoguePortion = (OCTET_STRING_t *) &any;
|
||||
any = ANY_new_fromType(&asn_DEF_ExternalPDU, &ext);
|
||||
tcm.choice.begin.dialoguePortion = (OCTET_STRING_t *) any;
|
||||
}
|
||||
/* Request components to CHA */
|
||||
/* Process components */
|
||||
/* Assemble TSL user data */
|
||||
tcm.choice.begin.components = assemble_components(&cp, td);
|
||||
tcm.choice.begin.components = td->pend_comp;
|
||||
td->pend_comp = talloc_zero(td, struct ComponentPortion);
|
||||
|
||||
/* Assign local transaction ID */
|
||||
trans_id = ntohl(td->trans.tid_local);
|
||||
|
@ -199,7 +172,7 @@ int tcap_csl_tc_begin_req(struct tcap_dialogue *td, OBJECT_IDENTIFIER_t *app_ctx
|
|||
|
||||
tcap_trans_set_state(&td->trans, TCAP_TS_INIT_SENT);
|
||||
|
||||
release_components(td);
|
||||
asn_DEF_TCMessage.free_struct(&asn_DEF_TCMessage, &tcm, 1);
|
||||
|
||||
return rc;
|
||||
}
|
||||
|
@ -399,7 +372,8 @@ int tcap_csl_tc_cont_req(struct tcap_dialogue *td, OBJECT_IDENTIFIER_t *app_ctx,
|
|||
/* Request components to CHA */
|
||||
/* Process components */
|
||||
/* Assemble TSL user data */
|
||||
tcm.choice.Continue.components = assemble_components(&cp, td);
|
||||
tcm.choice.Continue.components = td->pend_comp;
|
||||
td->pend_comp = talloc_zero(td, struct ComponentPortion);
|
||||
|
||||
/* Assign local transaction ID */
|
||||
trans_id = htonl(td->trans.tid_local);
|
||||
|
@ -417,8 +391,6 @@ int tcap_csl_tc_cont_req(struct tcap_dialogue *td, OBJECT_IDENTIFIER_t *app_ctx,
|
|||
|
||||
tcap_trans_set_state(&td->trans, TCAP_TS_ACTIVE);
|
||||
|
||||
release_components(td);
|
||||
|
||||
return rc;
|
||||
}
|
||||
|
||||
|
@ -469,7 +441,8 @@ int tcap_csl_tc_end_req(struct tcap_dialogue *td, OBJECT_IDENTIFIER_t *app_ctx,
|
|||
/* Request component to CHA */
|
||||
/* Process components */
|
||||
/* Assemble TLS user data */
|
||||
tcm.choice.end.components = assemble_components(&cp, td);
|
||||
tcm.choice.end.components = td->pend_comp;
|
||||
talloc_zero(td, struct ComponentPortion);
|
||||
/* TR-END.req to TSL */
|
||||
rc = tcap_tco_tr_end_req(&td->trans, &tcm);
|
||||
/* Dialogue terminated to CHA */
|
||||
|
|
|
@ -62,12 +62,18 @@ struct tcap_dialogue *tcap_dialg_alloc(uint32_t dialogue_id)
|
|||
if (!td)
|
||||
return NULL;
|
||||
|
||||
td->pend_comp = talloc_zero(td, struct ComponentPortion);
|
||||
if (!td->pend_comp) {
|
||||
talloc_free(td);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
td->dialogue_id = dialogue_id;
|
||||
td->trans.state = TCAP_TS_IDLE;
|
||||
td->trans.tid_local = tcap_trans_id_alloc();
|
||||
llist_add(&td->list, &tcap_dialogues);
|
||||
INIT_LLIST_HEAD(&td->ism_list);
|
||||
INIT_LLIST_HEAD(&td->pend_comp_list);
|
||||
|
||||
llist_add(&td->list, &tcap_dialogues);
|
||||
|
||||
printf("allocated Dialogue with ID 0x%08x\n", dialogue_id);
|
||||
|
||||
|
|
|
@ -38,12 +38,6 @@
|
|||
#define LIB_EXPORTED
|
||||
#endif
|
||||
|
||||
struct tcap_component {
|
||||
struct llist_head list;
|
||||
|
||||
struct Component comp; /* Invoke Component */
|
||||
};
|
||||
|
||||
enum tcap_transaction_state {
|
||||
TCAP_TS_INVALID,
|
||||
TCAP_TS_IDLE,
|
||||
|
@ -73,7 +67,7 @@ struct tcap_dialogue {
|
|||
struct llist_head ism_list;
|
||||
|
||||
/* list of pending components for this dialogue */
|
||||
struct llist_head pend_comp_list;
|
||||
struct ComponentPortion *pend_comp;
|
||||
|
||||
/* There is a 1:1 mapping of transactions to dialogues */
|
||||
struct tcap_transaction trans;
|
||||
|
|
|
@ -33,6 +33,7 @@
|
|||
#include "tcap_user.h"
|
||||
|
||||
static struct {
|
||||
int mode_sender;
|
||||
struct tcap_transport_entity *tte;
|
||||
unsigned int begin_rcvd:1;
|
||||
uint32_t dialg_id;
|
||||
|
@ -167,6 +168,9 @@ int main(int argc, char **argv)
|
|||
struct sockaddr_storage ss;
|
||||
struct sockaddr_in *sin = (struct sockaddr_in *)&ss;
|
||||
|
||||
if (argc > 1)
|
||||
test_state.mode_sender = 1;
|
||||
|
||||
talloc_enable_leak_report_full();
|
||||
signal(SIGINT, &signal_handler);
|
||||
signal(SIGSEGV, &signal_handler);
|
||||
|
@ -174,7 +178,10 @@ int main(int argc, char **argv)
|
|||
|
||||
ss.ss_family = AF_INET;
|
||||
sin->sin_addr.s_addr = INADDR_ANY;
|
||||
sin->sin_port = htons(4242);
|
||||
if (test_state.mode_sender)
|
||||
sin->sin_port = htons(4242);
|
||||
else
|
||||
sin->sin_port = htons(4243);
|
||||
|
||||
test_state.tte = tcap_transp_udp_create(&ss);
|
||||
if (!test_state.tte) {
|
||||
|
@ -183,12 +190,19 @@ int main(int argc, char **argv)
|
|||
}
|
||||
/* make sure we sent messages to ourselves */
|
||||
inet_aton("127.0.0.1", &sin->sin_addr);
|
||||
if (!test_state.mode_sender)
|
||||
sin->sin_port = htons(4242);
|
||||
else
|
||||
sin->sin_port = htons(4243);
|
||||
memcpy(&test_state.tte->remote_addr, &ss, sizeof(test_state.tte->remote_addr));
|
||||
|
||||
send_invoke(0x1234, 0, gprs_loc_upd_param, sizeof(gprs_loc_upd_param));
|
||||
send_invoke(0x1234, 1, NULL, 0);
|
||||
send_invoke(0x1234, -1, NULL, 0);
|
||||
send_begin(0x1234, &gprsLocationUpdateContext_v3);
|
||||
if (test_state.mode_sender) {
|
||||
/* sender mode, send primitives */
|
||||
send_invoke(0x1234, 0, gprs_loc_upd_param, sizeof(gprs_loc_upd_param));
|
||||
send_invoke(0x1234, 1, NULL, 0);
|
||||
send_invoke(0x1234, -1, NULL, 0);
|
||||
send_begin(0x1234, &gprsLocationUpdateContext_v3);
|
||||
}
|
||||
|
||||
while (1) {
|
||||
bsc_select_main(0);
|
||||
|
|
22
src/tcu.c
22
src/tcu.c
|
@ -242,11 +242,9 @@ LIB_EXPORTED int tcap_user_req_comp(enum tcap_primitive prim, struct tcap_compon
|
|||
LIB_EXPORTED int tcap_user_req_dialg(enum tcap_primitive prim, struct tcap_dialg_ind *tcdi)
|
||||
{
|
||||
/* Allocate some structures on the stack */
|
||||
OBJECT_IDENTIFIER_t _app_ctx;
|
||||
OBJECT_IDENTIFIER_t *app_ctx = NULL;
|
||||
EXTERNAL_t ext;
|
||||
struct user_information _user_info;
|
||||
struct user_information *user_info = NULL;
|
||||
OBJECT_IDENTIFIER_t *app_ctx;
|
||||
EXTERNAL_t *ext;
|
||||
struct user_information *user_info;
|
||||
struct tcap_dialogue *td;
|
||||
int rc = 0;
|
||||
|
||||
|
@ -268,8 +266,7 @@ LIB_EXPORTED int tcap_user_req_dialg(enum tcap_primitive prim, struct tcap_dialg
|
|||
|
||||
/* Parse the tcap_dialg_ind into something that the asn1c code understands */
|
||||
if (tcdi->app_ctx_present) {
|
||||
app_ctx = &_app_ctx;
|
||||
memset(app_ctx, 0, sizeof(&app_ctx));
|
||||
app_ctx = talloc_zero(td, OBJECT_IDENTIFIER_t);
|
||||
OBJECT_IDENTIFIER_set_arcs(app_ctx, &tcdi->app_ctx_name.arc,
|
||||
sizeof(tcdi->app_ctx_name.arc[0]),
|
||||
tcdi->app_ctx_name.num_arcs);
|
||||
|
@ -277,12 +274,11 @@ LIB_EXPORTED int tcap_user_req_dialg(enum tcap_primitive prim, struct tcap_dialg
|
|||
|
||||
/* Parse the tcap_dialg_ind into something that the asn1c code understands */
|
||||
if (tcdi->user_info_present) {
|
||||
user_info = &_user_info;
|
||||
memset(&ext, 0, sizeof(ext));
|
||||
memset(user_info, 0, sizeof(*user_info));
|
||||
ext.buf = tcdi->user_info.data;
|
||||
ext.size = tcdi->user_info.data_len;
|
||||
ASN_SEQUENCE_ADD(&user_info->list, &ext);
|
||||
ext = talloc_zero(td, EXTERNAL_t);
|
||||
ext->buf = tcdi->user_info.data;
|
||||
ext->size = tcdi->user_info.data_len;
|
||||
user_info = talloc_zero(ext, struct user_information);
|
||||
ASN_SEQUENCE_ADD(&user_info->list, ext);
|
||||
}
|
||||
|
||||
switch (prim) {
|
||||
|
|
Loading…
Reference in New Issue