예제 #1
0
파일: proxy.c 프로젝트: biddyweb/ims_core
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;
}
예제 #2
0
파일: proxy.c 프로젝트: UIKit0/OpenSIPS
/* same as add_proxy, but it doesn't add the proxy to the list
 * uses also SRV if possible & port==0 (quick hack) 
   works in shared memory */
struct proxy_l* mk_shm_proxy(str* name, unsigned short port, unsigned short proto,
		int is_sips)
{
	struct proxy_l* p;
	struct hostent* he;

	p=(struct proxy_l*) shm_malloc(sizeof(struct proxy_l));
	if (p==0){
		ser_error=E_OUT_OF_MEM;
		LM_CRIT("shm 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);
		shm_free(p);
		goto error;
	}
	if (hostent_shm_cpy(&(p->host), he)!=0){
		free_dns_res( p );
		shm_free(p);
		goto error;
	}
	return p;
error:
	return 0;
}
예제 #3
0
int update_sock_struct_from_via( union sockaddr_union* to,
								 struct sip_msg* msg,
								 struct via_body* via )
{
	struct hostent* he;
	str* name;
	int err;
	unsigned short port;

	port=0;
	if(via==msg->via1){ 
		/* _local_ reply, we ignore any rport or received value
		 * (but we will send back to the original port if rport is
		 *  present) */
		if ((msg->msg_flags&FL_FORCE_RPORT)||(via->rport))
			port=msg->rcv.src_port;
		else port=via->port;
		if(via->maddr)
			name= &(via->maddr->value);
		else
			name=&(via->host); /* received=ip in 1st via is ignored (it's
							  not added by us so it's bad) */
	}else{
		/* "normal" reply, we use rport's & received value if present */
		if (via->rport && via->rport->value.s){
			LM_DBG("using 'rport'\n");
			port=str2s(via->rport->value.s, via->rport->value.len, &err);
			if (err){
				LM_NOTICE("bad rport value(%.*s)\n",
					via->rport->value.len,via->rport->value.s);
				port=0;
			}
		}

		if (via->maddr){
			name= &(via->maddr->value);
			if (port==0) port=via->port?via->port:SIP_PORT; 
		} else if (via->received){
			LM_DBG("using 'received'\n");
			name=&(via->received->value);
			/* making sure that we won't do SRV lookup on "received" */
			if (port==0) port=via->port?via->port:SIP_PORT; 
		}else{
			LM_DBG("using via host\n");
			name=&(via->host);
			if (port==0) port=via->port;
		}
	}
	LM_DBG("trying SRV lookup\n");
	he=sip_resolvehost(name, &port, &via->proto, 0, 0);

	if (he==0){
		LM_NOTICE("resolve_host(%.*s) failure\n", name->len, name->s);
		return -1;
	}
		
	hostent2su( to, he, 0, port);
	return 1;
}
예제 #4
0
int update_sock_struct_from_via( union sockaddr_union* to,
									struct sip_msg* msg,
									struct via_body* via )
{
	struct hostent* he;
	str* name;
	int err;
	unsigned short port;
	char proto;

	port=0;
	if(via==msg->via1){
		/* _local_ reply, we ignore any rport or received value
		 * (but we will send back to the original port if rport is
		 *  present) */
		if ((msg->msg_flags&FL_FORCE_RPORT)||(via->rport))
			port=msg->rcv.src_port;
		else port=via->port;
		name=&(via->host); /* received=ip in 1st via is ignored (it's
							* not added by us so it's bad) */
	}else{
		/* "normal" reply, we use rport's & received value if present */
		if (via->rport && via->rport->value.s){
			LM_DBG("using 'rport'\n");
			port=str2s(via->rport->value.s, via->rport->value.len, &err);
			if (err){
				LM_ERR("bad rport value(%.*s)\n",
						via->rport->value.len, via->rport->value.s);
				port=0;
			}
		}
		if (via->received){
			LM_DBG("using 'received'\n");
			name=&(via->received->value);
			/* making sure that we won't do SRV lookup on "received"
			 * (possible if no DNS_IP_HACK is used)*/
			if (port==0) port=via->port?via->port:SIP_PORT;
		}else{
			LM_DBG("using via host\n");
			name=&(via->host);
			if (port==0) port=via->port;
		}
	}
	/* we do now a malloc/memcpy because gethostbyname loves \0-terminated
	 * strings; but only if host is not null terminated (host.s[len] will
	 * always be ok for a via)
	 */
	LM_DBG("trying SRV lookup\n");
	proto=via->proto;
	he=sip_resolvehost(name, &port, &proto);

	if (he==0){
		LM_NOTICE("resolve_host(%.*s) failure\n", name->len, name->s);
		return -1;
	}

	hostent2su(to, he, 0, port);
	return 1;
}
예제 #5
0
int rl_add_repl_dst(modparam_t type, void *val)
{
	char *host;
	int hlen, port;
	int proto;
	struct hostent *he;
	str st;

	rl_dests = pkg_realloc(rl_dests, (rl_dests_nr + 1) * sizeof(rl_repl_dst_t));
	if (!rl_dests) {
		LM_ERR("oom\n");
		return -1;
	}

	if (parse_phostport(val, strlen(val), &host, &hlen, &port, &proto) < 0) {
		LM_ERR("Bad replication destination IP!\n");
		return -1;
	}

	if (proto == PROTO_NONE)
		proto = PROTO_UDP;

	st.s = host;
	st.len = hlen;
	he = sip_resolvehost(&st, (unsigned short *)&port,
							  (unsigned short *)&proto, 0, 0);
	if (!he) {
		LM_ERR("Cannot resolve host: %.*s\n", hlen, host);
		return -1;
	}
	if (!port) {
		LM_ERR("no port specified for host %.*s\n", hlen, host);
		return -1;
	}

	rl_dests[rl_dests_nr].id = rl_dests_nr;
	rl_dests[rl_dests_nr].dst.s = (char *)val;
	rl_dests[rl_dests_nr].dst.len = strlen(rl_dests[rl_dests_nr].dst.s);
	hostent2su(&rl_dests[rl_dests_nr].to, he, 0, port);

	LM_DBG("Added destination <%.*s>\n",
			rl_dests[rl_dests_nr].dst.len, rl_dests[rl_dests_nr].dst.s);

	/* init done */
	rl_dests_nr++;

	return 1;
}
예제 #6
0
int
natping_contact(str contact, struct dest_info *dst) {
	struct sip_uri curi;
	struct hostent *he;
	str p_method, p_from;

	if (natping_method != NULL) {
		/* XXX: add send_sock handling */
		p_method.s = natping_method;
		p_method.len = strlen(p_method.s);
		p_from.s = "sip:registrar"; /* XXX */
		p_from.len = strlen(p_from.s);
		if (tmb.t_request(&p_method, &contact, &contact, &p_from,
		    NULL, NULL, NULL, NULL, NULL) == -1) {
			LOG(L_ERR, "ERROR: nathelper::natping(): t_request() failed\n");
			return -1;
		}
	} else {
		if (parse_uri(contact.s, contact.len, &curi) < 0) {
			LOG(L_ERR, "ERROR: nathelper::natping: can't parse contact uri\n");
			return -1;
		}
		if (curi.proto != PROTO_UDP && curi.proto != PROTO_NONE)
			return -1;
		if (curi.port_no == 0)
			curi.port_no = SIP_PORT;
		he = sip_resolvehost(&curi.host, &curi.port_no, PROTO_UDP);
		if (he == NULL){
			LOG(L_ERR, "ERROR: nathelper::natping: can't resolve host\n");
			return -1;
		}
		hostent2su(&dst->to, he, 0, curi.port_no);
		if (dst->send_sock == NULL) {
			dst->send_sock = force_socket ? force_socket :
			    get_send_socket(0, &dst->to, PROTO_UDP);
		}
		if (dst->send_sock == NULL) {
			LOG(L_ERR, "ERROR: nathelper::natping: can't get sending socket\n");
			return -1;
		}
		dst->proto=PROTO_UDP;
		udp_send(dst, (char *)sbuf, sizeof(sbuf));
	}
	return 1;
}
예제 #7
0
static int add_replication_dest(modparam_t type, void *val)
{
	struct replication_dest *rd;
	char *host;
	int hlen, port;
	int proto;
	struct hostent *he;
	str st;

	rd = pkg_malloc(sizeof(*rd));
	memset(rd, 0, sizeof(*rd));

	if (parse_phostport(val, strlen(val), &host, &hlen, &port, &proto) < 0) {
		LM_ERR("Bad replication destination IP!\n");
		return -1;
	}

	if (proto == PROTO_NONE)
		proto = PROTO_UDP;

	if (proto != PROTO_UDP) {
		LM_ERR("Dialog replication only supports UDP packets!\n");
		return -1;
	}

	st.s = host;
	st.len = hlen;
	he = sip_resolvehost(&st, (unsigned short *)&port,
							  (unsigned short *)&proto, 0, 0);
	if (!he) {
		LM_ERR("Cannot resolve host: %.*s\n", hlen, host);
		return -1;
	}

	hostent2su(&rd->to, he, 0, port);

	rd->next = replication_dests;
	replication_dests = rd;

	return 1;
}
예제 #8
0
파일: resolve.c 프로젝트: miao606/kamailio
/* resolve host, port, proto using sip rules (e.g. use SRV if port=0 a.s.o)
 *  and write the result in the sockaddr_union to
 *  returns -1 on error (resolve failed), 0 on success */
int sip_hostport2su(union sockaddr_union* su, str* name, unsigned short port,
						char* proto)
{
	struct hostent* he;
	
	he=sip_resolvehost(name, &port, proto);
	if (he==0){
		ser_error=E_BAD_ADDRESS;
		LOG(L_ERR, "ERROR: sip_hostport2su: could not resolve hostname:"
					" \"%.*s\"\n", name->len, name->s);
		goto error;
	}
	/* port filled by sip_resolvehost if empty*/
	if (hostent2su(su, he, 0, port)<0){
		ser_error=E_BAD_ADDRESS;
		goto error;
	}
	return 0;
error:
	return -1;
}
예제 #9
0
파일: enum.c 프로젝트: UIKit0/OpenSIPS
/*
 * Check if from user is a valid enum based user, and check to make sure
 * that the src_ip == an srv record that maps to the enum from user.
 */
int is_from_user_enum_2(struct sip_msg* _msg, char* _suffix, char* _service)
{
	struct ip_addr addr;
	struct hostent* he;
	unsigned short zp;
	unsigned short proto;
	char *user_s;
	int user_len, i, j;
	char name[MAX_DOMAIN_SIZE];
	char uri[MAX_URI_SIZE];
	struct sip_uri *furi;
	struct sip_uri luri;
	struct rdata* head;

	str* suffix;
	str* service;

	struct rdata* l;
	struct naptr_rdata* naptr;

	str pattern, replacement, result;
	char string[17];

	if (parse_from_header(_msg) < 0) {
	    LM_ERR("Failed to parse From header\n");
	    return -1;
	}
	
	if(_msg->from==NULL || get_from(_msg)==NULL) {
	    LM_DBG("No From header\n");
	    return -1;
	}

	if ((furi = parse_from_uri(_msg)) == NULL) {
	    LM_ERR("Failed to parse From URI\n");
	    return -1;
	}

	suffix = (str*)_suffix;
	service = (str*)_service;

	if (is_e164(&(furi->user)) == -1) {
	    LM_ERR("From URI user is not an E164 number\n");
	    return -1;
	}

	/* assert: the from user is a valid formatted e164 string */

	user_s = furi->user.s;
	user_len = furi->user.len;

	j = 0;
	for (i = user_len - 1; i > 0; i--) {
		name[j] = user_s[i];
		name[j + 1] = '.';
		j = j + 2;
	}

	memcpy(name + j, suffix->s, suffix->len + 1);

	head = get_record(name, T_NAPTR);

	if (head == 0) {
		LM_DBG("No NAPTR record found for %s.\n", name);
		return -3;
	}

	/* we have the naptr records, loop and find an srv record with */
	/* same ip address as source ip address, if we do then true is returned */

	for (l = head; l; l = l->next) {

		if (l->type != T_NAPTR) continue; /*should never happen*/
		naptr = (struct naptr_rdata*)l->rdata;
		if (naptr == 0) {
			LM_ERR("Null rdata in DNS response\n");
			free_rdata_list(head);
			return -4;
		}

		LM_DBG("ENUM query on %s: order %u, pref %u, flen %u, flags "
		       "'%.*s', slen %u, services '%.*s', rlen %u, "
		       "regexp '%.*s'\n",
		       name, naptr->order, naptr->pref,
		    naptr->flags_len, (int)(naptr->flags_len), ZSW(naptr->flags), naptr->services_len,
		    (int)(naptr->services_len), ZSW(naptr->services), naptr->regexp_len,
		    (int)(naptr->regexp_len), ZSW(naptr->regexp));

		if (sip_match(naptr, service) != 0) {
			if (parse_naptr_regexp(&(naptr->regexp[0]), naptr->regexp_len,
					 &pattern, &replacement) < 0) {
				free_rdata_list(head); /*clean up*/
				LM_ERR("Parsing of NAPTR regexp failed\n");
				return -5;
			}
#ifdef LATER
			if ((pattern.len == 4) && (strncmp(pattern.s, "^.*$", 4) == 0)) {
				LM_DBG("Resulted in replacement: '%.*s'\n",
				       replacement.len, ZSW(replacement.s));				
				retval = set_uri(_msg, replacement.s, replacement.len);
				free_rdata_list(head); /*clean up*/
				return retval;
			}
#endif
			result.s = &(uri[0]);
			result.len = MAX_URI_SIZE;
			/* Avoid making copies of pattern and replacement */
			pattern.s[pattern.len] = (char)0;
			replacement.s[replacement.len] = (char)0;
			/* We have already checked the size of
			   _msg->parsed_uri.user.s */ 
			memcpy(&(string[0]), user_s, user_len);
			string[user_len] = (char)0;
			if (reg_replace(pattern.s, replacement.s, &(string[0]),
					&result) < 0) {
				pattern.s[pattern.len] = '!';
				replacement.s[replacement.len] = '!';
				LM_ERR("Regexp replace failed\n");
				free_rdata_list(head); /*clean up*/
				return -6;
			}
			LM_DBG("Resulted in replacement: '%.*s'\n",
			    result.len, ZSW(result.s));

			if(parse_uri(result.s, result.len, &luri) < 0)
			{
				LM_ERR("Parsing of URI <%.*s> failed\n",
				       result.len, result.s);
				free_rdata_list(head); /*clean up*/
				return -7;
			}

			pattern.s[pattern.len] = '!';
			replacement.s[replacement.len] = '!';

			zp = 0;
			proto = PROTO_NONE;
			he = sip_resolvehost(&luri.host, &zp, &proto,
				(luri.type==SIPS_URI_T)?1:0 , 0);

			hostent2ip_addr(&addr, he, 0);

			if(ip_addr_cmp(&addr, &_msg->rcv.src_ip))
			{
				free_rdata_list(head);
				return(1);
			}
		}
	}
	free_rdata_list(head); /*clean up*/
	LM_DBG("FAIL\n");

    /* must not have found the record */
    return(-8);
}
예제 #10
0
파일: clusterer.c 프로젝트: Danfx/opensips
/* add a new information in the backend list*/
int add_info(table_entry_t **data, int *int_vals, unsigned long last_attempt, char **str_vals)
{
	char *host;
	int hlen, port;
	struct hostent *he;
	struct module_list *module;
	struct module_timestamp *new_timestamp;
	uint64_t ctime;
	int proto;
	int cluster_id;
	table_entry_t *head = NULL;
	table_entry_info_t *info_head = NULL;
	table_entry_value_t *value = NULL;
	str st;
	char *url;
	char *description;

	if (int_vals[INT_VALS_MACHINE_ID_COL] == server_id) {
		return 0;
	}

	url = str_vals[STR_VALS_URL_COL];

	if (url == NULL) {
		LM_ERR("no path specified\n");
		goto error;
	}

	if (parse_phostport(url, strlen(url), &host, &hlen, &port, &proto) < 0) {
		LM_ERR("Bad replication destination IP!\n");
		goto error;
	}

	if (proto == PROTO_NONE)
		proto = PROTO_UDP;

	cluster_id = int_vals[INT_VALS_CLUSTER_ID_COL];

	for (head = *data; head; head = head->next) {
		if (head->cluster_id == cluster_id) {
			info_head = head->info;
			while (info_head && info_head->proto != proto)
				info_head = info_head->next;

			if (!info_head) {
				info_head = shm_malloc(sizeof *info_head);
				if (!info_head) {
					LM_ERR("no more shm memory\n");
					goto error;
				}
				info_head->proto = proto;
				info_head->next = head->info;
				info_head->value = NULL;
				head->info = info_head;
			}
			break;
		}
	}

	if (!head) {
		head = shm_malloc(sizeof *head);
		if (!head) {
			LM_ERR("no more shm memory\n");
			goto error;
		}
		head->cluster_id = cluster_id;
		head->info = shm_malloc(sizeof(table_entry_info_t));
		if (!head->info) {
			LM_ERR("no more shm memory\n");
			goto error;
		}
		head->info->proto = proto;
		head->info->next = NULL;
		head->info->value = NULL;
		info_head = head->info;
		info_head->proto = proto;
		head->next = *data;
		*data = head;
	}

	/* allocating memory*/
	value = shm_malloc(sizeof *value);
	if (!value) {
		LM_ERR("no more shm memory\n");
		goto error;
	}

	value->machine_id = int_vals[INT_VALS_MACHINE_ID_COL];
	value->id = int_vals[INT_VALS_CLUSTERER_ID_COL];
	value->state = int_vals[INT_VALS_STATE_COL];
	value->last_attempt = last_attempt;
	value->duration = int_vals[INT_VALS_DURATION_COL];
	value->failed_attempts = int_vals[INT_VALS_FAILED_ATTEMPTS_COL];
	value->no_tries = int_vals[INT_VALS_NO_TRIES_COL];
	value->dirty_bit = 0;
	value->prev_no_tries = -1;
	value->in_timestamps = NULL;
	description = str_vals[STR_VALS_DESCRIPTION_COL];

	value->path.s = shm_malloc(strlen(url) * sizeof(char));

	if (!value->path.s) {
		LM_ERR("insufficient shm memory\n");
		goto error;
	}

	st.s = host;
	st.len = hlen;

	he = sip_resolvehost(&st, (unsigned short *) &port,
		(unsigned short *) &proto, 0, 0);
	if (!he) {
		LM_ERR("Cannot resolve host: %.*s\n", hlen, host);
		goto error;
	}

	hostent2su(&value->addr, he, 0, port);

	value->path.len = strlen(url);
	memcpy(value->path.s, url, value->path.len);

	if (strlen(description) != 0) {
		value->description.len = strlen(description);
		value->description.s = shm_malloc(value->description.len * sizeof(char));
		if (value->description.s == NULL) {
			LM_ERR("no more shm memory\n");
			goto error;
		}
		memcpy(value->description.s, description, value->description.len);
	} else {
		value->description.s = NULL;
		value->description.len = 0;
	}

	ctime = time(0);
	for (module = clusterer_modules; module; module = module->next) {
		if (cluster_id == module->accept_cluster_id && proto == module->proto) {
			new_timestamp = create_module_timestamp(ctime, module);
			if (new_timestamp == NULL)
				break;
			new_timestamp->next = value->in_timestamps;
			value->in_timestamps = new_timestamp;
		}
	}

	value->next = info_head->value;
	info_head->value = value;
	/* everything ok */
	return 0;
error:
	if (value) {
		if (value->description.s)
			shm_free(value->description.s);

		if (value->path.s)
			shm_free(value->path.s);
		shm_free(value);
	}
	if (info_head) {
		if (info_head->value == NULL) {
			if (head != NULL)
				head->info = head->info->next;
			shm_free(info_head);
		}
	}
	if (head) {
		if (head->info == NULL) {
			*tdata = (*tdata)->next;
			shm_free(head);
		}
	}
	return -1;
}
예제 #11
0
파일: save.c 프로젝트: dsanders11/opensips
/**
 * _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;
}
예제 #12
0
int add_node_info(node_info_t **new_info, cluster_info_t **cl_list, int *int_vals,
					char **str_vals)
{
	char *host;
	int hlen, port;
	int proto;
	struct hostent *he;
	int cluster_id;
	cluster_info_t *cluster = NULL;
	struct timeval t;
	str st;
	str seed_flag = str_init(SEED_NODE_FLAG_STR);

	cluster_id = int_vals[INT_VALS_CLUSTER_ID_COL];
	/* new_info is checked whether it is initialized or not in case of error,
	 * so we have to initialize it as soon as possible */
	*new_info = NULL;

	for (cluster = *cl_list; cluster && cluster->cluster_id != cluster_id;
		cluster = cluster->next) ;

	if (!cluster) {
		cluster = shm_malloc(sizeof *cluster);
		if (!cluster) {
			LM_ERR("no more shm memory\n");
			goto error;
		}
		memset(cluster, 0, sizeof *cluster);

		cluster->cluster_id = cluster_id;
		cluster->next = *cl_list;
		if ((cluster->lock = lock_alloc()) == NULL) {
			LM_CRIT("Failed to allocate lock\n");
			goto error;
		}
		if (!lock_init(cluster->lock)) {
			lock_dealloc(cluster->lock);
			LM_CRIT("Failed to init lock\n");
			goto error;
		}
		*cl_list = cluster;
	}

	*new_info = shm_malloc(sizeof **new_info);
	if (!*new_info) {
		LM_ERR("no more shm memory\n");
		goto error;
	}
	memset(*new_info, 0, sizeof **new_info);

	(*new_info)->flags = 0;

	(*new_info)->id = int_vals[INT_VALS_ID_COL];
	(*new_info)->node_id = int_vals[INT_VALS_NODE_ID_COL];
	if (int_vals[INT_VALS_STATE_COL])
		(*new_info)->flags |= NODE_STATE_ENABLED;
	else
		(*new_info)->flags &= ~NODE_STATE_ENABLED;

	if (int_vals[INT_VALS_NODE_ID_COL] != current_id)
		(*new_info)->link_state = LS_RESTART_PINGING;
	else
		(*new_info)->link_state = LS_UP;

	if (str_vals[STR_VALS_DESCRIPTION_COL] &&
		strlen(str_vals[STR_VALS_DESCRIPTION_COL]) != 0) {
		(*new_info)->description.len = strlen(str_vals[STR_VALS_DESCRIPTION_COL]);
		(*new_info)->description.s =
			shm_malloc((*new_info)->description.len * sizeof(char));
		if ((*new_info)->description.s == NULL) {
			LM_ERR("no more shm memory\n");
			goto error;
		}
		memcpy((*new_info)->description.s, str_vals[STR_VALS_DESCRIPTION_COL],
			(*new_info)->description.len);
	} else {
		(*new_info)->description.s = NULL;
		(*new_info)->description.len = 0;
	}

	if (str_vals[STR_VALS_SIP_ADDR_COL] &&
		strlen(str_vals[STR_VALS_SIP_ADDR_COL]) != 0) {
		(*new_info)->sip_addr.len = strlen(str_vals[STR_VALS_SIP_ADDR_COL]);
		(*new_info)->sip_addr.s = shm_malloc((*new_info)->sip_addr.len * sizeof(char));
		if ((*new_info)->sip_addr.s == NULL) {
			LM_ERR("no more shm memory\n");
			goto error;
		}
		memcpy((*new_info)->sip_addr.s, str_vals[STR_VALS_SIP_ADDR_COL],
			(*new_info)->sip_addr.len);
	} else {
		(*new_info)->sip_addr.s = NULL;
		(*new_info)->sip_addr.len = 0;
	}

	if (str_vals[STR_VALS_FLAGS_COL] &&
		strlen(str_vals[STR_VALS_FLAGS_COL]) != 0)
		if (memcmp(str_vals[STR_VALS_FLAGS_COL], seed_flag.s, seed_flag.len) == 0)
			(*new_info)->flags |= NODE_IS_SEED;

	if (str_vals[STR_VALS_URL_COL] == NULL) {
		LM_ERR("no url specified in DB\n");
		return 1;
	}
	(*new_info)->url.len = strlen(str_vals[STR_VALS_URL_COL]);
	(*new_info)->url.s = shm_malloc(strlen(str_vals[STR_VALS_URL_COL]) * sizeof(char));
	if (!(*new_info)->url.s) {
		LM_ERR("no more shm memory\n");
		goto error;
	}
	memcpy((*new_info)->url.s, str_vals[STR_VALS_URL_COL], (*new_info)->url.len);

	if (int_vals[INT_VALS_NODE_ID_COL] != current_id) {
		if (parse_phostport((*new_info)->url.s, (*new_info)->url.len, &host, &hlen,
			&port, &proto) < 0) {
			LM_ERR("Bad URL!\n");
			return 1;
		}

		if (proto == PROTO_NONE)
			proto = clusterer_proto;
		if (proto != clusterer_proto) {
			LM_ERR("Clusterer currently supports only BIN protocol, but node: %d "
				"has proto=%d\n", int_vals[INT_VALS_NODE_ID_COL], proto);
			return 1;
		}

		st.s = host;
		st.len = hlen;
		he = sip_resolvehost(&st, (unsigned short *) &port,
			(unsigned short *)&proto, 0, 0);
		if (!he) {
			LM_ERR("Cannot resolve host: %.*s\n", hlen, host);
			return 1;
		}

		hostent2su(&((*new_info)->addr), he, 0, port);

		t.tv_sec = 0;
		t.tv_usec = 0;
		(*new_info)->last_ping = t;
		(*new_info)->last_pong = t;
	}

	(*new_info)->priority = int_vals[INT_VALS_PRIORITY_COL];

	(*new_info)->no_ping_retries = int_vals[INT_VALS_NO_PING_RETRIES_COL];

	(*new_info)->cluster = cluster;

	(*new_info)->ls_seq_no = -1;
	(*new_info)->top_seq_no = -1;
	(*new_info)->ls_timestamp = 0;
	(*new_info)->top_timestamp = 0;

	(*new_info)->sp_info = shm_malloc(sizeof(struct node_search_info));
	if (!(*new_info)->sp_info) {
		LM_ERR("no more shm memory\n");
		goto error;
	}
	(*new_info)->sp_info->node = *new_info;

	if (int_vals[INT_VALS_NODE_ID_COL] != current_id) {
		(*new_info)->next = cluster->node_list;
		cluster->node_list = *new_info;
		cluster->no_nodes++;
		if (cluster->no_nodes > MAX_NO_NODES) {
			LM_ERR("Defined: %d nodes for cluster: %d, maximum number of nodes "
				"supported(%d) exceeded\n", cluster->no_nodes,
				cluster->cluster_id, MAX_NO_NODES);
			goto error;
		}
	} else {
		(*new_info)->next = NULL;
		cluster->current_node = *new_info;
	}

	if (((*new_info)->lock = lock_alloc()) == NULL) {
		LM_CRIT("Failed to allocate lock\n");
		goto error;
	}
	if (!lock_init((*new_info)->lock)) {
		lock_dealloc((*new_info)->lock);
		LM_CRIT("Failed to init lock\n");
		goto error;
	}

	return 0;
error:
	if (*new_info) {
		if ((*new_info)->sip_addr.s)
			shm_free((*new_info)->sip_addr.s);

		if ((*new_info)->description.s)
			shm_free((*new_info)->description.s);

		if ((*new_info)->url.s)
			shm_free((*new_info)->url.s);

		if ((*new_info)->sp_info)
			shm_free((*new_info)->sp_info);

		shm_free(*new_info);
	}
	return -1;
}
예제 #13
0
static void
timer(unsigned int ticks, void *param)
{
	int rval;
	void *buf, *cp;
	str c;
	struct sip_uri curi;
	union sockaddr_union to;
	struct hostent* he;
	struct socket_info* send_sock;

	buf = NULL;
	if (cblen > 0) {
		buf = pkg_malloc(cblen);
		if (buf == NULL) {
			LOG(L_ERR, "ERROR: nathelper::timer: out of memory\n");
			return;
		}
	}
	rval = get_all_ucontacts(buf, cblen);
	if (rval > 0) {
		if (buf != NULL)
			pkg_free(buf);
		cblen = rval * 2;
		buf = pkg_malloc(cblen);
		if (buf == NULL) {
			LOG(L_ERR, "ERROR: nathelper::timer: out of memory\n");
			return;
		}
		rval = get_all_ucontacts(buf, cblen);
		if (rval != 0) {
			pkg_free(buf);
			return;
		}
	}

	if (buf == NULL)
		return;

	cp = buf;
	while (1) {
		memcpy(&(c.len), cp, sizeof(c.len));
		if (c.len == 0)
			break;
		c.s = (char*)cp + sizeof(c.len);
		cp =  (char*)cp + sizeof(c.len) + c.len;
		if (parse_uri(c.s, c.len, &curi) < 0) {
			LOG(L_ERR, "ERROR: nathelper::timer: can't parse contact uri\n");
			continue;
		}
		if (curi.proto != PROTO_UDP && curi.proto != PROTO_NONE)
			continue;
		if (curi.port_no == 0)
			curi.port_no = SIP_PORT;
		he = sip_resolvehost(&curi.host, &curi.port_no, PROTO_UDP);
		if (he == NULL){
			LOG(L_ERR, "ERROR: nathelper::timer: can't resolve_hos\n");
			continue;
		}
		hostent2su(&to, he, 0, curi.port_no);
		send_sock = get_send_socket(&to, PROTO_UDP);
		if (send_sock == NULL) {
			LOG(L_ERR, "ERROR: nathelper::timer: can't get sending socket\n");
			continue;
		}
		udp_send(send_sock, (char *)sbuf, sizeof(sbuf), &to);
	}
	pkg_free(buf);
}
예제 #14
0
int
add_dst(
	rt_data_t *r,
	/* id */
	int id,
	/* ip address */ 
	char* ip,
	/* strip len */
	int strip,
	/* pri prefix */
	char* pri,
	/* dst type*/
	int type,
	/* dst attrs*/
	char* attrs
	)
{
	pgw_t *pgw=NULL, *tmp=NULL;
	pgw_addr_t *tmpa=NULL;
	struct hostent* he;
	struct sip_uri uri;
	struct ip_addr ipa;
	int l_ip,l_pri,l_attrs;
#define GWABUF_MAX_SIZE	512
	char gwabuf[GWABUF_MAX_SIZE];
	str gwas;

	if (NULL==r || NULL==ip) {
		LM_ERR("invalid parametres\n");
		goto err_exit;
	}

	l_ip = strlen(ip);
	l_pri = pri?strlen(pri):0;
	l_attrs = attrs?strlen(attrs):0;

	pgw = (pgw_t*)shm_malloc(sizeof(pgw_t) + l_ip + l_pri + l_attrs);
	if (NULL==pgw) {
		LM_ERR("no more shm mem (%u)\n",
			(unsigned int)(sizeof(pgw_t)+l_ip+l_pri +l_attrs));
		goto err_exit;
	}
	memset(pgw,0,sizeof(pgw_t));

	pgw->ip.len= l_ip;
	pgw->ip.s = (char*)(pgw+1);
	memcpy(pgw->ip.s, ip, l_ip);

	if (pri) {
		pgw->pri.len = l_pri;
		pgw->pri.s = ((char*)(pgw+1))+l_ip;
		memcpy(pgw->pri.s, pri, l_pri);
	}
	if (attrs) {
		pgw->attrs.len = l_attrs;
		pgw->attrs.s = ((char*)(pgw+1))+l_ip+l_pri;
		memcpy(pgw->attrs.s, attrs, l_attrs);
	}
	pgw->id = id;
	pgw->strip = strip;
	pgw->type = type;

	/* add address in the list */
	if(pgw->ip.len<5 || (strncasecmp("sip:", ip, 4)
			&&strncasecmp("sips:", ip, 5)))
	{
		if(pgw->ip.len+4>=GWABUF_MAX_SIZE) {
			LM_ERR("GW address (%d) longer "
				"than %d\n",pgw->ip.len+4,GWABUF_MAX_SIZE);
			goto err_exit;
		}
		memcpy(gwabuf, "sip:", 4);
		memcpy(gwabuf+4, ip, pgw->ip.len);
		gwas.s = gwabuf;
		gwas.len = 4+pgw->ip.len;
	} else {
		gwas.s = ip;
		gwas.len = pgw->ip.len;
	}

	memset(&uri, 0, sizeof(struct sip_uri));
	if(parse_uri(gwas.s, gwas.len, &uri)!=0) {
		LM_ERR("invalid uri <%.*s>\n",
			gwas.len, gwas.s);
		goto err_exit;
	}
	/* note we discard the port discovered by the resolve function - we are
	interested only in the port that was actually configured. */
	if ((he=sip_resolvehost( &uri.host, NULL, (char*)(void*)&uri.proto))==0 ) {
		if(dr_force_dns)
		{
			LM_ERR("cannot resolve <%.*s>\n",
				uri.host.len, uri.host.s);
			goto err_exit;
		} else {
			LM_DBG("cannot resolve <%.*s> - won't be used"
					" by is_from_gw()\n", uri.host.len, uri.host.s);
			goto done;
		}
	}
	hostent2ip_addr(&ipa, he, 0);
	tmpa = r->pgw_addr_l;
	while(tmpa) {
		if(tmpa->type==type && uri.port_no==tmpa->port
		&& ip_addr_cmp(&ipa, &tmpa->ip)) {
			LM_DBG("gw ip addr [%s]:%d loaded\n",
				ip_addr2a(&ipa), uri.port_no);
			goto done;
		}
		tmpa = tmpa->next;
	}
	
	LM_DBG("new gw ip addr [%s]\n", ip);
	tmpa = (pgw_addr_t*)shm_malloc(sizeof(pgw_addr_t));
	if(tmpa==NULL) {
		LM_ERR("no more shm mem (%u)\n",
			(unsigned int)sizeof(pgw_addr_t));
		goto err_exit;
	}
	memset(tmpa, 0, sizeof(pgw_addr_t));
	memcpy(&tmpa->ip, &ipa, sizeof(struct ip_addr));
	tmpa->port = uri.port_no;
	tmpa->type = type;
	tmpa->strip = strip;
	tmpa->next = r->pgw_addr_l;
	r->pgw_addr_l = tmpa;

done:
	if(NULL==r->pgw_l)
		r->pgw_l = pgw;
	else {
		tmp = r->pgw_l;
		while(NULL != tmp->next)
			tmp = tmp->next;
		tmp->next = pgw;
	}
	return 0;

err_exit:
	if(NULL!=pgw)
		shm_free(pgw);
	return -1;
}
예제 #15
0
파일: save.c 프로젝트: OpenSIPS/opensips
/**
 * _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;
}