static struct mi_root* ds_mi_set(struct mi_root* cmd_tree, void* param) { str sp; int ret; unsigned int group, state; struct mi_node* node; node = cmd_tree->node.kids; if(node == NULL) return init_mi_tree( 400, MI_MISSING_PARM_S, MI_MISSING_PARM_LEN); sp = node->value; if(sp.len<=0 || !sp.s) { LM_ERR("bad state value\n"); return init_mi_tree( 500, "bad state value", 15); } state = 1; if(sp.s[0]=='0' || sp.s[0]=='I' || sp.s[0]=='i') state = 0; node = node->next; if(node == NULL) return init_mi_tree( 400, MI_MISSING_PARM_S, MI_MISSING_PARM_LEN); sp = node->value; if(sp.s == NULL) { return init_mi_tree(500, "group not found", 15); } if(str2int(&sp, &group)) { LM_ERR("bad group value\n"); return init_mi_tree( 500, "bad group value", 16); } node= node->next; if(node == NULL) return init_mi_tree( 400, MI_MISSING_PARM_S, MI_MISSING_PARM_LEN); sp = node->value; if(sp.s == NULL) { return init_mi_tree(500,"address not found", 18 ); } if(state==1) ret = ds_set_state(group, &sp, DS_INACTIVE_DST, 0); else ret = ds_set_state(group, &sp, DS_INACTIVE_DST, 1); if(ret!=0) { return init_mi_tree(404, "destination not found", 21); } return init_mi_tree( 200, MI_OK_S, MI_OK_LEN); }
/** * Callback-Function for the OPTIONS-Request * This Function is called, as soon as the Transaction is finished * (e. g. a Response came in, the timeout was hit, ...) * */ static void ds_options_callback( struct cell *t, int type, struct tmcb_params *ps ) { int group = 0; str uri = {0, 0}; /* The Param does contain the group, in which the failed host * can be found.*/ if (!ps->param) { LM_DBG("No parameter provided, OPTIONS-Request was finished" " with code %d\n", ps->code); return; } /* The param is a (void*) Pointer, so we need to dereference it and * cast it to an int. */ group = (int)(long)(*ps->param); /* The SIP-URI is taken from the Transaction. * Remove the "To: " (s+4) and the trailing new-line (s - 4 (To: ) * - 2 (\r\n)). */ uri.s = t->to.s + 4; uri.len = t->to.len - 6; LM_DBG("OPTIONS-Request was finished with code %d (to %.*s, group %d)\n", ps->code, uri.len, uri.s, group); /* ps->code contains the result-code of the request. * * We accept "200 OK" by default and the custom codes * defined in options_reply_codes parameter*/ if ((ps->code == 200) || check_options_rplcode(ps->code)) { /* Set the according entry back to "Active": * remove the Probing/Inactive Flag and reset the failure counter. */ if (ds_set_state(group, &uri, DS_INACTIVE_DST|DS_PROBING_DST|DS_RESET_FAIL_DST, 0) != 0) { LM_ERR("Setting the state failed (%.*s, group %d)\n", uri.len, uri.s, group); } } /* if we always probe, and we get a timeout * or a reponse that is not within the allowed * reply codes, then disable*/ if(ds_probing_mode==1 && ps->code != 200 && (ps->code == 408 || !check_options_rplcode(ps->code))) { if (ds_set_state(group, &uri, DS_PROBING_DST, 1) != 0) { LM_ERR("Setting the probing state failed (%.*s, group %d)\n", uri.len, uri.s, group); } } return; }
int ds_mark_dst(struct sip_msg *msg, int mode) { int group, ret; struct usr_avp *prev_avp; int_str avp_value; if(!(ds_flags&DS_FAILOVER_ON)) { LM_WARN("failover support disabled\n"); return -1; } prev_avp = search_first_avp(grp_avp_type, grp_avp_name, &avp_value, 0); if(prev_avp==NULL || prev_avp->flags&AVP_VAL_STR) return -1; /* grp avp deleted -- strange */ group = avp_value.n; prev_avp = search_first_avp(dst_avp_type, dst_avp_name, &avp_value, 0); if(prev_avp==NULL || !(prev_avp->flags&AVP_VAL_STR)) return -1; /* dst avp deleted -- strange */ if(mode==1) { ret = ds_set_state(group, &avp_value.s, DS_INACTIVE_DST|DS_PROBING_DST, 0); } else if(mode==2) { ret = ds_set_state(group, &avp_value.s, DS_PROBING_DST, 1); if (ret == 0) ret = ds_set_state(group, &avp_value.s, DS_INACTIVE_DST, 0); } else { ret = ds_set_state(group, &avp_value.s, DS_INACTIVE_DST, 1); if (ret == 0) ret = ds_set_state(group, &avp_value.s, DS_PROBING_DST, 0); } LM_DBG("mode [%d] grp [%d] dst [%.*s]\n", mode, group, avp_value.s.len, avp_value.s.s); return (ret==0)?1:-1; }
static struct mi_root* ds_mi_set(struct mi_root* cmd_tree, void* param) { str sp, partition_name; int ret; unsigned int group, state; struct mi_node* node; ds_partition_t *partition; node = cmd_tree->node.kids; if(node == NULL) return init_mi_tree( 400, MI_MISSING_PARM_S, MI_MISSING_PARM_LEN); sp = node->value; if(sp.len<=0 || !sp.s) { LM_ERR("bad state value\n"); return init_mi_tree( 500, MI_SSTR("Bad state value") ); } if(sp.s[0]=='0' || sp.s[0]=='I' || sp.s[0]=='i') state = 0; else if(sp.s[0]=='p' || sp.s[0]=='P' || sp.s[0]=='2') state = 2; else if(sp.s[0]=='a' || sp.s[0]=='A' || sp.s[0]=='1') state = 1; else return init_mi_tree( 500, MI_SSTR("Bad state value") ); node = node->next; if(node == NULL) return init_mi_tree( 400, MI_MISSING_PARM_S, MI_MISSING_PARM_LEN); sp = node->value; if(sp.s == NULL) { return init_mi_tree(500, MI_SSTR("group not found")); } if (split_partition_argument(&sp, &partition_name) != 0) { LM_ERR("bad group format\n"); return init_mi_tree(500, MI_SSTR("bad group format")); } partition = find_partition_by_name(&partition_name); if (partition == NULL) { LM_ERR("partition does not exist\n"); return init_mi_tree(404, MI_SSTR(MI_UNK_PARTITION) ); } if(str2int(&sp, &group)) { LM_ERR("bad group value\n"); return init_mi_tree( 500, MI_SSTR("bad group value")); } node= node->next; if(node == NULL) return init_mi_tree( 400, MI_MISSING_PARM_S, MI_MISSING_PARM_LEN); sp = node->value; if(sp.s == NULL) { return init_mi_tree(500, MI_SSTR("address not found")); } if (state==1) { /* set active */ ret = ds_set_state(group, &sp, DS_INACTIVE_DST|DS_PROBING_DST, 0, partition); } else if (state==2) { /* set probing */ ret = ds_set_state(group, &sp, DS_PROBING_DST, 1, partition); if (ret==0) ret = ds_set_state(group, &sp, DS_INACTIVE_DST, 0, partition); } else { /* set inactive */ ret = ds_set_state(group, &sp, DS_INACTIVE_DST, 1, partition); if (ret == 0) ret = ds_set_state(group, &sp, DS_PROBING_DST, 0, partition); } if(ret!=0) return init_mi_tree(404, MI_SSTR("destination not found")); return init_mi_tree( 200, MI_OK_S, MI_OK_LEN); }