/** * clean old unconfirmed dialogs * */ int dlg_clean_run(ticks_t ti) { unsigned int i; unsigned int tm; dlg_cell_t *dlg; dlg_cell_t *tdlg; tm = (unsigned int)time(NULL); for(i=0; i<d_table->size; i++) { lock_set_get(d_table->locks, d_table->entries[i].lock_idx); dlg = d_table->entries[i].first; while (dlg) { tdlg = dlg; dlg = dlg->next; if(tdlg->state==DLG_STATE_UNCONFIRMED && tdlg->init_ts<tm-300) { /* dialog in early state older than 5min */ LM_NOTICE("dialog in early state is too old (%p ref %d)\n", tdlg, tdlg->ref); unlink_unsafe_dlg(&d_table->entries[i], tdlg); destroy_dlg(tdlg); } } lock_set_release(d_table->locks, d_table->entries[i].lock_idx); } return 0; }
/** * delete an entity from working list of a worker * - jwl : pointer to the workers list * - sid : id of the entity (connection to Jabber - usually SHOULD be FROM * header of the incoming SIP message * - _pid : process id of the worker */ void xj_wlist_del(xj_wlist jwl, xj_jkey jkey, int _pid) { int i; void *p; if(jwl==NULL || jkey==NULL || jkey->id==NULL || jkey->id->s==NULL) return; for(i=0; i < jwl->len; i++) if(jwl->workers[i].pid == _pid) break; if(i >= jwl->len) { LM_DBG("%d: key <%.*s> not found in [%d]...\n", _pid, jkey->id->len, jkey->id->s, i); return; } #ifdef XJ_EXTRA_DEBUG LM_DBG("%d: trying to delete entry for <%.*s>...\n", _pid, jkey->id->len, jkey->id->s); #endif lock_set_get(jwl->sems, i); p = del234(jwl->workers[i].sip_ids, (void*)jkey); if(p != NULL) { jwl->workers[i].nr--; #ifdef XJ_EXTRA_DEBUG LM_DBG("%d: sip id <%.*s> deleted\n", _pid, jkey->id->len, jkey->id->s); #endif xj_jkey_free_p(p); } lock_set_release(jwl->sems, i); }
/** * clean old unconfirmed dialogs * */ int dlg_clean_run(ticks_t ti) { unsigned int i; unsigned int tm; dlg_cell_t *dlg; dlg_cell_t *tdlg; tm = (unsigned int)time(NULL); for(i=0; i<d_table->size; i++) { lock_set_get(d_table->locks, d_table->entries[i].lock_idx); dlg = d_table->entries[i].first; while (dlg) { tdlg = dlg; dlg = dlg->next; if(tdlg->state==DLG_STATE_UNCONFIRMED && tdlg->init_ts<tm-300) { /* dialog in early state older than 5min */ LM_NOTICE("dialog in early state is too old (%p ref %d)\n", tdlg, tdlg->ref); unlink_unsafe_dlg(&d_table->entries[i], tdlg); destroy_dlg(tdlg); } if(tdlg->state==DLG_STATE_CONFIRMED_NA && tdlg->start_ts<tm-60) { if(update_dlg_timer(&tdlg->tl, 10)<0) { LM_ERR("failed to update dialog lifetime in long non-ack state\n"); } tdlg->lifetime = 10; tdlg->dflags |= DLG_FLAG_CHANGED; } } lock_set_release(d_table->locks, d_table->entries[i].lock_idx); } return 0; }
static int cfg_lock_helper(str *lkey, int mode) { unsigned int pos; if(_cfg_lock_set==NULL) { LM_ERR("lock set not initialized (attempt to do op: %d on: %.*s) -" " see param lock_set_size\n", mode, lkey->len, lkey->s); return -1; } pos = core_case_hash(lkey, 0, _cfg_lock_size); LM_DBG("cfg_lock mode %d on %u (%.*s)\n", mode, pos, lkey->len, lkey->s); if(mode==0) { /* Lock */ lock_set_get(_cfg_lock_set, pos); } else if (mode == 1) { /* Unlock */ lock_set_release(_cfg_lock_set, pos); } else { int res; /* Trylock */ res = lock_set_try(_cfg_lock_set, pos); if (res != 0) { LM_DBG("Failed to trylock \n"); /* Failed to lock */ return -1; } LM_DBG("Succeeded with trylock \n"); /* Succeeded in locking */ return 1; } return 1; }
static int cfg_lock_helper(str *lkey, int mode) { unsigned int pos; pos = core_case_hash(lkey, 0, _cfg_lock_size); LM_DBG("cfg_lock mode %d on %u\n", mode, pos); if(mode==0) { /* Lock */ lock_set_get(_cfg_lock_set, pos); } else if (mode == 1) { /* Unlock */ lock_set_release(_cfg_lock_set, pos); } else { int res; /* Trylock */ res = lock_set_try(_cfg_lock_set, pos); if (res != 0) { LM_DBG("Failed to trylock \n"); /* Failed to lock */ return -1; } LM_DBG("Succeeded with trylock \n"); /* Succeeded in locking */ return 1; } return 1; }
/** * Mark script in pos to be reloaded * pos -1: reload all scritps */ int lua_sr_reload_script(int pos) { int i, len = sr_lua_script_ver->len; if(_sr_lua_load_list!= NULL) { if (!sr_lua_script_ver) { LM_CRIT("shm for version not allocated\n"); return -1; } if (_app_lua_sr_reload==0) { LM_ERR("reload is not activated\n"); return -3; } if (pos<0) { // let's mark all the scripts to be reloaded for (i=0;i<len;i++) { lock_set_get(sr_lua_locks, i); sr_lua_script_ver->version[i] += 1; lock_set_release(sr_lua_locks, i); } } else { if (pos>=0 && pos<len) { lock_set_get(sr_lua_locks, pos); sr_lua_script_ver->version[pos] += 1; lock_set_release(sr_lua_locks, pos); LM_DBG("pos: %d set to reloaded\n", pos); } else { LM_ERR("pos out of range\n"); return -2; } } return 0; } LM_ERR("No script loaded\n"); return -1; }
/** * set the p.id's of the workers * - jwl : pointer to the workers list * - pids : p.id's array * - size : number of pids * return : 0 on success or <0 on error */ int xj_wlist_set_pid(xj_wlist jwl, int pid, int idx) { if(jwl == NULL || pid <= 0 || idx < 0 || idx >= jwl->len) return -1; lock_set_get(jwl->sems, idx); jwl->workers[idx].pid = pid; lock_set_release(jwl->sems, idx); return 0; }
/** * set the flag of the connection identified by 'jkey' * */ int xj_wlist_set_flag(xj_wlist jwl, xj_jkey jkey, int fl) { int i; xj_jkey p = NULL; if(jwl==NULL || jkey==NULL || jkey->id==NULL || jkey->id->s==NULL) return -1; #ifdef XJ_EXTRA_DEBUG LM_DBG("looking for <%.*s>" " having id=%d\n", jkey->id->len, jkey->id->s, jkey->hash); #endif i = 0; while(i < jwl->len) { lock_set_get(jwl->sems, i); if(jwl->workers[i].pid <= 0) { lock_set_release(jwl->sems, i); i++; continue; } if((p=find234(jwl->workers[i].sip_ids, (void*)jkey, NULL)) != NULL) { p->flag = fl; lock_set_release(jwl->sems, i); #ifdef XJ_EXTRA_DEBUG LM_DBG("the connection for <%.*s>" " marked with flag=%d", jkey->id->len, jkey->id->s, fl); #endif return jwl->workers[i].wpipe; } lock_set_release(jwl->sems, i); i++; } #ifdef XJ_EXTRA_DEBUG LM_DBG("entry does not exist for <%.*s>\n", jkey->id->len, jkey->id->s); #endif return -1; }
static void tls_static_locks_ops(int mode, int n, const char* file, int line) { if (n<0 || n>tls_static_locks_no) { LM_ERR("BUG - SSL Lib attempting to acquire bogus lock\n"); abort(); } if (mode & CRYPTO_LOCK) { lock_set_get(tls_static_locks,n); } else { lock_set_release(tls_static_locks,n); } }
/** * Checks if loaded version matches the shared * counter. If not equal reloads the script. */ int sr_lua_reload_script(void) { sr_lua_load_t *li = _sr_lua_load_list; int ret, i; char *txt; int sv_len = sr_lua_script_ver->len; if(li==NULL) { LM_DBG("No script loaded\n"); return 0; } if(_app_lua_sv==NULL) { _app_lua_sv = (int *) pkg_malloc(sizeof(int)*sv_len); if(_app_lua_sv==NULL) { LM_ERR("no more pkg memory\n"); return -1; } } for(i=0;i<sv_len;i++) { lock_set_get(sr_lua_locks, i); _app_lua_sv[i] = sr_lua_script_ver->version[i]; lock_set_release(sr_lua_locks, i); if(li->version!=_app_lua_sv[i]) { LM_DBG("loaded version:%d needed: %d Let's reload <%s>\n", li->version, _app_lua_sv[i], li->script); ret = luaL_dofile(_sr_L_env.LL, (const char*)li->script); if(ret!=0) { LM_ERR("failed to load Lua script: %s (err: %d)\n", li->script, ret); txt = (char*)lua_tostring(_sr_L_env.LL, -1); LM_ERR("error from Lua: %s\n", (txt)?txt:"unknown"); lua_pop(_sr_L_env.LL, 1); return -1; } li->version = _app_lua_sv[i]; LM_DBG("<%s> set to version %d\n", li->script, li->version); } else LM_DBG("No need to reload [%s] is version %d\n", li->script, li->version); li = li->next; } return 1; }
/** * return communication pipe with the worker that will process the message for * the id 'sid' only if it exists, or -1 if error * - jwl : pointer to the workers list * - sid : id of the entity (connection to Jabber - usually SHOULD be FROM * header of the incoming SIP message) * - p : will point to the SHM location of the 'sid' in jwl */ int xj_wlist_check(xj_wlist jwl, xj_jkey jkey, xj_jkey *p) { int i; if(jwl==NULL || jkey==NULL || jkey->id==NULL || jkey->id->s==NULL) return -1; i = 0; *p = NULL; while(i < jwl->len) { lock_set_get(jwl->sems, i); if(jwl->workers[i].pid <= 0) { lock_set_release(jwl->sems, i); i++; continue; } if((*p = find234(jwl->workers[i].sip_ids, (void*)jkey, NULL)) != NULL) { lock_set_release(jwl->sems, i); #ifdef XJ_EXTRA_DEBUG LM_DBG("entry exists for <%.*s> in the" " pool of <%d> [%d]\n",jkey->id->len, jkey->id->s, jwl->workers[i].pid,i); #endif return jwl->workers[i].wpipe; } lock_set_release(jwl->sems, i); i++; } #ifdef XJ_EXTRA_DEBUG LM_DBG("entry does not exist for <%.*s>\n", jkey->id->len, jkey->id->s); #endif return -1; }
/* normal locking callback */ static void locking_f(int mode, int n, const char* file, int line) { if (n<0 || n>=n_static_locks){ LOG(L_CRIT, "BUG: tls: locking_f (callback): invalid lock number: " " %d (range 0 - %d), called from %s:%d\n", n, n_static_locks, file, line); abort(); /* quick crash :-) */ } if (mode & CRYPTO_LOCK){ lock_set_get(static_locks, n); }else{ lock_set_release(static_locks, n); } }
static void clean_profiles(unsigned int ticks, void *param) { map_iterator_t it, del; unsigned int count; struct dlg_profile_table *profile; prof_value_info_t *rp; void **dst; int i; for (profile = profiles; profile; profile = profile->next) { if (!profile->has_value || profile->repl_type != REPL_PROTOBIN) continue; for (i = 0; i < profile->size; i++) { lock_set_get(profile->locks, i); if (map_first(profile->entries[i], &it) < 0) { LM_ERR("map does not exist\n"); goto next_entry; } while (iterator_is_valid(&it)) { dst = iterator_val(&it); if (!dst || !*dst) { LM_ERR("[BUG] bogus map[%d] state\n", i); goto next_val; } count = prof_val_get_count(dst); if (!count) { del = it; if (iterator_next(&it) < 0) LM_DBG("cannot find next iterator\n"); rp = (prof_value_info_t *) iterator_delete(&del); if (rp) { free_profile_val_t(rp); /*if (rp->noval) shm_free(rp->noval); shm_free(rp);*/ } continue; } next_val: if (iterator_next(&it) < 0) break; } next_entry: lock_set_release(profile->locks, i); } } }
int release_dynamic_lock(struct sip_msg *msg, char *string) { str ret; int hash; if (fixup_get_svalue(msg, (gparam_p)string, &ret) != 0) { LM_ERR("Get string from fixup param failed!\n"); return -1; } hash = (int)core_hash(&ret, NULL, lock_pool_size); lock_set_release(dynamic_locks, hash); LM_DBG("Released dynamic lock----- %d\n", hash); return 1; }
/* normal locking callback */ static void locking_f(int mode, int n, const char* file, int line) { if (n<0 || n>=n_static_locks){ LM_CRIT("locking (callback): invalid lock number: " " %d (range 0 - %d), called from %s:%d\n", n, n_static_locks, file, line); abort(); /* quick crash :-) */ } if (mode & CRYPTO_LOCK){ #ifdef EXTRA_DEBUG LM_DBG("lock get (%d): %d (%s:%d)\n", mode, n, file, line); #endif lock_set_get(static_locks, n); }else{ lock_set_release(static_locks, n); #ifdef EXTRA_DEBUG LM_DBG("lock release (%d): %d (%s:%d)\n", mode, n, file, line); #endif } }
/** * send disconnected info to all SIP users associated with worker idx * and clean the entries from wlist */ int xj_wlist_clean_jobs(xj_wlist jwl, int idx, int fl) { xj_jkey p; if(jwl==NULL || idx < 0 || idx >= jwl->len || !jwl->workers[idx].sip_ids) return -1; lock_set_get(jwl->sems, idx); while((p=(xj_jkey)delpos234(jwl->workers[idx].sip_ids, 0))!=NULL) { if(fl) { #ifdef XJ_EXTRA_DEBUG DBG("XJAB:xj_wlist_send_info: sending disconnect message" " to <%.*s>\n", p->id->len, p->id->s); #endif xj_send_sip_msgz(_PADDR(jwl), p->id, &jab_gw_name, XJ_DMSG_INF_DISCONNECTED, NULL); } jwl->workers[idx].nr--; xj_jkey_free_p(p); } lock_set_release(jwl->sems, idx); return 0; }
/* unlocks a tree branch */ static inline void prv_unlock_tree_branch(unsigned char b) { lock_set_release( root->entry_lock_set, root->entries[b].lock_idx); }
/** * return communication pipe with the worker that will process the message for * the id 'sid', or -1 if error * - jwl : pointer to the workers list * - sid : id of the entity (connection to Jabber - usually SHOULD be FROM * header of the incoming SIP message) * - p : will point to the SHM location of the 'sid' in jwl */ int xj_wlist_get(xj_wlist jwl, xj_jkey jkey, xj_jkey *p) { int i = 0, pos = -1, min = 100000; xj_jkey msid = NULL; if(jwl==NULL || jkey==NULL || jkey->id==NULL || jkey->id->s==NULL) return -1; *p = NULL; while(i < jwl->len) { lock_set_get(jwl->sems, i); if(jwl->workers[i].pid <= 0) { lock_set_release(jwl->sems, i); i++; continue; } if((*p = find234(jwl->workers[i].sip_ids, (void*)jkey, NULL))!=NULL) { if(pos >= 0) lock_set_release(jwl->sems, pos); lock_set_release(jwl->sems, i); #ifdef XJ_EXTRA_DEBUG LM_DBG("entry already exists for <%.*s> in the" " pool of <%d> [%d]\n",jkey->id->len, jkey->id->s, jwl->workers[i].pid,i); #endif return jwl->workers[i].wpipe; } if(min > jwl->workers[i].nr) { if(pos >= 0) lock_set_release(jwl->sems, pos); pos = i; min = jwl->workers[i].nr; } else lock_set_release(jwl->sems, i); i++; } if(pos >= 0 && jwl->workers[pos].nr < jwl->maxj) { jwl->workers[pos].nr++; msid = (xj_jkey)_M_SHM_MALLOC(sizeof(t_xj_jkey)); if(msid == NULL) goto error; msid->id = (str*)_M_SHM_MALLOC(sizeof(str)); if(msid->id == NULL) { _M_SHM_FREE(msid); goto error; } msid->id->s = (char*)_M_SHM_MALLOC(jkey->id->len); if(msid->id == NULL) { _M_SHM_FREE(msid->id); _M_SHM_FREE(msid); goto error; } if((*p = add234(jwl->workers[pos].sip_ids, msid)) != NULL) { msid->id->len = jkey->id->len; memcpy(msid->id->s, jkey->id->s, jkey->id->len); msid->hash = jkey->hash; msid->flag = XJ_FLAG_OPEN; lock_set_release(jwl->sems, pos); #ifdef XJ_EXTRA_DEBUG LM_DBG("new entry for <%.*s> in the pool of" " <%d> - [%d]\n", jkey->id->len, jkey->id->s, jwl->workers[pos].pid, pos); #endif return jwl->workers[pos].wpipe; } _M_SHM_FREE(msid->id->s); _M_SHM_FREE(msid->id); _M_SHM_FREE(msid); } error: if(pos >= 0) lock_set_release(jwl->sems, pos); LM_DBG("cannot create a new entry for <%.*s>\n", jkey->id->len, jkey->id->s); return -1; }
static void repl_prof_utimer_f(utime_t ticks, void *param) { #define REPL_PROF_TRYSEND() \ do { \ nr++; \ if (ret > repl_prof_buffer_th) { \ /* send the buffer */ \ if (nr) { \ dlg_replicate_profiles(); \ LM_DBG("sent %d records\n", nr); \ } \ if (bin_init(&module_name, REPLICATION_DLG_PROFILE, BIN_VERSION) < 0) { \ LM_ERR("cannot initiate bin buffer\n"); \ return; \ } \ nr = 0; \ } \ } while (0) struct dlg_profile_table *profile; static str module_name = str_init("dialog"); map_iterator_t it; unsigned int count; int i; int nr = 0; int ret; void **dst; str *value; if (bin_init(&module_name, REPLICATION_DLG_PROFILE, BIN_VERSION) < 0) { LM_ERR("cannot initiate bin buffer\n"); return; } for (profile = profiles; profile; profile = profile->next) { count = 0; if (!profile->has_value) { for (i = 0; i < profile->size; i++) { lock_set_get(profile->locks, i); count += profile->counts[i]; lock_set_release(profile->locks, i); } if ((ret = repl_prof_add(&profile->name, 0, NULL, count)) < 0) goto error; /* check if the profile should be sent */ REPL_PROF_TRYSEND(); } else { for (i = 0; i < profile->size; i++) { lock_set_get(profile->locks, i); if (map_first(profile->entries[i], &it) < 0) { LM_ERR("map does not exist\n"); goto next_entry; } while (iterator_is_valid(&it)) { dst = iterator_val(&it); if (!dst || !*dst) { LM_ERR("[BUG] bogus map[%d] state\n", i); goto next_val; } value = iterator_key(&it); if (!value) { LM_ERR("cannot retrieve profile's key\n"); goto next_val; } count = repl_prof_get(dst); if ((ret = repl_prof_add(&profile->name, 1, value, count)) < 0) goto error; /* check if the profile should be sent */ REPL_PROF_TRYSEND(); next_val: if (iterator_next(&it) < 0) break; } next_entry: lock_set_release(profile->locks, i); } } } goto done; error: LM_ERR("cannot add any more profiles in buffer\n"); done: /* check if there is anything else left to replicate */ LM_DBG("sent %d records\n", nr); if (nr) dlg_replicate_profiles(); #undef REPL_PROF_TRYSEND }
/*! * \brief SQL REPLACE implementation * \param _h structure representing database connection * \param _k key names * \param _v values of the keys * \param _n number of key=value pairs * \param _un number of keys to build the unique key, starting from first * \param _m mode - first update, then insert, or first insert, then update * \return 0 on success, negative on failure */ int db_postgres_replace(const db1_con_t* _h, const db_key_t* _k, const db_val_t* _v, const int _n, const int _un, const int _m) { unsigned int pos = 0; int i; if(_un > _n) { LM_ERR("number of columns for unique key is too high\n"); return -1; } if(_un > 0) { for(i=0; i<_un; i++) { if(!VAL_NULL(&_v[i])) { switch(VAL_TYPE(&_v[i])) { case DB1_INT: pos += VAL_UINT(&_v[i]); break; case DB1_STR: pos += get_hash1_raw((VAL_STR(&_v[i])).s, (VAL_STR(&_v[i])).len); break; case DB1_STRING: pos += get_hash1_raw(VAL_STRING(&_v[i]), strlen(VAL_STRING(&_v[i]))); break; default: break; } } } pos &= (_pg_lock_size-1); lock_set_get(_pg_lock_set, pos); if(db_postgres_update(_h, _k, 0, _v, _k + _un, _v + _un, _un, _n -_un)< 0) { LM_ERR("update failed\n"); lock_set_release(_pg_lock_set, pos); return -1; } if (db_postgres_affected_rows(_h) <= 0) { if(db_postgres_insert(_h, _k, _v, _n)< 0) { LM_ERR("insert failed\n"); lock_set_release(_pg_lock_set, pos); return -1; } LM_DBG("inserted new record in database table\n"); } else { LM_DBG("updated record in database table\n"); } lock_set_release(_pg_lock_set, pos); } else { if(db_postgres_insert(_h, _k, _v, _n)< 0) { LM_ERR("direct insert failed\n"); return -1; } LM_DBG("directly inserted new record in database table\n"); } return 0; }
static void dlg_replicated_profiles(struct receive_info *ri) { int index; time_t now; str name; str value; char *ip; unsigned short port; unsigned int counter; struct dlg_profile_table *profile; int has_value; int i; void **dst; repl_prof_value_t *rp; /* optimize profile search */ struct dlg_profile_table *old_profile = NULL; str old_name; /* match the server */ for (index = 0; index < repl_prof_dests_nr; index++) { if (su_cmp(&ri->src_su, &repl_prof_dests[index].to)) break; } if (index == repl_prof_dests_nr) { get_su_info(&ri->src_su.s, ip, port); LM_WARN("received bin packet from unknown source: %s:%hu\n", ip, port); return; } now = time(0); *repl_prof_dests[index].last_msg = now; for (;;) { if (bin_pop_str(&name) == 1) break; /* pop'ed all pipes */ /* check if the same profile was sent */ if (!old_profile || old_name.len != name.len || memcmp(name.s, old_name.s, name.len) != 0) { old_profile = get_dlg_profile(&name); if (!old_profile) { get_su_info(&ri->src_su.s, ip, port); LM_WARN("received unknown profile <%.*s> from %s:%hu\n", name.len, name.s, ip, port); } old_name = name; } profile = old_profile; if (bin_pop_int(&has_value) < 0) { LM_ERR("cannot pop profile's has_value int\n"); return; } if (has_value) { if (!profile->has_value) { get_su_info(&ri->src_su.s, ip, port); LM_WARN("The other end does not have a value for this profile:" "<%.*s> [%s:%hu]\n", profile->name.len, profile->name.s, ip, port); profile = NULL; } if (bin_pop_str(&value)) { LM_ERR("cannot pop the value of the profile\n"); return; } } if (bin_pop_int(&counter) < 0) { LM_ERR("cannot pop profile's counter\n"); return; } if (profile) { if (!profile->has_value) { lock_get(&profile->repl->lock); profile->repl->dsts[index].counter = counter; profile->repl->dsts[index].update = now; lock_release(&profile->repl->lock); } else { /* XXX: hack to make sure we find the proper index */ i = core_hash(&value, NULL, profile->size); lock_set_get(profile->locks, i); /* if counter is 0 and we don't have it, don't try to create */ if (!counter) { dst = map_find(profile->entries[i], value); if (!dst) goto release; } else { dst = map_get(profile->entries[i], value); } if (!*dst) { rp = shm_malloc(sizeof(repl_prof_value_t)); if (!rp) { LM_ERR("no more shm memory to allocate repl_prof_value\n"); goto release; } memset(rp, 0, sizeof(repl_prof_value_t)); *dst = rp; } else { rp = (repl_prof_value_t *)*dst; } if (!rp->noval) rp->noval = repl_prof_allocate(); if (rp->noval) { lock_release(&rp->noval->lock); rp->noval->dsts[index].counter = counter; rp->noval->dsts[index].update = now; lock_release(&rp->noval->lock); } release: lock_set_release(profile->locks, i); } } } return; }
void shvar_release_idx(int idx) { lock_set_release(shvar_locks, idx); }
/** * SER2Jab connection management - function to use with iHttp module * - be aware of who is able to use the ihttp because he can close any * open connection between SER and Jabber server */ int xjab_connections(ih_req_p _irp, void *_p, char *_bb, int *_bl, char *_hb, int *_hl) { t_xj_jkey jkey, *p; str _u; ih_param_p _ipp = NULL; int idx, i, maxcount; char *cp; if(!_irp || !_bb || !_bl || *_bl <= 0 || !_hb || !_hl || *_hl <= 0) return -1; *_hl = 0; *_hb = 0; idx = -1; strcpy(_bb, "<h4>Active XMPP connections</h4>"); if(_irp->params) { strcat(_bb, "<br><b>Close action is alpha release!</b><br>"); _ipp = _irp->params; i = 0; while(_ipp) { switch(_ipp->name[0]) { case 'w': idx = 0; cp = _ipp->value; while(*cp && *cp>='0' && *cp<='9') { idx = idx*10 + *cp-'0'; cp++; } i++; break; case 'u': _u.s = _ipp->value; _u.len = strlen(_ipp->value); jkey.id = &_u; i++; break; case 'i': jkey.hash = 0; cp = _ipp->value; while(*cp && *cp>='0' && *cp<='9') { jkey.hash = jkey.hash*10 + *cp-'0'; cp++; } i++; break; } _ipp = _ipp->next; } if(i!=3 || idx < 0 || idx >= jwl->len) { strcat(_bb, "<br><b><i>Bad parameters!</i></b>\n"); } else { strcat(_bb, "<br><b><i>The connection of ["); strcat(_bb, _u.s); if(xj_wlist_set_flag(jwl, &jkey, XJ_FLAG_CLOSE) < 0) strcat(_bb, "] does not exist!</i></b>\n"); else strcat(_bb, "] was scheduled for closing!</i></b>\n"); } *_bl = strlen(_bb); return 0; } if(jwl!=NULL && jwl->len > 0 && jwl->workers!=NULL) { for(idx=0; idx<jwl->len; idx++) { strcat(_bb, "<br><b><i>Worker["); strcat(_bb, int2str(idx, NULL)); strcat(_bb, "]</i></b> pid="); strcat(_bb, int2str(jwl->workers[idx].pid, NULL)); strcat(_bb, " nr of jobs="); strcat(_bb, int2str(jwl->workers[idx].nr, NULL)); if(!jwl->workers[idx].sip_ids) continue; lock_set_get(jwl->sems, idx); maxcount = count234(jwl->workers[idx].sip_ids); for (i = 0; i < maxcount; i++) { p = (xj_jkey)index234(jwl->workers[idx].sip_ids, i); if(p == NULL) continue; strcat(_bb, "<br> "); strcat(_bb, int2str(i, NULL)); strcat(_bb, ". "); strcat(_bb, "<a href=\"xjabc?w="); strcat(_bb, int2str(idx, NULL)); strcat(_bb, "&i="); strcat(_bb, int2str(p->hash, NULL)); strcat(_bb, "&u="); strncat(_bb, p->id->s, p->id->len); strcat(_bb, "\">close</a>"); strcat(_bb, " "); strcat(_bb, int2str(p->hash, NULL)); strcat(_bb, " "); strncat(_bb, p->id->s, p->id->len); } lock_set_release(jwl->sems, idx); } } *_bl = strlen(_bb); return 0; }
/*! * \brief Release a lock with a certain index * \param idx lock index */ void subs_release_idx(int idx) { lock_set_release(subs_locks, idx); }
void receive_prof_repl(bin_packet_t *packet) { time_t now; str name; str value; unsigned int counter; struct dlg_profile_table *profile; int has_value; int i; void **dst; prof_value_info_t *rp; repl_prof_count_t *destination; /* optimize profile search */ struct dlg_profile_table *old_profile = NULL; str old_name = {NULL,0}; if (!profile_repl_cluster) return; if (packet->type != REPLICATION_DLG_PROFILE) { LM_WARN("Invalid dialog binary packet command: %d (from node: %d in cluster: %d)\n", packet->type, packet->src_id, profile_repl_cluster); return; } now = time(0); //*repl_prof_dests[index].last_msg = now; for (;;) { if (bin_pop_str(packet ,&name) == 1) break; /* pop'ed all pipes */ /* check if the same profile was sent */ if (!old_profile || old_name.len != name.len || memcmp(name.s, old_name.s, name.len) != 0) { old_profile = get_dlg_profile(&name); if (!old_profile) LM_WARN("received unknown profile <%.*s> from node %d\n", name.len, name.s, packet->src_id); old_name = name; } profile = old_profile; if (bin_pop_int(packet, &has_value) < 0) { LM_ERR("cannot pop profile's has_value int\n"); return; } if (has_value) { if (!profile->has_value) { LM_WARN("The other end does not have a value for this profile:" "<%.*s> [node: %d]\n", profile->name.len, profile->name.s, packet->src_id); profile = NULL; } if (bin_pop_str(packet, &value)) { LM_ERR("cannot pop the value of the profile\n"); return; } } if (bin_pop_int(packet, &counter) < 0) { LM_ERR("cannot pop profile's counter\n"); return; } if (profile) { if (!profile->has_value) { lock_get(&profile->noval_repl_info->lock); destination = find_destination(profile->noval_repl_info, packet->src_id); if(destination == NULL){ lock_release(&profile->noval_repl_info->lock); return; } destination->counter = counter; destination->update = now; lock_release(&profile->noval_repl_info->lock); } else { /* XXX: hack to make sure we find the proper index */ i = core_hash(&value, NULL, profile->size); lock_set_get(profile->locks, i); /* if counter is 0 and we don't have it, don't try to create */ if (!counter) { dst = map_find(profile->entries[i], value); if (!dst) goto release; } else { dst = map_get(profile->entries[i], value); } if (!*dst) { rp = shm_malloc(sizeof(prof_value_info_t)); if (!rp) { LM_ERR("no more shm memory to allocate repl_prof_value\n"); goto release; } memset(rp, 0, sizeof(prof_value_info_t)); *dst = rp; } else { rp = (prof_value_info_t *) * dst; } if (!rp->noval) rp->noval = repl_prof_allocate(); if (rp->noval) { lock_release(&rp->noval->lock); destination = find_destination(rp->noval, packet->src_id); if (destination == NULL) { lock_release(&rp->noval->lock); lock_set_release(profile->locks, i); return; } destination->counter = counter; destination ->update = now; lock_release(&rp->noval->lock); } release: lock_set_release(profile->locks, i); } } } return; }
static void broadcast_profiles(utime_t ticks, void *param) { #define REPL_PROF_TRYSEND() \ do { \ nr++; \ if (ret > repl_prof_buffer_th) { \ /* send the buffer */ \ if (nr) \ dlg_replicate_profiles(&packet); \ bin_reset_back_pointer(&packet); \ nr = 0; \ } \ } while (0) struct dlg_profile_table *profile; map_iterator_t it; unsigned int count; int i; int nr = 0; int ret; void **dst; str *value; bin_packet_t packet; if (bin_init(&packet, &prof_repl_cap, REPLICATION_DLG_PROFILE, BIN_VERSION, 0) < 0) { LM_ERR("cannot initiate bin buffer\n"); return; } for (profile = profiles; profile; profile = profile->next) { if (!(profile->repl_type&REPL_PROTOBIN)) continue; count = 0; if (!profile->has_value) { count = noval_get_local_count(profile); if ((ret = repl_prof_add(&packet, &profile->name, 0, NULL, count)) < 0) goto error; /* check if the profile should be sent */ REPL_PROF_TRYSEND(); } else { for (i = 0; i < profile->size; i++) { lock_set_get(profile->locks, i); if (map_first(profile->entries[i], &it) < 0) { LM_ERR("map does not exist\n"); goto next_entry; } while (iterator_is_valid(&it)) { dst = iterator_val(&it); if (!dst || !*dst) { LM_ERR("[BUG] bogus map[%d] state\n", i); goto next_val; } value = iterator_key(&it); if (!value) { LM_ERR("cannot retrieve profile's key\n"); goto next_val; } count = prof_val_get_local_count(dst); if ((ret = repl_prof_add(&packet, &profile->name, 1, value, count)) < 0) goto error; /* check if the profile should be sent */ REPL_PROF_TRYSEND(); next_val: if (iterator_next(&it) < 0) break; } next_entry: lock_set_release(profile->locks, i); } } } goto done; error: LM_ERR("cannot add any more profiles in buffer\n"); bin_free_packet(&packet); done: /* check if there is anything else left to replicate */ if (nr) dlg_replicate_profiles(&packet); bin_free_packet(&packet); #undef REPL_PROF_TRYSEND }
void ul_release_idx(int idx) { lock_set_release(ul_locks, idx); }