Skip to content

Commit

Permalink
dispatcher: new variable $dsv(...)
Browse files Browse the repository at this point in the history
- access attributes related to response code when executing event routes
- $dsv(code) - the response code that triggered execution of the
event_route dispatcher:dst-up or dispatcher:dst-down
- $dsv(reason) - the response reason; $dsv(flags) - internal flags set
during event route execution
  • Loading branch information
miconda committed Nov 19, 2019
1 parent 792261b commit 9d59f5c
Show file tree
Hide file tree
Showing 3 changed files with 145 additions and 13 deletions.
66 changes: 56 additions & 10 deletions src/modules/dispatcher/dispatch.c
Expand Up @@ -105,7 +105,8 @@ int *next_idx = NULL;
#define _ds_list (ds_lists[*crt_idx])
#define _ds_list_nr (*ds_list_nr)

static void ds_run_route(struct sip_msg *msg, str *uri, char *route);
static void ds_run_route(struct sip_msg *msg, str *uri, char *route,
ds_rctx_t *rctx);

void shuffle_uint100array(unsigned int *arr);
int ds_reinit_rweight_on_state_change(
Expand Down Expand Up @@ -2484,6 +2485,7 @@ int ds_mark_dst(struct sip_msg *msg, int state)
sr_xavp_t *rxavp = NULL;
int group;
int ret;
ds_rctx_t rctx;

if(!(ds_flags & DS_FAILOVER_ON)) {
LM_WARN("failover support disabled\n");
Expand All @@ -2505,7 +2507,23 @@ int ds_mark_dst(struct sip_msg *msg, int state)
if(rxavp == NULL )
return -1; /* dst addr uri not available */

ret = ds_update_state(msg, group, &rxavp->val.v.s, state);
memset(&rctx, 0, sizeof(ds_rctx_t));
if(msg!=NULL) {
if(msg!=FAKED_REPLY) {
if(msg->first_line.type == SIP_REPLY) {
rctx.flags |= 1;
rctx.code = (int)msg->first_line.u.reply.statuscode;
rctx.reason = msg->first_line.u.reply.reason;
} else {
rctx.code = 820;
}
} else {
rctx.code = 810;
}
} else {
rctx.code = 800;
}
ret = ds_update_state(msg, group, &rxavp->val.v.s, state, &rctx);

LM_DBG("state [%d] grp [%d] dst [%.*s]\n", state, group, rxavp->val.v.s.len,
rxavp->val.v.s.s);
Expand Down Expand Up @@ -2682,7 +2700,8 @@ int ds_get_state(int group, str *address)
/**
* Update destionation's state
*/
int ds_update_state(sip_msg_t *msg, int group, str *address, int state)
int ds_update_state(sip_msg_t *msg, int group, str *address, int state,
ds_rctx_t *rctx)
{
int i = 0;
int old_state = 0;
Expand Down Expand Up @@ -2761,11 +2780,11 @@ int ds_update_state(sip_msg_t *msg, int group, str *address, int state)
}

if(!ds_skip_dst(old_state) && ds_skip_dst(idx->dlist[i].flags)) {
ds_run_route(msg, address, "dispatcher:dst-down");
ds_run_route(msg, address, "dispatcher:dst-down", rctx);

} else {
if(ds_skip_dst(old_state) && !ds_skip_dst(idx->dlist[i].flags))
ds_run_route(msg, address, "dispatcher:dst-up");
ds_run_route(msg, address, "dispatcher:dst-up", rctx);
}
if(idx->dlist[i].attrs.rweight > 0)
ds_reinit_rweight_on_state_change(
Expand All @@ -2780,7 +2799,20 @@ int ds_update_state(sip_msg_t *msg, int group, str *address, int state)
return -1;
}

static void ds_run_route(sip_msg_t *msg, str *uri, char *route)
/**
*
*/
static ds_rctx_t *_ds_rctx = NULL;

/**
*
*/
ds_rctx_t* ds_get_rctx(void)
{
return _ds_rctx;
}

static void ds_run_route(sip_msg_t *msg, str *uri, char *route, ds_rctx_t *rctx)
{
int rt, backup_rt;
struct run_act_ctx ctx;
Expand All @@ -2793,7 +2825,7 @@ static void ds_run_route(sip_msg_t *msg, str *uri, char *route)
return;
}

LM_DBG("ds_run_route event_route[%s]\n", route);
LM_DBG("executing event_route[%s]\n", route);

rt = -1;
if(ds_event_callback.s==NULL || ds_event_callback.len<=0) {
Expand Down Expand Up @@ -2824,6 +2856,7 @@ static void ds_run_route(sip_msg_t *msg, str *uri, char *route)
}

if(rt>=0 || ds_event_callback.len>0) {
_ds_rctx = rctx;
backup_rt = get_route_type();
set_route_type(REQUEST_ROUTE);
init_run_actions_ctx(&ctx);
Expand All @@ -2840,6 +2873,7 @@ static void ds_run_route(sip_msg_t *msg, str *uri, char *route)
}
}
set_route_type(backup_rt);
_ds_rctx = NULL;
}
}

Expand Down Expand Up @@ -3132,6 +3166,7 @@ static void ds_options_callback(
str uri = {0, 0};
sip_msg_t *fmsg;
int state;
ds_rctx_t rctx;

/* The param contains the group, in which the failed host
* can be found.*/
Expand All @@ -3154,8 +3189,19 @@ static void ds_options_callback(
uri.len = t->to.len - 8;
LM_DBG("OPTIONS-Request was finished with code %d (to %.*s, group %d)\n",
ps->code, uri.len, uri.s, group);
if (ds_ping_latency_stats)
if (ds_ping_latency_stats) {
ds_update_latency(group, &uri, ps->code);
}

memset(&rctx, 0, sizeof(ds_rctx_t));
rctx.code = ps->code;
if(ps->rpl!=NULL) {
if(ps->rpl!=FAKED_REPLY) {
rctx.flags |= 1;
rctx.reason = ps->rpl->first_line.u.reply.reason;
}
}

/* ps->code contains the result-code of the request.
*
* We accept both a "200 OK" or the configured reply as a valid response */
Expand All @@ -3170,7 +3216,7 @@ static void ds_options_callback(

/* Check if in the meantime someone disabled the target through RPC or MI */
if(!(ds_get_state(group, &uri) & DS_DISABLED_DST)
&& ds_update_state(fmsg, group, &uri, state) != 0) {
&& ds_update_state(fmsg, group, &uri, state, &rctx) != 0) {
LM_ERR("Setting the state failed (%.*s, group %d)\n", uri.len,
uri.s, group);
}
Expand All @@ -3180,7 +3226,7 @@ static void ds_options_callback(
state |= DS_PROBING_DST;
/* Check if in the meantime someone disabled the target through RPC or MI */
if(!(ds_get_state(group, &uri) & DS_DISABLED_DST)
&& ds_update_state(fmsg, group, &uri, state) != 0) {
&& ds_update_state(fmsg, group, &uri, state, &rctx) != 0) {
LM_ERR("Setting the probing state failed (%.*s, group %d)\n",
uri.len, uri.s, group);
}
Expand Down
12 changes: 10 additions & 2 deletions src/modules/dispatcher/dispatch.h
Expand Up @@ -72,9 +72,14 @@
#define DS_XAVP_CTX_SKIP_CNT 1

#define DS_IRMODE_NOIPADDR 1

/* clang-format on */

typedef struct ds_rctx {
int flags;
int code;
str reason;
} ds_rctx_t;

extern str ds_db_url;
extern str ds_table_name;
extern str ds_set_id_col;
Expand Down Expand Up @@ -134,7 +139,8 @@ int ds_select_dst(struct sip_msg *msg, int set, int alg, int mode);
int ds_update_dst(struct sip_msg *msg, int upos, int mode);
int ds_add_dst(int group, str *address, int flags);
int ds_remove_dst(int group, str *address);
int ds_update_state(sip_msg_t *msg, int group, str *address, int state);
int ds_update_state(sip_msg_t *msg, int group, str *address, int state,
ds_rctx_t *rctx);
int ds_reinit_state(int group, str *address, int state);
int ds_reinit_state_all(int group, int state);
int ds_mark_dst(struct sip_msg *msg, int mode);
Expand Down Expand Up @@ -259,4 +265,6 @@ void ds_avl_destroy(ds_set_t **node);

int ds_manage_routes(sip_msg_t *msg, ds_select_state_t *rstate);

ds_rctx_t* ds_get_rctx(void);

#endif
80 changes: 79 additions & 1 deletion src/modules/dispatcher/dispatcher.c
Expand Up @@ -183,6 +183,16 @@ static void destroy(void);

static int ds_warn_fixup(void** param, int param_no);

static int pv_get_dsv(sip_msg_t *msg, pv_param_t *param, pv_value_t *res);
static int pv_parse_dsv(pv_spec_p sp, str *in);

static pv_export_t mod_pvs[] = {
{ {"dsv", (sizeof("dsv")-1)}, PVT_OTHER, pv_get_dsv, 0,
pv_parse_dsv, 0, 0, 0 },

{ {0, 0}, 0, 0, 0, 0, 0, 0, 0 }
};

static cmd_export_t cmds[]={
{"ds_select", (cmd_function)w_ds_select, 2,
fixup_igp_igp, 0, ANY_ROUTE},
Expand Down Expand Up @@ -287,7 +297,7 @@ struct module_exports exports= {
cmds, /* cmd (cfg function) exports */
params, /* param exports */
0, /* exported rpc functions */
0, /* exported pseudo-variables */
mod_pvs, /* exported pseudo-variables */
0, /* response handling function */
mod_init, /* module init function */
child_init, /* per-child init function */
Expand Down Expand Up @@ -1160,6 +1170,74 @@ void ds_ping_reply_codes_update(str *gname, str *name)
ds_parse_reply_codes();
}

/**
*
*/
static int pv_get_dsv(sip_msg_t *msg, pv_param_t *param, pv_value_t *res)
{
ds_rctx_t *rctx;

if(param==NULL) {
return -1;
}
rctx = ds_get_rctx();
if(rctx==NULL) {
return pv_get_null(msg, param, res);
}
switch(param->pvn.u.isname.name.n)
{
case 0:
return pv_get_sintval(msg, param, res, rctx->code);
case 1:
if(rctx->reason.s!=NULL && rctx->reason.len>0) {
return pv_get_strval(msg, param, res, &rctx->reason);
}
return pv_get_null(msg, param, res);
case 2:
return pv_get_sintval(msg, param, res, rctx->flags);
default:
return pv_get_null(msg, param, res);
}
}

/**
*
*/
static int pv_parse_dsv(pv_spec_p sp, str *in)
{
if(sp==NULL || in==NULL || in->len<=0)
return -1;

switch(in->len)
{
case 4:
if(strncmp(in->s, "code", 4)==0)
sp->pvp.pvn.u.isname.name.n = 0;
else goto error;
break;
case 5:
if(strncmp(in->s, "flags", 5)==0)
sp->pvp.pvn.u.isname.name.n = 2;
else goto error;
break;
case 6:
if(strncmp(in->s, "reason", 6)==0)
sp->pvp.pvn.u.isname.name.n = 2;
else goto error;
break;
default:
goto error;
}
sp->pvp.pvn.type = PV_NAME_INTSTR;
sp->pvp.pvn.u.isname.type = 0;

return 0;

error:
LM_ERR("unknown PV key: %.*s\n", in->len, in->s);
return -1;
}

/* KEMI wrappers */
/**
*
Expand Down

0 comments on commit 9d59f5c

Please sign in to comment.