int pg_con(db_con_t* con) { struct pg_con* pcon; /* First try to lookup the connection in the connection pool and * re-use it if a match is found */ pcon = (struct pg_con*)db_pool_get(con->uri); if (pcon) { DBG("postgres: Connection to %.*s:%.*s found in connection pool\n", con->uri->scheme.len, ZSW(con->uri->scheme.s), con->uri->body.len, ZSW(con->uri->body.s)); goto found; } pcon = (struct pg_con*)pkg_malloc(sizeof(struct pg_con)); if (!pcon) { LOG(L_ERR, "postgres: No memory left\n"); goto error; } memset(pcon, '\0', sizeof(struct pg_con)); if (db_pool_entry_init(&pcon->gen, pg_con_free, con->uri) < 0) goto error; DBG("postgres: Preparing new connection to: %.*s:%.*s\n", con->uri->scheme.len, ZSW(con->uri->scheme.s), con->uri->body.len, ZSW(con->uri->body.s)); /* Put the newly created postgres connection into the pool */ db_pool_put((struct db_pool_entry*)pcon); DBG("postgres: Connection stored in connection pool\n"); found: /* Attach driver payload to the db_con structure and set connect and * disconnect functions */ DB_SET_PAYLOAD(con, pcon); con->connect = pg_con_connect; con->disconnect = pg_con_disconnect; return 0; error: if (pcon) { db_pool_entry_free(&pcon->gen); pkg_free(pcon); } return -1; }
/* * Print structure, for debugging only */ void print_event(event_t* _e) { printf("===Event===\n"); printf("text : \'%.*s\'\n", _e->text.len, ZSW(_e->text.s)); printf("parsed: %s\n", (_e->parsed == EVENT_PRESENCE) ? ("EVENT_PRESENCE") : ("EVENT_OTHER")); printf("===/Event===\n"); }
static int mod_init(void) { if(register_mi_mod(exports.name, mi_cmds)!=0) { LM_ERR("failed to register MI commands\n"); return -1; } if(dialplan_init_rpc()!=0) { LM_ERR("failed to register RPC commands\n"); return -1; } LM_DBG("db_url=%s/%d/%p\n", ZSW(dp_db_url.s), dp_db_url.len,dp_db_url.s); if(attr_pvar_s.s && attr_pvar_s.len>0) { attr_pvar = pv_cache_get(&attr_pvar_s); if( (attr_pvar==NULL) || ((attr_pvar->type != PVT_AVP) && (attr_pvar->type != PVT_XAVP) && (attr_pvar->type!=PVT_SCRIPTVAR))) { LM_ERR("invalid pvar name\n"); return -1; } } default_par2 = (dp_param_p)shm_malloc(sizeof(dp_param_t)); if(default_par2 == NULL){ LM_ERR("no shm more memory\n"); return -1; } memset(default_par2, 0, sizeof(dp_param_t)); /* emulate "$rU/$rU" as second parameter for dp_translate() */ default_param_s.len = strlen(default_param_s.s); default_par2->v.sp[0] = pv_cache_get(&default_param_s); if (default_par2->v.sp[0]==NULL) { LM_ERR("input pv is invalid\n"); return -1; } default_param_s.len = strlen(default_param_s.s); default_par2->v.sp[1] = pv_cache_get(&default_param_s); if (default_par2->v.sp[1]==NULL) { LM_ERR("output pv is invalid\n"); return -1; } if(dp_fetch_rows<=0) dp_fetch_rows = 1000; if(init_data() != 0) { LM_ERR("could not initialize data\n"); return -1; } return 0; }
/* * This routine is used when db_mode is * set to WRITE_THROUGH */ static inline int wt_timer(urecord_t* _r) { ucontact_t* ptr, *t; int not = 0; ptr = _r->contacts; while(ptr) { if (!VALID_CONTACT(ptr, act_time)) { /* run callbacks for EXPIRE event */ if (exists_ulcb_type(UL_CONTACT_EXPIRE)) { run_ul_callbacks( UL_CONTACT_EXPIRE, ptr); } notify_watchers(_r, ptr, PRES_OFFLINE); LOG(L_NOTICE, "Binding '%.*s','%.*s' has expired\n", ptr->uid->len, ZSW(ptr->uid->s), ptr->c.len, ZSW(ptr->c.s)); t = ptr; ptr = ptr->next; /* it was the last contact and it was in normal * state, so notify */ if (!ptr && t->state == CS_SYNC) not=1; if (db_delete_ucontact(t) < 0) { LOG(L_ERR, "wt_timer(): Error while deleting contact from " "database\n"); } delete_reg_avps(t); mem_delete_ucontact(_r, t); _r->slot->d->expired++; } else { /* the contact was unregistered and is not marked * for replication so remove it, but the notify was * already done during unregister */ ptr = ptr->next; } } return 0; }
/* * Generate AVPs from the database result */ static int generate_avps(db_res_t* result, db_rec_t *row) { int i; int_str iname, ivalue; str value; char buf[32]; for (i = 2; i < credentials_n + 2; i++) { value = row->fld[i].v.lstr; if (IS_NULL(row->fld[i])) continue; switch (row->fld[i].type) { case DB_STR: value = row->fld[i].v.lstr; break; case DB_INT: value.len = sprintf(buf, "%d", row->fld[i].v.int4); value.s = buf; break; default: abort(); break; } if (value.s == NULL) continue; iname.s = credentials[i - 2]; ivalue.s = value; if (add_avp(AVP_NAME_STR | AVP_VAL_STR | AVP_CLASS_USER, iname, ivalue) < 0) { LOG(L_ERR, "auth_db:generate_avps: Error while creating AVPs\n"); return -1; } DBG("auth_db:generate_avps: set string AVP \'%.*s = %.*s\'\n", iname.s.len, ZSW(iname.s.s), value.len, ZSW(value.s)); } return 0; }
/* * Print a record */ void print_urecord(FILE* _f, urecord_t* _r) { ucontact_t* ptr; fprintf(_f, "...Record(%p)...\n", _r); fprintf(_f, "domain: '%.*s'\n", _r->domain->len, ZSW(_r->domain->s)); fprintf(_f, "uid : '%.*s'\n", _r->uid.len, ZSW(_r->uid.s)); if (_r->contacts) { ptr = _r->contacts; while(ptr) { print_ucontact(_f, ptr); ptr = ptr->next; } } fprintf(_f, ".../Record...\n"); }
static inline int ldap_int2db_int(int* dst, str* src) { if (str2sint(src, dst) != 0) { ERR("ldap: Error while converting value '%.*s' to integer\n", src->len, ZSW(src->s)); return -1; } return 0; }
/* When done, this function also has the job to unref the dialog as removed * from timer list. This must be done in all cases!! */ void dlg_ontimeout( struct dlg_tl *tl) { struct dlg_cell *dlg; int new_state; int old_state; int unref; dlg = get_dlg_tl_payload(tl); LM_DBG("byeontimeout ? %d , state = %d\n",dlg->flags,dlg->state); if ( (dlg->flags&DLG_FLAG_BYEONTIMEOUT) && (dlg->state==DLG_STATE_CONFIRMED_NA || dlg->state==DLG_STATE_CONFIRMED)) { init_dlg_term_reason(dlg,"Lifetime Timeout",sizeof("Lifetime Timeout")-1); /* we just send the BYEs in both directions */ dlg_end_dlg( dlg, NULL); /* dialog is no longer refed by timer; from now one it is refed by the send_bye functions */ unref_dlg( dlg, 1); /* is not 100% sure, but do it */ if_update_stat( dlg_enable_stats, expired_dlgs, 1); return ; } next_state_dlg( dlg, DLG_EVENT_REQBYE, &old_state, &new_state, &unref); if (new_state==DLG_STATE_DELETED && old_state!=DLG_STATE_DELETED) { LM_DBG("timeout for dlg with CallID '%.*s' and tags '%.*s' '%.*s'\n", dlg->callid.len, dlg->callid.s, dlg->legs[DLG_CALLER_LEG].tag.len, dlg->legs[DLG_CALLER_LEG].tag.s, dlg->legs[callee_idx(dlg)].tag.len, ZSW(dlg->legs[callee_idx(dlg)].tag.s)); /*destroy linkers */ destroy_linkers(dlg->profile_links); dlg->profile_links = NULL; /* dialog timeout */ run_dlg_callbacks( DLGCB_EXPIRED, dlg, 0, DLG_DIR_NONE, 0); /* delete the dialog from DB */ if (should_remove_dlg_db()) remove_dialog_from_db(dlg); unref_dlg(dlg, unref + 1 /*timer list*/); if_update_stat( dlg_enable_stats, expired_dlgs, 1); if_update_stat( dlg_enable_stats, active_dlgs, -1); } else { unref_dlg(dlg, 1 /*just timer list*/); } return; }
/* * Check if domain is local */ int is_domain_local(str* _host) { if (db_mode == 0) { db_key_t keys[1]; db_val_t vals[1]; db_key_t cols[1]; db_res_t* res; keys[0]=domain_col.s; cols[0]=domain_col.s; if (domain_dbf.use_table(db_handle, domain_table.s) < 0) { LOG(L_ERR, "is_local(): Error while trying to use domain table\n"); return -1; } VAL_TYPE(vals) = DB_STR; VAL_NULL(vals) = 0; VAL_STR(vals).s = _host->s; VAL_STR(vals).len = _host->len; if (domain_dbf.query(db_handle, keys, 0, vals, cols, 1, 1, 0, &res) < 0 ) { LOG(L_ERR, "is_local(): Error while querying database\n"); return -1; } if (RES_ROW_N(res) == 0) { DBG("is_local(): Realm '%.*s' is not local\n", _host->len, ZSW(_host->s)); domain_dbf.free_result(db_handle, res); return -1; } else { DBG("is_local(): Realm '%.*s' is local\n", _host->len, ZSW(_host->s)); domain_dbf.free_result(db_handle, res); return 1; } } else { return hash_table_lookup (_host); } }
/*! * \brief Registers a new domain with usrloc * * Registers a new domain with usrloc. If the domain exists, * a pointer to existing structure will be returned, otherwise * a new domain will be created * \param _n domain name * \param _d new created domain * \return 0 on success, -1 on failure */ int register_udomain(const char* _n, udomain_t** _d) { dlist_t* d; str s; db1_con_t* con; s.s = (char*)_n; s.len = strlen(_n); if (find_dlist(&s, &d) == 0) { *_d = d->d; return 0; } if (new_dlist(&s, &d) < 0) { LM_ERR("failed to create new domain\n"); return -1; } /* Test tables from database if we are gonna * to use database */ if (db_mode != NO_DB) { con = ul_dbf.init(&db_url); if (!con) { LM_ERR("failed to open database connection\n"); goto err; } if(ul_version_table != 0 && db_check_table_version(&ul_dbf, con, &s, UL_TABLE_VERSION) < 0) { LM_ERR("error during table version check.\n"); goto err; } /* test if DB really exists */ if (testdb_udomain(con, d->d) < 0) { LM_ERR("testing domain '%.*s' failed\n", s.len, ZSW(s.s)); goto err; } ul_dbf.close(con); } d->next = root; root = d; *_d = d->d; return 0; err: if (con) ul_dbf.close(con); free_udomain(d->d); shm_free(d->name.s); shm_free(d); return -1; }
/* Retrieve did directly from database, without using memory cache. Use 0 as * the value of first parameter if you only want to know whether the entry is * in the database. The function returns 1 if there is such entry, 0 if not, * and -1 on error. The result is allocated using pkg_malloc and must be * freed. */ int db_get_did(str* did, str* domain) { db_res_t* res = NULL; db_rec_t* rec; if (!domain) { ERR("BUG:Invalid parameter value\n"); goto err; } get_did_cmd->match[0].v.lstr = *domain; if (db_exec(&res, get_did_cmd) < 0) { ERR("Error in database query\n"); goto err; } rec = db_first(res); if (rec) { /* Test flags first, we are only interested in rows * that are not disabled */ if (rec->fld[1].flags & DB_NULL || (rec->fld[1].v.bitmap & SRDB_DISABLED)) { db_res_free(res); return 0; } if (did) { if (rec->fld[0].flags & DB_NULL) { did->len = 0; did->s = 0; WARN("Domain '%.*s' has NULL did\n", domain->len, ZSW(domain->s)); } else { did->s = pkg_malloc(rec->fld[0].v.lstr.len); if (!did->s) { ERR("No memory left\n"); goto err; } memcpy(did->s, rec->fld[0].v.lstr.s, rec->fld[0].v.lstr.len); did->len = rec->fld[0].v.lstr.len; } } db_res_free(res); return 1; } else { db_res_free(res); return 0; } err: if (res) db_res_free(res); return -1; }
/*! * \brief Print a record, useful for debugging * \param _f print output * \param _r printed record */ void print_urecord(FILE* _f, urecord_t* _r) { ucontact_t* ptr; fprintf(_f, "...Record(%p)...\n", _r); fprintf(_f, "domain : '%.*s'\n", _r->domain->len, ZSW(_r->domain->s)); fprintf(_f, "aor : '%.*s'\n", _r->aor.len, ZSW(_r->aor.s)); fprintf(_f, "aorhash: '%u'\n", (unsigned)_r->aorhash); fprintf(_f, "slot: '%d'\n", _r->aorhash&(_r->slot->d->size-1)); if (_r->contacts) { ptr = _r->contacts; while(ptr) { print_ucontact(_f, ptr); ptr = ptr->next; } } fprintf(_f, ".../Record...\n"); }
/* * Generate AVPs from the database result */ static int generate_avps(VALUE_PAIR* received) { int_str name, val; VALUE_PAIR *vp; vp = rc_avpair_get(received, ATTRID(attrs[A_SER_UID].v), VENDOR(attrs[A_SER_UID].v)); if (vp == NULL) { WARN("RADIUS server did not send SER-UID attribute in digest authentication reply\n"); return -1; } val.s.len = vp->lvalue; val.s.s = vp->strvalue; name.s.s = "uid"; name.s.len = 3; if (add_avp(AVP_TRACK_FROM | AVP_CLASS_USER | AVP_NAME_STR | AVP_VAL_STR, name, val) < 0) { ERR("Unable to create UID attribute\n"); return -1; } vp = received; while ((vp = rc_avpair_get(vp, ATTRID(attrs[A_SER_ATTR].v), VENDOR(attrs[A_SER_ATTR].v)))) { attr_name_value(&name.s, &val.s, vp); if (name.s.len == 0) { ERR("Missing attribute name\n"); return -1; } if (add_avp(AVP_TRACK_FROM | AVP_CLASS_USER | AVP_NAME_STR | AVP_VAL_STR, name, val) < 0) { LOG(L_ERR, "generate_avps: Unable to create a new AVP\n"); return -1; } else { DBG("generate_avps: AVP '%.*s'='%.*s' has been added\n", name.s.len, ZSW(name.s.s), val.s.len, ZSW(val.s.s)); } vp = vp->next; } return 0; }
/* * Return true if the AOR in the Request-URI is registered, * it is similar to lookup but registered neither rewrites * the Request-URI nor appends branches */ int registered(struct sip_msg* _m, char* _t, char* _s) { str uri, aor; urecord_t* r; ucontact_t* ptr; int res; if (_m->new_uri.s) uri = _m->new_uri; else uri = _m->first_line.u.request.uri; if (extract_aor(&uri, &aor) < 0) { LOG(L_ERR, "registered(): Error while extracting address of record\n"); return -1; } ul.lock_udomain((udomain_t*)_t); res = ul.get_urecord((udomain_t*)_t, &aor, &r); if (res < 0) { ul.unlock_udomain((udomain_t*)_t); LOG(L_ERR, "registered(): Error while querying usrloc\n"); return -1; } if (res == 0) { ptr = r->contacts; while (ptr && !VALID_CONTACT(ptr, act_time)) { ptr = ptr->next; } if (ptr) { ul.unlock_udomain((udomain_t*)_t); DBG("registered(): '%.*s' found in usrloc\n", aor.len, ZSW(aor.s)); return 1; } } ul.unlock_udomain((udomain_t*)_t); DBG("registered(): '%.*s' not found in usrloc\n", aor.len, ZSW(aor.s)); return -1; }
/*! * \brief Print a record, useful for debugging * \param _f print output * \param _r printed record */ void print_impurecord(FILE* _f, impurecord_t* _r) { ucontact_t* ptr; fprintf(_f, "...Record(%p)...\n", _r); fprintf(_f, "domain : '%.*s'\n", _r->domain->len, ZSW(_r->domain->s)); fprintf(_f, "public_identity : '%.*s'\n", _r->public_identity.len, ZSW(_r->public_identity.s)); fprintf(_f, "aorhash: '%u'\n", (unsigned) _r->aorhash); fprintf(_f, "slot: '%d'\n", _r->aorhash & (_r->slot->d->size - 1)); fprintf(_f, "pi_ref: '%d'\n", _r->reg_state); fprintf(_f, "barring: '%d'\n", _r->barring); fprintf(_f, "ccf1: '%.*s'\n", _r->ccf1.len, _r->ccf1.s); fprintf(_f, "ccf2: '%.*s'\n", _r->ccf2.len, _r->ccf2.s); fprintf(_f, "ecf1: '%.*s'\n", _r->ecf1.len, _r->ecf1.s); fprintf(_f, "ecf2: '%.*s'\n", _r->ecf2.len, _r->ecf2.s); if (_r->s) { fprintf(_f, "IMS subs (#%d): '%p'\n", _r->s->service_profiles_cnt, _r->s); fprintf(_f, "#profiles: '%d\n", _r->s->service_profiles_cnt); } int header = 0; reg_subscriber* subscriber = _r->shead; while (subscriber) { if (!header) { fprintf(_f, "...Subscriptions...\n"); header = 1; } fprintf(_f, "watcher uri: <%.*s> and presentity uri: <%.*s>\n", subscriber->watcher_uri.len, subscriber->watcher_uri.s, subscriber->presentity_uri.len, subscriber->presentity_uri.s); fprintf(_f, "Expires: %ld\n", subscriber->expires); subscriber = subscriber->next; } if (_r->contacts) { ptr = _r->contacts; while (ptr) { print_ucontact(_f, ptr); ptr = ptr->next; } } fprintf(_f, ".../Record...\n\n\n\n"); }
/* * Return true if the AOR in the Request-URI is registered, * it is similar to lookup but registered neither rewrites * the Request-URI nor appends branches */ int registered2(struct sip_msg* _m, char* _t, char* p2) { str uid, aor; urecord_t* r; ucontact_t* ptr; int res; if (get_str_fparam(&aor, _m, (fparam_t*)p2) != 0) { ERR("Unable to get the AOR value\n"); return -1; } if (get_to_uid(&uid, _m) < 0) return -1; ul.lock_udomain((udomain_t*)_t); res = ul.get_urecord((udomain_t*)_t, &uid, &r); if (res < 0) { ul.unlock_udomain((udomain_t*)_t); LOG(L_ERR, "registered(): Error while querying usrloc\n"); return -1; } if (res == 0) { ptr = r->contacts; while (ptr && (!VALID_CONTACT(ptr, act_time) || !VALID_AOR(ptr, aor))) { ptr = ptr->next; } if (ptr) { ul.unlock_udomain((udomain_t*)_t); DBG("registered(): '%.*s' found in usrloc\n", uid.len, ZSW(uid.s)); return 1; } } ul.unlock_udomain((udomain_t*)_t); DBG("registered(): '%.*s' not found in usrloc\n", uid.len, ZSW(uid.s)); return -1; }
/*! * \brief Print contact, for debugging purposes only * \param _f output file * \param _c printed contact */ void print_ucontact(FILE* _f, ucontact_t* _c) { time_t t = time(0); char* st = ""; param_t * tmp; fprintf(_f, "~~~Contact(%p)~~~\n", _c); fprintf(_f, "domain : '%.*s'\n", _c->domain.len, ZSW(_c->domain.s)); fprintf(_f, "aor : '%.*s'\n", _c->aor.len, ZSW(_c->aor.s)); fprintf(_f, "Contact : '%.*s'\n", _c->c.len, ZSW(_c->c.s)); fprintf(_f, "Params :\n"); tmp = _c->params; while (tmp) { fprintf(_f, "Param Name: '%.*s' Param Body '%.*s'\n", tmp->name.len, ZSW(tmp->name.s), tmp->body.len, ZSW(tmp->body.s)); tmp = tmp->next; } fprintf(_f, "Expires : "); if (_c->expires == 0) { fprintf(_f, "Permanent\n"); } else if (_c->expires == UL_EXPIRED_TIME) { fprintf(_f, "Deleted\n"); } else if (t > _c->expires) { fprintf(_f, "Expired\n"); } else { fprintf(_f, "%u\n", (unsigned int) (_c->expires - t)); } fprintf(_f, "q : %s\n", q2str(_c->q, 0)); fprintf(_f, "Call-ID : '%.*s'\n", _c->callid.len, ZSW(_c->callid.s)); fprintf(_f, "CSeq : %d\n", _c->cseq); fprintf(_f, "User-Agent: '%.*s'\n", _c->user_agent.len, ZSW(_c->user_agent.s)); fprintf(_f, "received : '%.*s'\n", _c->received.len, ZSW(_c->received.s)); fprintf(_f, "Path : '%.*s'\n", _c->path.len, ZSW(_c->path.s)); fprintf(_f, "State : %s\n", st); fprintf(_f, "Flags : %u\n", _c->flags); if (_c->sock) { fprintf(_f, "Sock : %.*s (%p)\n", _c->sock->sock_str.len, _c->sock->sock_str.s, _c->sock); } else { fprintf(_f, "Sock : none (null)\n"); } fprintf(_f, "Methods : %u\n", _c->methods); fprintf(_f, "next : %p\n", _c->next); fprintf(_f, "prev : %p\n", _c->prev); fprintf(_f, "~~~/Contact~~~~\n"); }
/*! * \brief Create new DB connection structure * \param db_id */ void* db_cassa_new_connection(struct db_id* id) { struct cassa_con* ptr; if (!id) { LM_ERR("invalid db_id parameter value\n"); return 0; } if (id->port) { LM_DBG("opening connection: cassa://xxxx:xxxx@%s:%d/%s\n", ZSW(id->host), id->port, ZSW(id->database)); } else { LM_DBG("opening connection: cassa://xxxx:xxxx@%s/%s\n", ZSW(id->host), ZSW(id->database)); } ptr = (struct cassa_con*)pkg_malloc(sizeof(struct cassa_con)); if (!ptr) { LM_ERR("failed trying to allocated %lu bytes for connection structure." "\n", (unsigned long)sizeof(struct cassa_con)); return 0; } LM_DBG("%p=pkg_malloc(%lu)\n", ptr, (unsigned long)sizeof(struct cassa_con)); memset(ptr, 0, sizeof(struct cassa_con)); ptr->db_name.s = id->database; ptr->db_name.len = strlen(id->database); ptr->id = id; ptr->ref = 1; ptr->con = dbcassa_open(id); if(!ptr->con) { LM_ERR("Failed to open connection to Cassandra cluster\n"); pkg_free(ptr); return 0; } return ptr; }
static inline int _parse_ruri(str *uri, int *status, struct sip_uri *parsed_uri) { if (*status) return 1; if (parse_uri(uri->s, uri->len, parsed_uri)<0) { LM_ERR("bad uri <%.*s>\n", uri->len, ZSW(uri->s)); *status=0; return -1; } *status=1; return 1; }
int ldap_url_search( char* _ldap_url, int* _ld_result_count) { LDAPURLDesc *ludp; int rc; if (ldap_url_parse(_ldap_url, &ludp) != 0) { LM_ERR("invalid LDAP URL [%s]\n", ZSW(_ldap_url)); if (ludp != NULL) { ldap_free_urldesc(ludp); } return -2; } if (ludp->lud_host == NULL) { LM_ERR( "no ldap session name found in ldap URL [%s]\n", ZSW(_ldap_url)); return -2; } LM_DBG( "LDAP URL parsed into session_name" " [%s], base [%s], scope [%d], filter [%s]\n", ZSW(ludp->lud_host), ZSW(ludp->lud_dn), ludp->lud_scope, ZSW(ludp->lud_filter)); rc = ldap_params_search(_ld_result_count, ludp->lud_host, ludp->lud_dn, ludp->lud_scope, ludp->lud_attrs, ludp->lud_filter); ldap_free_urldesc(ludp); return rc; }
/* Module initialization function */ static int mod_init(void) { if (init_shmlock() != 0) { LM_CRIT("cannot initialize shmlock.\n"); return -1; } if (conf_init(mp_max_id) < 0) { LM_CRIT("cannot initialize configuration.\n"); return -1; } /* read module parameters and update configuration structure */ if (conf_parse_proxy(mp_proxy) < 0) { LM_CRIT("cannot parse proxy module parameter.\n"); return -1; } if (conf_parse_filter(mp_filter) < 0) { LM_CRIT("cannot parse filter module parameter.\n"); return -1; } if (conf_parse_switch(mp_switch) < 0) { LM_CRIT("cannot parse switch module parameter.\n"); return -1; } if (forward_active == 1) { /* register callback for id 0 */ if (register_script_cb(pre_script_filter, PRE_SCRIPT_CB|ONREPLY_CB, 0) < 0) { LM_CRIT("cannot register script callback for requests.\n"); return -1; } if (register_script_cb(pre_script_filter, PRE_SCRIPT_CB|ONREPLY_CB, 0) < 0) { LM_CRIT("cannot register script callback for replies.\n"); return -1; } } else { LM_INFO("forward functionality disabled"); } /* presence database */ LM_DBG("pres_db_url=%s/%d/%p\n", ZSW(pres_db_url.s), pres_db_url.len, pres_db_url.s); if(pres_db_init() < 0) { return -1; } return 0; }
/* * This timer routine is used when * db_mode is set to NO_DB */ static inline int nodb_timer(urecord_t* _r) { ucontact_t* ptr, *t; int not = 0; ptr = _r->contacts; while(ptr) { if (ptr->expires < act_time) { if (ptr->replicate != 0) { LOG(L_NOTICE, "Keeping binding '%.*s','%.*s' for replication\n", ptr->aor->len, ZSW(ptr->aor->s), ptr->c.len, ZSW(ptr->c.s)); /* keep it for replication, but it expired normaly * and was the last contact, so notify */ if (!ptr->next && ptr->state == CS_NEW) not=1; ptr = ptr->next; } else { LOG(L_NOTICE, "Binding '%.*s','%.*s' has expired\n", ptr->aor->len, ZSW(ptr->aor->s), ptr->c.len, ZSW(ptr->c.s)); t = ptr; ptr = ptr->next; /* it was the last contact and it was in normal * state, so notify */ if (!ptr && t->state == CS_NEW) not=1; mem_delete_ucontact(_r, t); _r->slot->d->expired++; } /* Last contact expired, notify watchers */ if (not) notify_watchers(_r, PRES_OFFLINE); } else { /* the contact was unregistered and is not marked * for replication so remove it, but the notify was * done during unregister */ if (ptr->state == CS_ZOMBIE_N && ptr->replicate == 0) { LOG(L_NOTICE, "removing spare zombie '%.*s','%.*s'\n", ptr->aor->len, ZSW(ptr->aor->s), ptr->c.len, ZSW(ptr->c.s)); t = ptr; ptr = ptr->next; mem_delete_ucontact(_r, t); } else ptr = ptr->next; } } return 0; }
void my_con_disconnect(db_con_t* con) { struct my_con* mcon; mcon = DB_GET_PAYLOAD(con); if ((mcon->flags & MY_CONNECTED) == 0) return; DBG("mysql: Disconnecting from %.*s:%.*s\n", con->uri->scheme.len, ZSW(con->uri->scheme.s), con->uri->body.len, ZSW(con->uri->body.s)); mysql_close(mcon->con); mcon->flags &= ~MY_CONNECTED; /* Increase the variable that keeps track of number of connection * resets on this connection. The mysql module uses the variable to * determine when a pre-compiled command needs to be uploaded to the * server again. If the number in the my_con structure is larger than * the number kept in my_cmd then it means that we have to upload the * command to the server again because the connection was reset. */ mcon->resets++; }
/* * This timer routine is used when * db_mode is set to NO_DB or READONLY */ static inline int nodb_timer(urecord_t* _r) { ucontact_t* ptr, *t; int not = 0; ptr = _r->contacts; while(ptr) { if (!VALID_CONTACT(ptr, act_time)) { /* run callbacks for EXPIRE event */ if (exists_ulcb_type(UL_CONTACT_EXPIRE)) run_ul_callbacks( UL_CONTACT_EXPIRE, ptr); notify_watchers(_r, ptr, PRES_OFFLINE); LOG(L_NOTICE, "Binding '%.*s','%.*s' has expired\n", ptr->uid->len, ZSW(ptr->uid->s), ptr->c.len, ZSW(ptr->c.s)); t = ptr; ptr = ptr->next; /* it was the last contact and it was in normal * state, so notify */ if (!ptr && t->state == CS_NEW) not=1; delete_reg_avps(t); mem_delete_ucontact(_r, t); _r->slot->d->expired++; } else { ptr = ptr->next; } } return 0; }
/*! \brief the term_impu_registered() function * Return true if the AOR in the Request-URI for the terminating user is registered */ int term_impu_registered(struct sip_msg* _m, char* _t, char* _s) { struct sip_msg *req; int i; str uri; impurecord_t* r; int res; // if (_m->new_uri.s) uri = _m->new_uri; // else uri = _m->first_line.u.request.uri; // // if (extract_aor(&uri, &aor) < 0) { // LM_ERR("failed to extract address of record\n"); // return -1; // } req = _m; if (!req) { LM_ERR(":term_impu_registered: NULL message!!!\n"); return -1; } if (req->first_line.type != SIP_REQUEST) { req = get_request_from_reply(req); } if (_m->new_uri.s) uri = _m->new_uri; else uri = _m->first_line.u.request.uri; for (i = 0; i < uri.len; i++) if (uri.s[i] == ';' || uri.s[i] == '?' || (i > 3 /*sip:*/ && uri.s[i] == ':' /*strip port*/)) { uri.len = i; break; } LM_DBG("term_impu_registered: Looking for <%.*s>\n", uri.len, uri.s); ul.lock_udomain((udomain_t*) _t, &uri); res = ul.get_impurecord((udomain_t*) _t, &uri, &r); if (res != 0) { ul.unlock_udomain((udomain_t*) _t, &uri); LM_ERR("failed to query for terminating IMPU or not found <%.*s>\n", uri.len, uri.s); return -1; } ul.unlock_udomain((udomain_t*) _t, &uri); LM_DBG("'%.*s' found in usrloc\n", uri.len, ZSW(uri.s)); return 1; }
/*! * \brief Set Request-URI as last Route header of a SIP * * Set Request-URI as last Route header of a SIP message, * this is necessary when forwarding to a strict router. * Allocates memory for message lump in private memory. * \param _m SIP message * \return negative on failure, 0 on success */ static inline int save_ruri(struct sip_msg* _m) { struct lump* anchor; char *s; int len; /* We must parse the whole message header here, because * the Request-URI must be saved in last Route HF in the message */ if (parse_headers(_m, HDR_EOH_F, 0) == -1) { LM_ERR("failed to parse message\n"); return -1; } /* Create an anchor */ anchor = anchor_lump(_m, _m->unparsed - _m->buf, 0, 0); if (anchor == 0) { LM_ERR("failed to get anchor\n"); return -2; } /* Create buffer for new lump */ len = RR_ROUTE_PREFIX_LEN + _m->first_line.u.request.uri.len + ROUTE_SUFFIX_LEN; s = (char*)pkg_malloc(len); if (!s) { LM_ERR("No memory pkg left\n"); return -3; } /* Create new header field */ memcpy(s, RR_ROUTE_PREFIX, RR_ROUTE_PREFIX_LEN); memcpy(s + RR_ROUTE_PREFIX_LEN, _m->first_line.u.request.uri.s, _m->first_line.u.request.uri.len); memcpy(s + RR_ROUTE_PREFIX_LEN + _m->first_line.u.request.uri.len, ROUTE_SUFFIX, ROUTE_SUFFIX_LEN); LM_DBG("New header: '%.*s'\n", len, ZSW(s)); /* Insert it */ if (insert_new_lump_before(anchor, s, len, 0) == 0) { pkg_free(s); LM_ERR("failed to insert lump\n"); return -4; } return 0; }
static inline int ldap_bit2db_int(int* dst, str* src) { int i, v; if (src->len > 32) { WARN("ldap: bitString '%.*s'B is longer than 32 bits, truncating\n", src->len, ZSW(src->s)); } v = 0; for(i = 0; i < src->len; i++) { v <<= 1; v += src->s[i] - '0'; } *dst = v; return 0; }
/* * Print domains stored in hash table */ void hash_table_print(struct trusted_list** hash_table, FILE* reply_file) { int i; struct trusted_list *np; for (i = 0; i < HASH_SIZE; i++) { np = hash_table[i]; while (np) { fprintf(reply_file, "%4d <%.*s, %d, %s>\n", i, np->src_ip.len, ZSW(np->src_ip.s), np->proto, np->pattern); np = np->next; } } }
static int child_init(int rank) { dlist_t* ptr; int i; if (rank == PROC_MAIN && ul_timer_procs > 0) { for (i = 0; i < ul_timer_procs; i++) { if (fork_sync_timer(PROC_TIMER, "IMS S-CSCF USRLOC Timer", 1 /*socks flag*/, ul_local_timer, (void*) (long) i, timer_interval /*sec*/) < 0) { LM_ERR("failed to start timer routine as process\n"); return -1; /* error */ } } } /* connecting to DB ? */ switch (db_mode) { case NO_DB: return 0; case WRITE_THROUGH: /* we need connection from working SIP and TIMER and MAIN * processes only */ if (rank <= 0 && rank != PROC_TIMER && rank != PROC_MAIN) return 0; break; } ul_dbh = ul_dbf.init(&db_url); /* Get a database connection per child */ if (!ul_dbh) { LM_ERR("child(%d): failed to connect to database\n", rank); return -1; } /* _rank==PROC_SIPINIT is used even when fork is disabled */ if (rank == PROC_SIPINIT && db_mode != DB_ONLY) { /* if cache is used, populate from DB */ for (ptr = root; ptr; ptr = ptr->next) { if (preload_udomain(ul_dbh, ptr->d) < 0) { LM_ERR("child(%d): failed to preload domain '%.*s'\n", rank, ptr->name.len, ZSW(ptr->name.s)); return -1; } } } return 0; }
int fifo_pa_watcherinfo(FILE *fifo, char *response_file) { char pdomain_s[MAX_P_URI]; char p_uri_s[MAX_P_URI]; pdomain_t *pdomain = NULL; presentity_t *presentity = NULL; str pdomain_name, p_uri; if (!read_line(pdomain_s, MAX_PDOMAIN, fifo, &pdomain_name.len) || pdomain_name.len == 0) { fifo_reply(response_file, "400 pa_watcherinfo: pdomain expected\n"); LOG(L_ERR, "ERROR: pa_watcherinfo: pdomain expected\n"); return 1; } pdomain_name.s = pdomain_s; if (!read_line(p_uri_s, MAX_P_URI, fifo, &p_uri.len) || p_uri.len == 0) { fifo_reply(response_file, "400 pa_watcherinfo: p_uri expected\n"); LOG(L_ERR, "ERROR: pa_watcherinfo: p_uri expected\n"); return 1; } p_uri.s = p_uri_s; register_pdomain(pdomain_s, &pdomain); if (!pdomain) { fifo_reply(response_file, "400 could not register pdomain\n"); LOG(L_ERR, "ERROR: pa_watcherinfo: could not register pdomain %.*s\n", pdomain_name.len, pdomain_name.s); return 1; } lock_pdomain(pdomain); find_presentity(pdomain, &p_uri, &presentity); if (presentity) { db_read_watcherinfo(presentity); } unlock_pdomain(pdomain); fifo_reply(response_file, "200 watcherinfo updated\n", "(%.*s)\n", p_uri.len, ZSW(p_uri.s)); return 1; }