int match_node(const node_info_t *a, const node_info_t *b, enum cl_node_match_op match_op) { switch (match_op) { case NODE_CMP_ANY: break; case NODE_CMP_EQ_SIP_ADDR: lock_get(a->lock); if (!a->sip_addr.s || !b->sip_addr.s || str_strcmp(&a->sip_addr, &b->sip_addr)) { lock_release(a->lock); return 0; } lock_release(a->lock); break; case NODE_CMP_NEQ_SIP_ADDR: lock_get(a->lock); if (!a->sip_addr.s || !b->sip_addr.s || !str_strcmp(&a->sip_addr, &b->sip_addr)) { lock_release(a->lock); return 0; } lock_release(a->lock); break; default: LM_BUG("unknown match_op: %d\n", match_op); return 0; } LM_DBG("matched node %d\n", b->node_id); return 1; }
/* returns -1 if any error * returns 1 if does not exist in hash * returns 0 if deleted succesfully * */ int pdt_remove_from_hash_list(hash_list_t *hl, str* sdomain, str *sd) { hash_t *it; int ret; if(hl==NULL || sd==NULL || sd->s==NULL || sdomain==NULL || sdomain->s==NULL) { LM_ERR("bad parameters\n"); return -1; /* wrong parameters, error */ } lock_get(&hl->hl_lock); /* search the it position where to remove from */ it = hl->hash; while(it!=NULL && str_strcmp(&it->sdomain, sdomain)<0) it = it->next; /* sdomain not found, nothing to delete */ if(it==NULL || str_strcmp(&it->sdomain, sdomain)>0) { lock_release(&hl->hl_lock); return 1; /* nothing to delete */ } ret = remove_from_hash(it, sd); lock_release(&hl->hl_lock); return ret; }
hash_t* pdt_search_hash(hash_list_t* hl, str *sd) { hash_t* it; if(sd==NULL || sd->s==NULL || hl==NULL) { LM_ERR("bad parameters\n"); return NULL; } lock_get(&hl->hl_lock); /* search the it position where to insert new domain */ it = hl->hash; while(it!=NULL && str_strcmp(&it->sdomain, sd)<0) it = it->next; if(it==NULL || str_strcmp(&it->sdomain, sd)>0) { lock_release(&hl->hl_lock); return NULL; } lock_release(&hl->hl_lock); return it; }
str* pdt_get_domain(pdt_tree_t *pl, str* sdomain, str *code, int *plen) { pdt_tree_t *it; int len; str *domain=NULL; if(pl==NULL || sdomain==NULL || sdomain->s==NULL || code == NULL || code->s == NULL) { LM_INFO("bad parameters\n"); return NULL; } it = pl; while(it!=NULL && str_strcmp(&it->sdomain, sdomain)<0) it = it->next; if(it==NULL || str_strcmp(&it->sdomain, sdomain)>0) return NULL; domain = get_domain(it, code, &len); if(plen!=NULL) *plen = len; return domain; }
static int fix_reset_flags(void **pflags) { str *flags = (str *)*pflags; str f_reset_all = str_init("reset_all"), f_reset_def = str_init("reset_default"), f_reset_added = str_init("reset_added"); if (!flags) { *pflags = 0; return 0; } if (!flags->s || *flags->s == '\0') *(int *)pflags = 0; else if (!str_strcmp(flags, &f_reset_all)) *(int *)pflags = RESET_ADDED|RESET_DEFAULT; else if (!str_strcmp(flags, &f_reset_def)) *(int *)pflags = RESET_DEFAULT; else if (!str_strcmp(flags, &f_reset_added)) *(int *)pflags = RESET_ADDED; else { LM_ERR("unknown reset type <%.*s>\n", flags->len, flags->s); return E_UNSPEC; } return 0; }
/* returns * 1 if domain already exists * 0 if domain does not exist * -1 if any error * */ int pdt_check_pd(hash_list_t *hl, str* sdomain, str *sp, str *sd) { hash_t *it; int d; if(hl==NULL || sd==NULL || sd->s==NULL || sdomain==NULL || sdomain->s==NULL) { LM_ERR(" bad parameters\n"); return -1; } lock_get(&hl->hl_lock); /* search the it position */ it = hl->hash; while(it!=NULL && str_strcmp(&it->sdomain, sdomain)<0) it = it->next; if(it==NULL || str_strcmp(&it->sdomain, sdomain)>0) { lock_release(&hl->hl_lock); return 0; } d = check_pd(it, sp, sd); lock_release(&hl->hl_lock); return d; }
static int sort_compare_common(const void* p1, const void* p2, int reverse) { const struct mystr* p_cmp1; const struct mystr* p_cmp2; const struct mystr_list_node* p_node1 = (const struct mystr_list_node*) p1; const struct mystr_list_node* p_node2 = (const struct mystr_list_node*) p2; if (!str_isempty(&p_node1->sort_key_str)) { p_cmp1 = &p_node1->sort_key_str; } else { p_cmp1 = &p_node1->str; } if (!str_isempty(&p_node2->sort_key_str)) { p_cmp2 = &p_node2->sort_key_str; } else { p_cmp2 = &p_node2->str; } if (reverse) { return str_strcmp(p_cmp2, p_cmp1); } else { return str_strcmp(p_cmp1, p_cmp2); } }
int pdt_add_to_tree(pdt_tree_t **dpt, str *sdomain, str *code, str *domain) { pdt_tree_t *ndl, *it, *prev; if( sdomain==NULL || sdomain->s==NULL || code==NULL || code->s==NULL || domain==NULL || domain->s==NULL) { LM_ERR("bad parameters\n"); return -1; } ndl = NULL; it = *dpt; prev = NULL; /* search the it position before which to insert new domain */ while(it!=NULL && str_strcmp(&it->sdomain, sdomain)<0) { prev = it; it = it->next; } // printf("sdomain:%.*s\n", sdomain->len, sdomain->s); /* add new sdomain*/ if(it==NULL || str_strcmp(&it->sdomain, sdomain)>0) { ndl = pdt_init_tree(sdomain); if(ndl==NULL) { LM_ERR("no more shm memory\n"); return -1; } if(add_to_tree(ndl, code, domain)<0) { LM_ERR("internal error!\n"); return -1; } ndl->next = it; /* new domain must be added as first element */ if(prev==NULL) *dpt = ndl; else prev->next=ndl; } else /* add (prefix, code) to already present sdomain */ if(add_to_tree(it, code, domain)<0) { LM_ERR("internal error!\n"); return -1; } return 0; }
m_tree_t* mt_get_tree(str *tname) { m_tree_t *it; int ret; if(_ptree==NULL || *_ptree==NULL) return NULL; if( tname==NULL || tname->s==NULL) { LM_ERR("bad parameters\n"); return NULL; } it = *_ptree; /* search the tree for the asked tname */ while(it!=NULL) { ret = str_strcmp(&it->tname, tname); if(ret>0) return NULL; if(ret==0) return it; it = it->next; } return it; }
/* you must release the lock for switchable reading if @lock_stop_r = 0 * in case of error the lock is released by the function */ struct dlg_sharing_tag *get_shtag(str *tag_name, int lock_stop_r) { struct dlg_sharing_tag *tag; int lock_old_flag; lock_start_sw_read(shtags_lock); for (tag = *shtags_list; tag && str_strcmp(&tag->name, tag_name); tag = tag->next) ; if (!tag) { lock_switch_write(shtags_lock, lock_old_flag); if ((tag = create_dlg_shtag(tag_name)) == NULL) { LM_ERR("Failed to create sharing tag\n"); lock_switch_read(shtags_lock, lock_old_flag); lock_stop_sw_read(shtags_lock); return NULL; } lock_switch_read(shtags_lock, lock_old_flag); } if (lock_stop_r) lock_stop_sw_read(shtags_lock); return tag; }
int flag_list_to_bitmask(str *flags, enum flag_type type, char delim) { char *p, *lim; char *crt_flag; str name; struct flag_entry *e; int ret = 0; if (flags->len < 0) return 0; lim = flags->s + flags->len; crt_flag = flags->s; for (p = flags->s; p <= lim; p++) { if (p == lim || *p == delim) { name.s = crt_flag; name.len = p - crt_flag; for (e = flag_lists[type]; e; e = e->next) { if (e->name.len == p - crt_flag && str_strcmp(&e->name, &name) == 0) { ret |= 1 << e->bit; break; } } crt_flag = p + 1; } } return ret; }
/** * writes the next_domain avp using the rule list of failure_tree * * @param frr_head the head of the failure route rule list * @param host last tried host * @param reply_code the last reply code * @param flags flags for the failure route rule * @param dstavp the name of the AVP where to store the next domain * * @return 0 on success, -1 on failure */ static int set_next_domain_on_rule(struct failure_route_rule *frr_head, const str *host, const str *reply_code, const flag_t flags, const gparam_t *dstavp) { struct failure_route_rule * rr; int_str avp_val; assert(frr_head != NULL); LM_DBG("searching for matching routing rules"); for (rr = frr_head; rr != NULL; rr = rr->next) { /* LM_DBG("rr.flags=%d rr.mask=%d flags=%d\n", rr->flags, rr->mask, flags); LM_DBG("rr.host.len=%d host.len=%d\n", rr->host.len, host->len); LM_DBG("rr.host.s='%.*s' host.s='%.*s'\n", rr->host.len, rr->host.s, host->len, host->s); LM_DBG("rr.reply_code.len=%d reply_code.len=%d\n", rr->reply_code.len, reply_code->len); LM_DBG("rr.reply_code.s='%.*s' reply_code.s='%.*s'\n", rr->reply_code.len, rr->reply_code.s, reply_code->len, reply_code->s); */ if (((rr->mask & flags) == rr->flags) && ((rr->host.len == 0) || (str_strcmp(host, &rr->host)==0)) && (reply_code_matcher(&(rr->reply_code), reply_code)==0)) { avp_val.n = rr->next_domain; if (add_avp(dstavp->v.pve->spec->pvp.pvn.u.isname.type, dstavp->v.pve->spec->pvp.pvn.u.isname.name, avp_val)<0) { LM_ERR("set AVP failed\n"); return -1; } LM_INFO("next_domain is %d\n", rr->next_domain); return 0; } } LM_INFO("no matching rule for (flags=%d, host='%.*s', reply_code='%.*s') found\n", flags, host->len, host->s, reply_code->len, reply_code->s); return -1; }
/** * writes the next_domain avp using the rule list of route_tree * * @param failure_tree the current failure routing tree node * @param host last tried host * @param reply_code the last reply code * @param flags flags for the failure route rule * @param dstavp the name of the AVP where to store the next domain * * @return 0 on success, -1 on failure */ static int set_next_domain_on_rule(const struct failure_route_tree_item *failure_tree, const str *host, const str *reply_code, const flag_t flags, const struct multiparam_t *dstavp) { struct failure_route_rule * rr; int_str avp_val; assert(failure_tree != NULL); LM_DBG("searching for matching routing rules"); for (rr = failure_tree->rule_list; rr != NULL; rr = rr->next) { /* LM_DBG("rr.flags=%d rr.mask=%d flags=%d\n", rr->flags, rr->mask, flags); LM_DBG("rr.host.len=%d host.len=%d\n", rr->host.len, host->len); LM_DBG("rr.host.s='%.*s' host.s='%.*s'\n", rr->host.len, rr->host.s, host->len, host->s); LM_DBG("rr.reply_code.len=%d reply_code.len=%d\n", rr->reply_code.len, reply_code->len); LM_DBG("rr.reply_code.s='%.*s' reply_code.s='%.*s'\n", rr->reply_code.len, rr->reply_code.s, reply_code->len, reply_code->s); */ if (((rr->mask & flags) == rr->flags) && ((rr->host.len == 0) || (str_strcmp(host, &rr->host)==0)) && (reply_code_matcher(&(rr->reply_code), reply_code)==0)) { avp_val.n = rr->next_domain; if (add_avp(dstavp->u.a.flags, dstavp->u.a.name, avp_val)<0) { LM_ERR("set AVP failed\n"); return -1; } LM_INFO("next_domain is %d.\n", rr->next_domain); return 0; } } return -1; }
m_tree_t *mt_add_tree(m_tree_t **dpt, str *tname, str *dbtable, int type) { m_tree_t *it = NULL; m_tree_t *prev = NULL; m_tree_t *ndl = NULL; if(dpt==NULL) return NULL; it = *dpt; prev = NULL; /* search the it position before which to insert new tvalue */ while(it!=NULL && str_strcmp(&it->tname, tname)<0) { prev = it; it = it->next; } if(it!=NULL && str_strcmp(&it->tname, tname)==0) { return it; } /* add new tname*/ if(it==NULL || str_strcmp(&it->tname, tname)>0) { LM_DBG("adding new tname [%s]\n", tname->s); ndl = mt_init_tree(tname, dbtable, type); if(ndl==NULL) { LM_ERR("no more shm memory\n"); return NULL; } ndl->next = it; /* new tvalue must be added as first element */ if(prev==NULL) *dpt = ndl; else prev->next=ndl; } return ndl; }
/** * The function MUST be called only in the pre-forking phases of OpenSIPS * (mod_init() or in function fixups) */ int get_flag_id_by_name(int flag_type, char *flag_name) { struct flag_entry *it, **flag_list; str fn; if (!flag_name) { LM_DBG("Flag name is null!\n"); return -1; } fn.s = flag_name; fn.len = strlen(flag_name); if (fn.len == 0) { LM_WARN("found empty string flag modparam! possible scripting error?\n"); return -1; } if (flag_type < 0 || flag_type > FLAG_LIST_COUNT) { LM_ERR("Invalid flag list: %d\n", flag_type); return -2; } flag_list = flag_lists + flag_type; if (*flag_list && (*flag_list)->bit == MAX_FLAG) { LM_CRIT("Maximum number of message flags reached! (32 flags)\n"); return E_CFG; } /* Check if flag has been already defined */ for (it = *flag_list; it; it = it->next) { if (str_strcmp(&it->name, &fn) == 0) { return it->bit; } } if (!(it = pkg_malloc(sizeof(*it) + fn.len))) { LM_CRIT("Out of memory!\n"); return E_OUT_OF_MEM; } it->name.s = (char *)(it + 1); it->name.len = fn.len; memcpy(it->name.s, fn.s, fn.len); it->bit = (*flag_list ? (*flag_list)->bit + 1 : 0); it->next = *flag_list; *flag_list = it; LM_DBG("New flag: [ %.*s : %d ][%d]\n", fn.len, fn.s, it->bit, flag_type); return it->bit; }
struct route_rule * find_rule_by_host(struct route_flags * rf, str * host){ struct route_rule * rr; rr = rf->rule_list; while(rr){ if(str_strcmp(&(rr->host), host) == 0){ return rr; } rr = rr->next; } return NULL; }
static dp_head_p dp_get_head(str part_name){ dp_head_p start; for (start = dp_hlist; start && str_strcmp(&part_name, &start->partition); start = start->next); return start; }
/* Retrieves the corresponding entry of the given partition name */ dp_connection_list_p dp_get_connection(str * partition) { dp_connection_list_t *el; el = dp_conns; while (el && str_strcmp(partition, &el->partition)) { el = el->next; } return el; }
struct pm_part_struct *get_part_struct(str *name) { struct pm_part_struct *it; for (it=part_structs; it; it = it->next) { if (str_strcmp(name, &it->name) == 0) return it; } return NULL; }
int ssl_handshake(struct vsf_session* p_sess, int fd) { /* SECURITY: data SSL connections don't have any auth on them as part of the * protocol. If a client sends an unfortunately optional client cert then * we can check for a match between the control and data connections. */ SSL* p_ssl; int reused; if (p_sess->p_data_ssl != NULL) { die("p_data_ssl should be NULL."); } /* Initiate the SSL connection by either calling accept or connect */ p_ssl = get_ssl(p_sess, fd); if (p_ssl == NULL) { return 0; } p_sess->p_data_ssl = p_ssl; setup_bio_callbacks(p_ssl); reused = SSL_session_reused(p_ssl); if (tunable_require_ssl_reuse && !reused) { str_alloc_text(&debug_str, "No SSL session reuse on data channel."); vsf_log_line(p_sess, kVSFLogEntryDebug, &debug_str); ssl_data_close(p_sess); return 0; } if (str_getlen(&p_sess->control_cert_digest) > 0) { static struct mystr data_cert_digest; if (!ssl_cert_digest(p_ssl, p_sess, &data_cert_digest)) { str_alloc_text(&debug_str, "Missing cert on data channel."); vsf_log_line(p_sess, kVSFLogEntryDebug, &debug_str); ssl_data_close(p_sess); return 0; } if (str_strcmp(&p_sess->control_cert_digest, &data_cert_digest)) { str_alloc_text(&debug_str, "DIFFERENT cert on data channel."); vsf_log_line(p_sess, kVSFLogEntryDebug, &debug_str); ssl_data_close(p_sess); return 0; } if (tunable_debug_ssl) { str_alloc_text(&debug_str, "Matching cert on data channel."); vsf_log_line(p_sess, kVSFLogEntryDebug, &debug_str); } } return 1; }
/** * Searches for the ID of a name * * @param map the mapping list to search in * @param size the size of the list * @param name the name, we are looking for * * @return values: on succcess the id for this name, -1 on failure */ int map_name2id(struct name_map_t * map, int size, const str * name) { int i; if ((!name) || (name->len <= 0)) { return -1; } for (i=0; i<size; i++) { if (str_strcmp(&map[i].name, name) == 0) return map[i].id; } return -1; }
struct pm_partition *get_partition(str *part_name) { struct pm_partition *it; for (it=get_partitions(); it; it=it->next) { if (!str_strcmp(part_name, &it->name)) break; } return it; }
static ds_partition_t* find_partition_by_name (const str *partition_name) { if (partition_name->len == 0) return default_partition; ds_partition_t *part_it; for (part_it = partitions; part_it; part_it = part_it->next) if (str_strcmp(&part_it->name, partition_name) == 0) break; return part_it; //and NULL if there's no partition matching the name }
/* should be called under writing lock */ struct dlg_sharing_tag *get_shtag_unsafe(str *tag_name) { struct dlg_sharing_tag *tag; for (tag = *shtags_list; tag && str_strcmp(&tag->name, tag_name); tag = tag->next) ; if (!tag && !(tag = create_dlg_shtag(tag_name))) { LM_ERR("Failed to create replication tag\n"); return NULL; } return tag; }
static service_t *find_service(rls_services_t *rls, const str_t *uri) { service_t *srv; if (!rls) return NULL; srv = SEQUENCE_FIRST(rls->rls_services); while (srv) { /* TRACE_LOG("comparing %s to %.*s\n", srv->uri, FMT_STR(*uri)); */ if (str_strcmp(uri, srv->uri) == 0) return srv; srv = SEQUENCE_NEXT(srv); } return NULL; }
pdt_tree_t* pdt_get_tree(pdt_tree_t *pl, str *sdomain) { pdt_tree_t *it; if(pl==NULL) return NULL; if( sdomain==NULL || sdomain->s==NULL) { LM_ERR("bad parameters\n"); return NULL; } it = pl; /* search the tree for the asked sdomain */ while(it!=NULL && str_strcmp(&it->sdomain, sdomain)<0) it = it->next; if(it==NULL || str_strcmp(&it->sdomain, sdomain)>0) return NULL; return it; }
static int carrier_data_fixup(struct route_data_t * rd){ int i; str tmp; tmp = default_tree; rd->default_carrier_id = -1; for(i=0; i<rd->carrier_num; i++){ if(rd->carriers[i]){ if(str_strcmp(rd->carriers[i]->name, &tmp) == 0){ rd->default_carrier_id = rd->carriers[i]->id; } } } if(rd->default_carrier_id < 0){ LM_ERR("default_carrier not found\n"); } return 0; }
int cl_get_my_index(int cluster_id, str *capability, int *nr_nodes) { int i, j, tmp; int sorted[MAX_NO_NODES]; node_info_t *node; cluster_info_t *cl; struct remote_cap *cap; lock_start_read(cl_list_lock); cl = get_cluster_by_id(cluster_id); if (!cl) { LM_ERR("cluster id: %d not found!\n", cluster_id); lock_stop_read(cl_list_lock); return -1; } *nr_nodes = 0; for (node = cl->node_list; node; node = node->next) if (get_next_hop(node) > 0) { lock_get(node->lock); for (cap = node->capabilities; cap; cap = cap->next) if (!str_strcmp(capability, &cap->name)) break; if (cap && cap->flags & CAP_STATE_OK) sorted[(*nr_nodes)++] = node->node_id; lock_release(node->lock); } lock_stop_read(cl_list_lock); /* sort array of reachable node ids */ for (i = 1; i < *nr_nodes; i++) { tmp = sorted[i]; for (j = i - 1; j >= 0 && sorted[j] > tmp; j = j - 1) sorted[j+1] = sorted[j]; sorted[j+1] = tmp; } for (i = 0; i < *nr_nodes && sorted[i] < current_id; i++) ; (*nr_nodes)++; return i; }
/* Parse an argument "partition_name[DELIM]arg_value". The arg string will be modified and will contain only "arg_value" The found_head will contain the head which has the name "partition_name" If the head doesn't exist it will be created */ static int parse_partition_argument(str *arg, ds_db_head_t **found_head) { str partition_name; if (split_partition_argument(arg, &partition_name) != 0) return -1; if (partition_name.len == 0 || str_strcmp(&default_db_head.partition_name, &partition_name) == 0){ *found_head = &default_db_head; return 0; } /* There is a partition name in arg so we won't use default head*/ ds_db_head_t *heads_it; for (heads_it = ds_db_heads; heads_it; heads_it = heads_it->next) if (memcmp(partition_name.s, heads_it->partition_name.s, partition_name.len) == 0){ /* This partition already exists */ *found_head = heads_it; return 0; } /* The partition does not exist - we create it */ ds_db_head_t *new_partition = pkg_malloc(sizeof (ds_db_head_t)); if (new_partition == NULL) { LM_ERR("failed to alocate data in shm\n"); return -1; } /* Set default head values */ memset(new_partition, 0, sizeof(ds_db_head_t)); new_partition->next = ds_db_heads; ds_db_heads = new_partition; new_partition->partition_name = partition_name; *found_head = new_partition; return 0; }
static int get_gpart(str *input, gpartition_t *partition) { if (input->s == NULL) { partition->type = GPART_TYPE_POINTER; partition->v.p = default_partition; return 0; } if (input->s[0] == PV_MARKER) { partition->type = GPART_TYPE_PVS; partition->v.pvs = shm_malloc(sizeof(pv_spec_t)); if (partition->v.pvs == NULL) { LM_ERR ("no more shared memory\n"); return -1; } char *end; if ((end = pv_parse_spec(input, partition->v.pvs)) == NULL) { LM_ERR ("cannot parse variable\n"); return -1; } if (end - input->s != input->len) { LM_ERR ("wrong format for partition\n"); return -1; } return 0; } /* We have a static partition name */ ds_partition_t *part_it = partitions; for (; part_it; part_it = part_it->next) if (str_strcmp(&part_it->name, input) == 0) { partition->type = GPART_TYPE_POINTER; partition->v.p = part_it; return 0; } LM_ERR ("partition <%.*s> not found\n", input->len, input->s); return -1; }