Exemplo n.º 1
0
/*!
 * \brief Get pointer to ucontact with given contact
 * \param _r record where to search the contacts
 * \param _c contact string
 * \param _callid callid
 * \param _path path
 * \param _cseq CSEQ number
 * \param _co found contact
 * \return 0 - found, 1 - not found, -1 - invalid found,
 * -2 - found, but to be skipped (same cseq) - don't forget to release_ucontact so dec. the ref counter
 */
int get_scontact(str* _c, str* _callid, str* _path, int _cseq, struct ucontact** _co) {
    unsigned int sl;
    ucontact_t* ptr;
    int with_callid = 0;
    ptr = 0;
    *_co = 0;

    sl = core_hash(_c, 0, contact_list->size);
    LM_DBG("looking for contact [%.*s] in slot %d\n", _c->len, _c->s, sl);
    get_act_time();

    lock_contact_slot_i(sl);

    switch (matching_mode) {
    case CONTACT_ONLY:
        ptr = contact_match(sl, _c);
        break;
    case CONTACT_CALLID:
        ptr = contact_callid_match(sl, _c, _callid);
        with_callid = 1;
        break;
    case CONTACT_PATH:
        ptr = contact_path_match(sl, _c, _path);
        break;
    case CONTACT_PORT_IP_ONLY:
        ptr = contact_port_ip_match(sl, _c);
        break;
    default:
        LM_CRIT("unknown matching_mode %d\n", matching_mode);
        unlock_contact_slot_i(sl);
        return -1;
    }

    if (ptr) {
        LM_DBG("have partially found a contact\n");
        /* found -> check callid and cseq */
        if (!with_callid || (_callid && ptr->callid.len == _callid->len
                             && memcmp(_callid->s, ptr->callid.s, _callid->len) == 0)) {
            if (_cseq < ptr->cseq) {
                LM_DBG("cseq less than expected\n");
            }

        }
        LM_DBG("contact found p=[%p], aor:[%.*s] and contact:[%.*s], state [%d]\n", ptr, ptr->aor.len, ptr->aor.s, ptr->c.len, ptr->c.s, ptr->state);
        ref_contact_unsafe(ptr);
        *_co = ptr;
        unlock_contact_slot_i(sl); /*TODO: we probably need to ref count here..... */
        return 0;
    }
    unlock_contact_slot_i(sl);

    return 1;
}
Exemplo n.º 2
0
/*!
+ * \brief Match a contact record to a contact string and path
+ * \param ptr contact record
+ * \param _c contact string
+ * \param _path path
+ * \return ptr on successfull match, 0 when they not match
+ */
static inline struct ucontact* contact_path_match(ucontact_t* ptr, str* _c, str *_path) {
    /* if no path is preset (in REGISTER request) or use_path is not configured
       in registrar module, default to contact_match() */
    if (_path == NULL) return contact_match(ptr, _c);

    while (ptr) {
        if ((_c->len == ptr->c.len) && (_path->len == ptr->path.len)
                && !memcmp(_c->s, ptr->c.s, _c->len)
                && !memcmp(_path->s, ptr->path.s, _path->len)
                ) {
            return ptr;
        }

        ptr = ptr->next;
    }
    return 0;
}
Exemplo n.º 3
0
/*!
 * \brief Get pointer to ucontact with given contact
 * \param _r record where to search the contacts
 * \param _c contact string
 * \param _callid callid
 * \param _path path
 * \param _cseq CSEQ number
 * \param _co found contact
 * \return 0 - found, 1 - not found, -1 - invalid found,
 * -2 - found, but to be skipped (same cseq)
 */
int get_ucontact(impurecord_t* _r, str* _c, str* _callid, str* _path, int _cseq, struct ucontact** _co) {
    ucontact_t* ptr;
    int no_callid;

    ptr = 0;
    no_callid = 0;
    *_co = 0;

    switch (matching_mode) {
        case CONTACT_ONLY:
            ptr = contact_match(_r->contacts, _c);
            break;
        case CONTACT_CALLID:
            ptr = contact_callid_match(_r->contacts, _c, _callid);
            no_callid = 1;
            break;
        case CONTACT_PATH:
            ptr = contact_path_match(_r->contacts, _c, _path);
            break;
	case CONTACT_PORT_IP_ONLY:
	    ptr = contact_port_ip_match(_r->contacts, _c);
	    break;
        default:
            LM_CRIT("unknown matching_mode %d\n", matching_mode);
            return -1;
    }

    if (ptr) {
        /* found -> check callid and cseq */
        if (no_callid || (ptr->callid.len == _callid->len
                && memcmp(_callid->s, ptr->callid.s, _callid->len) == 0)) {
            if (_cseq < ptr->cseq)
                return -1;
            if (_cseq == ptr->cseq) {
                get_act_time();
                return (ptr->last_modified + cseq_delay > act_time) ? -2 : -1;
            }
        }
        *_co = ptr;
        return 0;
    }

    return 1;
}
Exemplo n.º 4
0
/*!
+ * \brief Match a contact record to a contact string and path
+ * \param ptr contact record
+ * \param _c contact string
+ * \param _path path
+ * \return ptr on successfull match, 0 when they not match
+ */
static inline struct ucontact* contact_path_match(unsigned int slot, str* _c, str *_path) {
    ucontact_t* ptr = contact_list->slot[slot].first;
    /* if no path is preset (in REGISTER request) or use_path is not configured
       in registrar module, default to contact_match() */
    if (_path == NULL) return contact_match(slot, _c);

    while (ptr) {
        if ((_c->len == ptr->c.len) && (_path->len == ptr->path.len)
                && !memcmp(_c->s, ptr->c.s, _c->len)
                && !memcmp(_path->s, ptr->path.s, _path->len)
                && VALID_CONTACT(ptr, act_time)
           ) {
            return ptr;
        }

        ptr = ptr->next;
    }
    return 0;
}