Example #1
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;
        }
    }
}
Example #2
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 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;
        }
    }
}