/*! \brief * Module destroy function */ static void destroy(void) { /* we need to sync DB in order to flush the cache */ if (ul_dbh) { ul_unlock_locks(); if (sync_lock) lock_start_read(sync_lock); if (synchronize_all_udomains() != 0) { LM_ERR("flushing cache failed\n"); } if (sync_lock) { lock_stop_read(sync_lock); lock_destroy_rw(sync_lock); sync_lock = 0; } ul_dbf.close(ul_dbh); } free_all_udomains(); ul_destroy_locks(); /* free callbacks list */ destroy_ulcb_list(); }
static int w_lb_count_call(struct sip_msg *req, char *ip, char *port, char *grp, char *rl, char *dir) { struct lb_grp_param *lbgp = (struct lb_grp_param *)grp; struct lb_res_str_list *lb_rl; struct lb_res_parse *lbp; struct ip_addr *ipa; pv_value_t val; pv_elem_t *model; int grp_no; int port_no; str dest; int ret; /* get the ip address */ if (pv_get_spec_value( req, (pv_spec_t*)ip, &val)!=0) { LM_ERR("failed to get IP value from PV\n"); return -1; } if ( (val.flags&PV_VAL_STR)==0 ) { LM_ERR("IP PV val is not string\n"); return -1; } if ( (ipa=str2ip( &val.rs ))==NULL ) { LM_ERR("IP val is not IP <%.*s>\n",val.rs.len,val.rs.s); return -1; } /* get the port */ if (port) { if (fixup_get_ivalue( req, (gparam_p)port, &port_no)!=0) { LM_ERR("failed to get PORT value from PV\n"); return -1; } } else { port_no = 0; } /* get the group */ if (lbgp->grp_pv) { if (pv_get_spec_value( req, (pv_spec_p)lbgp->grp_pv, &val)!=0) { LM_ERR("failed to get PV value\n"); return -1; } if ( (val.flags&PV_VAL_INT)==0 ) { LM_ERR("PV vals is not integer\n"); return -1; } grp_no = val.ri; } else { grp_no = lbgp->grp_no; } /* get the resources list */ lbp = (struct lb_res_parse *)rl; if (lbp->type & RES_ELEM) { model = (pv_elem_p)lbp->param; if (pv_printf_s(req, model, &dest) || dest.len <= 0) { LM_ERR("cannot create resource string\n"); return -1; } lb_rl = parse_resources_list(dest.s, 0); if (!lb_rl) { LM_ERR("cannot create resource list\n"); return -1; } } else lb_rl = (struct lb_res_str_list *)lbp->param; lock_start_read( ref_lock ); ret = lb_count_call( *curr_data, req, ipa, port_no, grp_no, lb_rl, dir ? (int)*(unsigned int *)dir : 0); lock_stop_read( ref_lock ); if (lbp->type & RES_ELEM) pkg_free(lb_rl); if (ret<0) return ret; return 1; }
static int w_lb_start(struct sip_msg *req, char *grp, char *rl, char *fl) { int ret; int grp_no; struct lb_grp_param *lbgp = (struct lb_grp_param *)grp; pv_value_t val; struct lb_res_str_list *lb_rl; struct lb_res_parse *lbp; pv_elem_t *model; str dest; str flstr = {0,0}; int flags=LB_FLAGS_DEFAULT; char *f; if (lbgp->grp_pv) { if (pv_get_spec_value( req, (pv_spec_p)lbgp->grp_pv, &val)!=0) { LM_ERR("failed to get PV value\n"); return -1; } if ( (val.flags&PV_VAL_INT)==0 ) { LM_ERR("PV vals is not integer\n"); return -1; } grp_no = val.ri; } else { grp_no = lbgp->grp_no; } lbp = (struct lb_res_parse *)rl; if (lbp->type & RES_ELEM) { model = (pv_elem_p)lbp->param; if (pv_printf_s(req, model, &dest) || dest.len <= 0) { LM_ERR("cannot create resource string\n"); return -1; } lb_rl = parse_resources_list(dest.s, 0); if (!lb_rl) { LM_ERR("cannot create resource list\n"); return -1; } } else lb_rl = (struct lb_res_str_list *)lbp->param; if( fl ) { if( fixup_get_svalue(req, (gparam_p)fl, &flstr) != 0 ) { LM_ERR("failed to extract flags\n"); return -1; } for( f=flstr.s ; f<flstr.s+flstr.len ; f++ ) { switch( *f ) { case 'r': flags |= LB_FLAGS_RELATIVE; LM_DBG("using relative versus absolute estimation\n"); break; case 'n': flags |= LB_FLAGS_NEGATIVE; LM_DBG("do not skip negative loads\n"); break; case 's': flags |= LB_FLAGS_RANDOM; LM_DBG("pick a random destination among all selected dsts with equal load\n"); break; default: LM_DBG("skipping unknown flag: [%c]\n", *f); } } } lock_start_read( ref_lock ); /* do lb */ ret = do_lb_start(req, grp_no, lb_rl, flags, *curr_data); lock_stop_read( ref_lock ); if (lbp->type & RES_ELEM) pkg_free(lb_rl); if (ret<0) return ret; return 1; }
static struct mi_root* mi_lb_list(struct mi_root *cmd_tree, void *param) { struct mi_root *rpl_tree; struct mi_node *dst_node; struct mi_node *node, *node1; struct mi_attr *attr; struct lb_dst *dst; char *p; int len; int i; rpl_tree = init_mi_tree( 200, MI_OK_S, MI_OK_LEN); if (rpl_tree==NULL) return NULL; rpl_tree->node.flags |= MI_IS_ARRAY; lock_start_read( ref_lock ); /* go through all destination */ for( dst=(*curr_data)->dsts ; dst ; dst=dst->next) { /* add a destination node */ dst_node = add_mi_node_child( &rpl_tree->node, 0, "Destination", 11, dst->uri.s, dst->uri.len); if (dst_node==0) goto error; /* add some attributes to the destination node */ p= int2str((unsigned long)dst->id, &len); attr = add_mi_attr( dst_node, MI_DUP_VALUE, "id", 2, p, len); if (attr==0) goto error; p= int2str((unsigned long)dst->group, &len); attr = add_mi_attr( dst_node, MI_DUP_VALUE, "group", 5, p, len); if (attr==0) goto error; if (dst->flags&LB_DST_STAT_DSBL_FLAG) { attr = add_mi_attr( dst_node, 0, "enabled", 7, "no", 2); } else { attr = add_mi_attr( dst_node, 0, "enabled", 7, "yes", 3); } if (attr==0) goto error; if (dst->flags&LB_DST_STAT_NOEN_FLAG) { attr = add_mi_attr( dst_node, 0, "auto-reenable", 13, "off", 3); } else { attr = add_mi_attr( dst_node, 0, "auto-reenable", 13, "on", 2); } if (attr==0) goto error; node = add_mi_node_child( dst_node, MI_IS_ARRAY, "Resources", 9, NULL, 0); if (node==0) goto error; /* go through all resources */ for( i=0 ; i<dst->rmap_no ; i++) { /* add a resource node */ node1 = add_mi_node_child( node, 0, "Resource", 8, dst->rmap[i].resource->name.s,dst->rmap[i].resource->name.len); if (node1==0) goto error; /* add some attributes to the destination node */ p= int2str((unsigned long)dst->rmap[i].max_load, &len); attr = add_mi_attr( node1, MI_DUP_VALUE, "max", 3, p, len); if (attr==0) goto error; p= int2str((unsigned long)lb_dlg_binds.get_profile_size (dst->rmap[i].resource->profile, &dst->profile_id), &len); attr = add_mi_attr( node1, MI_DUP_VALUE, "load", 4, p, len); if (attr==0) goto error; } } lock_stop_read( ref_lock ); return rpl_tree; error: lock_stop_read( ref_lock ); free_mi_tree(rpl_tree); return 0; }
static struct mi_root* mi_lb_status(struct mi_root *cmd, void *param) { struct mi_root *rpl_tree; struct lb_dst *dst; struct mi_node *node; unsigned int id, stat; unsigned int old_flags; node = cmd->node.kids; if (node==NULL) return init_mi_tree( 400, MI_MISSING_PARM_S, MI_MISSING_PARM_LEN); /* id (param 1) */ if (str2int( &node->value, &id) < 0) return init_mi_tree( 400, MI_SSTR(MI_BAD_PARM_S)); lock_start_read( ref_lock ); /* status (param 2) */ node = node->next; if (node == NULL) { /* return the status -> find the destination */ for(dst=(*curr_data)->dsts; dst && dst->id!=id ;dst=dst->next); if (dst==NULL) { rpl_tree = init_mi_tree( 404, MI_SSTR("Destination ID not found")); } else { rpl_tree = init_mi_tree( 200, MI_OK_S, MI_OK_LEN); if (rpl_tree!=NULL) { if (dst->flags&LB_DST_STAT_DSBL_FLAG) { node = add_mi_node_child( &rpl_tree->node, 0, "enable", 6, "no", 2); } else { node = add_mi_node_child( &rpl_tree->node, 0, "enable", 6, "yes", 3); } if (node==NULL) {free_mi_tree(rpl_tree); rpl_tree=NULL;} } } } else { /* set the status */ if (node->next) { rpl_tree = init_mi_tree( 400, MI_MISSING_PARM_S, MI_MISSING_PARM_LEN); } else if (str2int( &node->value, &stat) < 0) { rpl_tree = init_mi_tree( 400, MI_SSTR(MI_BAD_PARM_S)); } else { /* find the destination */ for( dst=(*curr_data)->dsts ; dst && dst->id!=id ; dst=dst->next); if (dst==NULL) { rpl_tree = init_mi_tree( 404, MI_SSTR("Destination ID not found")); } else { /* set the disable/enable */ old_flags = dst->flags; if (stat) { dst->flags &= ~ (LB_DST_STAT_DSBL_FLAG|LB_DST_STAT_NOEN_FLAG); } else { dst->flags |= LB_DST_STAT_DSBL_FLAG|LB_DST_STAT_NOEN_FLAG; } if (old_flags != dst->flags) { lb_status_changed(dst); if( lb_prob_verbose ) LM_INFO("manually %s destination %d <%.*s>\n", (stat ? "enable" : "disable"), dst->id, dst->uri.len, dst->uri.s ); } lock_stop_read( ref_lock ); return init_mi_tree( 200, MI_OK_S, MI_OK_LEN); } } } lock_stop_read( ref_lock ); return rpl_tree; }
/* lists the clusters' topology as viewed by the current node*/ static struct mi_root * clusterer_list_topology(struct mi_root *cmd_tree, void *param) { cluster_info_t *cl; node_info_t *n_info; struct mi_root *rpl_tree = NULL; struct mi_node *node = NULL; struct mi_node *node_s = NULL; struct mi_attr* attr; str val; char neigh_list[512]; struct neighbour *neigh; rpl_tree = init_mi_tree(200, MI_OK_S, MI_OK_LEN); if (!rpl_tree) return NULL; rpl_tree->node.flags |= MI_IS_ARRAY; lock_start_read(cl_list_lock); /* iterate through clusters */ for (cl = *cluster_list; cl; cl = cl->next) { val.s = int2str(cl->cluster_id, &val.len); node = add_mi_node_child(&rpl_tree->node, MI_DUP_VALUE|MI_IS_ARRAY, MI_SSTR("Cluster"), val.s, val.len); if (!node) goto error; val.s = int2str(current_id, &val.len); node_s = add_mi_node_child(node, MI_DUP_VALUE, MI_SSTR("Node"), val.s, val.len); if (!node_s) goto error; memset(neigh_list, 0, 500); for (neigh = cl->current_node->neighbour_list; neigh; neigh = neigh->next) { sprintf(neigh_list + strlen(neigh_list), "%d ", neigh->node->node_id); } val.s = neigh_list; val.len = strlen(neigh_list); attr = add_mi_attr(node_s, MI_DUP_VALUE, MI_SSTR("Neighbours"), val.s, val.len); if (!attr) goto error; for (n_info = cl->node_list; n_info; n_info = n_info->next) { val.s = int2str(n_info->node_id, &val.len); node_s = add_mi_node_child(node, MI_DUP_VALUE, MI_SSTR("Node"), val.s, val.len); if (!node_s) goto error; memset(neigh_list, 0, 500); lock_get(n_info->lock); for (neigh = n_info->neighbour_list; neigh; neigh = neigh->next) { sprintf(neigh_list + strlen(neigh_list), "%d ", neigh->node->node_id); } if (n_info->link_state == LS_UP) sprintf(neigh_list + strlen(neigh_list), "%d ", current_id); lock_release(n_info->lock); val.s = neigh_list; val.len = strlen(neigh_list); attr = add_mi_attr(node_s, MI_DUP_VALUE, MI_SSTR("Neighbours"), val.s, val.len); if (!attr) goto error; } } lock_stop_read(cl_list_lock); return rpl_tree; error: lock_stop_read(cl_list_lock); if (rpl_tree) free_mi_tree(rpl_tree); return NULL; }
static struct mi_root * clusterer_list(struct mi_root *cmd_tree, void *param) { cluster_info_t *cl; node_info_t *n_info; struct mi_root *rpl_tree = NULL; struct mi_node *node = NULL; struct mi_node *node_s = NULL; struct mi_attr* attr; str val; static str str_up = str_init("Up "); static str str_prob = str_init("Probe "); static str str_down = str_init("Down "); static str str_none = str_init("none"); int n_hop; rpl_tree = init_mi_tree(200, MI_OK_S, MI_OK_LEN); if (!rpl_tree) return NULL; rpl_tree->node.flags |= MI_IS_ARRAY; lock_start_read(cl_list_lock); /* iterate through clusters */ for (cl = *cluster_list; cl; cl = cl->next) { val.s = int2str(cl->cluster_id, &val.len); node = add_mi_node_child(&rpl_tree->node, MI_DUP_VALUE|MI_IS_ARRAY, MI_SSTR("Cluster"), val.s, val.len); if (!node) goto error; /* iterate through servers */ for (n_info = cl->node_list; n_info; n_info = n_info->next) { val.s = int2str(n_info->node_id, &val.len); node_s = add_mi_node_child(node, MI_DUP_VALUE, MI_SSTR("Node"), val.s, val.len); if (!node) goto error; val.s = sint2str(n_info->id, &val.len); attr = add_mi_attr(node_s, MI_DUP_VALUE, MI_SSTR("DB_ID"), val.s, val.len); if (!attr) goto error; attr = add_mi_attr(node_s, MI_DUP_VALUE, MI_SSTR("URL"), n_info->url.s, n_info->url.len); if (!attr) goto error; lock_get(n_info->lock); val.s = int2str(n_info->flags & NODE_STATE_ENABLED ? 1 : 0, &val.len); attr = add_mi_attr(node_s, MI_DUP_VALUE, MI_SSTR("Enabled"), val.s, val.len); if (!attr) { lock_release(n_info->lock); goto error; } if (n_info->link_state == LS_UP) val = str_up; else if (n_info->link_state == LS_DOWN) val = str_down; else val = str_prob; attr = add_mi_attr(node_s, MI_DUP_VALUE, MI_SSTR("Link_state"), val.s, val.len); if (!attr) { lock_release(n_info->lock); goto error; } lock_release(n_info->lock); n_hop = get_next_hop(n_info); if (n_hop <= 0) val = str_none; else val.s = int2str(n_hop, &val.len); attr = add_mi_attr(node_s, MI_DUP_VALUE, MI_SSTR("Next_hop"), val.s, val.len); if (!attr) goto error; if (n_info->description.s) attr = add_mi_attr(node_s, MI_DUP_VALUE, MI_SSTR("Description"), n_info->description.s, n_info->description.len); else attr = add_mi_attr(node_s, MI_DUP_VALUE, MI_SSTR("Description"), "none", 4); if (!attr) goto error; } } lock_stop_read(cl_list_lock); return rpl_tree; error: lock_stop_read(cl_list_lock); if (rpl_tree) free_mi_tree(rpl_tree); return NULL; }
/* lists all valid connections */ static struct mi_root * clusterer_list(struct mi_root *cmd_tree, void *param) { table_entry_t *head_table; table_entry_info_t *info; table_entry_value_t *value; struct mi_root *rpl_tree = NULL; struct mi_node *node = NULL; struct mi_node *node_s = NULL; struct mi_attr* attr; str val; rpl_tree = init_mi_tree(200, MI_OK_S, MI_OK_LEN); if (!rpl_tree) return NULL; rpl_tree->node.flags |= MI_IS_ARRAY; lock_start_read(ref_lock); /* iterate through clusters */ for (head_table = *tdata; head_table; head_table = head_table->next) { val.s = int2str(head_table->cluster_id, &val.len); node = add_mi_node_child(&rpl_tree->node, MI_DUP_VALUE|MI_IS_ARRAY, MI_SSTR("Cluster"), val.s, val.len); if (!node) goto error; /* iterate through supported protocols */ for (info = head_table->info; info; info = info->next) { /* iterate through servers */ for (value = info->value; value; value = value->next) { val.s = int2str(value->machine_id, &val.len); node_s = add_mi_node_child(node, MI_DUP_VALUE, MI_SSTR("Server"), val.s, val.len); if (!node) goto error; val.s = int2str(value->id, &val.len); attr = add_mi_attr(node_s, MI_DUP_VALUE, MI_SSTR("DB_ID"), val.s, val.len); if (!attr) goto error; attr = add_mi_attr(node_s, MI_DUP_VALUE, MI_SSTR("URL"), value->path.s, value->path.len); if (!attr) goto error; val.s = int2str(value->state, &val.len); attr = add_mi_attr(node_s, MI_DUP_VALUE, MI_SSTR("State"), val.s, val.len); if (!attr) goto error; val.s = int2str(value->last_attempt, &val.len); attr = add_mi_attr(node_s, MI_DUP_VALUE, MI_SSTR("Last_failed_attempt"), val.s, val.len); if (!attr) goto error; val.s = int2str(value->failed_attempts, &val.len); attr = add_mi_attr(node_s, MI_DUP_VALUE, MI_SSTR("Max_failed_attempts"), val.s, val.len); if (!attr) goto error; val.s = int2str(value->no_tries, &val.len); attr = add_mi_attr(node_s, MI_DUP_VALUE, MI_SSTR("no_tries"), val.s, val.len); if (!attr) goto error; val.s = int2str(value->duration, &val.len); attr = add_mi_attr(node_s, MI_DUP_VALUE, MI_SSTR("Seconds_until_enabling"), val.s, val.len); if (!attr) goto error; if (value->description.s) attr = add_mi_attr(node_s, MI_DUP_VALUE, MI_SSTR("Description"), value->description.s, value->description.len); else attr = add_mi_attr(node_s, MI_DUP_VALUE, MI_SSTR("Description"), "none", 4); if (!attr) goto error; } } } lock_stop_read(ref_lock); return rpl_tree; error: lock_stop_read(ref_lock); if (rpl_tree) free_mi_tree(rpl_tree); return NULL; }
static int dp_translate_f(struct sip_msg *msg, char *str1, char *str2, char *attr_spec) { int dpid; str input, output; dpl_id_p idp; dp_param_p id_par, repl_par; str attrs, *attrs_par; dp_connection_list_p connection; pv_value_t pval; str partition_name; if (!msg) return -1; /* verify first param's value */ id_par = (dp_param_p) str1; if (dp_get_ivalue(msg, id_par, &dpid) != 0){ LM_ERR("no dpid value\n"); return -1; } switch( id_par->type ) { case DP_VAL_INT : if (dp_get_svalue(msg, id_par->v.pv_id.partition, &partition_name)) { LM_ERR("invalid partition\n"); return -1; } goto GET_CONN; case DP_VAL_SPEC : if (dp_get_svalue(msg, id_par->v.sp[1], &partition_name)) { LM_ERR("invalid partition\n"); return -1; } GET_CONN: if (!(id_par->hash = dp_get_connection(&partition_name))) { LM_ERR("invalid partition\n"); return -1; } break; default : break; } LM_DBG("dpid is %i partition is %.*s\n", dpid, id_par->hash->partition.len, id_par->hash->partition.s); repl_par = (str2!=NULL) ? ((dp_param_p)str2) : default_par2; if (dp_get_svalue(msg, repl_par->v.sp[0], &input)!=0){ LM_ERR("invalid param 2\n"); return -1; } LM_DBG("input is %.*s\n", input.len, input.s); connection = id_par->hash; /* ref the data for reading */ lock_start_read( connection->ref_lock ); if ((idp = select_dpid(connection, dpid, connection->crt_index)) == 0) { LM_DBG("no information available for dpid %i\n", dpid); goto error; } LM_DBG("Checking with dpid %i\n", idp->dp_id); attrs_par = attr_spec ? &attrs : NULL; if (translate(msg, input, &output, idp, attrs_par) != 0) { LM_DBG("could not translate %.*s " "with dpid %i\n", input.len, input.s, idp->dp_id); goto error; } LM_DBG("input %.*s with dpid %i => output %.*s\n", input.len, input.s, idp->dp_id, output.len, output.s); /* set the output */ if (dp_update(msg, &repl_par->v.sp[0], &repl_par->v.sp[1], &output) != 0) { LM_ERR("cannot set the output\n"); goto error; } /* we are done reading -> unref the data */ lock_stop_read( connection->ref_lock ); if (attr_spec) { pval.flags = PV_VAL_STR; pval.rs = attrs; if (pv_set_value(msg, (pv_spec_p)attr_spec, 0, &pval) != 0) { LM_ERR("failed to set value '%.*s' for the attr pvar!\n", attrs.len, attrs.s); goto error; } } return 1; error: /* we are done reading -> unref the data */ lock_stop_read( connection->ref_lock ); return -1; }
static struct mi_root * mi_translate(struct mi_root *cmd, void *param) { struct mi_root* rpl= NULL; struct mi_node* root, *node; char *p; dpl_id_p idp; str dpid_str, partition_str; str input; int dpid; str attrs; str output= {0, 0}; dp_connection_list_p connection = NULL; node = cmd->node.kids; if(node == NULL) return init_mi_tree( 400, MI_MISSING_PARM_S, MI_MISSING_PARM_LEN); /* Get the id parameter */ dpid_str = node->value; if(dpid_str.s == NULL || dpid_str.len== 0) { LM_ERR( "empty idp parameter\n"); return init_mi_tree(404, "Empty id parameter", 18); } p = parse_dp_command(dpid_str.s, dpid_str.len, &partition_str); if (p == NULL) { LM_ERR("Invalid dp command\n"); return init_mi_tree(404, "Invalid dp command", 18); } if (partition_str.s == NULL || partition_str.len == 0) { partition_str.s = DEFAULT_PARTITION; partition_str.len = sizeof(DEFAULT_PARTITION) - 1; } connection = dp_get_connection(&partition_str); dpid_str.len -= (p - dpid_str.s); dpid_str.s = p; if (!connection) { LM_ERR("Unable to get connection\n"); return init_mi_tree(400, "Wrong db connection parameter", 24); } if(str2sint(&dpid_str, &dpid) != 0) { LM_ERR("Wrong id parameter - should be an integer\n"); return init_mi_tree(404, "Wrong id parameter", 18); } node = node->next; if(node == NULL) return init_mi_tree( 400, MI_MISSING_PARM_S, MI_MISSING_PARM_LEN); if(node->next!= NULL) return init_mi_tree( 400, MI_MISSING_PARM_S, MI_MISSING_PARM_LEN); input = node->value; if(input.s == NULL || input.len== 0) { LM_ERR( "empty input parameter\n"); return init_mi_tree(404, "Empty input parameter", 21); } /* ref the data for reading */ lock_start_read( connection->ref_lock ); if ((idp = select_dpid(connection, dpid, connection->crt_index)) ==0 ){ LM_ERR("no information available for dpid %i\n", dpid); lock_stop_read( connection->ref_lock ); return init_mi_tree(404, "No information available for dpid", 33); } if (translate(NULL, input, &output, idp, &attrs)!=0){ LM_DBG("could not translate %.*s with dpid %i\n", input.len, input.s, idp->dp_id); lock_stop_read( connection->ref_lock ); return init_mi_tree(404, "No translation", 14); } /* we are done reading -> unref the data */ lock_stop_read( connection->ref_lock ); LM_DBG("input %.*s with dpid %i => output %.*s\n", input.len, input.s, idp->dp_id, output.len, output.s); rpl = init_mi_tree( 200, MI_OK_S, MI_OK_LEN); if (rpl==0) goto error; root= &rpl->node; node = add_mi_node_child(root, 0, "Output", 6, output.s, output.len ); if( node == NULL) goto error; node = add_mi_node_child(root, 0, "ATTRIBUTES", 10, attrs.s, attrs.len); if( node == NULL) goto error; return rpl; error: if(rpl) free_mi_tree(rpl); return 0; }
static struct mi_root * mi_translate(struct mi_root *cmd, void *param) { struct mi_root* rpl= NULL; struct mi_node* root, *node; dpl_id_p idp; str dpid_str; str input; int dpid; str attrs; str output= {0, 0}; node = cmd->node.kids; if(node == NULL) return init_mi_tree( 400, MI_MISSING_PARM_S, MI_MISSING_PARM_LEN); /* Get the id parameter */ dpid_str = node->value; if(dpid_str.s == NULL || dpid_str.len== 0) { LM_ERR( "empty idp parameter\n"); return init_mi_tree(404, "Empty id parameter", 18); } if(str2sint(&dpid_str, &dpid) != 0) { LM_ERR("Wrong id parameter - should be an integer\n"); return init_mi_tree(404, "Wrong id parameter", 18); } node = node->next; if(node == NULL) return init_mi_tree( 400, MI_MISSING_PARM_S, MI_MISSING_PARM_LEN); if(node->next!= NULL) return init_mi_tree( 400, MI_MISSING_PARM_S, MI_MISSING_PARM_LEN); input= node->value; if(input.s == NULL || input.len== 0) { LM_ERR( "empty input parameter\n"); return init_mi_tree(404, "Empty input parameter", 21); } LM_DBG("input is %.*s\n", input.len, input.s); /* ref the data for reading */ lock_start_read( ref_lock ); if ((idp = select_dpid(dpid)) ==0 ){ LM_ERR("no information available for dpid %i\n", dpid); lock_stop_read( ref_lock ); return init_mi_tree(404, "No information available for dpid", 33); } if (translate(NULL, input, &output, idp, &attrs)!=0){ LM_DBG("could not translate %.*s with dpid %i\n", input.len, input.s, idp->dp_id); goto error1; } /* we are done reading -> unref the data */ lock_stop_read( ref_lock ); LM_DBG("input %.*s with dpid %i => output %.*s\n", input.len, input.s, idp->dp_id, output.len, output.s); rpl = init_mi_tree( 200, MI_OK_S, MI_OK_LEN); if (rpl==0) goto error; root= &rpl->node; node = add_mi_node_child(root, 0, "Output", 6, output.s, output.len ); if( node == NULL) goto error; node = add_mi_node_child(root, 0, "ATTRIBUTES", 10, attrs.s, attrs.len); if( node == NULL) goto error; return rpl; error1: /* we are done reading -> unref the data */ lock_stop_read( ref_lock ); error: if(rpl) free_mi_tree(rpl); return 0; }
static int dp_translate_f(struct sip_msg* msg, char* str1, char* str2) { int dpid; str input, output; dpl_id_p idp; dp_param_p id_par, repl_par; str attrs, * attrs_par; if(!msg) return -1; /*verify first param's value*/ id_par = (dp_param_p) str1; if (dp_get_ivalue(msg, id_par, &dpid) != 0){ LM_ERR("no dpid value\n"); return -1; } LM_DBG("dpid is %i\n", dpid); repl_par = (str2!=NULL)? ((dp_param_p)str2):default_par2; if (dp_get_svalue(msg, repl_par->v.sp[0], &input)!=0){ LM_ERR("invalid param 2\n"); return -1; } LM_DBG("input is %.*s\n", input.len, input.s); /* ref the data for reading */ lock_start_read( ref_lock ); if ((idp = select_dpid(dpid)) ==0 ){ LM_DBG("no information available for dpid %i\n", dpid); goto error; } attrs_par = (!attr_pvar)?NULL:&attrs; if (translate(msg, input, &output, idp, attrs_par)!=0){ LM_DBG("could not translate %.*s " "with dpid %i\n", input.len, input.s, idp->dp_id); goto error; } LM_DBG("input %.*s with dpid %i => output %.*s\n", input.len, input.s, idp->dp_id, output.len, output.s); /*set the output*/ if (dp_update(msg, &repl_par->v.sp[0], &repl_par->v.sp[1], &output, attrs_par) !=0){ LM_ERR("cannot set the output\n"); goto error; } /* we are done reading -> unref the data */ lock_stop_read( ref_lock ); return 1; error: /* we are done reading -> unref the data */ lock_stop_read( ref_lock ); return -1; }
/* lists the clusters' topology as viewed by the current node*/ static mi_response_t *clusterer_list_topology(const mi_params_t *params, struct mi_handler *async_hdl) { mi_response_t *resp = NULL; mi_item_t *resp_obj; mi_item_t *clusters_arr, *cluster_item, *nodes_arr, *node_item; mi_item_t *neigh_arr; cluster_info_t *cl; node_info_t *n_info; struct neighbour *neigh; resp = init_mi_result_object(&resp_obj); if (!resp) return 0; clusters_arr = add_mi_array(resp_obj, MI_SSTR("Clusters")); if (!clusters_arr) { free_mi_response(resp); return 0; } lock_start_read(cl_list_lock); /* iterate through clusters */ for (cl = *cluster_list; cl; cl = cl->next) { cluster_item = add_mi_object(clusters_arr, NULL, 0); if (!cluster_item) goto error; if (add_mi_number(cluster_item, MI_SSTR("cluster_id"), cl->cluster_id) < 0) goto error; nodes_arr = add_mi_array(cluster_item, MI_SSTR("Nodes")); if (!nodes_arr) goto error; node_item = add_mi_object(nodes_arr, 0, 0); if (!node_item) goto error; if (add_mi_number(node_item, MI_SSTR("node_id"), current_id) < 0) goto error; neigh_arr = add_mi_array(node_item, MI_SSTR("Neighbours")); if (!neigh_arr) goto error; for (neigh = cl->current_node->neighbour_list; neigh; neigh = neigh->next) if (add_mi_number(neigh_arr, 0,0, neigh->node->node_id) < 0) goto error; for (n_info = cl->node_list; n_info; n_info = n_info->next) { node_item = add_mi_object(nodes_arr, NULL, 0); if (!node_item) goto error; if (add_mi_number(node_item, MI_SSTR("node_id"), n_info->node_id) < 0) goto error; neigh_arr = add_mi_array(node_item, MI_SSTR("Neighbours")); if (!neigh_arr) goto error; lock_get(n_info->lock); for (neigh = n_info->neighbour_list; neigh; neigh = neigh->next) if (add_mi_number(neigh_arr, 0,0, neigh->node->node_id) < 0) { lock_release(n_info->lock); goto error; } if (n_info->link_state == LS_UP) if (add_mi_number(neigh_arr, 0,0, current_id) < 0) { lock_release(n_info->lock); goto error; } lock_release(n_info->lock); } } lock_stop_read(cl_list_lock); return resp; error: lock_stop_read(cl_list_lock); if (resp) free_mi_response(resp); return NULL; }
static mi_response_t *clusterer_list_cap(const mi_params_t *params, struct mi_handler *async_hdl) { mi_response_t *resp = NULL; mi_item_t *resp_obj; mi_item_t *clusters_arr, *cluster_item; mi_item_t *cap_arr, *cap_item; cluster_info_t *cl; struct local_cap *cap; static str str_ok = str_init("Ok"); static str str_not_synced = str_init("not synced"); resp = init_mi_result_object(&resp_obj); if (!resp) return 0; clusters_arr = add_mi_array(resp_obj, MI_SSTR("Clusters")); if (!clusters_arr) { free_mi_response(resp); return 0; } lock_start_read(cl_list_lock); for (cl = *cluster_list; cl; cl = cl->next) { cluster_item = add_mi_object(clusters_arr, NULL, 0); if (!cluster_item) goto error; if (add_mi_number(cluster_item, MI_SSTR("cluster_id"), cl->cluster_id) < 0) goto error; cap_arr = add_mi_array(cluster_item, MI_SSTR("Capabilities")); if (!cap_arr) goto error; for (cap = cl->capabilities; cap; cap = cap->next) { cap_item = add_mi_object(cap_arr, NULL, 0); if (!cap_item) goto error; if (add_mi_string(cap_item, MI_SSTR("name"), cap->reg.name.s, cap->reg.name.len) < 0) goto error; lock_get(cl->lock); if (add_mi_string(cap_item, MI_SSTR("state"), (cap->flags & CAP_STATE_OK) ? str_ok.s : str_not_synced.s, (cap->flags & CAP_STATE_OK) ? str_ok.len : str_not_synced.len) < 0) { lock_release(cl->lock); goto error; } lock_release(cl->lock); } } lock_stop_read(cl_list_lock); return resp; error: lock_stop_read(cl_list_lock); if (resp) free_mi_response(resp); return NULL; }
static mi_response_t *clusterer_list(const mi_params_t *params, struct mi_handler *async_hdl) { cluster_info_t *cl; node_info_t *n_info; str val; mi_response_t *resp = NULL; mi_item_t *resp_obj; mi_item_t *clusters_arr, *cluster_item, *nodes_arr, *node_item; static str str_up = str_init("Up"); static str str_prob = str_init("Probe"); static str str_down = str_init("Down"); static str str_none = str_init("none"); int n_hop; resp = init_mi_result_object(&resp_obj); if (!resp) return 0; clusters_arr = add_mi_array(resp_obj, MI_SSTR("Clusters")); if (!clusters_arr) { free_mi_response(resp); return 0; } lock_start_read(cl_list_lock); /* iterate through clusters */ for (cl = *cluster_list; cl; cl = cl->next) { cluster_item = add_mi_object(clusters_arr, NULL, 0); if (!cluster_item) goto error; if (add_mi_number(cluster_item, MI_SSTR("cluster_id"), cl->cluster_id) < 0) goto error; nodes_arr = add_mi_array(cluster_item, MI_SSTR("Nodes")); if (!nodes_arr) goto error; /* iterate through nodes */ for (n_info = cl->node_list; n_info; n_info = n_info->next) { node_item = add_mi_object(nodes_arr, NULL, 0); if (!node_item) goto error; if (add_mi_number(node_item, MI_SSTR("node_id"), n_info->node_id) < 0) goto error; if (add_mi_number(node_item, MI_SSTR("db_id"), n_info->id) < 0) goto error; if (add_mi_string(node_item, MI_SSTR("url"), n_info->url.s, n_info->url.len) < 0) goto error; lock_get(n_info->lock); if (n_info->link_state == LS_UP) val = str_up; else if (n_info->link_state == LS_DOWN) val = str_down; else val = str_prob; if (add_mi_string(node_item, MI_SSTR("link_state"), val.s, val.len) < 0) { lock_release(n_info->lock); goto error; } lock_release(n_info->lock); n_hop = get_next_hop(n_info); if (n_hop <= 0) val = str_none; else val.s = int2str(n_hop, &val.len); if (add_mi_string(node_item, MI_SSTR("next_hop"), val.s, val.len) < 0) goto error; if (n_info->description.s) { if (add_mi_string(node_item, MI_SSTR("description"), n_info->description.s, n_info->description.len) < 0) goto error; } else if (add_mi_string(node_item, MI_SSTR("description"), MI_SSTR("none")) < 0) goto error; } } lock_stop_read(cl_list_lock); return resp; error: lock_stop_read(cl_list_lock); if (resp) free_mi_response(resp); return NULL; }
/* change the r-uri if it is a PSTN format */ static int prefix2domain(struct sip_msg* msg, int mode, int sd_en) { str *d, p, all={"*",1}; int plen; struct sip_uri uri; if(msg==NULL) { LM_ERR("received null msg\n"); return -1; } /* parse the uri, if not yet */ if(msg->parsed_uri_ok==0) if(parse_sip_msg_uri(msg)<0) { LM_ERR("failed to parse the R-URI\n"); return -1; } /* if the user part begin with the prefix for PSTN users, extract the code*/ if (msg->parsed_uri.user.len<=0) { LM_DBG("user part of the message is empty\n"); return -1; } if(prefix.len>0) { if (msg->parsed_uri.user.len<=prefix.len) { LM_DBG("user part is less than prefix\n"); return -1; } if(strncasecmp(prefix.s, msg->parsed_uri.user.s, prefix.len)!=0) { LM_DBG("PSTN prefix did not matched\n"); return -1; } } if(prefix.len>0 && prefix.len < msg->parsed_uri.user.len && strncasecmp(prefix.s, msg->parsed_uri.user.s, prefix.len)!=0) { LM_DBG("PSTN prefix did not matched\n"); return -1; } p.s = msg->parsed_uri.user.s + prefix.len; p.len = msg->parsed_uri.user.len - prefix.len; lock_start_read( pdt_lock ); if(sd_en==2) { /* take the domain from FROM uri as sdomain */ if(parse_from_header(msg)<0 || msg->from == NULL || get_from(msg)==NULL) { LM_ERR("cannot parse FROM header\n"); goto error; } memset(&uri, 0, sizeof(struct sip_uri)); if (parse_uri(get_from(msg)->uri.s, get_from(msg)->uri.len , &uri)<0) { LM_ERR("failed to parse From uri\n"); goto error; } /* find the domain that corresponds to this prefix */ plen = 0; if((d=pdt_get_domain(*_ptree, &uri.host, &p, &plen))==NULL) { plen = 0; if((d=pdt_get_domain(*_ptree, &all, &p, &plen))==NULL) { LM_INFO("no prefix found in [%.*s]\n", p.len, p.s); goto error; } } } else if(sd_en==1) { /* take the domain from FROM uri as sdomain */ if(parse_from_header(msg)<0 || msg->from == NULL || get_from(msg)==NULL) { LM_ERR("ERROR cannot parse FROM header\n"); goto error; } memset(&uri, 0, sizeof(struct sip_uri)); if (parse_uri(get_from(msg)->uri.s, get_from(msg)->uri.len , &uri)<0) { LM_ERR("failed to parse From uri\n"); goto error; } /* find the domain that corresponds to this prefix */ plen = 0; if((d=pdt_get_domain(*_ptree, &uri.host, &p, &plen))==NULL) { LM_INFO("no prefix found in [%.*s]\n", p.len, p.s); goto error; } } else { /* find the domain that corresponds to this prefix */ plen = 0; if((d=pdt_get_domain(*_ptree, &all, &p, &plen))==NULL) { LM_INFO("no prefix found in [%.*s]\n", p.len, p.s); goto error; } } /* update the new uri */ if(update_new_uri(msg, plen, d, mode)<0) { LM_ERR("new_uri cannot be updated\n"); goto error; } lock_stop_read( pdt_lock ); return 1; error: lock_stop_read( pdt_lock ); return -1; }