/*
 * Create and insert new contact
 * into urecord
 */
int insert_ucontact(urecord_t* _r, str* aor, str* _c, time_t _e, qvalue_t _q, str* _cid, 
					int _cs, unsigned int _flags, struct ucontact** _con, str* _ua, str* _recv,
					struct socket_info* sock, str* _inst, int sid)
{
	if (mem_insert_ucontact(_r, aor, _c, _e, _q, _cid, _cs, _flags, _con, _ua, _recv, sock, _inst, sid) < 0) {
		LOG(L_ERR, "insert_ucontact(): Error while inserting contact\n");
		return -1;
	}

	notify_watchers(_r, *_con, (_e > 0) ? PRES_ONLINE : PRES_OFFLINE);

	if (exists_ulcb_type(UL_CONTACT_INSERT)) {
		run_ul_callbacks( UL_CONTACT_INSERT, *_con);
	}

	save_reg_avps(*_con);
	
	if (db_mode == WRITE_THROUGH) {
		if (db_store_ucontact(*_con) < 0) {
			LOG(L_ERR, "insert_ucontact(): Error while inserting in database\n");
		}
		(*_con)->state = CS_SYNC;
	}

	return 0;
}
Exemple #2
0
/*!
 * \brief Create and insert new contact into impurecord
 * \param _r record into the new contact should be inserted
 * \param _contact contact string
 * \param _ci contact information
 * \param _c new created contact
 * \return 0 on success, -1 on failure
 */
int insert_ucontact(impurecord_t* _r, str* _contact, ucontact_info_t* _ci, ucontact_t** _c) {
    //First check our constraints
    if (maxcontact > 0 && maxcontact_behaviour > 0) {
        ucontact_t* contact = _r->contacts;
        int numcontacts = 0;
        while (contact) {
            numcontacts++;
            contact = contact->next;
        }
        if (numcontacts >= maxcontact) {
            switch (maxcontact_behaviour) {
                case 1://reject
                    LM_ERR("too many contacts already registered for IMPU <%.*s>\n", _r->public_identity.len, _r->public_identity.s);
                    return -1;
                case 2://overwrite oldest
                    LM_DBG("Too many contacts already registered, overwriting oldest for IMPU <%.*s>\n", _r->public_identity.len, _r->public_identity.s);
                    //we can just remove the first one seeing the contacts are ordered on insertion with newest last and oldest first
                    mem_delete_ucontact(_r, _r->contacts);
                    break;
                default://unknown
                    LM_ERR("unknown maxcontact behaviour..... ignoring\n");
                    break;
            }
        }
    }

    //at this stage we are safe to insert the new contact
    LM_DBG("INSERTing ucontact in usrloc module\n");
    if (((*_c) = mem_insert_ucontact(_r, _contact, _ci)) == 0) {
        LM_ERR("failed to insert contact\n");
        return -1;
    }

    /*DB?*/
	if (db_mode == WRITE_THROUGH && db_insert_ucontact(_r, *_c) != 0) {
		LM_ERR("error inserting contact into db");
		return -1;
	}

    if (exists_ulcb_type(NULL, UL_CONTACT_INSERT)) {
        run_ul_callbacks(NULL, UL_CONTACT_INSERT, _r, *_c);
    }
    if (exists_ulcb_type(_r->cbs, UL_IMPU_NEW_CONTACT)) {
        run_ul_callbacks(_r->cbs, UL_IMPU_NEW_CONTACT, _r, *_c);
    }

    return 0;
}
/*
 * Create and insert new contact
 * into urecord
 */
int insert_ucontact_rep(urecord_t* _r, str* _c, time_t _e, float _q, str* _cid, 
			int _cs, unsigned int _flags, int _rep, struct ucontact** _con)
{
	if (mem_insert_ucontact(_r, _c, _e, _q, _cid, _cs, _flags, _rep, _con) < 0) {
		LOG(L_ERR, "insert_ucontact(): Error while inserting contact\n");
		return -1;
	}

	notify_watchers(_r, PRES_ONLINE);
	
	if (db_mode == WRITE_THROUGH) {
		if (db_insert_ucontact(*_con) < 0) {
			LOG(L_ERR, "insert_ucontact(): Error while inserting in database\n");
			mem_delete_ucontact(_r, *_con);
			return -2;
		}
		(*_con)->state=CS_SYNC;
	}

	return 0;
}
Exemple #4
0
/*!
 * \brief Create and insert new contact into urecord
 * \param _r record into the new contact should be inserted
 * \param _contact contact string
 * \param _ci contact information
 * \param _c new created contact
 * \return 0 on success, -1 on failure
 */
int insert_ucontact(urecord_t* _r, str* _contact, ucontact_info_t* _ci,
															ucontact_t** _c)
{
	if ( ((*_c)=mem_insert_ucontact(_r, _contact, _ci)) == 0) {
		LM_ERR("failed to insert contact\n");
		return -1;
	}

	if (exists_ulcb_type(UL_CONTACT_INSERT)) {
		run_ul_callbacks( UL_CONTACT_INSERT, *_c);
	}

	if (db_mode == WRITE_THROUGH || db_mode==DB_ONLY) {
		if (db_insert_ucontact(*_c) < 0) {
			LM_ERR("failed to insert in database\n");
			return -1;
		} else {
			(*_c)->state = CS_SYNC;
		}
	}

	return 0;
}
Exemple #5
0
int preload_udomain(db_con_t* _c, udomain_t* _d)
{
	char b[256];
	db_key_t columns[11];
	db_res_t* res;
	db_row_t* row;
	int i, cseq;
	unsigned int flags;
	struct socket_info* sock;
	str uid, contact, callid, ua, received, instance, aor;
	str* rec;
	time_t expires;
	qvalue_t q;

	urecord_t* r;
	ucontact_t* c;

	columns[0] = uid_col.s;
	columns[1] = contact_col.s;
	columns[2] = expires_col.s;
	columns[3] = q_col.s;
	columns[4] = callid_col.s;
	columns[5] = cseq_col.s;
	columns[6] = flags_col.s;
	columns[7] = user_agent_col.s;
	columns[8] = received_col.s;
	columns[9] = instance_col.s;
	columns[10] = aor_col.s;
	
	memcpy(b, _d->name->s, _d->name->len);
	b[_d->name->len] = '\0';

	if (ul_dbf.use_table(_c, b) < 0) {
		LOG(L_ERR, "preload_udomain(): Error in use_table\n");
		return -1;
	}

	if (ul_dbf.query(_c, 0, 0, 0, columns, 0, 11, 0, &res) < 0) {
		LOG(L_ERR, "preload_udomain(): Error while doing db_query\n");
		return -1;
	}

	if (RES_ROW_N(res) == 0) {
		DBG("preload_udomain(): Table is empty\n");
		ul_dbf.free_result(_c, res);
		return 0;
	}

	lock_udomain(_d);

	for(i = 0; i < RES_ROW_N(res); i++) {
		row = RES_ROWS(res) + i;
		
		uid.s      = (char*)VAL_STRING(ROW_VALUES(row));
		if (uid.s == 0) {
			LOG(L_CRIT, "preload_udomain: ERROR: bad uid "
							"record in table %s\n", b);
			LOG(L_CRIT, "preload_udomain: ERROR: skipping...\n");
			continue;
		} else {
			uid.len = strlen(uid.s);
		}

		contact.s = (char*)VAL_STRING(ROW_VALUES(row) + 1);
		if (contact.s == 0) {
			LOG(L_CRIT, "preload_udomain: ERROR: bad contact "
							"record in table %s\n", b);
			LOG(L_CRIT, "preload_udomain: ERROR: for username %.*s\n",
							uid.len, uid.s);
			LOG(L_CRIT, "preload_udomain: ERROR: skipping...\n");
			continue;
		} else {
			contact.len = strlen(contact.s);
		}
		expires     = VAL_TIME  (ROW_VALUES(row) + 2);
		q           = double2q(VAL_DOUBLE(ROW_VALUES(row) + 3));
		cseq        = VAL_INT   (ROW_VALUES(row) + 5);
		callid.s    = (char*)VAL_STRING(ROW_VALUES(row) + 4);
		if (callid.s == 0) {
			LOG(L_CRIT, "preload_udomain: ERROR: bad callid record in"
							" table %s\n", b);
			LOG(L_CRIT, "preload_udomain: ERROR: for username %.*s,"
							" contact %.*s\n",
							uid.len, uid.s, contact.len, contact.s);
			LOG(L_CRIT, "preload_udomain: ERROR: skipping...\n");
			continue;
		} else {
			callid.len  = strlen(callid.s);
		}

		flags  = VAL_BITMAP(ROW_VALUES(row) + 6);

		ua.s  = (char*)VAL_STRING(ROW_VALUES(row) + 7);
		if (ua.s) {
			ua.len = strlen(ua.s);
		} else {
			ua.len = 0;
		}

		if (!VAL_NULL(ROW_VALUES(row) + 8)) {
			received.s  = (char*)VAL_STRING(ROW_VALUES(row) + 8);
			if (received.s) {
				received.len = strlen(received.s);
				rec = &received;

				sock = find_socket(&received);
			} else {
				received.len = 0;
				rec = 0;
				sock = 0;
			}
		} else {
			received.s = 0;
			received.len = 0;
			rec = 0;
			sock = 0;
		}

		if (!VAL_NULL(ROW_VALUES(row) + 9)) {
			instance.s  = (char*)VAL_STRING(ROW_VALUES(row) + 9);
			if (instance.s) {
				instance.len = strlen(instance.s);
			} else {
				instance.len = 0;
			}
		} else {
			instance.s = 0;
			instance.len = 0;
		}

		if (!VAL_NULL(ROW_VALUES(row) + 10)) {
			aor.s  = (char*)VAL_STRING(ROW_VALUES(row) + 10);
			if (aor.s) {
				aor.len = strlen(aor.s);
			} else {
				aor.len = 0;
			}
		} else {
			aor.s = 0;
			aor.len = 0;
		}

		if (get_urecord(_d, &uid, &r) > 0) {
			if (mem_insert_urecord(_d, &uid, &r) < 0) {
				LOG(L_ERR, "preload_udomain(): Can't create a record\n");
				ul_dbf.free_result(_c, res);
				unlock_udomain(_d);
				return -2;
			}
		}
		
		if (mem_insert_ucontact(r, &aor, &contact, expires, q, &callid, cseq, flags, &c, &ua, rec, sock, &instance) < 0) {
			LOG(L_ERR, "preload_udomain(): Error while inserting contact\n");
			ul_dbf.free_result(_c, res);
			unlock_udomain(_d);
			return -3;
		}

		db_read_reg_avps(_c, c);

		     /* We have to do this, because insert_ucontact sets state to CS_NEW
		      * and we have the contact in the database already
			  * we also store zombies in database so we have to restore
			  * the correct state
		      */
		c->state = CS_SYNC;
	}

	ul_dbf.free_result(_c, res);
	unlock_udomain(_d);
	return 0;
}
Exemple #6
0
/*!
 * \brief Loads from DB all contacts for a RUID
 * \param _c database connection
 * \param _d domain
 * \param _aor address of record
 * \return pointer to the record on success, 0 on errors or if nothing is found
 */
urecord_t* db_load_urecord_by_ruid(udomain_t* _d, str *_ruid)
{
    ucontact_info_t *ci;
    db_key_t columns[18];
    db_key_t keys[1];
    db_key_t order;
    db_val_t vals[1];
    db1_res_t* res = NULL;
    db_row_t *row;
    str contact;
    str aor;
    char aorbuf[512];
    str domain;

    urecord_t* r;
    ucontact_t* c;

    keys[0] = &ruid_col;
    vals[0].type = DB1_STR;
    vals[0].nul = 0;
    vals[0].val.str_val = *_ruid;

    columns[0] = &contact_col;
    columns[1] = &expires_col;
    columns[2] = &q_col;
    columns[3] = &callid_col;
    columns[4] = &cseq_col;
    columns[5] = &flags_col;
    columns[6] = &cflags_col;
    columns[7] = &user_agent_col;
    columns[8] = &received_col;
    columns[9] = &path_col;
    columns[10] = &sock_col;
    columns[11] = &methods_col;
    columns[12] = &last_mod_col;
    columns[13] = &ruid_col;
    columns[14] = &instance_col;
    columns[15] = &user_col;
    columns[16] = &reg_id_col;
    columns[17] = &domain_col;

    if (desc_time_order)
        order = &last_mod_col;
    else
        order = &q_col;

    if (ul_db_layer_query(_d,  &vals[0].val.str_val,  &vals[1].val.str_val, keys, 0, vals, columns, 1, 18, order,
                          &res) < 0) {
        LM_ERR("db_query failed\n");
        return 0;
    }

    if (RES_ROW_N(res) == 0) {
        LM_DBG("aor %.*s not found in table %.*s\n",_ruid->len, _ruid->s,
               _d->name->len, _d->name->s);
        ul_db_layer_free_result(_d, res);
        return 0;
    }

    r = 0;

    /* use first row - shouldn't be more */
    row = RES_ROWS(res);

    ci = dbrow2info(ROW_VALUES(RES_ROWS(res)), &contact);
    if (ci==0) {
        LM_ERR("skipping record for %.*s in table %s\n",
               _ruid->len, _ruid->s, _d->name->s);
        goto done;
    }

    aor.s = (char*)VAL_STRING(ROW_VALUES(row) + 15);
    aor.len = strlen(aor.s);

    if (use_domain) {
        domain.s = (char*)VAL_STRING(ROW_VALUES(row) + 17);
        if (VAL_NULL(ROW_VALUES(row)+17) || domain.s==0 || domain.s[0]==0) {
            LM_CRIT("empty domain record for user %.*s...skipping\n",
                    aor.len, aor.s);
            goto done;
        }
        domain.len = strlen(domain.s);
        if(aor.len + domain.len + 2 >= 512) {
            LM_ERR("AoR is too big\n");
            goto done;
        }
        memcpy(aorbuf, aor.s, aor.len);
        aorbuf[aor.len] = '@';
        memcpy(aorbuf + aor.len + 1, domain.s, domain.len);
        aor.len += 1 + domain.len;
        aor.s = aorbuf;
        aor.s[aor.len] = '\0';
    }
    get_static_urecord( _d, &aor, &r);

    if ( (c=mem_insert_ucontact(r, &contact, ci)) == 0) {
        LM_ERR("mem_insert failed\n");
        free_urecord(r);
        ul_db_layer_free_result(_d, res);
        return 0;
    }

    /* We have to do this, because insert_ucontact sets state to CS_NEW
     * and we have the contact in the database already */
    c->state = CS_SYNC;

done:
    ul_db_layer_free_result(_d, res);
    ;
    return r;
}
Exemple #7
0
/*!
 * \brief Loads from DB all contacts for an AOR
 * \param _c database connection
 * \param _d domain
 * \param _aor address of record
 * \return pointer to the record on success, 0 on errors or if nothing is found
 */
urecord_t* db_load_urecord(udomain_t* _d, str *_aor)
{
    ucontact_info_t *ci;
    db_key_t columns[16];
    db_key_t keys[2];
    db_key_t order;
    db_val_t vals[2];
    db1_res_t* res = NULL;
    str contact;
    char *domain;
    int i;

    urecord_t* r;
    ucontact_t* c;

    keys[0] = &user_col;
    vals[0].type = DB1_STR;
    vals[0].nul = 0;
    if (use_domain) {
        keys[1] = &domain_col;
        vals[1].type = DB1_STR;
        vals[1].nul = 0;
        domain = memchr(_aor->s, '@', _aor->len);
        vals[0].val.str_val.s   = _aor->s;
        if (domain==0) {
            vals[0].val.str_val.len = 0;
            vals[1].val.str_val = *_aor;
        } else {
            vals[0].val.str_val.len = domain - _aor->s;
            vals[1].val.str_val.s   = domain+1;
            vals[1].val.str_val.len = _aor->s + _aor->len - domain - 1;
        }
    } else {
        vals[0].val.str_val = *_aor;
    }

    columns[0] = &contact_col;
    columns[1] = &expires_col;
    columns[2] = &q_col;
    columns[3] = &callid_col;
    columns[4] = &cseq_col;
    columns[5] = &flags_col;
    columns[6] = &cflags_col;
    columns[7] = &user_agent_col;
    columns[8] = &received_col;
    columns[9] = &path_col;
    columns[10] = &sock_col;
    columns[11] = &methods_col;
    columns[12] = &last_mod_col;
    columns[13] = &ruid_col;
    columns[14] = &instance_col;
    columns[15] = &reg_id_col;

    if (desc_time_order)
        order = &last_mod_col;
    else
        order = &q_col;

    if (ul_db_layer_query(_d,  &vals[0].val.str_val,  &vals[1].val.str_val, keys, 0, vals, columns, (use_domain)?2:1, 16, order,
                          &res) < 0) {
        LM_ERR("db_query failed\n");
        return 0;
    }

    if (RES_ROW_N(res) == 0) {
        LM_DBG("aor %.*s not found in table %.*s\n",_aor->len, _aor->s, _d->name->len, _d->name->s);

        ul_db_layer_free_result(_d, res);
        return 0;
    }

    r = 0;

    for(i = 0; i < RES_ROW_N(res); i++) {
        ci = dbrow2info(  ROW_VALUES(RES_ROWS(res) + i), &contact);
        if (ci==0) {
            LM_ERR("skipping record for %.*s in table %s\n",
                   _aor->len, _aor->s, _d->name->s);
            continue;
        }

        if ( r==0 )
            get_static_urecord( _d, _aor, &r);

        if ( (c=mem_insert_ucontact(r, &contact, ci)) == 0) {
            LM_ERR("mem_insert failed\n");
            free_urecord(r);
            ul_db_layer_free_result(_d, res);
            return 0;
        }

        /* We have to do this, because insert_ucontact sets state to CS_NEW
         * and we have the contact in the database already */
        c->state = CS_SYNC;
    }

    ul_db_layer_free_result(_d, res);
    return r;
}