Exemplo n.º 1
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;
}
Exemplo n.º 2
0
/*!
 * \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;
		}
	}
}
Exemplo n.º 3
0
/*!
 * \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;
		}
	}
}
Exemplo n.º 4
0
/*!
 * \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_scontact(struct ucontact* _c) {
    int ret = 0;

    LM_DBG("Deleting contact: [%.*s]\n", _c->c.len, _c->c.s);
    /*DB?*/
    if (db_mode == WRITE_THROUGH && db_delete_ucontact(_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(_c);

    return ret;
}
Exemplo n.º 5
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;
}
Exemplo n.º 6
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;
}
Exemplo n.º 7
0
/*!
 * \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;
}
Exemplo n.º 8
0
/*!
 * \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;
}
Exemplo n.º 9
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;
}
Exemplo n.º 10
0
/*
 * 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;
}
Exemplo n.º 11
0
/*
 * Delete ucontact from urecord
 */
int delete_ucontact(urecord_t* _r, struct ucontact* _c)
{
	struct ucontact* ptr;

	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");
			}
		}
		mem_delete_ucontact(_r, _c);
	}

	ptr = _r->contacts;
	while(ptr) {
		if (ptr->state < CS_ZOMBIE_N) return 0;
		ptr = ptr->next;
	}
	notify_watchers(_r, PRES_OFFLINE);

	return 0;
}
Exemplo n.º 12
0
/*
 * 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;
}
Exemplo n.º 13
0
/*!
 * \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;
        }
    }
}
Exemplo n.º 14
0
/*
 * 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;
}
Exemplo n.º 15
0
/*
 * 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 (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_ZOMBIE_N) not=1;

				ptr = ptr->next;
			}
			else {
					/* state == ZOMBIE the contact was remove by user */
				if (ptr->state < CS_ZOMBIE_N) { 
					LOG(L_NOTICE, "Binding '%.*s','%.*s' has expired\n",
					    ptr->aor->len, ZSW(ptr->aor->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");
					}
				}

				mem_delete_ucontact(_r, t);
			}
			if (not) notify_watchers(_r, PRES_OFFLINE);
		} 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_insert_ucontact(ptr) < 0) {
					LOG(L_ERR, "wb_timer(): Error while inserting contact into database\n");
				}
				break;

			case 2: /* update */
				if (db_update_ucontact(ptr) < 0) {
					LOG(L_ERR, "wb_timer(): Error while updating contact in db\n");
				}
				break;
			case 3: /* delete from memory */
				mem_delete_ucontact(_r, ptr);
				break;
			case 4: /* delete */
				if (db_delete_ucontact(ptr) < 0) {
					LOG(L_ERR, "wb_timer(): Can't delete contact from database\n");
				}
				mem_delete_ucontact(_r, ptr);
				break;
			}

			ptr = ptr->next;
		}
	}

	return 0;
}