Skip to content

Commit

Permalink
Fix overflow when using large number of GW per rule
Browse files Browse the repository at this point in the history
Instead of fix-size internal buffer, user self-scaling buffers for handling/sorting the destinations/gateways in rules and carriers.
Fixes #1910

Cherry pick from e5991e1
  • Loading branch information
bogdan-iancu committed Jan 8, 2020
1 parent d5ed44c commit dd20710
Showing 1 changed file with 34 additions and 6 deletions.
40 changes: 34 additions & 6 deletions modules/drouting/drouting.c
Expand Up @@ -2405,12 +2405,27 @@ static int use_next_gw_w_part(struct sip_msg* msg,
}


#define DR_MAX_GWLIST 64
#define resize_dr_sort_buffer( _buf, _old_size, _new_size, _error) \
do { \
if (_new_size > _old_size) { \
/* need a larger buffer */ \
_buf = (unsigned short*)pkg_realloc( _buf, \
_new_size *sizeof(unsigned short) ); \
if (_buf==NULL) { \
LM_ERR("no more pkg mem (needed %ld)\n", \
_new_size*sizeof(unsigned short));\
_old_size = 0; \
goto _error;\
}\
_old_size = _new_size; \
} \
}while(0) \

static int sort_rt_dst(pgw_list_t *pgwl, unsigned short size,
int weight, unsigned short *idx)
{
unsigned short running_sum[DR_MAX_GWLIST];
static unsigned short *running_sum = NULL;
static unsigned short sum_buf_size = 0;
unsigned int i, first, weight_sum, rand_no;

/* populate the index array */
Expand All @@ -2421,6 +2436,7 @@ static int sort_rt_dst(pgw_list_t *pgwl, unsigned short size,
return 0;

while (size-first>1) {
resize_dr_sort_buffer( running_sum, sum_buf_size, size, err);
/* calculate the running sum */
for( i=first,weight_sum=0 ; i<size ; i++ ) {
weight_sum += pgwl[ idx[i] ].weight ;
Expand All @@ -2437,7 +2453,7 @@ static int sort_rt_dst(pgw_list_t *pgwl, unsigned short size,
if (running_sum[i]>rand_no) break;
if (i==size) {
LM_CRIT("bug in weight sort\n");
return -1;
goto err;
}
} else {
/* randomly select index */
Expand All @@ -2455,6 +2471,8 @@ static int sort_rt_dst(pgw_list_t *pgwl, unsigned short size,
}

return 0;
err:
return -1;
}


Expand Down Expand Up @@ -2603,8 +2621,10 @@ struct head_db * get_partition(const str *name) {
static int do_routing(struct sip_msg* msg, dr_part_group_t * part_group,
int flags, gparam_t* whitelist)
{
unsigned short dsts_idx[DR_MAX_GWLIST];
unsigned short carrier_idx[DR_MAX_GWLIST];
static unsigned short *dsts_idx = NULL;
static unsigned short dsts_idx_size = 0;
static unsigned short *carrier_idx = NULL;
static unsigned short carrier_idx_size = 0;
struct to_body *from;
struct sip_uri uri;
rt_info_t *rt_info;
Expand Down Expand Up @@ -2885,6 +2905,7 @@ static int do_routing(struct sip_msg* msg, dr_part_group_t * part_group,
}

/* sort the destination elements in the rule */
resize_dr_sort_buffer( dsts_idx, dsts_idx_size, rt_info->pgwa_len, error2);
i = sort_rt_dst(rt_info->pgwl, rt_info->pgwa_len,
flags&DR_PARAM_USE_WEIGTH, dsts_idx);
if (i!=0) {
Expand Down Expand Up @@ -2928,6 +2949,8 @@ static int do_routing(struct sip_msg* msg, dr_part_group_t * part_group,
continue;

/* sort the gws of the carrier */
resize_dr_sort_buffer( carrier_idx, carrier_idx_size,
dst->dst.carrier->pgwa_len, skip);
j = sort_rt_dst(dst->dst.carrier->pgwl, dst->dst.carrier->pgwa_len,
dst->dst.carrier->flags&DR_CR_FLAG_WEIGHT, carrier_idx);
if (j!=0) {
Expand Down Expand Up @@ -2968,6 +2991,8 @@ static int do_routing(struct sip_msg* msg, dr_part_group_t * part_group,
}

}
skip:
;

} else {

Expand Down Expand Up @@ -3151,7 +3176,8 @@ static int do_routing(struct sip_msg* msg, dr_part_group_t * part_group,
static int route2_carrier(struct sip_msg* msg, char* part_carrier,
char* gw_att_pv, char* carr_att_pv)
{
unsigned short carrier_idx[DR_MAX_GWLIST];
static unsigned short *carrier_idx;
static unsigned short carrier_idx_size;
struct sip_uri uri;
pgw_list_t *cdst;
pcr_t *cr;
Expand Down Expand Up @@ -3249,6 +3275,8 @@ static int route2_carrier(struct sip_msg* msg, char* part_carrier,
goto no_gws;

/* sort the gws of the carrier */
resize_dr_sort_buffer( carrier_idx, carrier_idx_size,
cr->pgwa_len, error);
j = sort_rt_dst( cr->pgwl, cr->pgwa_len, cr->flags&DR_CR_FLAG_WEIGHT,
carrier_idx);
if (j!=0) {
Expand Down

0 comments on commit dd20710

Please sign in to comment.