Module: sip-router Branch: master Commit: 295716363562d88bce3db39e0f1bc605b1cc8257 URL: http://git.sip-router.org/cgi-bin/gitweb.cgi/sip-router/?a=commit;h=29571636...
Author: Pawel.Kuzak pawel.kuzak@1und1.de Committer: lucian balanceanu lucian.balanceanu@1and1.ro Date: Wed Jul 30 13:59:49 2014 +0300
acc: fix cdr extra2strar allocation issues
- for more than 10 string cdr_extra parameters, the addresses used by the new parameters overwrite the previous ones; our solution is to allocate memory for the cdr extra params with pkg_malloc() and free it once it is no longer needed.
---
modules/acc/acc.c | 7 ++++++- modules/acc/acc_cdr.c | 27 ++++++++++++++++++++------- modules/acc/acc_extra.c | 39 ++++++++++++++++++--------------------- modules/acc/acc_extra.h | 12 ++++++++++++ modules/acc/acc_mod.c | 3 --- 5 files changed, 56 insertions(+), 32 deletions(-)
diff --git a/modules/acc/acc.c b/modules/acc/acc.c index 418e709..51dfde5 100644 --- a/modules/acc/acc.c +++ b/modules/acc/acc.c @@ -229,6 +229,7 @@ int acc_log_request( struct sip_msg *rq) char *p; int n; int m; + int o = 0; int i; struct tm *t;
@@ -236,7 +237,9 @@ int acc_log_request( struct sip_msg *rq) m = core2strar( rq, val_arr, int_arr, type_arr);
/* get extra values */ - m += extra2strar( log_extra, rq, val_arr+m, int_arr+m, type_arr+m); + o += extra2strar( log_extra, rq, val_arr+m, int_arr+m, type_arr+m); + + m += o;
for ( i=0,p=log_msg ; i<m ; i++ ) { if (p+1+log_attrs[i].len+1+val_arr[i].len >= log_msg_end) { @@ -314,6 +317,8 @@ int acc_log_request( struct sip_msg *rq) acc_env.text.len, acc_env.text.s,(unsigned long)acc_env.ts, log_msg); } + /* free memory allocated by extra2strar */ + free_strar_mem( &(type_arr[m-o]), &(val_arr[m-o]), o, m);
return 1; } diff --git a/modules/acc/acc_cdr.c b/modules/acc/acc_cdr.c index c8d2684..bc2e66b 100644 --- a/modules/acc/acc_cdr.c +++ b/modules/acc/acc_cdr.c @@ -131,6 +131,7 @@ static int db_write_cdr( struct dlg_cell* dialog, struct sip_msg* message) { int m = 0; + int n = 0; int i; db_func_t *df=NULL; db1_con_t *dh=NULL; @@ -163,11 +164,12 @@ static int db_write_cdr( struct dlg_cell* dialog, /* get extra values */ if (message) { - m += extra2strar( cdr_extra, + n += extra2strar( cdr_extra, message, cdr_value_array + m, cdr_int_array + m, cdr_type_array + m); + m += n; } else if (cdr_expired_dlg_enable){ LM_WARN( "fallback to dlg_only search because of message doesn't exist.\n"); m += extra2strar_dlg_only( cdr_extra, @@ -187,27 +189,34 @@ static int db_write_cdr( struct dlg_cell* dialog,
if (df->use_table(dh, &acc_cdrs_table /*table*/) < 0) { LM_ERR("error in use_table\n"); - return -1; + goto error; }
if(acc_db_insert_mode==1 && df->insert_delayed!=NULL) { if (df->insert_delayed(dh, db_cdr_keys, db_cdr_vals, m) < 0) { LM_ERR("failed to insert delayed into database\n"); - return -1; + goto error; } } else if(acc_db_insert_mode==2 && df->insert_async!=NULL) { if (df->insert_async(dh, db_cdr_keys, db_cdr_vals, m) < 0) { LM_ERR("failed to insert async into database\n"); - return -1; + goto error; } } else { if (df->insert(dh, db_cdr_keys, db_cdr_vals, m) < 0) { LM_ERR("failed to insert into database\n"); - return -1; + goto error; } }
+ /* Free memory allocated by acc_extra.c/extra2strar */ + free_strar_mem( &(cdr_type_array[m-n]), &(cdr_value_array[m-n]), n, m); return 0; + +error: + /* Free memory allocated by acc_extra.c/extra2strar */ + free_strar_mem( &(cdr_type_array[m-n]), &(cdr_value_array[m-n]), n, m); + return -1; } #endif
@@ -221,6 +230,7 @@ static int log_write_cdr( struct dlg_cell* dialog, 2;// -2 because of the string ending '\n\0' char* message_position = NULL; int message_index = 0; + int extra_index = 0; int counter = 0;
if(cdr_log_enable==0) @@ -235,7 +245,7 @@ static int log_write_cdr( struct dlg_cell* dialog, /* get extra values */ if (message) { - message_index += extra2strar( cdr_extra, + extra_index += extra2strar( cdr_extra, message, cdr_value_array + message_index, cdr_int_array + message_index, @@ -249,7 +259,7 @@ static int log_write_cdr( struct dlg_cell* dialog, cdr_type_array + message_index, &dlgb); } - + message_index += extra_index;
for( counter = 0, message_position = cdr_message; counter < message_index ; @@ -296,6 +306,9 @@ static int log_write_cdr( struct dlg_cell* dialog,
LM_GEN2( cdr_facility, log_level, "%s", cdr_message);
+ /* free memory allocated by extra2strar, nothing is done in case no extra strings were found by extra2strar */ + free_strar_mem( &(cdr_type_array[message_index-extra_index]), &(cdr_value_array[message_index-extra_index]), + extra_index, message_index); return 0; }
diff --git a/modules/acc/acc_extra.c b/modules/acc/acc_extra.c index 4847109..e9b6e4d 100644 --- a/modules/acc/acc_extra.c +++ b/modules/acc/acc_extra.c @@ -63,16 +63,6 @@ /* here we copy the strings returned by int2str (which uses a static buffer) */ static char int_buf[INT2STR_MAX_LEN*MAX_ACC_INT_BUF];
-static char *static_detector = 0; - -void init_acc_extra(void) -{ - int i; - /* ugly trick to get the address of the static buffer */ - static_detector = int2str( (unsigned long)3, &i) + i; -} - - struct acc_extra *parse_acc_leg(char *extra_str) { struct acc_extra *legs; @@ -249,10 +239,10 @@ int extra2strar(struct acc_extra *extra, struct sip_msg *rq, str *val_arr, { pv_value_t value; int n; - int r; + int i;
n = 0; - r = 0; + i = 0; while (extra) { /* get the value */ @@ -272,15 +262,22 @@ int extra2strar(struct acc_extra *extra, struct sip_msg *rq, str *val_arr, val_arr[n].len = 0; type_arr[n] = TYPE_NULL; } else { - /* set the value into the acc buffer */ - if (value.rs.s+value.rs.len==static_detector) { - val_arr[n].s = int_buf + r*INT2STR_MAX_LEN; - val_arr[n].len = value.rs.len; - memcpy(val_arr[n].s, value.rs.s, value.rs.len); - r++; - } else { - val_arr[n] = value.rs; - } + val_arr[n].s = (char *)pkg_malloc(value.rs.len); + if (val_arr[n].s == NULL ) { + LM_ERR("extra2strar: out of memory.\n"); + /* Cleanup already allocated memory and + return that we didn't do anything */ + for (i = 0; i < n ; i++) { + if (NULL != val_arr[i].s){ + pkg_free(val_arr[i].s); + val_arr[i].s = NULL; + } + } + n = 0; + goto done; + } + memcpy(val_arr[n].s, value.rs.s, value.rs.len); + val_arr[n].len = value.rs.len; if (value.flags&PV_VAL_INT) { int_arr[n] = value.ri; type_arr[n] = TYPE_INT; diff --git a/modules/acc/acc_extra.h b/modules/acc/acc_extra.h index 13112b9..c906683 100644 --- a/modules/acc/acc_extra.h +++ b/modules/acc/acc_extra.h @@ -43,6 +43,7 @@ #ifndef _ACC_EXTRA_H_ #define _ACC_EXTRA_H_
+#include "acc_api.h" #include "../../str.h" #include "../../pvar.h" #include "../../parser/msg_parser.h" @@ -72,5 +73,16 @@ int extra2int( struct acc_extra *extra, int *attrs ); int extra2attrs( struct acc_extra *extra, struct attr *attrs, int offset); #endif
+static inline void free_strar_mem( char* type_arr, str* alloc_arr, int dim_arr, int dim_ext){ + int i = 0; + for ( i = 0; i < dim_arr; i ++ ) { + if (( TYPE_NULL != type_arr[i] ) && ( NULL != alloc_arr[i].s)) { + LM_DBG("Freeing memory, type is %d, message_index %d, index i %d\n", + type_arr[i], dim_ext - dim_arr, i); + pkg_free( alloc_arr[i].s) ; + alloc_arr[i].s = NULL; + } + } +} #endif
diff --git a/modules/acc/acc_mod.c b/modules/acc/acc_mod.c index acd620c..831a137 100644 --- a/modules/acc/acc_mod.c +++ b/modules/acc/acc_mod.c @@ -528,9 +528,6 @@ static int mod_init( void ) return -1; }
- /* init the extra engine */ - init_acc_extra(); - /* configure multi-leg accounting */ if (leg_info_str && (leg_info=parse_acc_leg(leg_info_str))==0 ) { LM_ERR("failed to parse multileg_info param\n");
Hi,
At 1&1, we found it useful to trigger the generation of AVPs even if authentication fails. Do you find such a facility useful for upstream? The changes are really small as you can see from the attached patch.
Thank you, Lucian Balaceanu
Hello,
it could be useful in various cases, when the password is wrong, the credentials to be available in config.
What I would like to discuss a bit further is whether this should be made a module parameter or not. Database query is done anyhow, so the extra processing is only pushing credentials values in avps when password was wrong.
Thinking of how I use the credentials so far, I won't be affected by this change. Other opinions?
Cheers, Daniel
On 30/07/14 17:39, Lucian Balaceanu wrote:
Hi,
At 1&1, we found it useful to trigger the generation of AVPs even if authentication fails. Do you find such a facility useful for upstream? The changes are really small as you can see from the attached patch.
Thank you, Lucian Balaceanu
sr-dev mailing list sr-dev@lists.sip-router.org http://lists.sip-router.org/cgi-bin/mailman/listinfo/sr-dev
That's for sure a rare case. So I'd prefer it not to be a default behavior.
BTW, any example of real use-case?
2014-08-04 18:08 GMT+04:00 Daniel-Constantin Mierla miconda@gmail.com:
Hello,
it could be useful in various cases, when the password is wrong, the credentials to be available in config.
What I would like to discuss a bit further is whether this should be made a module parameter or not. Database query is done anyhow, so the extra processing is only pushing credentials values in avps when password was wrong.
Thinking of how I use the credentials so far, I won't be affected by this change. Other opinions?
Cheers, Daniel
On 30/07/14 17:39, Lucian Balaceanu wrote:
Hi,
At 1&1, we found it useful to trigger the generation of AVPs even if authentication fails. Do you find such a facility useful for upstream? The changes are really small as you can see from the attached patch.
Thank you, Lucian Balaceanu
sr-dev mailing listsr-dev@lists.sip-router.orghttp://lists.sip-router.org/cgi-bin/mailman/listinfo/sr-dev
-- Daniel-Constantin Mierla - http://www.asipto.comhttp://twitter.com/#!/miconda - http://www.linkedin.com/in/miconda
sr-dev mailing list sr-dev@lists.sip-router.org http://lists.sip-router.org/cgi-bin/mailman/listinfo/sr-dev
Hi,
Sorry for the late reply to this issue. After some investigation we think there might not be such a strong need for the patch as we don't see real use cases. We'll drop the patch.
Thank you, Lucian
On 08/05/2014 11:31 AM, Alekzander Spiridonov wrote:
That's for sure a rare case. So I'd prefer it not to be a default behavior.
BTW, any example of real use-case?
2014-08-04 18:08 GMT+04:00 Daniel-Constantin Mierla <miconda@gmail.com mailto:miconda@gmail.com>:
Hello, it could be useful in various cases, when the password is wrong, the credentials to be available in config. What I would like to discuss a bit further is whether this should be made a module parameter or not. Database query is done anyhow, so the extra processing is only pushing credentials values in avps when password was wrong. Thinking of how I use the credentials so far, I won't be affected by this change. Other opinions? Cheers, Daniel On 30/07/14 17:39, Lucian Balaceanu wrote:
Hi, At 1&1, we found it useful to trigger the generation of AVPs even if authentication fails. Do you find such a facility useful for upstream? The changes are really small as you can see from the attached patch. Thank you, Lucian Balaceanu _______________________________________________ sr-dev mailing list sr-dev@lists.sip-router.org <mailto:sr-dev@lists.sip-router.org> http://lists.sip-router.org/cgi-bin/mailman/listinfo/sr-dev
-- Daniel-Constantin Mierla -http://www.asipto.com http://twitter.com/#!/miconda <http://twitter.com/#%21/miconda> -http://www.linkedin.com/in/miconda _______________________________________________ sr-dev mailing list sr-dev@lists.sip-router.org <mailto:sr-dev@lists.sip-router.org> http://lists.sip-router.org/cgi-bin/mailman/listinfo/sr-dev
-- Best regards, Alekzander Spiridonov
sr-dev mailing list sr-dev@lists.sip-router.org http://lists.sip-router.org/cgi-bin/mailman/listinfo/sr-dev