Example #1
0
/*
 * Create an AVP to be used by registrar with the source IP and port
 * of the REGISTER
 */
static int
fix_nated_register_f(struct sip_msg* msg, char* str1, char* str2)
{
	contact_t* c;
	struct lump* anchor;
	char* param;
	str uri;

	if (create_rcv_uri(&uri, msg) < 0) {
		return -1;
	}

	if (contact_iterator(&c, msg, 0) < 0) {
		return -1;
	}

	while(c) {
		param = (char*)pkg_malloc(RECEIVED_LEN + 2 + uri.len);
		if (!param) {
			ERR("No memory left\n");
			return -1;
		}
		memcpy(param, RECEIVED, RECEIVED_LEN);
		param[RECEIVED_LEN] = '\"';
		memcpy(param + RECEIVED_LEN + 1, uri.s, uri.len);
		param[RECEIVED_LEN + 1 + uri.len] = '\"';

		anchor = anchor_lump(msg, c->name.s + c->len - msg->buf, 0, 0);
		if (anchor == NULL) {
			ERR("anchor_lump failed\n");
			return -1;
		}

		if (insert_new_lump_after(anchor, param, RECEIVED_LEN + 1 + uri.len + 1, 0) == 0) {
			ERR("insert_new_lump_after failed\n");
			pkg_free(param);
			return -1;
		}

		if (contact_iterator(&c, msg, c) < 0) {
			return -1;
		}
	}

	return 1;
}
Example #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, str* aor, contact_t* _c, str* _ua, str* aor_filter)
{
	ucontact_t* c, *c2;
	str callid;
	int cseq, e, ret;
	int set, reset;
	qvalue_t q;
	unsigned int nated;
	str* recv, *inst;
	
	if (isflagset(_m, save_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, aor_filter);
			return -1;
		}
	}

	_c = get_first_contact(_m);

	while(_c) {
		if (calc_contact_expires(_m, _c->expires, &e) < 0) {
			build_contact(_r->contacts, aor_filter);
			LOG(L_ERR, "update(): Error while calculating expires\n");
			return -1;
		}

		if(_c->instance) {
			inst = &_c->instance->body;
		} else {
			inst = 0;
		}

		if (ul.get_ucontact_by_instance(_r, &_c->uri, inst, &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 (nated & FL_NAT) {
					if (create_rcv_uri(&recv, _m) < 0) {
						ERR("Error while creating rcv URI\n");
						rerrno = R_UL_INS_C;
						return -4;
					}
				} else {
					recv = 0;
				}

				if (ul.insert_ucontact(_r, aor, &_c->uri, e, q, &callid, cseq, 
						       nated | mem_only,
						       &c2, _ua, recv, 
						       _m->rcv.bind_address,
							   inst) < 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 (nated & FL_NAT) {
					if (create_rcv_uri(&recv, _m) < 0) {
						ERR("Error while creating rcv URI\n");
					        rerrno = R_UL_UPD_C;
						return -4;
					}
				} else {
					recv = 0;
				}

				set = nated | mem_only;
				reset = ~(nated | mem_only) & (FL_NAT | FL_MEM);
				if (ul.update_ucontact(c, &_c->uri, aor, e, q, &callid, cseq, set, reset, _ua, recv, _m->rcv.bind_address, inst) < 0) {
					rerrno = R_UL_UPD_C;
					LOG(L_ERR, "update(): Error while updating contact\n");
					return -8;
				}
			}
		}
		_c = get_next_contact(_c);
	}

	return 0;
}
Example #3
0
/*
 * Message contained some contacts, but record with same address
 * of record was not found so we have to create a new record
 * and insert all contacts from the message that have expires
 * > 0
 */
static inline int insert(struct sip_msg* _m, str* aor, contact_t* _c, udomain_t* _d, str* _u, str *ua, str* aor_filter)
{
	urecord_t* r = 0;
	ucontact_t* c;
	int e, cseq;
	qvalue_t q;
	str callid;
	unsigned int flags;
	str *recv, *inst;
	int num;

	if (isflagset(_m, save_nat_flag) == 1) flags = FL_NAT;
	else flags = FL_NONE;

	flags |= mem_only;

	num = 0;
	while(_c) {
		if (calc_contact_expires(_m, _c->expires, &e) < 0) {
			LOG(L_ERR, "insert(): Error while calculating expires\n");
			return -1;
		}
		     /* Skip contacts with zero expires */
		if (e == 0) goto skip;

		if (max_contacts && (num >= max_contacts)) {
			rerrno = R_TOO_MANY;
			ul.delete_urecord(_d, _u);
			return -1;
		}
		num++;
		
	        if (r == 0) {
			if (ul.insert_urecord(_d, _u, &r) < 0) {
				rerrno = R_UL_NEW_R;
				LOG(L_ERR, "insert(): Can't insert new record structure\n");
				return -2;
			}
		}
		
		     /* Calculate q value of the contact */
		if (calc_contact_q(_c->q, &q) < 0) {
			LOG(L_ERR, "insert(): Error while calculating q\n");
			ul.delete_urecord(_d, _u);
			return -3;
		}

		     /* Get callid of the message */
		callid = _m->callid->body;	
		trim_trailing(&callid);
		
		     /* Get CSeq number of the message */
		if (str2int(&get_cseq(_m)->number, (unsigned int*)&cseq) < 0) {
			rerrno = R_INV_CSEQ;
			LOG(L_ERR, "insert(): Error while converting cseq number\n");
			ul.delete_urecord(_d, _u);
			return -4;
		}

		if (_c->received) {
			recv = &_c->received->body;
		} else if (flags & FL_NAT) {
			if (create_rcv_uri(&recv, _m) < 0) {
				ERR("Error while creating rcv URI\n");
				ul.delete_urecord(_d, _u);
				return -4;
			}
		} else {
			recv = 0;
		}

		if(_c->instance) {
			inst = &_c->instance->body;
		} else {
			inst = 0;
		}

		if (ul.insert_ucontact(r, aor, &_c->uri, e, q, &callid, cseq, flags, &c, ua, recv, 
				       _m->rcv.bind_address, inst) < 0) {
			rerrno = R_UL_INS_C;
			LOG(L_ERR, "insert(): Error while inserting contact\n");
			ul.delete_urecord(_d, _u);
			return -5;
		}
		
	skip:
		_c = get_next_contact(_c);
	}
	
	if (r) {
		if (!r->contacts) {
			ul.delete_urecord(_d, _u);
		} else {
			build_contact(r->contacts, aor_filter);
		}
	}
	
	return 0;
}