Skip to content

Commit

Permalink
drouting: Fix rule fallback across multiple prefixless rules ('')
Browse files Browse the repository at this point in the history
Mostly affects the "do_routing() + use_next_gw()" scripting logic.

(cherry picked from commit fd5066a)
(cherry picked from commit 435aa4b)
  • Loading branch information
liviuchircu committed Dec 14, 2023
1 parent 35f8ea7 commit 51c76af
Show file tree
Hide file tree
Showing 4 changed files with 42 additions and 20 deletions.
2 changes: 1 addition & 1 deletion modules/drouting/dr_api_internal.c
Original file line number Diff line number Diff line change
Expand Up @@ -71,7 +71,7 @@ static inline void * get_qr_rule_handle(rt_info_t *rule) {
rt_info_t* find_rule_by_prefix_unsafe(ptree_t *pt, ptree_node_t *noprefix,
str prefix, unsigned int grp_id, unsigned int *matched_len)
{
unsigned int rule_idx = 0;
int rule_idx = 0;
rt_info_t *rt_info;

rt_info = get_prefix(pt, &prefix, grp_id,matched_len, &rule_idx);
Expand Down
31 changes: 18 additions & 13 deletions modules/drouting/drouting.c
Original file line number Diff line number Diff line change
Expand Up @@ -3127,7 +3127,7 @@ static int do_routing(struct sip_msg* msg, struct head_db *part, int grp,
pgw_list_t *dst, *cdst;
pgw_list_t *wl_list;
unsigned int prefix_len;
unsigned int rule_idx;
int rule_idx;
struct head_db *current_partition=NULL;
unsigned short wl_len;
str username;
Expand Down Expand Up @@ -3258,7 +3258,7 @@ static int do_routing(struct sip_msg* msg, struct head_db *part, int grp,
}
username = val.s;
/* still something to look for ? */
if (username.len==0) return -1;
if (username.len==0 && rule_idx<0) return -1;

/* original RURI to be used when building RURIs for new attempts */
if (search_first_avp( AVP_VAL_STR, current_partition->avpID_store_ruri,
Expand Down Expand Up @@ -3289,7 +3289,7 @@ static int do_routing(struct sip_msg* msg, struct head_db *part, int grp,
username.len = prefix_len -(rule_idx?0:1);
LM_DBG("doing internal fallback, prefix_len=%d,rule_idx=%d\n",
username.len, rule_idx);
if (username.len==0 && rule_idx==0) {
if (username.len==0 && rule_idx<=0) {
/* disable failover as nothing left */
flags = flags & ~DR_PARAM_RULE_FALLBACK;
goto error2;
Expand All @@ -3306,18 +3306,24 @@ static int do_routing(struct sip_msg* msg, struct head_db *part, int grp,
}

if (rt_info==0) {
LM_DBG("no matching for prefix \"%.*s\"\n",
username.len, username.s);
LM_DBG("no matching for prefix \"%.*s\" idx: %d\n",
username.len, username.s, rule_idx);
/* try prefixless rules */
rt_info = check_rt(&current_partition->rdata->noprefix,
(unsigned int)grp);
if (rule_idx >= 0)
rt_info = _check_rt(&current_partition->rdata->noprefix,
(unsigned int)grp, &rule_idx);
if (rt_info==0) {
LM_DBG("no prefixless matching for "
"grp %d\n", grp);
goto error2;
}
prefix_len = 0;
rule_idx = 0;

LM_DBG("prefixless matching successful, crt-index: %d\n", rule_idx);

/* "stop" marker for reaching the last prefixless route */
if (rule_idx == 0)
rule_idx = -1;
}

if (rt_info->route_idx && (rt_idx=get_script_route_ID_by_name
Expand All @@ -3336,7 +3342,7 @@ static int do_routing(struct sip_msg* msg, struct head_db *part, int grp,
goto no_gws;

/* do we have anything left to failover to ? */
if (prefix_len==0 && rule_idx==0)
if (prefix_len==0 && rule_idx<=0)
/* disable failover as nothing left */
flags = flags & ~DR_PARAM_RULE_FALLBACK;

Expand Down Expand Up @@ -3548,10 +3554,9 @@ static int do_routing(struct sip_msg* msg, struct head_db *part, int grp,
if ( !(flags & DR_PARAM_INTERNAL_TRIGGERED) ) {
/* first time - we need to save some date, to be able to
* do the rule fallback later in "next_gw" , but do it only if
* there is place for fallback (more rules or shorter prefix are
* available) */
if (prefix_len!=0 || rule_idx!=0) {
LM_DBG("saving rule_idx %d, prefix %.*s\n",rule_idx,
* there is room for fallback (more rules are available) */
if (rule_idx>0) {
LM_DBG("saving rule_idx %d, prefix '%.*s'\n",rule_idx,
prefix_len - (rule_idx?0:1), username.s);
val.n = rule_idx;
if (add_avp( 0 , current_partition->avpID_store_index, val) ) {
Expand Down
18 changes: 14 additions & 4 deletions modules/drouting/prefix_tree.c
Original file line number Diff line number Diff line change
Expand Up @@ -84,7 +84,7 @@ static inline rt_info_t*
internal_check_rt(
ptree_node_t *ptn,
unsigned int rgid,
unsigned int *rgidx
int *rgidx
)
{
int i,j;
Expand Down Expand Up @@ -126,18 +126,28 @@ check_rt(
unsigned int rgid
)
{
unsigned int rgidx = 0;
int rgidx = 0;
return internal_check_rt( ptn, rgid, &rgidx);
}

rt_info_t*
_check_rt(
ptree_node_t *ptn,
unsigned int rgid,
int *rgidx
)
{
return internal_check_rt( ptn, rgid, rgidx);
}


rt_info_t*
get_prefix(
ptree_t *ptree,
str* prefix,
unsigned int rgid,
unsigned int *matched_len,
unsigned int *rgidx
int *rgidx
)
{
rt_info_t *rt = NULL;
Expand All @@ -147,7 +157,7 @@ get_prefix(

if(NULL == ptree)
goto err_exit;
if(NULL == prefix)
if(NULL == prefix || prefix->len == 0)
goto err_exit;
tmp = prefix->s;
if (tmp == NULL)
Expand Down
11 changes: 9 additions & 2 deletions modules/drouting/prefix_tree.h
Original file line number Diff line number Diff line change
Expand Up @@ -203,8 +203,8 @@ get_prefix(
ptree_t *ptree,
str* prefix,
unsigned int rgid,
unsigned int *rgidx,
unsigned int *matched_len
unsigned int *matched_len,
int *rgidx
);

int
Expand Down Expand Up @@ -255,4 +255,11 @@ check_rt(
unsigned int rgid
);

rt_info_t*
_check_rt(
ptree_node_t *ptn,
unsigned int rgid,
int *rgidx
);

#endif

0 comments on commit 51c76af

Please sign in to comment.