Example #1
0
struct proxy_l* mk_proxy(str* name, unsigned short port, unsigned short proto,
		int is_sips)
{
	struct proxy_l* p;
	struct hostent* he;

	p=(struct proxy_l*) pkg_malloc(sizeof(struct proxy_l));
	if (p==0){
		ser_error=E_OUT_OF_MEM;
		LM_CRIT("pkg memory allocation failure\n");
		goto error;
	}
	memset(p,0,sizeof(struct proxy_l));
	p->name=*name;
	p->port=port;
	p->proto=proto;

	LM_DBG("doing DNS lookup...\n");
	he = sip_resolvehost(name, &(p->port), &p->proto, is_sips,
		disable_dns_failover?0:&p->dn );
	if (he==0){
		ser_error=E_BAD_ADDRESS;
		LM_CRIT("could not resolve hostname: \"%.*s\"\n", name->len, name->s);
		pkg_free(p);
		goto error;
	}
	if (hostent_cpy(&(p->host), he)!=0){
		free_dns_res( p );
		pkg_free(p);
		goto error;
	}
	return p;
error:
	return 0;
}
Example #2
0
struct proxy_l* mk_proxy(str* name, unsigned short port, int proto)
{
	struct proxy_l* p;
	struct hostent* he;

	p=(struct proxy_l*) pkg_malloc(sizeof(struct proxy_l));
	if (p==0){
		ser_error=E_OUT_OF_MEM;
		LOG(L_CRIT, "ERROR: mk_proxy: memory allocation failure\n");
		goto error;
	}
	memset(p,0,sizeof(struct proxy_l));
	p->name=*name;
	p->port=port;
	p->proto=proto;

	DBG("DEBUG: mk_proxy: doing DNS lookup...\n");
	he=sip_resolvehost(name, &(p->port), proto);
	if (he==0){
		ser_error=E_BAD_ADDRESS;
		LOG(L_CRIT, "ERROR: mk_proxy: could not resolve hostname:"
					" \"%.*s\"\n", name->len, name->s);
		pkg_free(p);
		goto error;
	}
	if (hostent_cpy(&(p->host), he)!=0){
		pkg_free(p);
		goto error;
	}
	p->ok=1;
	return p;
error:
	return 0;
}
Example #3
0
/**
 * _remove - Delete an entire AOR entry or just one or more of its Contacts
 * Parameter format: _remove(domain, AOR[, Contact URI or plain hostname])
 *
 * @udomain:     (udomain_t *)
 * @aor_gp:      address-of-record as a SIP URI (plain string or pvar)
 * @contact_gp:  contact to be deleted or domain in front of multiple contacts
 *
 * @return:      1 on success, negative on failure
 */
int _remove(struct sip_msg *msg, char *udomain, char *aor_gp, char *contact_gp)
{
	struct sip_uri puri;
	struct hostent delete_he, *he;
	urecord_t *record;
	ucontact_t *contact, *it;
	str uri, aor_user, delete_user = { NULL, 0 };
	int err, count = 0;
	int delete_by_hostname = 0;
	unsigned short delete_port;

	memset(&delete_he, 0, sizeof delete_he);

	if (fixup_get_svalue(msg, (gparam_p)aor_gp, &uri) != 0) {
		LM_ERR("failed to get gparam_t value\n");
		return E_UNSPEC;
	}

	if (extract_aor( &uri, &aor_user,0,0) < 0) {
		LM_ERR("failed to extract Address Of Record\n");
		return E_BAD_URI;
	}

	ul.lock_udomain((udomain_t *)udomain, &aor_user);

	if (ul.get_urecord((udomain_t *)udomain, &aor_user, &record) != 0) {
		LM_DBG("no record '%.*s' found!\n", aor_user.len, aor_user.s);
		err = 1;
		goto out_unlock;
	}

	/* if no contact uri param is given, delete the whole urecord entry */
	if (!contact_gp) {
		if (ul.delete_urecord((udomain_t *)udomain, &aor_user, record, 0) != 0) {
			LM_ERR("failed to delete urecord for aor '%.*s'\n",
			        aor_user.len, aor_user.s);
			err = E_UNSPEC;
			goto out_unlock;
		}

		err = 1;
		goto out_unlock;
	}

	if (fixup_get_svalue(msg, (gparam_p)contact_gp, &uri) != 0) {
		LM_ERR("failed to retrieve value of contact pv\n");
		err = E_UNSPEC;
		goto out_unlock;
	}

	/* minimum two-letters for the domain name */
	if (uri.len < 5) {
		LM_ERR("Invalid domain given: '%.*s'\n", uri.len, uri.s);
		err = E_INVALID_PARAMS;
		goto out_unlock;
	}

	/* a domain/IP address was given instead of a SIP contact URI */
	if (uri.s[0] != 's' || uri.s[1] != 'i' ||
	    uri.s[2] != 'p' || (uri.s[3] != ':' &&
	                        (uri.s[3] != 's' || uri.s[4] != ':'))) {

		delete_by_hostname = 1;

		he = sip_resolvehost(&uri, &delete_port, NULL, 0, NULL);
		if (!he) {
			LM_ERR("cannot resolve given host: '%.*s'\n", uri.len, uri.s);
			err = E_UNSPEC;
			goto out_unlock;
		}

		LM_DBG("Delete by host: '%s'\n",
		        inet_ntoa(*(struct in_addr *)(he->h_addr_list[0])));
	} else {
		LM_DBG("parsing uri: %.*s\n", uri.len, uri.s);

		if (parse_uri(uri.s, uri.len, &puri) != 0) {
			LM_ERR("failed to parse contact uri: '%.*s'\n",
			        uri.len, uri.s);
			err = E_BAD_URI;
			goto out_unlock;
		}

		delete_user = puri.user;

		he = sip_resolvehost(&puri.host, &delete_port, &puri.proto, 0, NULL);
		if (!he) {
			LM_ERR("cannot resolve given uri: '%.*s'\n", uri.len, uri.s);
			err = E_UNSPEC;
			goto out_unlock;
		}

		if (puri.port_no > 0)
			delete_port  = puri.port_no;

		LM_DBG("Delete by contact: [ User %.*s | Host %s | Port %d ]\n",
		        delete_user.len, delete_user.s,
		        inet_ntoa(*(struct in_addr *)(he->h_addr_list[0])),
				delete_port);
	}

	if (hostent_cpy(&delete_he, he) != 0) {
		LM_ERR("no more pkg mem\n");
		err = E_OUT_OF_MEM;
		goto out_unlock;
	}

	for (it = record->contacts; it; ) {
		contact = it;
		it = it->next;
		count++;

		LM_DBG("parsing contact uri '%.*s'\n", contact->c.len, contact->c.s);

		if (parse_uri(contact->c.s, contact->c.len, &puri) != 0) {
			LM_ERR("failed to parse contact uri: '%.*s'\n",
			        contact->c.len, contact->c.s);
			err = E_BAD_URI;
			goto out_unlock;
		}

		/* if necessary, solve the next_hop towards the contact */
		he = sip_resolvehost(&contact->next_hop.name,
		                     &contact->next_hop.port,
		                     &contact->next_hop.proto, 0, NULL);
		if (!he) {
			LM_ERR("failed to resolve next hop of contact '%.*s'\n",
			        contact->c.len, contact->c.s);
			continue;
		}

		LM_DBG("Contact: [ User %.*s | Host %s | Port %d ]\n",
		        puri.user.len, puri.user.s,
		        inet_ntoa(*(struct in_addr *)(he->h_addr_list[0])),
				puri.port_no);

		if (delete_by_hostname) {
			if (!memcmp(delete_he.h_addr_list[0],
			            he->h_addr_list[0], he->h_length))
			{
				ul.delete_ucontact(record, contact, 0);
				count--;
			}
		} else {
			if (delete_user.len == puri.user.len &&
			    delete_port == puri.port_no &&
			    !memcmp(delete_he.h_addr_list[0],
			            he->h_addr_list[0], he->h_length)
				&& !memcmp(delete_user.s, puri.user.s, puri.user.len))
			{
				ul.delete_ucontact(record, contact, 0);
				count--;
			}
		}
	}

	err = 1;

	/* remove the AOR if no more contacts are attached */
	if (count == 0) {
		if (ul.delete_urecord((udomain_t *)udomain, &aor_user, record, 0) != 0) {
			LM_ERR("failed to delete urecord for aor '%.*s'\n",
			        aor_user.len, aor_user.s);
			err = 1;
		}
	}

out_unlock:
	ul.unlock_udomain((udomain_t *)udomain, &aor_user);
	free_hostent(&delete_he);

	return err;
}
Example #4
0
/**
 * _remove - Delete an entire AOR entry or one or more of its Contacts
 *
 * @domain:          logical domain name (usually name of location table)
 * @aor_gp:          address-of-record as a SIP URI (plain string or pvar)
 * @contact_gp:      contact URI to be deleted
 * @next_hop_gp:     IP/domain in front of contacts to be deleted
 * @sip_instance_gp: delete contacts with given "+sip_instance"
 *
 * @return:      1 on success, negative on failure
 */
int _remove(struct sip_msg *msg, void *udomain, str *aor_uri, str *match_ct,
            str *match_next_hop, str *match_sin)
{
	struct hostent delete_nh_he, *he;
	urecord_t *record;
	ucontact_t *contact, *it;
	str aor_user;
	int ret = 1;
	unsigned short delete_port = 0;

	if (extract_aor(aor_uri, &aor_user, 0, 0) < 0) {
		LM_ERR("failed to extract Address Of Record\n");
		return E_BAD_URI;
	}

	ul.lock_udomain((udomain_t *)udomain, &aor_user);

	if (ul.get_urecord((udomain_t *)udomain, &aor_user, &record) != 0) {
		LM_DBG("no record '%.*s' found!\n", aor_user.len, aor_user.s);
		goto out_unlock;
	}

	/* without any additional filtering, delete the whole urecord entry */
	if (!match_ct && !match_next_hop && !match_sin) {
		if (ul.delete_urecord((udomain_t *)udomain, &aor_user, record, 0) != 0) {
			LM_ERR("failed to delete urecord for aor '%.*s'\n",
			        aor_user.len, aor_user.s);
			ret = E_UNSPEC;
			goto out_unlock;
		}

		goto out_unlock;
	}

	if (match_ct && match_ct->s)
		LM_DBG("Delete by contact: [%.*s]\n", match_ct->len, match_ct->s);

	if (match_sin && match_sin->s)
			LM_DBG("Delete by sip_instance: [%.*s]\n",
				match_sin->len, match_sin->s);

	if (match_next_hop->s) {
		he = sip_resolvehost(match_next_hop, &delete_port, NULL, 0, NULL);
		if (!he) {
			LM_ERR("cannot resolve given host: '%.*s'\n",
			       match_next_hop->len, match_next_hop->s);
			ret = E_UNSPEC;
			goto out_unlock;
		}

		LM_DBG("Delete by host: '%s'\n",
		        inet_ntoa(*(struct in_addr *)(he->h_addr_list[0])));

		if (hostent_cpy(&delete_nh_he, he) != 0) {
			LM_ERR("no more pkg mem\n");
			ret = E_OUT_OF_MEM;
			goto out_unlock;
		}
	}


	for (it = record->contacts; it; ) {
		contact = it;
		it = it->next;

		LM_DBG("checking contact uri '%.*s'\n", contact->c.len, contact->c.s);

		he = sip_resolvehost(&contact->next_hop.name,
		                     &contact->next_hop.port,
		                     &contact->next_hop.proto, 0, NULL);
		if (!he) {
			LM_ERR("failed to resolve next hop %.*s of contact '%.*s'\n",
				contact->next_hop.name.len, contact->next_hop.name.s,
				contact->c.len, contact->c.s);
			continue;
		}

		LM_DBG("next hop is [%.*s] resolving to [%s]\n",
			contact->next_hop.name.len, contact->next_hop.name.s,
			inet_ntoa(*(struct in_addr *)(he->h_addr_list[0])));

		if (match_next_hop->s) {
			if (memcmp(delete_nh_he.h_addr_list[0],
			he->h_addr_list[0], he->h_length))
				continue;
		}

		if (match_ct->s) {
			if (match_ct->len != contact->c.len ||
			memcmp(match_ct->s, contact->c.s, match_ct->len))
				continue;
		}

		if (match_sin->s) {
			if (str_strcmp(match_sin, &contact->instance))
				continue;
		}

		ul.delete_ucontact(record, contact, 0);
	}

	ul.release_urecord(record, 0);

out_unlock:
	ul.unlock_udomain((udomain_t *)udomain, &aor_user);
	if (match_next_hop->s)
		free_hostent(&delete_nh_he);

	return ret;
}