コード例 #1
0
ファイル: ucontact.c プロジェクト: alezzandro/kamailio
/*!
 * \brief Update ucontact with new values
 * \param _r record the contact belongs to
 * \param _c updated contact
 * \param _ci new contact informations
 * \return 0 on success, -1 on failure
 */
int update_ucontact(struct impurecord* _r, ucontact_t* _c, ucontact_info_t* _ci) {
    /* we have to update memory in any case, but database directly
     * only in db_mode 1 */
    LM_DBG("Updating contact aor: [%.*s] and contact uri: [%.*s]\n", _c->aor.len, _c->aor.s, _c->c.len, _c->c.s);
    if (mem_update_ucontact(_c, _ci) < 0) {
        LM_ERR("failed to update memory\n");
        return -1;
    }
    
    if (db_mode == WRITE_THROUGH && (db_insert_ucontact(_r, _c) != 0)) {  /* this is an insert/update */
	LM_ERR("failed to update contact in DB [%.*s]\n", _c->aor.len, _c->aor.s);
	return -1;
    }
    
    //make sure IMPU is linked to this contact
    link_contact_to_impu(_r, _c, 1);

    /* run callbacks for UPDATE event */
    if (exists_ulcb_type(_c->cbs, UL_CONTACT_UPDATE)) {
        LM_DBG("exists callback for type= UL_CONTACT_UPDATE\n");
        run_ul_callbacks(_c->cbs, UL_CONTACT_UPDATE, _r, _c);
    }
    if (exists_ulcb_type(_r->cbs, UL_IMPU_UPDATE_CONTACT)) {
        run_ul_callbacks(_r->cbs, UL_IMPU_UPDATE_CONTACT, _r, _c);
    }

//    update_contact_pos(_r, _c);

    return 0;
}
コード例 #2
0
ファイル: impurecord.c プロジェクト: Jared-Prime/kamailio
/*!
 * \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;
}
コード例 #3
0
ファイル: urecord.c プロジェクト: AndreyRybkin/kamailio
/*!
 * \brief Write through timer, used for WRITE_THROUGH db_mode
 *
 * Write through timer, used for WRITE_THROUGH db_mode. Process all
 * contacts from the record, delete all expired ones from the DB.
 * \param _r processed record
 * \note currently unused, this mode is also handled by the wb_timer
 */
static inline void wt_timer(urecord_t* _r)
{
	ucontact_t* ptr, *t;

	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);
			}

			LM_DBG("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;

			if (db_delete_ucontact(t) < 0) {
				LM_ERR("deleting contact from database failed\n");
			}
			mem_delete_ucontact(_r, t);
			update_stat( _r->slot->d->expires, 1);
		} else {
			ptr = ptr->next;
		}
	}
}
コード例 #4
0
ファイル: urecord.c プロジェクト: SibghatullahSheikh/kamailio
/*
 * 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;
}
コード例 #5
0
ファイル: urecord.c プロジェクト: AndreyRybkin/kamailio
/*!
 * \brief Write-back timer, used for WRITE_BACK db_mode
 *
 * Write-back timer, used for WRITE_BACK db_mode. Process
 * all contacts from the record, delete expired ones from the DB.
 * Furthermore it updates changed contacts, and also insert new
 * ones in the DB.
 * \param _r processed record
 */
static inline void wb_timer(urecord_t* _r)
{
	ucontact_t* ptr, *t;
	cstate_t old_state;
	int op;

	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);
			}

			LM_DBG("Binding '%.*s','%.*s' has expired\n",
				ptr->aor->len, ZSW(ptr->aor->s),
				ptr->c.len, ZSW(ptr->c.s));
			update_stat( _r->slot->d->expires, 1);

			t = ptr;
			ptr = ptr->next;

			/* Should we remove the contact from the database ? */
			if (st_expired_ucontact(t) == 1) {
				if (db_delete_ucontact(t) < 0) {
					LM_ERR("failed to delete contact from the database\n");
				}
			}

			mem_delete_ucontact(_r, t);
		} else {
			/* Determine the operation we have to do */
			old_state = ptr->state;
			op = st_flush_ucontact(ptr);

			switch(op) {
			case 0: /* do nothing, contact is synchronized */
				break;

			case 1: /* insert */
				if (db_insert_ucontact(ptr) < 0) {
					LM_ERR("inserting contact into database failed\n");
					ptr->state = old_state;
				}
				break;

			case 2: /* update */
				if (db_update_ucontact(ptr) < 0) {
					LM_ERR("updating contact in db failed\n");
					ptr->state = old_state;
				}
				break;
			}

			ptr = ptr->next;
		}
	}
}
コード例 #6
0
ファイル: pcontact.c プロジェクト: adubovikov/kamailio
static inline void nodb_timer(pcontact_t* _c)
{
	LM_DBG("Running nodb timer on <%.*s>, "
			"Reg state: %s, "
			"Expires: %d, "
			"Expires in: %d seconds, "
			"Received: %.*s:%d, "
                        "Path: %.*s, "
			"Proto: %d, "
                        "Hash: %u, " 
                        "Slot: %u\n",
			_c->aor.len, _c->aor.s,
			reg_state_to_string(_c->reg_state),
			(int)_c->expires,
			(int)(_c->expires - time(NULL)),
			_c->received_host.len, _c->received_host.s,
			_c->received_port,
                        _c->path.len, _c->path.s,
			_c->received_proto,
                        _c->aorhash,
                        _c->sl);

	get_act_time();
        
        
        if ((_c->expires - act_time) + expires_grace <= 0) {//we've allowed some grace time TODO: add as parameter
        //if ((_c->expires - act_time) <= -10) {//we've allowed some grace time TODO: add as parameter
		LM_DBG("pcscf contact <%.*s> has expired and will be removed\n", _c->aor.len, _c->aor.s);
		if (exists_ulcb_type(PCSCF_CONTACT_EXPIRE)) {
			run_ul_callbacks(PCSCF_CONTACT_EXPIRE, _c);
		}

		if (db_mode == WRITE_THROUGH && db_delete_pcontact(_c) != 0) {
			LM_ERR("Error deleting ims_usrloc_pcscf record in DB");
		}

		update_stat(_c->slot->d->expired, 1);
		mem_delete_pcontact(_c->slot->d, _c);
		return;
	}

	//TODO: this is just for tmp debugging
//	p = _c->head;
//	while (p) {
//		if (p->is_default)
//			LM_DBG("public identity %i (default): <%.*s>\n", i, p->public_identity.len, p->public_identity.s);
//		else
//			LM_DBG("public identity %i: <%.*s>\n", i, p->public_identity.len, p->public_identity.s);
//		i++;
//		p=p->next;
//	}
//
//	LM_DBG("There are %i service routes as follows:\n", _c->num_service_routes);
//	for (i=0; i<_c->num_service_routes; i++) {
//		LM_DBG("service route %i: <%.*s>\n", i+1, _c->service_routes[i].len, _c->service_routes[i].s);
//	}
}
コード例 #7
0
ファイル: impurecord.c プロジェクト: Jared-Prime/kamailio
/*!
 * \brief Delete ucontact from impurecord
 * \param _r record where the contact belongs to
 * \param _c deleted contact
 * \return 0 on success, -1 on failure
 */
int delete_ucontact(impurecord_t* _r, struct ucontact* _c) {
    int ret = 0;
    
    if (exists_ulcb_type(_c->cbs, UL_CONTACT_DELETE)) {
        run_ul_callbacks(_c->cbs, UL_CONTACT_DELETE, _r, _c);
    }
    if (exists_ulcb_type(_r->cbs, UL_IMPU_DELETE_CONTACT)) {
        run_ul_callbacks(_r->cbs, UL_IMPU_DELETE_CONTACT, _r, _c);
    }

	/*DB?*/
	if (db_mode == WRITE_THROUGH && db_delete_ucontact(_r, _c) != 0) {
		LM_ERR("error removing contact from DB [%.*s]... will still remove from memory\n", _c->c.len, _c->c.s);

	}

    mem_delete_ucontact(_r, _c);

    return ret;
}
コード例 #8
0
ファイル: udomain.c プロジェクト: aallamaa/kamailio
int delete_pcontact(udomain_t* _d, str* _aor, struct pcontact* _c)
{
	if (_c==0) {
		if (get_pcontact(_d, _aor, &_c) > 0) {
			return 0;
		}
	}
	if (exists_ulcb_type(PCSCF_CONTACT_DELETE)) {
		run_ul_callbacks(PCSCF_CONTACT_DELETE, _c);
	}
	mem_delete_pcontact(_d, _c);

	return 0;
}
コード例 #9
0
ファイル: ucontact.c プロジェクト: SipSeb/kamailio
/*!
 * \brief Update ucontact with new values
 * \param _r record the contact belongs to
 * \param _c updated contact
 * \param _ci new contact informations
 * \return 0 on success, -1 on failure
 */
int update_ucontact(struct urecord* _r, ucontact_t* _c, ucontact_info_t* _ci)
{
    int res;

	/* we have to update memory in any case, but database directly
	 * only in db_mode 1 */
	if (mem_update_ucontact( _c, _ci) < 0) {
		LM_ERR("failed to update memory\n");
		return -1;
	}

	/* run callbacks for UPDATE event */
	if (exists_ulcb_type(UL_CONTACT_UPDATE))
	{
		LM_DBG("exists callback for type= UL_CONTACT_UPDATE\n");
		run_ul_callbacks( UL_CONTACT_UPDATE, _c);
	}

	if (_r && db_mode!=DB_ONLY)
		update_contact_pos( _r, _c);

	st_update_ucontact(_c);

	if (db_mode == WRITE_THROUGH || db_mode==DB_ONLY) {
		/*
		 * prevent problems when we're in a failover situation: the first DB contains
		 * the complete location entries, the other misses some of them. Before the
		 * update it checks for a entry in the first DB, this is ok. But the update
		 * in the second DB will not work. Thus the expire mechanism don't work, it
		 * takes too long until both DBs have the same number of entries again.
		 */
		if (ul_db_update_as_insert)
		    res = db_insert_ucontact(_c);
        else
            res = db_update_ucontact(_c);
        if (res < 0 ) 
        {
            LM_ERR("failed to update database\n");
            return -1;
        } else {
			_c->state = CS_SYNC;
		}
	}
	return 0;
}
コード例 #10
0
ファイル: urecord.c プロジェクト: SibghatullahSheikh/kamailio
/*
 * 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;
}
コード例 #11
0
ファイル: urecord.c プロジェクト: AndreyRybkin/kamailio
/*!
 * \brief Delete ucontact from urecord
 * \param _r record where the contact belongs to
 * \param _c deleted contact
 * \return 0 on success, -1 on failure
 */
int delete_ucontact(urecord_t* _r, struct ucontact* _c)
{
	int ret = 0;

	if (exists_ulcb_type(UL_CONTACT_DELETE)) {
		run_ul_callbacks( UL_CONTACT_DELETE, _c);
	}

	if (st_delete_ucontact(_c) > 0) {
		if (db_mode == WRITE_THROUGH || db_mode==DB_ONLY) {
			if (db_delete_ucontact(_c) < 0) {
				LM_ERR("failed to remove contact from database\n");
				ret = -1;
			}
		}

		mem_delete_ucontact(_r, _c);
	}

	return ret;
}
コード例 #12
0
ファイル: udomain.c プロジェクト: badwtg1111/kamailio
int delete_pcontact(udomain_t* _d, str* _aor, struct pcontact* _c)
{
	if (_c==0) {
		if (get_pcontact(_d, _aor, &_c) > 0) {
			return 0;
		}
	}

	if (exists_ulcb_type(PCSCF_CONTACT_DELETE)) {
		run_ul_callbacks(PCSCF_CONTACT_DELETE, _c);
	}

	if (db_mode == WRITE_THROUGH && db_delete_pcontact(_c) != 0) {
		LM_ERR("Error deleting contact from DB");
		return -1;
	}

	mem_delete_pcontact(_d, _c);

	return 0;
}
コード例 #13
0
ファイル: urecord.c プロジェクト: SibghatullahSheikh/kamailio
/*
 * Delete ucontact from urecord
 */
int delete_ucontact(urecord_t* _r, struct ucontact* _c)
{
	if (exists_ulcb_type(UL_CONTACT_DELETE)) {
		run_ul_callbacks( UL_CONTACT_DELETE, _c);
	}

	notify_watchers(_r, _c, PRES_OFFLINE);
	
	if (st_delete_ucontact(_c) > 0) {
		if (db_mode == WRITE_THROUGH) {
			if (db_delete_ucontact(_c) < 0) {
				LOG(L_ERR, "delete_ucontact(): Can't remove contact from "
							"database\n");
			}
		}

		delete_reg_avps(_c);
		mem_delete_ucontact(_r, _c);
	}

	return 0;
}
コード例 #14
0
ファイル: urecord.c プロジェクト: AndreyRybkin/kamailio
/*!
 * \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;
}
コード例 #15
0
ファイル: udomain.c プロジェクト: AlessioCasco/kamailio
/*!
 * \brief Delete a impurecord from domain
 * \param _d domain where the record should be deleted
 * \param _aor address of record
 * \param _r deleted record
 * \return 0 on success, -1 if the record could not be deleted
 */
int delete_impurecord(udomain_t* _d, str* _aor, struct impurecord* _r) {
    //    struct ucontact* c;//, *t;

    LM_DBG("Deleting IMPURECORD [%.*s]\n", _r->public_identity.len, _r->public_identity.s);

    if (_r == 0) {
	if (get_impurecord(_d, _aor, &_r) > 0) {
	    return 0;
	}
    }

    //TODO: need to unref the contacts in the contact list (not delete them), the timer should delete all contacts that are unreffed
    //    c = _r->contacts;
    //    while (c) {
    //	t = c;
    //	c = c->next;
    //	if (delete_ucontact(_r, t) < 0) {
    //	    LM_ERR("deleting contact failed [%.*s]\n", c->aor.len, c->aor.s);
    //	    return -1;
    //	}
    //    }

    if (exists_ulcb_type(_r->cbs, UL_IMPU_DELETE)) {
	run_ul_callbacks(_r->cbs, UL_IMPU_DELETE, _r, 0);
    }

    /*DB?*/
    if (db_mode == WRITE_THROUGH
	    && db_delete_impurecord(_d, _r) != 0) {
	LM_ERR("error deleting IMPU record from db");
	return 0;
    }

    mem_delete_impurecord(_d, _r);
    return 0;
}
コード例 #16
0
ファイル: udomain.c プロジェクト: Gitlab11/kamailio
/*!
 * \brief Delete a impurecord from domain
 * \param _d domain where the record should be deleted
 * \param _aor address of record - used only if _r in next param is null
 * \param _r deleted record to delete - if null will use the aor to search (assumed that domain is locked).
 * \return 0 on success, -1 if the record could not be deleted
 */
int delete_impurecord(udomain_t* _d, str* _aor, struct impurecord* _r) {
    LM_DBG("Deleting IMPURECORD [%.*s]\n", _r->public_identity.len, _r->public_identity.s);

    if (_r == 0) {
        LM_DBG("no impurecord passed in - let's search\n");
        if (get_impurecord(_d, _aor, &_r) != 0) {
            return 0;
        }
    }

    if (exists_ulcb_type(_r->cbs, UL_IMPU_DELETE)) {
        run_ul_callbacks(_r->cbs, UL_IMPU_DELETE, _r, 0);
    }

    /*DB?*/
    if (db_mode == WRITE_THROUGH
            && db_delete_impurecord(_d, _r) != 0) {
        LM_ERR("error deleting IMPU record from db...continuing to remove from memory\n");
    }

    mem_delete_impurecord(_d, _r);

    return 0;
}
コード例 #17
0
ファイル: urecord.c プロジェクト: SibghatullahSheikh/kamailio
/*
 * 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;
}
コード例 #18
0
ファイル: urecord.c プロジェクト: SibghatullahSheikh/kamailio
/*
 * Write-back timer
 */
static inline int wb_timer(urecord_t* _r)
{
	ucontact_t* ptr, *t;
	int op;
	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));
			if (ptr->next == 0) not=1;
			_r->slot->d->expired++;

			t = ptr;
			ptr = ptr->next;
			
			     /* Should we remove the contact from the database ? */
			if (st_expired_ucontact(t) == 1) {
				if (db_delete_ucontact(t) < 0) {
					LOG(L_ERR, "wb_timer(): Can't delete contact from the database\n");
				}
			}
			
			delete_reg_avps(t);
			mem_delete_ucontact(_r, t);
		} else {
			     /* Determine the operation we have to do */
			op = st_flush_ucontact(ptr);
			
			switch(op) {
			case 0: /* do nothing, contact is synchronized */
				break;

			case 1: /* insert */
				if (db_store_ucontact(ptr) < 0) {
					LOG(L_ERR, "wb_timer(): Error while inserting contact into database\n");
				}
				break;

			case 2: /* update */
				if (db_store_ucontact(ptr) < 0) {
					LOG(L_ERR, "wb_timer(): Error while updating contact in db\n");
				}
				break;

			case 4: /* delete */
				if (db_delete_ucontact(ptr) < 0) {
					LOG(L_ERR, "wb_timer(): Can't delete contact from database\n");
				}
				     /* fall through to the next case statement */

			case 3: /* delete from memory */
				delete_reg_avps(ptr);
				mem_delete_ucontact(_r, ptr);
				break;
			}

			ptr = ptr->next;
		}
	}

	return 0;
}
コード例 #19
0
ファイル: udomain.c プロジェクト: aallamaa/kamailio
int update_pcontact(struct udomain* _d, struct pcontact_info* _ci, struct pcontact* _c) //TODO: should prob move this to pcontact
{
	int is_default = 1;
	ppublic_t* ppublic_ptr;
	int i;

	_c->reg_state = _ci->reg_state;

	if (_ci->expires > 0) {
		_c->expires = _ci->expires;
	}

	if (_ci->num_service_routes > 0 && _ci->service_routes) {
		//replace all existing service routes
		if (_c->service_routes) { //remove old service routes
			for (i=0; i<_c->num_service_routes; i++) {
				if (_c->service_routes[i].s)
					shm_free(_c->service_routes[i].s);
				shm_free(_c->service_routes);
				_c->service_routes=0;
				_c->num_service_routes=0;
			}
		}
		//now add the new service routes
		if (_ci->num_service_routes > 0) {
			_c->service_routes = shm_malloc(_ci->num_service_routes*sizeof(str));
			if (!_c->service_routes) {
				LM_ERR("no more shm mem trying to allocate [%ld bytes]\n", _ci->num_service_routes*sizeof(str));
				goto out_of_memory;
			} else {
				for (i=0; i<_ci->num_service_routes; i++) {
					STR_SHM_DUP(_c->service_routes[i], _ci->service_routes[i], "update_pcontact");
				}
				_c->num_service_routes = _ci->num_service_routes;
			}
		}
	}

	if (_ci->num_public_ids > 0 && _ci->public_ids) {
		if (_c->head) {
			LM_DBG("ppublic's already exist.... .not updating\n");
		} else {
			for (i = 0; i < _ci->num_public_ids; i++) {
				if (i > 0)
					is_default = 0; //only the first one is default - P-Associated-uri (first one is default)
				if (new_ppublic(&_ci->public_ids[i], is_default, &ppublic_ptr) != 0) {
					LM_ERR("unable to create new ppublic\n");
				} else {
					insert_ppublic(_c, ppublic_ptr);
				}
			}
		}
	}

	// update received info (if info is available):
	if (_ci->received_host.len > 0) {
		if (_c->received_host.s)
			shm_free(_c->received_host.s);
		STR_SHM_DUP(_c->received_host, _ci->received_host, "update_pcontact");
	}
	if (_ci->received_port > 0) _c->received_port = _ci->received_port;
	if (_ci->received_proto > 0) _c->received_proto = _ci->received_proto;

	//TODO: update path, etc
	run_ul_callbacks(PCSCF_CONTACT_UPDATE, _c);
	return 0;

out_of_memory:
	return -1;
}
コード例 #20
0
ファイル: impurecord.c プロジェクト: Jared-Prime/kamailio
/* update an existing impurecord. if one doesnt exist it will be created.
 * make sure yuo lock the domain before calling this and unlock it afterwards
 * return: 0 on success, -1 on failure
 */
int update_impurecord(struct udomain* _d, str* public_identity, int reg_state, int send_sar_on_delete, int barring, int is_primary, ims_subscription** s, str* ccf1, str* ccf2, str* ecf1, str* ecf2, struct impurecord** _r) {
    int res;

    res = get_impurecord(_d, public_identity, _r);
    if (res != 0) {
        if (reg_state != IMPU_NOT_REGISTERED && s) {
            LM_DBG("No existing impu record for <%.*s>.... creating new one\n", public_identity->len, public_identity->s);
            res = insert_impurecord(_d, public_identity, reg_state, barring, s, ccf1, ccf2, ecf1, ecf2, _r);

            //for the first time we create an IMPU we must set the primary record (we don't worry about it on updates - ignored)
            (*_r)->is_primary = is_primary; //TODO = this should prob move to insert_impurecord fn

            if (reg_state == IMPU_UNREGISTERED) {
                //update unreg expiry so the unreg record is not stored 'forever'
                (*_r)->expires = time(NULL) + unreg_validity;
            }
            if (res != 0) {
                LM_ERR("Unable to insert new IMPU for <%.*s>\n", public_identity->len, public_identity->s);
                return -1;
            } else {
                run_ul_callbacks(NULL, UL_IMPU_INSERT, *_r, NULL);
                return 0;
            }
        } else {
            LM_DBG("no IMPU found to update and data not valid to create new one - not a problem record was probably removed as it has no contacts\n");
            return 0;
        }

    }

    //if we get here, we have a record to update
    LM_DBG("updating IMPU record with public identity for <%.*s>\n", public_identity->len, public_identity->s);
    (*_r)->reg_state = reg_state;
    if (reg_state == IMPU_UNREGISTERED) {
        //update unreg expiry so the unreg record is not stored 'forever'
        (*_r)->expires = time(NULL) + unreg_validity;
    }
    if (barring >= 0) (*_r)->barring = barring;
    
    if (send_sar_on_delete >= 0) (*_r)->send_sar_on_delete = send_sar_on_delete;
    
    if (ccf1) {
        if ((*_r)->ccf1.s)
            shm_free((*_r)->ccf1.s);
        STR_SHM_DUP((*_r)->ccf1, *ccf1, "SHM CCF1");
    }
    if (ccf2) {
        if ((*_r)->ccf2.s)
            shm_free((*_r)->ccf2.s);
        STR_SHM_DUP((*_r)->ccf2, *ccf2, "SHM CCF2");
    }
    if (ecf1) {
        if ((*_r)->ecf1.s)
            shm_free((*_r)->ecf1.s);
        STR_SHM_DUP((*_r)->ecf1, *ecf1, "SHM ECF1");
    }
    if (ecf2) {
        if ((*_r)->ecf2.s)
            shm_free((*_r)->ecf2.s);
        STR_SHM_DUP((*_r)->ecf2, *ecf2, "SHM ECF2");
    }

    if (s) {
        LM_DBG("we have a new ims_subscription\n");
        if ((*_r)->s) {
            lock_get((*_r)->s->lock);
            if ((*_r)->s->ref_count == 1) {
                LM_DBG("freeing user data as no longer referenced\n");
                free_ims_subscription_data((*_r)->s); //no need to release lock after this. its gone ;)
                (*_r)->s = 0;
            } else {
                (*_r)->s->ref_count--;
                LM_DBG("new ref count for ims sub is %d\n", (*_r)->s->ref_count);
                lock_release((*_r)->s->lock);
            }
        }
        (*_r)->s = *s;
        lock_get((*_r)->s->lock);
        (*_r)->s->ref_count++;
        lock_release((*_r)->s->lock);
    }

    run_ul_callbacks((*_r)->cbs, UL_IMPU_UPDATE, *_r, NULL);
    return 0;

out_of_memory:
    unlock_udomain(_d, public_identity);
    return -1;
}
コード例 #21
0
ファイル: impurecord.c プロジェクト: Jared-Prime/kamailio
/*!
 * \brief Expires timer for NO_DB db_mode
 *
 * Expires timer for NO_DB db_mode, process all contacts from
 * the record, delete the expired ones from memory.
 * \param _r processed record
 */
static inline void nodb_timer(impurecord_t* _r) {
    ucontact_t* ptr, *t;
    
    unsigned int hash_code = 0;

    reg_subscriber *s;
    subs_t* sub_dialog;

    get_act_time();

    s = _r->shead;
    LM_DBG("Checking validity of IMPU: <%.*s> registration subscriptions\n", _r->public_identity.len, _r->public_identity.s);
    while (s) {
        if (!valid_subscriber(s)) {
            LM_DBG("DBG:registrar_timer: Subscriber with watcher_contact <%.*s> and presentity uri <%.*s> expired and removed.\n",
                    s->watcher_contact.len, s->watcher_contact.s, s->presentity_uri.len, s->presentity_uri.s);
            delete_subscriber(_r, s);
        } else {
            LM_DBG("DBG:registrar_timer: Subscriber with watcher_contact <%.*s> and presentity uri <%.*s> is valid and expires in %d seconds.\n",
                    s->watcher_contact.len, s->watcher_contact.s, s->presentity_uri.len, s->presentity_uri.s,
                    (unsigned int) (s->expires - time(NULL)));
	    hash_code = core_hash(&s->call_id, &s->to_tag, sub_dialog_hash_size);
	    LM_DBG("Hash size: <%i>", sub_dialog_hash_size);
	    LM_DBG("Searching sub dialog hash info with call_id: <%.*s> and ttag <%.*s> ftag <%.*s> and hash code <%i>", s->call_id.len, s->call_id.s, s->to_tag.len, s->to_tag.s, s->from_tag.len, s->from_tag.s, hash_code);
	    /* search the record in hash table */
	    lock_get(&sub_dialog_table[hash_code].lock);
	    sub_dialog= pres_search_shtable(sub_dialog_table, s->call_id, s->to_tag, s->from_tag, hash_code);
	    if(sub_dialog== NULL)
	    {
		LM_ERR("DBG:registrar_timer: Subscription has no dialog record in hash table\n");
	    }else {
		LM_DBG("DBG:registrar_timer: Subscription has dialog record in hash table with presentity uri <%.*s>\n", sub_dialog->pres_uri.len, sub_dialog->pres_uri.s);
	    }
	    
	    lock_release(&sub_dialog_table[hash_code].lock);
        }
        s = s->next;
    }

    ptr = _r->contacts;
    LM_DBG("Checking validity of IMPU: <%.*s> contacts\n", _r->public_identity.len, _r->public_identity.s);

    while (ptr) {
        if (!VALID_CONTACT(ptr, act_time)) {
            /* run callbacks for EXPIRE event */
            if (exists_ulcb_type(ptr->cbs, UL_CONTACT_EXPIRE))
                run_ul_callbacks(ptr->cbs, UL_CONTACT_EXPIRE, _r, ptr);

            if (exists_ulcb_type(_r->cbs, UL_IMPU_EXPIRE_CONTACT)) {
                run_ul_callbacks(_r->cbs, UL_IMPU_EXPIRE_CONTACT, _r, ptr);
            }

            LM_DBG("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;

			if (db_mode == WRITE_THROUGH && db_delete_ucontact(_r, t) != 0) {
				LM_ERR("error removing contact from DB [%.*s]... will still remove from memory\n", t->c.len, t->c.s);
			}

            mem_delete_ucontact(_r, t);
            update_stat(_r->slot->d->expires, 1);
        } else {
            LM_DBG("IMPU:<%.*s> - contact:<%.*s> is valid and expires in %d seconds\n", _r->public_identity.len, _r->public_identity.s,
                    ptr->c.len, ptr->c.s,
                    (unsigned int) (ptr->expires - time(NULL)));
            ptr = ptr->next;
        }
    }
}
コード例 #22
0
ファイル: impurecord.c プロジェクト: nakchak/kamailio
/*!
 * \brief Expires timer for NO_DB db_mode
 *
 * Expires timer for NO_DB db_mode, process all contacts from
 * the record, delete the expired ones from memory.
 * \param _r processed record
 */
static inline void process_impurecord(impurecord_t* _r) {
    int flag, mustdeleteimpu = 1, n, k;
    unsigned int sl;
    ucontact_t* ptr;
    int hascontacts;
    udomain_t* _d;
    reg_subscriber *s;
    subs_t* sub_dialog;

    get_act_time();

    s = _r->shead;
    LM_DBG("Checking validity of IMPU: <%.*s> registration subscriptions\n", _r->public_identity.len, _r->public_identity.s);
    while (s) {
        if (!valid_subscriber(s, act_time)) {
            LM_DBG("DBG:registrar_timer: Subscriber with watcher_contact <%.*s> and presentity uri <%.*s> expired and removed.\n",
                   s->watcher_contact.len, s->watcher_contact.s, s->presentity_uri.len, s->presentity_uri.s);
            delete_subscriber(_r, s);
        } else {
            LM_DBG("DBG:registrar_timer: Subscriber with watcher_contact <%.*s> and presentity uri <%.*s> is valid and expires in %d seconds.\n",
                   s->watcher_contact.len, s->watcher_contact.s, s->presentity_uri.len, s->presentity_uri.s,
                   (unsigned int) (s->expires - time(NULL)));
            sl = core_hash(&s->call_id, &s->to_tag, sub_dialog_hash_size);
            LM_DBG("Hash size: <%i>", sub_dialog_hash_size);
            LM_DBG("Searching sub dialog hash info with call_id: <%.*s> and ttag <%.*s> ftag <%.*s> and hash code <%i>", s->call_id.len, s->call_id.s, s->to_tag.len, s->to_tag.s, s->from_tag.len, s->from_tag.s, sl);
            /* search the record in hash table */
            lock_get(&sub_dialog_table[sl].lock);
            sub_dialog = pres_search_shtable(sub_dialog_table, s->call_id, s->to_tag, s->from_tag, sl);
            if (sub_dialog == NULL) {
                LM_ERR("DBG:registrar_timer: Subscription has no dialog record in hash table\n");
            } else {
                LM_DBG("DBG:registrar_timer: Subscription has dialog record in hash table with presentity uri <%.*s>\n", sub_dialog->pres_uri.len, sub_dialog->pres_uri.s);
            }
            lock_release(&sub_dialog_table[sl].lock);
            mustdeleteimpu = 0;
        }
        s = s->next;
    }

    LM_DBG("\tPublic Identity %.*s, Barred: [%d], State: [%s]\n",
           _r->public_identity.len, _r->public_identity.s,
           _r->barring,
           get_impu_regstate_as_string(_r->reg_state));
    flag = 0;
    hascontacts = 0;
    num_contacts_to_expire = 0;
    for (k = 0; (k < _r->num_contacts) && (k < MAX_CONTACTS_PER_IMPU); k++) {
        if ((ptr = _r->newcontacts[k])) {
            flag = 1;
            if (!VALID_CONTACT(ptr, act_time)) {
                if (ptr->state == CONTACT_DELETED) {
                    LM_DBG("Contact: <%.*s> has been deleted - unlinking from IMPU\n", ptr->c.len, ptr->c.s);
                    contacts_to_expire[num_contacts_to_expire] = ptr;
                    num_contacts_to_expire++;
                } else if (ptr->state == CONTACT_EXPIRE_PENDING_NOTIFY) {
                    LM_DBG("Contact: <%.*s> is in state CONTACT_EXPIRE_PENDING_NOTIFY....running callback\n", ptr->c.len, ptr->c.s);
                    if (exists_ulcb_type(_r->cbs, UL_IMPU_DELETE_CONTACT)) {
                        LM_DBG("Running callback UL_IMPU_DELETE_CONTACT for contact [%.*s] and impu [%.*s]\n", ptr->c.len, ptr->c.s, _r->public_identity.len, _r->public_identity.s);
                        run_ul_callbacks(_r->cbs, UL_IMPU_DELETE_CONTACT, _r, ptr);
                    }
                    hascontacts = 1;    // we do this because the impu must only be deleted if in state deleted....
                    mustdeleteimpu = 0;
                } else if (ptr->state == CONTACT_VALID) {
                    LM_DBG("Contact: <%.*s> is in state valid but it has expired.... ignoring as the contact check will set the appropriate action/state\n", ptr->c.len, ptr->c.s);
                    mustdeleteimpu = 0;
                    hascontacts = 1;
                } else {
                    LM_WARN("Bogus state for contact [%.*s] - state: %d... ignoring", ptr->c.len, ptr->c.s, ptr->state);
                    mustdeleteimpu = 0;
                    hascontacts = 1;
                }
            } else {
                LM_DBG("\t\tContact #%i - %.*s, Ref [%d] (expires in %ld seconds) (State: %d)\n",
                       k, ptr->c.len, ptr->c.s, ptr->ref_count, ptr->expires - act_time, ptr->state);
                mustdeleteimpu = 0;
                hascontacts = 1;
            }
        } else {
            LM_WARN("num_contacts and actual data not consistent... .aborting\n");
            break;
        }
    }

    if (num_contacts_to_expire > 0) {
        LM_DBG("\tThere are %d contacts to expire/unlink\n", num_contacts_to_expire);
        for (n = 0; n < num_contacts_to_expire; n++) {
            ptr = contacts_to_expire[n];
            LM_DBG("\t\texpiring contact %i: [%.*s] in slot [%d]\n", n, contacts_to_expire[n]->c.len, contacts_to_expire[n]->c.s, contacts_to_expire[n]->sl);
            sl = ptr->sl;
            lock_contact_slot_i(sl);
            unlink_contact_from_impu(_r, ptr, 1, 0 /*implicit dereg of contact from IMPU*/);
            unlock_contact_slot_i(sl);
        }
    }

    if (!flag)
        LM_DBG("no contacts\n");

    if (mustdeleteimpu) {
        register_udomain("location", &_d);
        delete_impurecord(_d, &_r->public_identity, _r);
    } else {
        if (!hascontacts) {
            LM_DBG("This impu is not to be deleted but has no contacts - changing state to IMPU_UNREGISTERED\n");
            _r->reg_state = IMPU_UNREGISTERED;
        }
    }
}