From 2e7a6f8cddcb6d59c3ee21d4271b69517ccba2e0 Mon Sep 17 00:00:00 2001 From: Harald Welte Date: Tue, 20 Jul 2010 00:17:03 +0200 Subject: [PATCH] fix some more memory leaks and make sure we always allocate dynamically --- src/csl_cha_cco.c | 10 +++---- src/csl_cha_ism.c | 4 +++ src/csl_dha.c | 75 +++++++++++++++++++++++++---------------------- src/dialogue.c | 27 +++++++++++++---- src/tcap.h | 2 ++ src/tcap_test.c | 37 +++++++++++++++-------- src/tcu.c | 1 + 7 files changed, 98 insertions(+), 58 deletions(-) diff --git a/src/csl_cha_cco.c b/src/csl_cha_cco.c index 474cd7b..a8e89ed 100644 --- a/src/csl_cha_cco.c +++ b/src/csl_cha_cco.c @@ -116,7 +116,7 @@ int tcap_cha_tc_invoke_req(struct tcap_dialogue *td, uint8_t op_class, int8_t in inv->parameter = gen_param(comp, param, param_len); /* Make component available for this Dialogue ID */ - asn_sequence_add(&td->pend_comp->list, comp); + tcap_dialg_comp_add(td, comp); return 0; } @@ -185,7 +185,7 @@ int tcap_cha_tc_result_req(struct tcap_dialogue *td, int8_t inv_id, int last, retres->parameter = gen_param(comp, param, param_len); /* Mark component available for this dialogue ID */ - asn_sequence_add(&td->pend_comp->list, comp); + tcap_dialg_comp_add(td, comp); return 0; } @@ -216,7 +216,7 @@ int tcap_cha_tc_u_error_req(struct tcap_dialogue *td, int8_t inv_id, gen_param(comp, param, param_len); /* Mark component available for this dialogue ID */ - asn_sequence_add(&td->pend_comp->list, comp); + tcap_dialg_comp_add(td, comp); return 0; } @@ -271,8 +271,8 @@ int tcap_cha_tc_u_rej_req(struct tcap_dialogue *td, int8_t *invoke_id, tcap_ism_terminate(ti); } - /* FIXME: Mark component available for this dialogue ID */ - asn_sequence_add(&td->pend_comp->list, comp); + /* Mark component available for this dialogue ID */ + tcap_dialg_comp_add(td, comp); return 0; } diff --git a/src/csl_cha_ism.c b/src/csl_cha_ism.c index 32f16d5..3e74ec3 100644 --- a/src/csl_cha_ism.c +++ b/src/csl_cha_ism.c @@ -64,6 +64,8 @@ static void tcap_ism_inv_timer_exp(void *_ti) { struct tcap_invocation *ti = _ti; + fprintf(stdout, "ISM Invoke Timer expired for InvokeID=%d\n", ti->invoke_id); + switch (ti->state) { case TCAP_IS_OP_SENT_CL1: case TCAP_IS_OP_SENT_CL2: @@ -83,6 +85,8 @@ static void tcap_ism_rej_timer_exp(void *_ti) { struct tcap_invocation *ti = _ti; + fprintf(stdout, "ISM Reject Timer expired for InvokeID=%d\n", ti->invoke_id); + if (ti->state != TCAP_IS_WAIT_REJECT) return; diff --git a/src/csl_dha.c b/src/csl_dha.c index 34239e1..1cdbb2c 100644 --- a/src/csl_dha.c +++ b/src/csl_dha.c @@ -85,6 +85,9 @@ int tcap_csl_tc_uni_req(struct tcap_dialogue *td, OBJECT_IDENTIFIER_t *app_ctx, if (app_ctx) { AUDT_apdu_t *audt; /* build AUDT apdu */ + + any = talloc_zero(tcm, ANY_t); + ext = talloc_zero(any, ExternalPDU_t); dial = talloc_zero(td, UniDialoguePDU_t); dial->present = UniDialoguePDU_PR_unidialoguePDU; audt = &dial->choice.unidialoguePDU; @@ -96,9 +99,9 @@ int tcap_csl_tc_uni_req(struct tcap_dialogue *td, OBJECT_IDENTIFIER_t *app_ctx, fprintf(stdout, "\nTC-UNI.req Dialogue portion:\n"); xer_fprint(stdout, &asn_DEF_UniDialoguePDU, dial); - ext = talloc_zero(dial, ExternalPDU_t); ANY_fromType((ANY_t *) &ext->dialog, &asn_DEF_UniDialoguePDU, dial); - any = ANY_new_fromType(&asn_DEF_ExternalPDU, ext); + + ANY_fromType(any, &asn_DEF_ExternalPDU, ext); tcm->choice.unidirectional.dialoguePortion = (OCTET_STRING_t *) any; } /* Request components to CHA */ @@ -106,7 +109,7 @@ int tcap_csl_tc_uni_req(struct tcap_dialogue *td, OBJECT_IDENTIFIER_t *app_ctx, /* Assemble TSL user data */ 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); + td->pend_comp = NULL; /* TR-UNI-REQ to TSL */ rc = tcap_tco_tr_uni_req(&td->trans, tcm); @@ -136,8 +139,11 @@ 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; + /* Build AARQ apdu */ - dial = talloc_zero(tcm, DialoguePDU_t); + any = talloc_zero(tcm, ANY_t); + ext = talloc_zero(any, ExternalPDU_t); + dial = talloc_zero(ext, DialoguePDU_t); dial->present = DialoguePDU_PR_dialogueRequest; aarq = &dial->choice.dialogueRequest; @@ -148,22 +154,20 @@ int tcap_csl_tc_begin_req(struct tcap_dialogue *td, OBJECT_IDENTIFIER_t *app_ctx memcpy(&aarq->application_context_name, app_ctx, sizeof(aarq->application_context_name)); /* Set protocol_version = 1 */ aarq->protocol_version = &dial_version1; - /* Build AARQ apdu */ + fprintf(stdout, "\nTC-BEGIN.req Dialogue portion:\n"); xer_fprint(stdout, &asn_DEF_DialoguePDU, dial); - ext = talloc_zero(dial, ExternalPDU_t); - rc = ANY_fromType((ANY_t *) &ext->dialog, &asn_DEF_DialoguePDU, dial); - if (rc < 0) - fprintf(stderr, "Error encoding DialoguePDU portion\n"); - any = ANY_new_fromType(&asn_DEF_ExternalPDU, ext); + ANY_fromType((ANY_t *) &ext->dialog, &asn_DEF_DialoguePDU, dial); + + ANY_fromType(any, &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 = td->pend_comp; - td->pend_comp = talloc_zero(td, struct ComponentPortion); + td->pend_comp = NULL; /* Assign local transaction ID */ trans_id = ntohl(td->trans.tid_local); @@ -305,15 +309,18 @@ int tcap_csl_tr_begin_ind(struct tcap_transaction *tt, struct TCMessage *tcmsg, return rc; } -static int gen_ext_AARE(struct DialoguePDU *dial, ANY_t *any, ExternalPDU_t *ext, - OBJECT_IDENTIFIER_t *app_ctx, struct user_information *user_info) +static ANY_t *gen_ext_AARE(struct tcap_dialogue *td, OBJECT_IDENTIFIER_t *app_ctx, + struct user_information *user_info) { + ANY_t *any; + ExternalPDU_t *ext; + DialoguePDU_t *dial; AARE_apdu_t *aare; int rc; - memset(any, 0, sizeof(*any)); - memset(ext, 0, sizeof(*ext)); - memset(dial, 0, sizeof(*dial)); + any = talloc_zero(td, ANY_t); + ext = talloc_zero(any, ExternalPDU_t); + dial = talloc_zero(ext, DialoguePDU_t); dial->present = DialoguePDU_PR_dialogueResponse; aare = &dial->choice.dialogueResponse; @@ -330,26 +337,25 @@ static int gen_ext_AARE(struct DialoguePDU *dial, ANY_t *any, ExternalPDU_t *ext rc = ANY_fromType((ANY_t *) &ext->dialog, &asn_DEF_DialoguePDU, dial); if (rc < 0) { fprintf(stderr, "Error generating ExternalPDU from DialoguePDU\n"); - return rc; + return NULL; } /* Link External PDU into Dialogue Portion */ rc = ANY_fromType(any, &asn_DEF_ExternalPDU, ext); if (rc < 0) { fprintf(stderr, "Error generating ANY_t from ExternalPDU\n"); - return rc; + return NULL; } - return 0; + xer_fprint(stdout, &asn_DEF_DialoguePDU, dial); + + return any; } /* TC-CONTINUE.req from TCU */ int tcap_csl_tc_cont_req(struct tcap_dialogue *td, OBJECT_IDENTIFIER_t *app_ctx, struct user_information *user_info) { struct TCMessage tcm; - struct ComponentPortion cp; - ExternalPDU_t ext; - DialoguePDU_t dial; - ANY_t any; + ANY_t *any; uint32_t trans_id; int rc = 0; @@ -359,10 +365,9 @@ int tcap_csl_tc_cont_req(struct tcap_dialogue *td, OBJECT_IDENTIFIER_t *app_ctx, switch (td->trans.state) { case TCAP_TS_INIT_RECV: if (app_ctx) { - gen_ext_AARE(&dial, &any, &ext, app_ctx, user_info); fprintf(stdout, "\nTC-CONTINUE.req Dialogue portion:\n"); - xer_fprint(stdout, &asn_DEF_DialoguePDU, &dial); - tcm.choice.Continue.dialoguePortion = (OCTET_STRING_t *) &any; + any = gen_ext_AARE(td, app_ctx, user_info); + tcm.choice.Continue.dialoguePortion = (OCTET_STRING_t *) any; } break; case TCAP_TS_ACTIVE: @@ -376,7 +381,7 @@ int tcap_csl_tc_cont_req(struct tcap_dialogue *td, OBJECT_IDENTIFIER_t *app_ctx, /* Process components */ /* Assemble TSL user data */ tcm.choice.Continue.components = td->pend_comp; - td->pend_comp = talloc_zero(td, struct ComponentPortion); + td->pend_comp = NULL; /* Assign local transaction ID */ trans_id = htonl(td->trans.tid_local); @@ -394,6 +399,8 @@ int tcap_csl_tc_cont_req(struct tcap_dialogue *td, OBJECT_IDENTIFIER_t *app_ctx, tcap_trans_set_state(&td->trans, TCAP_TS_ACTIVE); + asn_DEF_ANY.free_struct(&asn_DEF_ANY, any, 0); + return rc; } @@ -401,10 +408,7 @@ int tcap_csl_tc_cont_req(struct tcap_dialogue *td, OBJECT_IDENTIFIER_t *app_ctx, int tcap_csl_tc_end_req(struct tcap_dialogue *td, OBJECT_IDENTIFIER_t *app_ctx, struct user_information *user_info, int prearranged) { struct TCMessage tcm; - struct ComponentPortion cp; - ExternalPDU_t ext; - DialoguePDU_t dial; - ANY_t any; + ANY_t *any; int rc = 0; memset(&tcm, 0, sizeof(tcm)); @@ -436,16 +440,15 @@ int tcap_csl_tc_end_req(struct tcap_dialogue *td, OBJECT_IDENTIFIER_t *app_ctx, return rc; } if (td->trans.state == TCAP_TS_INIT_RECV && (app_ctx && user_info)) { - gen_ext_AARE(&dial, &any, &ext, app_ctx, user_info); fprintf(stdout, "\nTC-END.req Dialogue portion:\n"); - xer_fprint(stdout, &asn_DEF_DialoguePDU, &dial); - tcm.choice.end.dialoguePortion = (OCTET_STRING_t *) &any; + any = gen_ext_AARE(td, app_ctx, user_info); + tcm.choice.end.dialoguePortion = (OCTET_STRING_t *) any; } /* Request component to CHA */ /* Process components */ /* Assemble TLS user data */ tcm.choice.end.components = td->pend_comp; - talloc_zero(td, struct ComponentPortion); + td->pend_comp = NULL; /* TR-END.req to TSL */ rc = tcap_tco_tr_end_req(&td->trans, &tcm); /* Dialogue terminated to CHA */ @@ -453,6 +456,8 @@ int tcap_csl_tc_end_req(struct tcap_dialogue *td, OBJECT_IDENTIFIER_t *app_ctx, /* Free Dialogue ID */ tcap_dialg_free(td); + asn_DEF_ANY.free_struct(&asn_DEF_ANY, any, 0); + return rc; } diff --git a/src/dialogue.c b/src/dialogue.c index 082ca34..4659807 100644 --- a/src/dialogue.c +++ b/src/dialogue.c @@ -18,6 +18,9 @@ * along with this program. If not, see . */ +#include +#include +#include #include #include @@ -56,18 +59,30 @@ struct tcap_dialogue *tcap_dialg_by_dialg_id(uint32_t dialogue_id) return NULL; } +static void _comp_seq_elem_free(Component_t *comp) +{ + asn_DEF_Component.free_struct(&asn_DEF_Component, comp, 0); +} + + +/* Add a single component to the list of pending components of this dialogue */ +int tcap_dialg_comp_add(struct tcap_dialogue *td, Component_t *comp) +{ + if (!td->pend_comp) { + td->pend_comp = talloc_zero(td, struct ComponentPortion); + if (!td->pend_comp) + return -ENOMEM; + td->pend_comp->list.free = _comp_seq_elem_free; + } + ASN_SEQUENCE_ADD(&td->pend_comp->list, comp); +} + struct tcap_dialogue *tcap_dialg_alloc(uint32_t dialogue_id) { struct tcap_dialogue *td = talloc_zero(tall_tcap_dialg_ctx, struct tcap_dialogue); 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(); diff --git a/src/tcap.h b/src/tcap.h index 2aa51a4..288c2bb 100644 --- a/src/tcap.h +++ b/src/tcap.h @@ -243,6 +243,8 @@ uint32_t tcap_trans_id_alloc(void); const char *tcap_trans_state_name(enum tcap_transaction_state ts); const char *tcap_inv_state_name(enum tcap_invocation_state is); void tcap_trans_set_state(struct tcap_transaction *tt, enum tcap_transaction_state st); +/* Add a single component to the list of pending components of this dialogue */ +int tcap_dialg_comp_add(struct tcap_dialogue *td, Component_t *comp); /* scXp.c */ diff --git a/src/tcap_test.c b/src/tcap_test.c index 9311994..2bd9538 100644 --- a/src/tcap_test.c +++ b/src/tcap_test.c @@ -40,9 +40,16 @@ static struct { uint32_t dialg_id; } test_state; -static int send_continue(uint32_t dialg_id, struct tcap_obj_ident *app_ctx, struct tcap_user_info *user_info) +static int send_cont_end(uint32_t dialg_id, struct tcap_obj_ident *app_ctx, struct tcap_user_info *user_info, + int end) { struct tcap_dialg_ind tcdi; + enum tcap_primitive prim; + + if (end) + prim = TCAP_PR_TC_END; + else + prim = TCAP_PR_TC_CONTINUE; memset(&tcdi, 0, sizeof(tcdi)); tcdi.dialg_id = dialg_id; @@ -68,11 +75,11 @@ static uint8_t gprs_loc_upd_param[] = { 0x33, 0x34, 0x35, 0x04, 0x01, 0x31, 0x04, 0x07, 0x31, 0x2e, 0x32, 0x2e, 0x33, 0x2e, 0x34 }; -static int send_invoke(uint32_t dialg_id, int8_t invoke_id, uint8_t *param, uint32_t param_len) +static int send_comp_req(enum tcap_primitive prim, uint32_t dialg_id, + int8_t invoke_id, uint8_t *param, uint32_t param_len) { struct tcap_component_ind tcci; - memset(&tcci, 0, sizeof(tcci)); tcci.dialg_id = dialg_id; tcci.invoke_id = invoke_id; @@ -86,7 +93,7 @@ static int send_invoke(uint32_t dialg_id, int8_t invoke_id, uint8_t *param, uint memcpy(&tcci.parameter.data, param, param_len); tcci.parameter.data_len = param_len; - return tcap_user_req_comp(TCAP_PR_TC_INVOKE, &tcci); + return tcap_user_req_comp(prim, &tcci); } static int send_begin(uint32_t dialg_id, struct tcap_obj_ident *app_ctx) @@ -120,6 +127,8 @@ int tcap_user_ind_dialg(enum tcap_primitive prim, struct tcap_dialg_ind *tcdi) printf("\n"); + talloc_free(tcdi); + return 0; } @@ -127,20 +136,24 @@ int tcap_user_ind_comp(enum tcap_primitive prim, struct tcap_component_ind *tcci { printf("-> USER_IND_COMP(%s)\n", tcap_prim_name(prim)); - if (!test_state.begin_rcvd) + if (!test_state.begin_rcvd) { + talloc_free(tcci); return -1; + } switch (prim) { case TCAP_PR_TC_INVOKE: /* actually process the invoke */ - send_invoke(test_state.dialg_id, 0, NULL, 0); + send_comp_req(TCAP_PR_TC_RESULT_L, test_state.dialg_id, 0, NULL, 0); if (tcci->last_component) - send_continue(test_state.dialg_id, &gprsLocationUpdateContext_v3, NULL); + send_cont_end(test_state.dialg_id, &gprsLocationUpdateContext_v3, NULL, 1); break; default: break; } + talloc_free(tcci); + return 0; } @@ -170,8 +183,8 @@ int main(int argc, char **argv) talloc_enable_leak_report_full(); signal(SIGINT, &signal_handler); - signal(SIGSEGV, &signal_handler); - signal(SIGABRT, &signal_handler); + //signal(SIGSEGV, &signal_handler); + //signal(SIGABRT, &signal_handler); ss.ss_family = AF_INET; sin->sin_addr.s_addr = INADDR_ANY; @@ -195,9 +208,9 @@ int main(int argc, char **argv) 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_comp_req(TCAP_PR_TC_INVOKE, 0x1234, 0, gprs_loc_upd_param, sizeof(gprs_loc_upd_param)); + send_comp_req(TCAP_PR_TC_INVOKE, 0x1234, 1, NULL, 0); + send_comp_req(TCAP_PR_TC_INVOKE, 0x1234, -1, NULL, 0); send_begin(0x1234, &gprsLocationUpdateContext_v3); } diff --git a/src/tcu.c b/src/tcu.c index 08e6390..e72a483 100644 --- a/src/tcu.c +++ b/src/tcu.c @@ -119,6 +119,7 @@ static int _tcap_tcu_dialg_ind(enum tcap_primitive prim, struct tcap_dialogue *t rc = fill_tcap_dialg_ind(tcdi, app_ctx_name, user_info); if (rc < 0) { /* FIXME: reject the dialogue */ + fprintf(stderr, "Error filling the Dialogue Indication\n"); return rc; } if (comp_present)