Exemplo n.º 1
0
Arquivo: save.c Projeto: OPSF/uClinux
/*
 * 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;
}
Exemplo n.º 2
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;
}