/* * Message contained some contacts and appropriate * record was found, so we have to walk through * all contacts and do the following: * 1) If contact in usrloc doesn't exists and * expires > 0, insert new contact * 2) If contact in usrloc exists and expires * > 0, update the contact * 3) If contact in usrloc exists and expires * == 0, delete contact */ static inline int update(struct sip_msg* _m, urecord_t* _r, contact_t* _c, str* _ua) { ucontact_t* c, *c2; str callid; int cseq, e, ret; int set, reset; qvalue_t q; unsigned int nated; str* recv; int_str rcv_avp; int_str val; rcv_avp.n=rcv_avp_no; if (isflagset(_m, nat_flag) == 1) { nated = FL_NAT; } else { nated = FL_NONE; } if (max_contacts) { ret = test_max_contacts(_m, _r, _c); if (ret != 0) { build_contact(_r->contacts); return -1; } } _c = get_first_contact(_m); while(_c) { if (calc_contact_expires(_m, _c->expires, &e) < 0) { build_contact(_r->contacts); LOG(L_ERR, "update(): Error while calculating expires\n"); return -1; } if (ul.get_ucontact(_r, &_c->uri, &c) > 0) { /* Contact not found */ if (e != 0) { /* Calculate q value of the contact */ if (calc_contact_q(_c->q, &q) < 0) { LOG(L_ERR, "update(): Error while calculating q\n"); return -2; } /* Get callid of the message */ callid = _m->callid->body; trim_trailing(&callid); /* Get CSeq number of the message */ if (str2int(&(((struct cseq_body*)_m->cseq->parsed)->number), (unsigned int*) &cseq) < 0) { rerrno = R_INV_CSEQ; LOG(L_ERR, "update(): Error while converting cseq number\n"); return -3; } if (_c->received) { recv = &_c->received->body; } else if (search_first_avp(0, rcv_avp, &val)) { recv = val.s; } else { recv = 0; } if (ul.insert_ucontact(_r, &_c->uri, e, q, &callid, cseq, nated | mem_only, &c2, _ua, recv) < 0) { rerrno = R_UL_INS_C; LOG(L_ERR, "update(): Error while inserting contact\n"); return -4; } } } else { if (e == 0) { if (mem_only) { c->flags |= FL_MEM; } else { c->flags &= ~FL_MEM; } if (ul.delete_ucontact(_r, c) < 0) { rerrno = R_UL_DEL_C; LOG(L_ERR, "update(): Error while deleting contact\n"); return -5; } } else { /* Calculate q value of the contact */ if (calc_contact_q(_c->q, &q) < 0) { LOG(L_ERR, "update(): Error while calculating q\n"); return -6; } /* Get callid of the message */ callid = _m->callid->body; trim_trailing(&callid); /* Get CSeq number of the message */ if (str2int(&(((struct cseq_body*)_m->cseq->parsed)->number), (unsigned int*)&cseq) < 0) { rerrno = R_INV_CSEQ; LOG(L_ERR, "update(): Error while converting cseq number\n"); return -7; } if (_c->received) { recv = &_c->received->body; } else if (search_first_avp(0, rcv_avp, &val)) { recv = val.s; } else { recv = 0; } set = nated | mem_only; reset = ~(nated | mem_only) & (FL_NAT | FL_MEM); if (ul.update_ucontact(c, e, q, &callid, cseq, set, reset, _ua, recv) < 0) { rerrno = R_UL_UPD_C; LOG(L_ERR, "update(): Error while updating contact\n"); return -8; } if (desc_time_order) { move_on_top(_r, c); } } } _c = get_next_contact(_c); } return 0; }
/* * Message contained some contacts and appropriate * record was found, so we have to walk through * all contacts and do the following: * 1) If contact in usrloc doesn't exists and * expires > 0, insert new contact * 2) If contact in usrloc exists and expires * > 0, update the contact * 3) If contact in usrloc exists and expires * == 0, delete contact */ static inline int update(struct sip_msg* _m, urecord_t* _r, contact_t* _c, str* _ua) { ucontact_t* c, *c2; str callid; int cseq, e; int set, reset; qvalue_t q; unsigned int flags; str* recv; int_str rcv_avp; int_str val; struct socket_info *sock; rcv_avp.n=rcv_avp_no; /* is nated flag */ if (nat_flag!=-1 && _m->flags&nat_flag) flags = FL_NAT; else flags = FL_NONE; /* nat type flag */ if (sip_natping_flag!=-1 && _m->flags&sip_natping_flag) flags |= FL_NAT_SIPPING; if (max_contacts) { if (test_max_contacts(_m, _r, _c) != 0 ) return -1; } _c = get_first_contact(_m); while(_c) { if (calc_contact_expires(_m, _c->expires, &e) < 0) { LOG(L_ERR, "update(): Error while calculating expires\n"); return -1; } if (ul.get_ucontact(_r, &_c->uri, &c) > 0) { /* Contact not found */ if (e != 0) { /* Calculate q value of the contact */ if (calc_contact_q(_c->q, &q) < 0) { LOG(L_ERR, "update(): Error while calculating q\n"); return -2; } /* Get callid of the message */ callid = _m->callid->body; trim_trailing(&callid); /* Get CSeq number of the message */ if (str2int(&(((struct cseq_body*)_m->cseq->parsed)->number), (unsigned int*) &cseq) < 0) { rerrno = R_INV_CSEQ; LOG(L_ERR, "update(): Error while converting cseq number\n"); return -3; } if (_c->received) { recv = &_c->received->body; } else if (search_first_avp(0, rcv_avp, &val)) { recv = val.s; } else { recv = 0; } if (sock_flag!=-1 && (_m->flags&sock_flag)!=0) { sock = get_sock_hdr(_m); if (sock==0) sock = _m->rcv.bind_address; } else { sock = _m->rcv.bind_address; } if (ul.insert_ucontact(_r, &_c->uri, e, q, &callid, cseq, flags | mem_only, &c2, _ua, recv, sock) < 0) { rerrno = R_UL_INS_C; LOG(L_ERR, "update(): Error while inserting contact\n"); return -4; } } } else { if (e == 0) { if (mem_only) { c->flags |= FL_MEM; } else { c->flags &= ~FL_MEM; } if (ul.delete_ucontact(_r, c) < 0) { rerrno = R_UL_DEL_C; LOG(L_ERR, "update(): Error while deleting contact\n"); return -5; } } else { /* Calculate q value of the contact */ if (calc_contact_q(_c->q, &q) < 0) { LOG(L_ERR, "update(): Error while calculating q\n"); return -6; } /* Get callid of the message */ callid = _m->callid->body; trim_trailing(&callid); /* Get CSeq number of the message */ if (str2int(&(((struct cseq_body*)_m->cseq->parsed)->number), (unsigned int*)&cseq) < 0) { rerrno = R_INV_CSEQ; LOG(L_ERR,"update(): Error while converting cseq number\n"); return -7; } if (_c->received) { recv = &_c->received->body; } else if (search_first_avp(0, rcv_avp, &val)) { recv = val.s; } else { recv = 0; } if (sock_flag!=-1 && (_m->flags&sock_flag)!=0) { sock = get_sock_hdr(_m); if (sock==0) sock = _m->rcv.bind_address; } else { sock = _m->rcv.bind_address; } set = flags | mem_only; reset = ~(flags | mem_only) & (FL_NAT|FL_MEM|FL_NAT_SIPPING); if (ul.update_ucontact(c, e, q, &callid, cseq, set, reset, _ua, recv, sock) < 0) { rerrno = R_UL_UPD_C; LOG(L_ERR, "update(): Error while updating contact\n"); return -8; } if (desc_time_order) { move_on_top(_r, c); } } } _c = get_next_contact(_c); } return 0; }