fix some more memory leaks and make sure we always allocate dynamically

This commit is contained in:
Harald Welte 2010-07-20 00:17:03 +02:00
parent 7b907ec4d4
commit 2e7a6f8cdd
7 changed files with 98 additions and 58 deletions

View File

@ -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;
}

View File

@ -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;

View File

@ -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;
}

View File

@ -18,6 +18,9 @@
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#include <unistd.h>
#include <stdint.h>
#include <errno.h>
#include <osmocore/linuxlist.h>
#include <osmocore/talloc.h>
@ -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();

View File

@ -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 */

View File

@ -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);
}

View File

@ -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)