コード例 #1
0
ファイル: erl_helpers.c プロジェクト: AlessioCasco/kamailio
/**
 * \brief Initialize C node server and returns listen socket.
 */
int erl_init_node(ei_cnode *ec, const str *alivename, const str *hostname, const str *cookie)
{
	/* identifies a specific instance of a C node. */
	short creation = getpid();
	struct addrinfo *ai = NULL;
	struct sockaddr *addr = NULL;
	ip_addr_t ip;

	char nodename[MAXNODELEN];

	int result;
	int listen_fd;
	int port;

	unsigned timeout_ms = CONNECT_TIMEOUT;
	int epmdfd;

	/* copy the nodename into something we can modify */
	if (snprintf(nodename, MAXNODELEN, "%.*s@%.*s", STR_FMT(alivename), STR_FMT(hostname)) >= MAXNODELEN) {
		LM_CRIT("the node name %.*s@%.*s is too large max length allowed is %d\n", STR_FMT(alivename), STR_FMT(hostname), MAXNODELEN-1);
		return -1;
	}

	if ((listen_fd = erl_passive_socket(hostname->s, 128, &ai)) == -1) {
		return -1;
	}

	/* use first ip address only, it's internal Erlang connection to empd */
	addr = (struct sockaddr*) ai->ai_addr;

	if ((result = ei_connect_xinit(ec, hostname->s, alivename->s, nodename, (Erl_IpAddr) &(((struct sockaddr_in*)ai->ai_addr)->sin_addr), cookie->s, creation)) < 0) {

		LM_CRIT("failed to initialize self as node %s\n", nodename);
		erl_close_socket(listen_fd);
		return -1;
	}

	port = sockaddr_port(addr);
	sockaddr2ip_addr(&ip, addr);

	/* publish */
	if ((epmdfd = ei_publish_tmo(ec, port, timeout_ms)) == -1) {

		LM_ERR("Failed to publish port %u to epmd, check is epmd started\n", port);

		erl_close_socket(listen_fd);
		return -1;
	} else {
		LM_DBG("listen on %s:%u[%u]/[%d] as %s\n",ip_addr2strz(&ip),port,listen_fd,epmdfd,nodename);
	}

	freeaddrinfo(ai);
	return listen_fd;
}
コード例 #2
0
ファイル: erl_helpers.c プロジェクト: AlessioCasco/kamailio
/**
 * @brief Initialize Erlang connection
 */
int erl_init_ec(ei_cnode *ec, const str *alivename, const str *hostname, const str *cookie)
{
	/* identifies a specific instance of a C node. */
	short creation = getpid();
	struct addrinfo *ai = NULL;
	struct sockaddr *addr = NULL;
	ip_addr_t ip;

	char nodename[MAXNODELEN];

	int result;
	int port;

	/* copy the nodename into something we can modify */
	if (snprintf(nodename, MAXNODELEN, "%.*s@%.*s", STR_FMT(alivename), STR_FMT(hostname)) >= MAXNODELEN) {
		LM_CRIT("the node name %.*s@%.*s is too large max length allowed is %d\n", STR_FMT(alivename), STR_FMT(hostname), MAXNODELEN-1);
		return -1;
	}

	if (erl_active_socket(hostname->s, 128, &ai)) {
		return -1;
	}

	addr = (struct sockaddr*) ai->ai_addr;
	sockaddr2ip_addr(&ip,addr);

	if ((result = ei_connect_xinit(ec, hostname->s, alivename->s, nodename, (Erl_IpAddr) &(((struct sockaddr_in*)ai->ai_addr)->sin_addr), cookie->s, creation)) < 0) {

		LM_CRIT("failed to initialize self as cnode name %s\n", nodename);
		return -1;
	}

	port = sockaddr_port(addr);

	LM_DBG("initialized ec for cnode '%s' on %.*s[%s] creation %d.\n", nodename, STR_FMT(hostname), ip_addr2strz(&ip), creation);

	freeaddrinfo(ai);
	return 0;
}
コード例 #3
0
ファイル: socket_info.c プロジェクト: Gaoithe/openimscore_ims
/* add all family type addresses of interface if_name to the socket_info array
 * if if_name==0, adds all addresses on all interfaces
 * WARNING: it only works with ipv6 addresses on FreeBSD
 * return: -1 on error, 0 on success
 */
int add_interfaces(char* if_name, int family, unsigned short port,
					unsigned short proto,
					struct socket_info** list)
{
	struct ifconf ifc;
	struct ifreq ifr;
	struct ifreq ifrcopy;
	char*  last;
	char* p;
	int size;
	int lastlen;
	int s;
	char* tmp;
	struct ip_addr addr;
	int ret;
	enum si_flags flags;
	
#ifdef HAVE_SOCKADDR_SA_LEN
	#ifndef MAX
		#define MAX(a,b) ( ((a)>(b))?(a):(b))
	#endif
#endif
	/* ipv4 or ipv6 only*/
	flags=SI_NONE;
	s=socket(family, SOCK_DGRAM, 0);
	ret=-1;
	lastlen=0;
	ifc.ifc_req=0;
	for (size=100; ; size*=2){
		ifc.ifc_len=size*sizeof(struct ifreq);
		ifc.ifc_req=(struct ifreq*) pkg_malloc(size*sizeof(struct ifreq));
		if (ifc.ifc_req==0){
			LOG(L_ERR, "ERROR: add_interfaces: memory allocation failure\n");
			goto error;
		}
		if (ioctl(s, SIOCGIFCONF, &ifc)==-1){
			if(errno==EBADF) return 0; /* invalid descriptor => no such ifs*/
			LOG(L_ERR, "ERROR: add_interfaces: ioctl failed: %s\n",
					strerror(errno));
			goto error;
		}
		if  ((lastlen) && (ifc.ifc_len==lastlen)) break; /*success,
														   len not changed*/
		lastlen=ifc.ifc_len;
		/* try a bigger array*/
		pkg_free(ifc.ifc_req);
	}
	
	last=(char*)ifc.ifc_req+ifc.ifc_len;
	for(p=(char*)ifc.ifc_req; p<last;
			p+=
			#ifdef __OS_linux
				sizeof(ifr) /* works on x86_64 too */
			#else
				(sizeof(ifr.ifr_name)+
				#ifdef  HAVE_SOCKADDR_SA_LEN
					MAX(ifr.ifr_addr.sa_len, sizeof(struct sockaddr))
				#else
					( (ifr.ifr_addr.sa_family==AF_INET)?
						sizeof(struct sockaddr_in):
						((ifr.ifr_addr.sa_family==AF_INET6)?
						sizeof(struct sockaddr_in6):sizeof(struct sockaddr)) )
				#endif
				)
			#endif
		)
	{
		/* copy contents into ifr structure
		 * warning: it might be longer (e.g. ipv6 address) */
		memcpy(&ifr, p, sizeof(ifr));
		if (ifr.ifr_addr.sa_family!=family){
			/*printf("strange family %d skipping...\n",
					ifr->ifr_addr.sa_family);*/
			continue;
		}
		
		/*get flags*/
		ifrcopy=ifr;
		if (ioctl(s, SIOCGIFFLAGS,  &ifrcopy)!=-1){ /* ignore errors */
			/* ignore down ifs only if listening on all of them*/
			if (if_name==0){ 
				/* if if not up, skip it*/
				if (!(ifrcopy.ifr_flags & IFF_UP)) continue;
			}
		}
		
		
		
		if ((if_name==0)||
			(strncmp(if_name, ifr.ifr_name, sizeof(ifr.ifr_name))==0)){
			
			/*add address*/
			sockaddr2ip_addr(&addr, 
					(struct sockaddr*)(p+(long)&((struct ifreq*)0)->ifr_addr));
			if ((tmp=ip_addr2a(&addr))==0) goto error;
			/* check if loopback */
			if (ifrcopy.ifr_flags & IFF_LOOPBACK) 
				flags|=SI_IS_LO;
			/* add it to one of the lists */
			if (new_sock2list(tmp, port, proto, flags, list)!=0){
				LOG(L_ERR, "ERROR: add_interfaces: new_sock2list failed\n");
				goto error;
			}
			ret=0;
		}
			/*
			printf("%s:\n", ifr->ifr_name);
			printf("        ");
			print_sockaddr(&(ifr->ifr_addr));
			printf("        ");
			ls_ifflags(ifr->ifr_name, family, options);
			printf("\n");*/
	}
	pkg_free(ifc.ifc_req); /*clean up*/
	close(s);
	return  ret;
error:
	if (ifc.ifc_req) pkg_free(ifc.ifc_req);
	close(s);
	return -1;
}
コード例 #4
0
ファイル: registrant.c プロジェクト: KISSMonX/opensips
int run_mi_reg_list(void *e_data, void *data, void *r_data)
{
	struct mi_root* rpl_tree = (struct mi_root*)data;
	struct mi_node *node, *node1;
	struct mi_attr* attr;
	reg_record_t *rec = (reg_record_t*)e_data;
	int len;
	char* p;
	struct ip_addr addr;

	node = add_mi_node_child(&rpl_tree->node, MI_DUP_VALUE, "AOR", 3,
							rec->td.rem_uri.s, rec->td.rem_uri.len);
	if(node == NULL) goto error;
	p = int2str(rec->expires, &len);
	attr = add_mi_attr(node, MI_DUP_VALUE, "expires", 7, p, len);
	if(attr == NULL) goto error;

	node1 = add_mi_node_child(node, MI_DUP_VALUE, "state", 5,
							uac_reg_state[rec->state].s, uac_reg_state[rec->state].len);
	if(node1 == NULL) goto error;

	p = ctime(&rec->last_register_sent);
	len = strlen(p)-1;
	node1 = add_mi_node_child(node, MI_DUP_VALUE, "last_register_sent", 18, p, len);
	if(node1 == NULL) goto error;

	p = ctime(&rec->registration_timeout);
	len = strlen(p)-1;
	node1 = add_mi_node_child(node, MI_DUP_VALUE, "registration_t_out", 18, p, len);
	if(node1 == NULL) goto error;

	node1 = add_mi_node_child(node, MI_DUP_VALUE, "registrar", 9,
							rec->td.rem_target.s, rec->td.rem_target.len);
	if(node1 == NULL) goto error;

	node1 = add_mi_node_child(node, MI_DUP_VALUE, "binding", 7,
							rec->contact_uri.s, rec->contact_uri.len);
	if(node1 == NULL) goto error;

	if(rec->td.loc_uri.s != rec->td.rem_uri.s) {
		node1 = add_mi_node_child(node, MI_DUP_VALUE,
								"third_party_registrant", 12,
								rec->td.loc_uri.s, rec->td.loc_uri.len);
		if(node1 == NULL) goto error;
	}

	if (rec->td.obp.s && rec->td.obp.len) {
		node1 = add_mi_node_child(node, MI_DUP_VALUE,
								"proxy", 5, rec->td.obp.s, rec->td.obp.len);
		if(node1 == NULL) goto error;
	}

	switch(rec->td.forced_to_su.s.sa_family) {
	case AF_UNSPEC:
		break;
	case AF_INET:
	case AF_INET6:
		node1 = add_mi_node_child(node, MI_DUP_VALUE, "dst_IP", 6,
			(rec->td.forced_to_su.s.sa_family==AF_INET)?"IPv4":"IPv6", 4);
		sockaddr2ip_addr(&addr, &rec->td.forced_to_su.s);
		p = ip_addr2a(&addr);
		if (p == NULL) goto error;
		len = strlen(p);
		attr = add_mi_attr(node1, MI_DUP_VALUE, "ip", 2, p, len);
		if(attr == NULL) goto error;
		break;
	default:
		LM_ERR("unexpected sa_family [%d]\n", rec->td.forced_to_su.s.sa_family);
		node1 = add_mi_node_child(node, MI_DUP_VALUE, "dst_IP", 6, "Error", 5);
		p = int2str(rec->td.forced_to_su.s.sa_family, &len);
		attr = add_mi_attr(node, MI_DUP_VALUE, "sa_family", 9, p, len);
		if(attr == NULL) goto error;
	}

	/* action successfuly completed on current list element */
	return 0; /* continue list traversal */
error:
	LM_ERR("Unable to create reply\n");
	return -1; /* exit list traversal */
}
コード例 #5
0
ファイル: registrant.c プロジェクト: UIKit0/OpenSIPS
static struct mi_root* mi_reg_list(struct mi_root* cmd, void* param)
{
	struct mi_root *rpl_tree;
	struct mi_node *rpl=NULL, *node, *node1;
	struct mi_attr* attr;
	reg_record_t *rec;
	int i, len;
	char* p;
	struct ip_addr addr;

	rpl_tree = init_mi_tree( 200, MI_OK_S, MI_OK_LEN);
	if (rpl_tree==NULL) return NULL;
	rpl = &rpl_tree->node;

	for(i = 0; i< reg_hsize; i++) {
		lock_get(&reg_htable[i].lock);
		rec = reg_htable[i].first;
		while (rec) {
			node = add_mi_node_child(rpl, MI_DUP_VALUE, "AOR", 3,
					rec->td.rem_uri.s, rec->td.rem_uri.len);
			if(node == NULL) goto error;
			p = int2str(rec->state, &len);
			attr = add_mi_attr(node, MI_DUP_VALUE, "state", 5, p, len);
			if(attr == NULL) goto error;
			p = int2str(rec->expires, &len);
			attr = add_mi_attr(node, MI_DUP_VALUE, "expires", 7, p, len);
			if(attr == NULL) goto error;
			p = int2str((unsigned int)rec->last_register_sent, &len);
			attr = add_mi_attr(node, MI_DUP_VALUE, "last_register_sent", 18, p, len);
                        if(attr == NULL) goto error;
			p = int2str((unsigned int)rec->registration_timeout, &len);
			attr = add_mi_attr(node, MI_DUP_VALUE, "registration_timeout", 20, p, len);
                        if(attr == NULL) goto error;

			node1 = add_mi_node_child(node, MI_DUP_VALUE, "registrar", 9,
					rec->td.rem_target.s, rec->td.rem_target.len);
			if(node1 == NULL) goto error;

			node1 = add_mi_node_child(node, MI_DUP_VALUE, "binding", 7,
					rec->contact_uri.s, rec->contact_uri.len);
			if(node1 == NULL) goto error;

			if(rec->td.loc_uri.s != rec->td.rem_uri.s) {
				node1 = add_mi_node_child(node, MI_DUP_VALUE,
						"third_party_registrant", 12,
						rec->td.loc_uri.s, rec->td.loc_uri.len);
				if(node1 == NULL) goto error;
			}

			if (rec->td.obp.s && rec->td.obp.len) {
				node1 = add_mi_node_child(node, MI_DUP_VALUE,
						"proxy", 5, rec->td.obp.s, rec->td.obp.len);
				if(node1 == NULL) goto error;
			}

			switch(rec->td.forced_to_su.s.sa_family) {
			case AF_UNSPEC:
				break;
			case AF_INET:
			case AF_INET6:
				node1 = add_mi_node_child(node, MI_DUP_VALUE,
					"dst_IP", 6,
					(rec->td.forced_to_su.s.sa_family==AF_INET)?
						"IPv4":"IPv6", 4);
				sockaddr2ip_addr(&addr, &rec->td.forced_to_su.s);
				p = ip_addr2a(&addr);
				if (p == NULL) goto error;
				len = strlen(p);
				attr = add_mi_attr(node1, MI_DUP_VALUE, "ip", 2,
					p, len);
				if(attr == NULL) goto error;
				break;
			default:
				LM_ERR("unexpected sa_family [%d]\n",
					rec->td.forced_to_su.s.sa_family);
				node1 = add_mi_node_child(node, MI_DUP_VALUE,
					"dst_IP", 6, "Error", 5);
				p = int2str(rec->td.forced_to_su.s.sa_family, &len);
				attr = add_mi_attr(node, MI_DUP_VALUE, "sa_family", 9,
					p, len);
				if(attr == NULL) goto error;
			}

			rec = rec->next;
		}
		lock_release(&reg_htable[i].lock);
	}
	return rpl_tree;
error:
	lock_release(&reg_htable[i].lock);
	LM_ERR("Unable to create reply\n");
	free_mi_tree(rpl_tree);
	return NULL;
}
コード例 #6
0
ファイル: utils.c プロジェクト: BackupTheBerlios/mystun
/* add all family type addresses of interface if_name to the socket_info array
 * if if_name==0, adds all addresses on all interfaces
 * WARNING: it only works with ipv6 addresses on FreeBSD
 * return: -1 on error, 0 on success
 */
int add_interfaces(char* if_name, int family, unsigned short port)
{
	struct ifconf ifc;
	struct ifreq ifr;
	struct ifreq ifrcopy;
	char*  last;
	char* p;
	int size;
	int lastlen;
	int s;
	char* tmp;
	struct ip_addr addr;
	int ret;

#ifdef HAVE_SOCKADDR_SA_LEN
#ifndef MAX
#define MAX(a,b) ( ((a)>(b))?(a):(b))
#endif
#endif
	/* ipv4 or ipv6 only*/
	s=socket(family, SOCK_DGRAM, 0);
	ret=-1;
	lastlen=0;
	ifc.ifc_req=0;
	for (size=10; ; size*=2)
    {
		ifc.ifc_len=size*sizeof(struct ifreq);
		ifc.ifc_req=(struct ifreq*) malloc(size*sizeof(struct ifreq));
		if (ifc.ifc_req==0)
        {
			fprintf(stderr, "memory allocation failure\n");
			goto error;
		}
		if (ioctl(s, SIOCGIFCONF, &ifc)==-1)
        {
			if(errno==EBADF) return 0; /* invalid descriptor => no such ifs*/
			fprintf(stderr, "ioctl failed: %s\n", strerror(errno));
			goto error;
		}
		if  ((lastlen) && (ifc.ifc_len==lastlen)) break; /*success,  len not changed*/
		lastlen=ifc.ifc_len;
		/* try a bigger array*/
		free(ifc.ifc_req);
	}
	
	last=(char*)ifc.ifc_req+ifc.ifc_len;

	for(p=(char*)ifc.ifc_req; p<last;
       p+=(sizeof(ifr.ifr_name)+
#ifdef  HAVE_SOCKADDR_SA_LEN
        		MAX(ifr.ifr_addr.sa_len, sizeof(struct sockaddr))
#else	
			(sizeof(struct sockaddr_in))
			/*	( (ifr.ifr_addr.sa_family==AF_INET)?sizeof(struct sockaddr_in):((ifr.ifr_addr.sa_family==AF_INET6)?sizeof(struct sockaddr_in6):sizeof(struct sockaddr)) )*/
#endif
				)
		)
	{
		/* copy contents into ifr structure
		 * warning: it might be longer (e.g. ipv6 address) */
		memcpy(&ifr, p, sizeof(ifr));
		if (ifr.ifr_addr.sa_family!=family)
        {
			printf("strange family %d skipping...\n",ifr.ifr_addr.sa_family);
			continue;
		}
		
		/*get flags*/
		ifrcopy=ifr;
		if (ioctl(s, SIOCGIFFLAGS,  &ifrcopy)!=-1)
		{ /* ignore errors */
			/* ignore down ifs only if listening on all of them*/
			if (if_name==0)
			{ 
				/* if if not up, skip it*/
				if (!(ifrcopy.ifr_flags & IFF_UP)) continue;
			}
		}
		
		
		
		if ((if_name==0)||
			(strncmp(if_name, ifr.ifr_name, sizeof(ifr.ifr_name))==0))
        {
			
				/*add address*/
			if (sock_no<MAX_LISTEN)
			{
				sockaddr2ip_addr(&addr,(struct sockaddr*)(p+(long)&((struct ifreq*)0)->ifr_addr));
				if ((tmp=ip_addr2a(&addr))==0) goto error;
				/* fill the strings*/
            			sock_info[sock_no].address = addr;
				sock_info[sock_no].name.s=(char*)malloc(strlen(tmp)+1);
				if(sock_info[sock_no].name.s==0)
            			{
					fprintf(stderr, "Out of memory.\n");
					goto error;
				}
				/* fill in the new name and port */
				sock_info[sock_no].name.len=strlen(tmp);
				strncpy(sock_info[sock_no].name.s, tmp,sock_info[sock_no].name.len+1);
				sock_info[sock_no].port_no=port;
				/* mark if loopback */
				if (ifrcopy.ifr_flags & IFF_LOOPBACK) 
					sock_info[sock_no].is_lo=1;
				sock_no++;
				ret=0;
			}else
			{
				fprintf(stderr, "Too many addresses (max %d)\n", MAX_LISTEN);
				goto error;
			}
		}
			/*
			DBG("%s:\n", ifr.ifr_name);
			print_sockaddr(&(ifr.ifr_addr));
			DBG("        ");
			ls_ifflags(ifr.ifr_name, family, 0);
			DBG("\n");
            */
	}
	free(ifc.ifc_req); /*clean up*/
	close(s);
	return  ret;
error:
	if (ifc.ifc_req) free(ifc.ifc_req);
	close(s);
	return -1;
}