Beispiel #1
0
int compare_rtpp(struct rtpp_node *r_node, struct rtpp_notify_node *n_node)
{
	char buffer[BUF_LEN];
	char *p;
	struct hostent *rtpp_server;

	if (r_node->rn_umode != n_node->mode)
		return 0;

	memcpy(buffer,r_node->rn_address,strlen(r_node->rn_address));
	p = strrchr(buffer, ':');
	if (!p) {
		LM_ERR("invalid address %s\n", r_node->rn_address);
		return 0;
	}
	*p = 0;

	rtpp_server = resolvehost(buffer, 0);
	if (!rtpp_server || !rtpp_server->h_addr) {
		LM_ERR("cannot resolve hostname %s\n", r_node->rn_address);
		return 0;
	}

	if (memcmp(n_node->addr, rtpp_server->h_addr, rtpp_server->h_length)!= 0)
		return 0;
	return 1;
}
Beispiel #2
0
static union sockaddr_union *jsonrpc_get_dst(str *ip_port)
{
	static union sockaddr_union _su;
	struct hostent *hentity;
	char *p, bk;
	str host;
	str port;
	int iport;
	int err;

	if (!ip_port || !ip_port->len) {
		LM_ERR("no IP:port specified!\n");
		return NULL;
	}

	/* search for the port */
	p = memchr(ip_port->s, ':', ip_port->len);
	if (!p) {
		LM_ERR("invalid IP:port %.*s\n", ip_port->len, ip_port->s);
		return NULL;
	}
	host.s = ip_port->s;
	host.len = p - ip_port->s;

	/* remaining should be port */
	port.s = p + 1;
	port.len = ip_port->len - (host.len + 1/* : */);
	trim(&port);

	iport = str2s(port.s, port.len, &err);
	if (iport <= 0 || err != 0 || iport > 65535) {
		LM_ERR("Invalid port specified [%.*s]\n", port.len, port.s);
		return NULL;
	}

	trim(&host);

	/* null terminate host */
	bk = host.s[host.len];
	host.s[host.len] = 0;

	hentity = resolvehost(host.s, 0);
	host.s[host.len] = bk;
	if (!hentity) {
		LM_ERR("cannot resolve host %s\n", host.s);
		return NULL;
	}
	if(hostent2su(&_su, hentity, 0, iport)){
		LM_ERR("failed to resolve %s\n", host.s);
		return NULL;
	}
	
	return &_su;
}
Beispiel #3
0
uint32_t rc_get_ipaddr (char *host)
{
	const struct hostent* he;
	struct in_addr** addr_list;

	he=resolvehost(host, 0/*do test if is ip*/);

	/* FIXME the function is not for IPV6 */
	addr_list = (struct in_addr **)he->h_addr_list;
	if (addr_list[0])
		return addr_list[0]->s_addr;

	return 0;

}
Beispiel #4
0
int net_listen(char *server, int port)
{
	int fd;
	struct sockaddr_in sin;
	int on = 1;

	memset(&sin, 0, sizeof(struct sockaddr_in));
	sin.sin_family = AF_INET;
	sin.sin_port = htons(port);

	if (!inet_aton(server, &sin.sin_addr)) {
		struct hostent *host;

		LM_DBG("resolving %s...\n", server);

		if (!(host = resolvehost(server,0))) {
			LM_ERR("resolving %s failed (%s).\n", server,
					hstrerror(h_errno));
			return -1;
		}
		memcpy(&sin.sin_addr, host->h_addr_list[0], host->h_length);
	}

	if ((fd = socket(PF_INET, SOCK_STREAM, 0)) < 0) {
		LM_ERR("socket() failed: %s\n", strerror(errno));
		return -1;
	}

	LM_DBG("listening on %s:%d\n", inet_ntoa(sin.sin_addr), port);

	if (setsockopt(fd, SOL_SOCKET, SO_REUSEADDR, &on, sizeof(on)) < 0) {
		LM_WARN("setsockopt(SO_REUSEADDR) failed: %s\n",strerror(errno));
	}

	if (bind(fd, (struct sockaddr *) &sin, sizeof(struct sockaddr_in)) < 0) {
		LM_ERR("bind() failed: %s\n", strerror(errno));
		close(fd);
		return -1;
	}

	if (listen(fd, 1) < 0) {
		LM_ERR("listen() failed: %s\n", strerror(errno));
		close(fd);
		return -1;
	}

	return fd;
}
Beispiel #5
0
struct rtpp_notify_node *new_rtpp_notify_node(struct rtpp_node *crt_rtpp)
{
	char buffer[BUF_LEN];
	char *p;
	struct hostent *rtpp_server;
	struct rtpp_notify_node *rtpp_lst;

	rtpp_lst = (struct rtpp_notify_node*)
		shm_malloc(sizeof(struct rtpp_notify_node));
	if (!rtpp_lst) {
		LM_ERR("no shm more memory\n");
		return NULL;
	}

	rtpp_lst->mode = crt_rtpp->rn_umode;
	rtpp_lst->index = 0;
	rtpp_lst->next = NULL;
	memcpy(buffer,crt_rtpp->rn_address,strlen(crt_rtpp->rn_address));
	p = strrchr(buffer, ':');
	if (!p) {
		LM_ERR("invalid address %s\n", crt_rtpp->rn_address);
		goto error;
	}
	*p = 0;

	rtpp_server = resolvehost(buffer, 0);
	if (!rtpp_server || !rtpp_server->h_addr) {
		LM_ERR("cannot resolve hostname %s\n", crt_rtpp->rn_address);
		goto error;
	}

	rtpp_lst->addr = (char*)shm_malloc(rtpp_server->h_length);
	if (!rtpp_lst->addr) {
		LM_ERR("no more shm memory\n");
		goto error;
	}
	memcpy(rtpp_lst->addr,rtpp_server->h_addr,rtpp_server->h_length);
	return rtpp_lst;

error:
	shm_free(rtpp_lst);
	return NULL;

}
Beispiel #6
0
int net_connect(char *server, int port)
{
	int fd;
	struct sockaddr_in sin;

	memset(&sin, 0, sizeof(struct sockaddr_in));
	sin.sin_family = AF_INET;
	sin.sin_port = htons(port);

	if (!inet_aton(server, &sin.sin_addr)) {
		struct hostent *host;

		LM_DBG("resolving %s...\n", server);

		if (!(host = resolvehost(server,0))) {
			LM_ERR("resolving %s failed (%s).\n", server,
					hstrerror(h_errno));
			return -1;
		}
		memcpy(&sin.sin_addr, host->h_addr_list[0], host->h_length);
	}

	if ((fd = socket(PF_INET, SOCK_STREAM, 0)) < 0) {
		LM_ERR("socket() failed: %s\n", strerror(errno));
		return -1;
	}

	LM_DBG("connecting to %s:%d...\n", inet_ntoa(sin.sin_addr), port);

	if (connect(fd, (struct sockaddr *) &sin, sizeof(struct sockaddr_in)) < 0) {
		LM_ERR("connect() failed: %s\n", strerror(errno));
		close(fd);
		return -1;
	}

	LM_DBG("connected to %s:%d...\n", inet_ntoa(sin.sin_addr), port);
	return fd;
}
Beispiel #7
0
/**
 * connect to JABBER server
 */
int xj_jcon_connect(xj_jcon jbc)
{
    struct sockaddr_in address;
    struct hostent *he;
    int sock;

    // open connection to server
    if((sock = socket(AF_INET, SOCK_STREAM, 0))<0)
    {
    	LM_DBG("failed to create the socket\n");
        return -1;
    }
#ifdef XJ_EXTRA_DEBUG
	LM_DBG("socket [%d]\n", sock);
#endif
    he=resolvehost(jbc->hostname,0);
    if(he == NULL)
    {
    	LM_DBG("failed to get info about Jabber server address\n");
        return -1;
    }

    // fill the fields of the address
    memcpy(&address.sin_addr, he->h_addr, he->h_length);
    address.sin_family=AF_INET;
    address.sin_port=htons(jbc->port);

    // try to connect with Jabber server
    if (connect(sock, (struct sockaddr *)&address, sizeof(address))<0)
    {
    	LM_DBG("failed to connect with Jabber server\n");
        return -1;
    }
    jbc->sock = sock;

    return 0;
}
Beispiel #8
0
/* it initializes the TCP connection */ 
int init_mytcp(char* host, int port)
{
	int sockfd;
	struct sockaddr_in serv_addr;
	struct hostent *server;
    
	sockfd = socket(PF_INET, SOCK_STREAM, 0);
	
    if (sockfd < 0) 
	{
		LM_ERR("error creating the socket\n");
		return -1;
	}	
	
    server = resolvehost(host,0);
    if (server == NULL) 
	{
		LM_ERR("error finding the host\n");
		return -1;
    }

    memset((char *) &serv_addr, 0, sizeof(serv_addr));
    serv_addr.sin_family = PF_INET;
    memcpy((char *)&serv_addr.sin_addr.s_addr, (char *)server->h_addr,
					server->h_length);
    serv_addr.sin_port = htons(port);
	
    if (connect(sockfd, (const struct sockaddr *)&serv_addr, 
							sizeof(serv_addr)) < 0) 
	{
        LM_ERR("error connecting to the "
						"DIAMETER client\n");
		return -1;
	}	

	return sockfd;
}
Beispiel #9
0
/* internal sip srv resolver: resolves a host name trying:
 * - SRV lookup if the address is not an ip *port==0. The result of the SRV
 *   query will be used for an A/AAAA lookup.
 *  - normal A/AAAA lookup (either fallback from the above or if *port!=0
 *   and *proto!=0 or port==0 && proto==0)
 * when performing SRV lookup (*port==0) it will use *proto to look for
 * tcp or udp hosts, otherwise proto is unused; if proto==0 => no SRV lookup
 * If zt is set, name will be assumed to be 0 terminated and some copy 
 * operations will be avoided.
 * If is_srv is set it will assume name has the srv prefixes for sip already
 *  appended and it's already 0-term'ed; if not it will append them internally.
 * If ars !=0, it will first try to look through them and only if the SRV
 *   record is not found it will try doing a DNS query  (ars will not be
 *   freed, the caller should take care of them)
 * returns: hostent struct & *port filled with the port from the SRV record;
 *  0 on error
 */
struct hostent* srv_sip_resolvehost(str* name, int zt, unsigned short* port,
									char* proto, int is_srv, struct rdata* ars)
{
	struct hostent* he;
	struct ip_addr* ip;
	static char tmp[MAX_DNS_NAME]; /* tmp. buff. for SRV lookups and
	                                  null. term  strings */
	struct rdata* l;
	struct srv_rdata* srv;
	struct rdata* srv_head;
	char* srv_target;
	char srv_proto;

	/* init */
	srv_head=0;
	srv_target=0;
	if (name->len >= MAX_DNS_NAME) {
		LOG(L_ERR, "sip_resolvehost: domain name too long\n");
		he=0;
		goto end;
	}
#ifdef RESOLVE_DBG
	DBG("srv_sip_resolvehost: %.*s:%d proto=%d\n", name->len, name->s,
			port?(int)*port:-1, proto?(int)*proto:-1);
#endif
	if (is_srv){
		/* skip directly to srv resolving */
		srv_proto=(proto)?*proto:0;
		*port=(srv_proto==PROTO_TLS)?SIPS_PORT:SIP_PORT;
		if (zt){
			srv_target=name->s; /* name.s must be 0 terminated in
								  this case */
		}else{
			memcpy(tmp, name->s, name->len);
			tmp[name->len] = '\0';
			srv_target=tmp;
		}
		goto do_srv; /* skip to the actual srv query */
	}
	if (proto){ /* makes sure we have a protocol set*/
		if (*proto==0)
			*proto=srv_proto=PROTO_UDP; /* default */
		else
			srv_proto=*proto;
	}else{
		srv_proto=PROTO_UDP;
	}
	/* try SRV if no port specified (draft-ietf-sip-srv-06) */
	if ((port)&&(*port==0)){
		*port=(srv_proto==PROTO_TLS)?SIPS_PORT:SIP_PORT; /* just in case we
														  don't find another */
		/* check if it's an ip address */
		if (((ip=str2ip(name))!=0)
#ifdef	USE_IPV6
			  || ((ip=str2ip6(name))!=0) 
#endif
			 ){
			/* we are lucky, this is an ip address */
			he=ip_addr2he(name, ip);
			goto end;
		}
		if ((name->len+SRV_MAX_PREFIX_LEN+1)>MAX_DNS_NAME){
			LOG(L_WARN, "WARNING: sip_resolvehost: domain name too long (%d),"
						" unable to perform SRV lookup\n", name->len);
		}else{
			
			switch(srv_proto){
				case PROTO_NONE: /* no proto specified, use udp */
					if (proto)
						*proto=PROTO_UDP;
					/* no break */
				case PROTO_UDP:
					memcpy(tmp, SRV_UDP_PREFIX, SRV_UDP_PREFIX_LEN);
					memcpy(tmp+SRV_UDP_PREFIX_LEN, name->s, name->len);
					tmp[SRV_UDP_PREFIX_LEN + name->len] = '\0';
					break;
				case PROTO_TCP:
					memcpy(tmp, SRV_TCP_PREFIX, SRV_TCP_PREFIX_LEN);
					memcpy(tmp+SRV_TCP_PREFIX_LEN, name->s, name->len);
					tmp[SRV_TCP_PREFIX_LEN + name->len] = '\0';
					break;
				case PROTO_TLS:
					memcpy(tmp, SRV_TLS_PREFIX, SRV_TLS_PREFIX_LEN);
					memcpy(tmp+SRV_TLS_PREFIX_LEN, name->s, name->len);
					tmp[SRV_TLS_PREFIX_LEN + name->len] = '\0';
					break;
				case PROTO_SCTP:
					memcpy(tmp, SRV_SCTP_PREFIX, SRV_SCTP_PREFIX_LEN);
					memcpy(tmp+SRV_SCTP_PREFIX_LEN, name->s, name->len);
					tmp[SRV_SCTP_PREFIX_LEN + name->len] = '\0';
					break;
				default:
					LOG(L_CRIT, "BUG: sip_resolvehost: unknown proto %d\n",
							srv_proto);
					he=0;
					goto end;
			}
			srv_target=tmp;
do_srv:
			/* try to find the SRV records inside previous ARs  first*/
			for (l=ars; l; l=l->next){
				if (l->type!=T_SRV) continue; 
				srv=(struct srv_rdata*) l->rdata;
				if (srv==0){
					LOG(L_CRIT, "sip_resolvehost: BUG: null rdata\n");
					/* cleanup on exit only */
					break;
				}
				he=resolvehost(srv->name);
				if (he!=0){
					/* we found it*/
#ifdef RESOLVE_DBG
					DBG("sip_resolvehost: found SRV(%s) = %s:%d in AR\n",
							srv_target, srv->name, srv->port);
#endif
					*port=srv->port;
					/* cleanup on exit */
					goto end;
				}
			}
			srv_head=get_record(srv_target, T_SRV, RES_ONLY_TYPE);
			for(l=srv_head; l; l=l->next){
				if (l->type!=T_SRV) continue; /*should never happen*/
				srv=(struct srv_rdata*) l->rdata;
				if (srv==0){
					LOG(L_CRIT, "sip_resolvehost: BUG: null rdata\n");
					/* cleanup on exit only */
					break;
				}
				he=resolvehost(srv->name);
				if (he!=0){
					/* we found it*/
#ifdef RESOLVE_DBG
					DBG("sip_resolvehost: SRV(%s) = %s:%d\n",
							srv_target, srv->name, srv->port);
#endif
					*port=srv->port;
					/* cleanup on exit */
					goto end;
				}
			}
			if (is_srv){
				/* if the name was already into SRV format it doesn't make
				 * any sense to fall back to A/AAAA */
				he=0;
				goto end;
			}
			/* cleanup on exit */
#ifdef RESOLVE_DBG
			DBG("sip_resolvehost: no SRV record found for %.*s," 
					" trying 'normal' lookup...\n", name->len, name->s);
#endif
		}
	}
/*skip_srv:*/
	if (likely(!zt)){
		memcpy(tmp, name->s, name->len);
		tmp[name->len] = '\0';
		he=resolvehost(tmp);
	}else{
		he=resolvehost(name->s);
	}
end:
#ifdef RESOLVE_DBG
	DBG("srv_sip_resolvehost: returning %p (%.*s:%d proto=%d)\n",
			he, name->len, name->s,
			port?(int)*port:-1, proto?(int)*proto:-1);
#endif
	if (srv_head)
		free_rdata_list(srv_head);
	return he;
}
Beispiel #10
0
/* eval_elem helping function, returns an op param */
inline static int comp_ip(struct ip_addr* ip, void* param, int op, int subtype)
{
	struct hostent* he;
	char ** h;
	int ret;
	str tmp;

	ret=-1;
	switch(subtype){
		case NET_ST:
			switch(op){
				case EQUAL_OP:
					ret=(matchnet(ip, (struct net*) param)==1);
					break;
				case DIFF_OP:
					ret=(matchnet(ip, (struct net*) param)!=1);
					break;
				default:
					goto error_op;
			}
			break;
		case STRING_ST:
		case RE_ST:
			switch(op){
				case EQUAL_OP:
				case MATCH_OP:
					/* 1: compare with ip2str*/
					ret=comp_str(ip_addr2a(ip), param, op, subtype);
					if (ret==1) break;
					/* 2: resolve (name) & compare w/ all the ips */
					if (subtype==STRING_ST){
						he=resolvehost((char*)param);
						if (he==0){
							DBG("comp_ip: could not resolve %s\n",
									(char*)param);
						}else if (he->h_addrtype==ip->af){
							for(h=he->h_addr_list;(ret!=1)&& (*h); h++){
								ret=(memcmp(ip->u.addr, *h, ip->len)==0);
							}
							if (ret==1) break;
						}
					}
					/* 3: (slow) rev dns the address
					* and compare with all the aliases
					* !!??!! review: remove this? */
					he=rev_resolvehost(ip);
					if (he==0){
						print_ip( "comp_ip: could not rev_resolve ip address:"
									" ", ip, "\n");
					ret=0;
					}else{
						/*  compare with primary host name */
						ret=comp_str(he->h_name, param, op, subtype);
						/* compare with all the aliases */
						for(h=he->h_aliases; (ret!=1) && (*h); h++){
							ret=comp_str(*h, param, op, subtype);
						}
					}
					break;
				case DIFF_OP:
					ret=comp_ip(ip, param, EQUAL_OP, subtype);
					if (ret>=0) ret=!ret;
					break;
				default:
					goto error_op;
			}
			break;
		case MYSELF_ST: /* check if it's one of our addresses*/
			tmp.s=ip_addr2a(ip);
			tmp.len=strlen(tmp.s);
			ret=check_self_op(op, &tmp, 0);
			break;
		default:
			LOG(L_CRIT, "BUG: comp_ip: invalid type for "
						" src_ip or dst_ip (%d)\n", subtype);
			ret=-1;
	}
	return ret;
error_op:
	LOG(L_CRIT, "BUG: comp_ip: invalid operator %d\n", op);
	return -1;
	
}
Beispiel #11
0
/* returns 0 if ok, <0 on error */
static int fix_actions(struct action* a)
{
	struct action *t;
	struct proxy_l* p;
	char *tmp;
	int ret;
	cmd_export_t* cmd;
	struct sr_module* mod;
	str s;
	struct hostent* he;
	struct ip_addr ip;
	struct socket_info* si;
	
	if (a==0){
		LOG(L_CRIT,"BUG: fix_actions: null pointer\n");
		return E_BUG;
	}
	for(t=a; t!=0; t=t->next){
		switch(t->type){
			case FORWARD_T:
			case FORWARD_TLS_T:
			case FORWARD_TCP_T:
			case FORWARD_UDP_T:
			case SEND_T:
			case SEND_TCP_T:
					switch(t->p1_type){
						case IP_ST: 
							tmp=strdup(ip_addr2a(
										(struct ip_addr*)t->p1.data));
							if (tmp==0){
								LOG(L_CRIT, "ERROR: fix_actions:"
										"memory allocation failure\n");
								return E_OUT_OF_MEM;
							}
							t->p1_type=STRING_ST;
							t->p1.string=tmp;
							/* no break */
						case STRING_ST:
							s.s = t->p1.string;
							s.len = strlen(s.s);
							p=add_proxy(&s, t->p2.number, 0); /* FIXME proto*/
							if (p==0) return E_BAD_ADDRESS;
							t->p1.data=p;
							t->p1_type=PROXY_ST;
							break;
						case URIHOST_ST:
							break;
						default:
							LOG(L_CRIT, "BUG: fix_actions: invalid type"
									"%d (should be string or number)\n",
										t->type);
							return E_BUG;
					}
					break;
			case IF_T:
				if (t->p1_type!=EXPR_ST){
					LOG(L_CRIT, "BUG: fix_actions: invalid subtype"
								"%d for if (should be expr)\n",
								t->p1_type);
					return E_BUG;
				}else if( (t->p2_type!=ACTIONS_ST)&&(t->p2_type!=NOSUBTYPE) ){
					LOG(L_CRIT, "BUG: fix_actions: invalid subtype"
								"%d for if() {...} (should be action)\n",
								t->p2_type);
					return E_BUG;
				}else if( (t->p3_type!=ACTIONS_ST)&&(t->p3_type!=NOSUBTYPE) ){
					LOG(L_CRIT, "BUG: fix_actions: invalid subtype"
								"%d for if() {} else{...}(should be action)\n",
								t->p3_type);
					return E_BUG;
				}
				if (t->p1.data){
					if ((ret=fix_expr((struct expr*)t->p1.data))<0)
						return ret;
				}
				if ( (t->p2_type==ACTIONS_ST)&&(t->p2.data) ){
					if ((ret=fix_actions((struct action*)t->p2.data))<0)
						return ret;
				}
				if ( (t->p3_type==ACTIONS_ST)&&(t->p3.data) ){
						if ((ret=fix_actions((struct action*)t->p3.data))<0)
						return ret;
				}
				break;
			case MODULE_T:
				if ((mod=find_module(t->p1.data, &cmd))!=0){
					DBG("fixing %s %s\n", mod->path, cmd->name);
					if (cmd->fixup){
						if (cmd->param_no>0){
							ret=cmd->fixup(&t->p2.data, 1);
							t->p2_type=MODFIXUP_ST;
							if (ret<0) return ret;
						}
						if (cmd->param_no>1){
							ret=cmd->fixup(&t->p3.data, 2);
							t->p3_type=MODFIXUP_ST;
							if (ret<0) return ret;
						}
					}
				}
				break;
			case FORCE_SEND_SOCKET_T:
				if (t->p1_type!=SOCKID_ST){
					LOG(L_CRIT, "BUG: fix_actions: invalid subtype"
								"%d for force_send_socket\n",
								t->p1_type);
					return E_BUG;
				}
				he=resolvehost(((struct socket_id*)t->p1.data)->name);
				if (he==0){
					LOG(L_ERR, "ERROR: fix_actions: force_send_socket:"
								" could not resolve %s\n",
								((struct socket_id*)t->p1.data)->name);
					return E_BAD_ADDRESS;
				}
				hostent2ip_addr(&ip, he, 0);
				si=find_si(&ip, ((struct socket_id*)t->p1.data)->port,
								((struct socket_id*)t->p1.data)->proto);
				if (si==0){
					LOG(L_ERR, "ERROR: fix_actions: bad force_send_socket"
							" argument: %s:%d (ser doesn't listen on it)\n",
							((struct socket_id*)t->p1.data)->name,
							((struct socket_id*)t->p1.data)->port);
					return E_BAD_ADDRESS;
				}
				t->p1.data=si;
				t->p1_type=SOCKETINFO_ST;
				break;
		}
	}
	return 0;
}
Beispiel #12
0
int xl_mod_init()
{
#ifdef HOST_NAME_MAX
#define HOSTNAME_MAX HOST_NAME_MAX
#else
#define HOSTNAME_MAX 256
#endif
	char *s, *d;
	struct hostent *he;
	int i;

	s=(char*)pkg_malloc(HOSTNAME_MAX);
	if (gethostname(s, HOSTNAME_MAX)<0) {
		str_fullname.len = 0;
		str_fullname.s = NULL;
		str_hostname.len = 0;
		str_hostname.s = NULL;
		str_domainname.len = 0;
		str_domainname.s = NULL;
	} else {
		str_fullname.len = strlen(s);
		str_fullname.s = s;

		d=strchr(s, '.');
		if (d) {
			str_hostname.len=d-s;
			str_hostname.s=s;
			str_domainname.len=str_fullname.len-str_hostname.len-1;
			str_domainname.s=d+1;
		} else {
			str_hostname=str_fullname;
			str_domainname.len=0;
			str_domainname.s=NULL;
		}
	}
	pkg_realloc(s, str_fullname.len+1); /* this will leave the ending \0 */

	str_ipaddr.len=0;
	str_ipaddr.s=NULL;

	s=(char*)pkg_malloc(HOSTNAME_MAX);
	if (str_fullname.len) {
		he=resolvehost(str_fullname.s);
		if (he) {
			if ((strlen(he->h_name)!=str_fullname.len) || strncmp(he->h_name, str_fullname.s, str_fullname.len)) {
				LOG(L_WARN, "WARNING: xl_mod_init: DIFFERENT hostname '%.*s' and gethostbyname '%s'\n", str_fullname.len, ZSW(str_hostname.s), he->h_name);
			}

			if (he->h_addr_list) {
				for (i=0; he->h_addr_list[i]; i++) {
					if (inet_ntop(he->h_addrtype, he->h_addr_list[i], s, HOSTNAME_MAX)) {
						if (!i) {
							str_ipaddr.len=strlen(s);
							str_ipaddr.s=(char*)pkg_malloc(str_ipaddr.len);
							if (str_ipaddr.s) {
								memcpy(str_ipaddr.s, s, str_ipaddr.len);
							} else {
								str_ipaddr.len=0;
								LOG(L_ERR, "ERROR: xl_mod_init: No memory left for str_ipaddr\n");
							}
						} else {
							LOG(L_WARN, "WARNING: xl_mod_init: more IP %s not used\n", s);
						}
					}
				}
			} else {
				LOG(L_WARN, "WARNING: xl_mod_init: can't resolve hostname's address\n");
			}

		}
	}
	pkg_free(s);

	DBG("Hostname:   %.*s\n", str_hostname.len, ZSW(str_hostname.s));
	DBG("Domainname: %.*s\n", str_domainname.len, ZSW(str_domainname.s));
	DBG("Fullname:   %.*s\n", str_fullname.len, ZSW(str_fullname.s));
	DBG("IPaddr:     %.*s\n", str_ipaddr.len, ZSW(str_ipaddr.s));

	return 0;
}
static evi_reply_sock* datagram_parse(str socket, int is_unix)
{
	evi_reply_sock *sock = NULL;
	unsigned short port = 0;
	char *p = NULL, *host = 0;
	int len = 0;
	struct hostent *hentity;

	if (!socket.len || !socket.s) {
		LM_ERR("no socket specified\n");
		return NULL;
	}

	len = socket.len;
	host = socket.s;
	if (!is_unix) {
		p = memchr(host, COLON_C, len);
		if (!p || p == host) {
			LM_ERR("port not specified <%.*s>\n", len, host);
			return NULL;
		}
		port = str2s(p + 1, host + len - p - 1, 0);
		if (port == 0) {
			LM_DBG("malformed port: %.*s\n",
					(int)(host + len - p - 1), p + 1);
			return NULL;
		}
		LM_DBG("port is %d\n", port);
		len = p - host;
	}

	/* host */
	if (!host || len <= 0) {
		LM_ERR("malformed address %s\n", host);
		goto error;
	}
	sock = shm_malloc(sizeof(evi_reply_sock) + len);
	if (!sock) {
		LM_ERR("no more memory for socket\n");
		return NULL;
	}

	memset(sock, 0, sizeof(evi_reply_sock));

	/* only UDP has port */
	if (port) {
		sock->flags = EVI_PORT;
		sock->port = port;
		
		/* also build sockaddr */
		*p = 0;
		hentity = resolvehost(host, 0);
		if (!hentity) {
			LM_ERR("cannot resolve host %s\n", host);
			goto error;
		}
		if(hostent2su(&sock->src_addr.udp_addr, hentity, 0, port)){
			LM_ERR("failed to resolve %s\n", host);
			goto error;
		}
		sock->flags |= EVI_SOCKET | DGRAM_UDP_FLAG;
	} else {
		sock->src_addr.unix_addr.sun_family = AF_LOCAL;
		memcpy(sock->src_addr.unix_addr.sun_path, host, len);
		sock->src_addr.unix_addr.sun_path[len] = 0;
		sock->flags |= EVI_SOCKET | DGRAM_UNIX_FLAG;
	}

	LM_DBG("address is <%.*s>\n", len, host);
	sock->address.s = (char *) (sock + 1);
	sock->address.len = len;
	memcpy(sock->address.s, host, len);
	sock->flags |= EVI_ADDRESS;

	/* needs expire */
	sock->flags |= EVI_EXPIRE;

	return sock;
error:
	if (sock)
		shm_free(sock);
	return NULL;
}
Beispiel #14
0
/**
 * @brief build a dmq node
 */
dmq_node_t *build_dmq_node(str *uri, int shm)
{
	dmq_node_t *ret = NULL;
	param_hooks_t hooks;
	param_t *params;

	/* For DNS-Lookups */
	static char hn[256];
	struct hostent *he;

	LM_DBG("build_dmq_node %.*s with %s memory\n", STR_FMT(uri),
			shm ? "shm" : "private");

	if(shm) {
		ret = shm_malloc(sizeof(dmq_node_t));
		if(ret == NULL) {
			LM_ERR("no more shm\n");
			goto error;
		}
		memset(ret, 0, sizeof(dmq_node_t));
		if(shm_str_dup(&ret->orig_uri, uri) < 0) {
			goto error;
		}
	} else {
		ret = pkg_malloc(sizeof(dmq_node_t));
		if(ret == NULL) {
			LM_ERR("no more pkg\n");
			goto error;
		}
		memset(ret, 0, sizeof(dmq_node_t));
		if(pkg_str_dup(&ret->orig_uri, uri) < 0) {
			goto error;
		}
	}
	set_default_dmq_node_params(ret);
	if(parse_uri(ret->orig_uri.s, ret->orig_uri.len, &ret->uri) < 0
			|| ret->uri.host.len > 254) {
		LM_ERR("error parsing uri\n");
		goto error;
	}
	/* if any parameters found, parse them */
	if(parse_params(&ret->uri.params, CLASS_ANY, &hooks, &params) < 0) {
		LM_ERR("error parsing params\n");
		goto error;
	}
	/* if any params found */
	if(params) {
		if(set_dmq_node_params(ret, params) < 0) {
			free_params(params);
			LM_ERR("error setting parameters\n");
			goto error;
		}
		free_params(params);
	} else {
		LM_DBG("no dmqnode params found\n");
	}
	/* resolve hostname */
	strncpy(hn, ret->uri.host.s, ret->uri.host.len);
	hn[ret->uri.host.len] = '\0';
	he = resolvehost(hn);
	if(he == 0) {
		LM_ERR("could not resolve %.*s\n", ret->uri.host.len, ret->uri.host.s);
		goto error;
	}
	hostent2ip_addr(&ret->ip_address, he, 0);

	return ret;

error:
	if(ret != NULL) {
		destroy_dmq_node(ret, shm);
	}
	return NULL;
}
Beispiel #15
0
static int mi_mod_init(void)
{
	unsigned int port_no;
	int n;
	struct stat filestat;
	struct hostent * host;
	char *p, *host_s;
	str port_str;

	/* checking the mi_socket module param */
	LM_DBG("testing socket existance...\n");

	if( mi_socket==NULL || *mi_socket == 0) {
		LM_ERR("no DATAGRAM_ socket configured\n");
		return -1;
	}

	LM_DBG("the socket's name/address is %s\n", mi_socket);

	memset( &mi_dtgram_addr, 0, sizeof(mi_dtgram_addr) );

	if(strncmp(mi_socket, "udp:",4) == 0)
	{
		/*for an UDP socket*/
		LM_DBG("we have an udp socket\n");
		/*separate proto and host */
		p = mi_socket+4;
		if( (*(p)) == '\0') {
			LM_ERR("malformed ip address\n");
			return -1;
		}
		host_s=p;
		LM_DBG("the remaining address after separating the protocol is %s\n",p);

		if( (p = strrchr(p+1, ':')) == 0 ) {
			LM_ERR("no port specified\n");
			return -1;
		}

		/*the address contains a port number*/
		*p = '\0';
		p++;
		port_str.s = p;
		port_str.len = strlen(p);
		LM_DBG("the port string is %s\n", p);
		if(str2int(&port_str, &port_no) != 0 ) {
			LM_ERR("there is not a valid number port\n");
			return -1;
		}
		*p = '\0';
		if (port_no<1024  || port_no>MAX_NB_PORT)
		{
			LM_ERR("invalid port number; must be in [1024,%d]\n",MAX_NB_PORT);
			return -1;
		}
		
		if(! (host = resolvehost(host_s)) ) {
			LM_ERR("failed to resolve %s\n", host_s);
			return -1;
		}
		LM_DBG("the ip is %s\n",host_s);
		if(hostent2su( &(mi_dtgram_addr.udp_addr), host, 0, port_no ) !=0){
			LM_ERR("failed to resolve %s\n", mi_socket);
			return -1;
		}
		mi_socket_domain = host->h_addrtype;
		goto done;
	} 
	/* in case of a Unix socket*/
	LM_DBG("we have an UNIX socket\n");
		
	n=stat(mi_socket, &filestat);
	if( n==0) {
		LM_INFO("the socket %s already exists, trying to delete it...\n", mi_socket);
		if(config_check==0) {
			if (unlink(mi_socket)<0) {
				LM_ERR("cannot delete old socket: %s\n", strerror(errno));
				return -1;
			}
		}
	} else if (n<0 && errno!=ENOENT) {
		LM_ERR("socket stat failed:%s\n", strerror(errno));
		return -1;
	}

	/* check mi_unix_socket_mode */
	if(!mi_unix_socket_mode) {
		LM_WARN("cannot specify mi_unix_socket_mode = 0, forcing it to rw-------\n");
		mi_unix_socket_mode = S_IRUSR| S_IWUSR;
	}
	
	if (mi_unix_socket_uid_s) {
		if (user2uid(&mi_unix_socket_uid, &mi_unix_socket_gid, mi_unix_socket_uid_s)<0) {
			LM_ERR("bad user name %s\n", mi_unix_socket_uid_s);
			return -1;
		}
	}
	
	if (mi_unix_socket_gid_s) {
		if (group2gid(&mi_unix_socket_gid, mi_unix_socket_gid_s)<0) {
			LM_ERR("bad group name %s\n", mi_unix_socket_gid_s);
			return -1;
		}
	}

	/*create the unix socket address*/
	mi_dtgram_addr.unix_addr.sun_family = AF_LOCAL;
	memcpy( mi_dtgram_addr.unix_addr.sun_path, mi_socket, strlen(mi_socket));

done:
	/* add space for extra processes */
	register_procs(mi_procs[0].no);
	/* add child to update local config framework structures */
	cfg_register_child(mi_procs[0].no);

	return 0;
}
Beispiel #16
0
/* fixes a socket list => resolve addresses, 
 * interface names, fills missing members, remove duplicates
 * fills type_flags if not null with SOCKET_T_IPV4 and/or SOCKET_T_IPV6*/
static int fix_socket_list(struct socket_info **list, int* type_flags)
{
	struct socket_info* si;
	struct socket_info* l;
	struct socket_info* next;
	char* tmp;
	int len;
	struct hostent* he;
	char** h;
	
	if (type_flags)
		*type_flags=0;
	/* try to change all the interface names into addresses
	 *  --ugly hack */
	for (si=*list;si;){
		next=si->next;
		if (add_interfaces(si->name.s, AF_INET, si->port_no,
							si->proto, list)!=-1){
			/* success => remove current entry (shift the entire array)*/
			sock_listrm(list, si);
			free_sock_info(si);
		}
		si=next;
	}
	/* get ips & fill the port numbers*/
#ifdef EXTRA_DEBUG
	DBG("Listening on \n");
#endif
	for (si=*list;si;si=si->next){
		/* fix port number, port_no should be !=0 here */
		if (si->port_no==0){
#ifdef USE_TLS
			si->port_no= (si->proto==PROTO_TLS)?tls_port_no:port_no;
#else
			si->port_no= port_no;
#endif
		}
		tmp=int2str(si->port_no, &len);
		if (len>=MAX_PORT_LEN){
			LOG(L_ERR, "ERROR: fix_socket_list: bad port number: %d\n", 
						si->port_no);
			goto error;
		}
		si->port_no_str.s=(char*)pkg_malloc(len+1);
		if (si->port_no_str.s==0){
			LOG(L_ERR, "ERROR: fix_socket_list: out of memory.\n");
			goto error;
		}
		strncpy(si->port_no_str.s, tmp, len+1);
		si->port_no_str.len=len;
		
		/* get "official hostnames", all the aliases etc. */
		he=resolvehost(si->name.s);
		if (he==0){
			LOG(L_ERR, "ERROR: fix_socket_list: could not resolve %s\n",
					si->name.s);
			goto error;
		}
		/* check if we got the official name */
		if (strcasecmp(he->h_name, si->name.s)!=0){
			if (add_alias(si->name.s, si->name.len,
							si->port_no, si->proto)<0){
				LOG(L_ERR, "ERROR: fix_socket_list: add_alias failed\n");
			}
			/* change the official name */
			pkg_free(si->name.s);
			si->name.s=(char*)pkg_malloc(strlen(he->h_name)+1);
			if (si->name.s==0){
				LOG(L_ERR,  "ERROR: fix_socket_list: out of memory.\n");
				goto error;
			}
			si->name.len=strlen(he->h_name);
			strncpy(si->name.s, he->h_name, si->name.len+1);
		}
		/* add the aliases*/
		for(h=he->h_aliases; h && *h; h++)
			if (add_alias(*h, strlen(*h), si->port_no, si->proto)<0){
				LOG(L_ERR, "ERROR: fix_socket_list: add_alias failed\n");
			}
		hostent2ip_addr(&si->address, he, 0); /*convert to ip_addr 
														 format*/
		if (type_flags){
			*type_flags|=(si->address.af==AF_INET)?SOCKET_T_IPV4:SOCKET_T_IPV6;
		}
		if ((tmp=ip_addr2a(&si->address))==0) goto error;
		si->address_str.s=(char*)pkg_malloc(strlen(tmp)+1);
		if (si->address_str.s==0){
			LOG(L_ERR, "ERROR: fix_socket_list: out of memory.\n");
			goto error;
		}
		strncpy(si->address_str.s, tmp, strlen(tmp)+1);
		/* set is_ip (1 if name is an ip address, 0 otherwise) */
		si->address_str.len=strlen(tmp);
		if 	(	(si->address_str.len==si->name.len)&&
				(strncasecmp(si->address_str.s, si->name.s,
								si->address_str.len)==0)
			){
				si->flags|=SI_IS_IP;
				/* do rev. DNS on it (for aliases)*/
				he=rev_resolvehost(&si->address);
				if (he==0){
					LOG(L_WARN, "WARNING: fix_socket_list:"
							" could not rev. resolve %s\n",
							si->name.s);
				}else{
					/* add the aliases*/
					if (add_alias(he->h_name, strlen(he->h_name),
									si->port_no, si->proto)<0){
						LOG(L_ERR, "ERROR: fix_socket_list:"
									"add_alias failed\n");
					}
					for(h=he->h_aliases; h && *h; h++)
						if (add_alias(*h,strlen(*h),si->port_no,si->proto)<0){
							LOG(L_ERR, "ERROR: fix_socket_list:"
									" add_alias failed\n");
						}
				}
		}

#ifdef USE_MCAST
		     /* Check if it is an multicast address and
		      * set the flag if so
		      */
		if (is_mcast(&si->address)) {
			si->flags |= SI_IS_MCAST;
		}
#endif /* USE_MCAST */

#ifdef EXTRA_DEBUG
		printf("              %.*s [%s]:%s%s\n", si->name.len, 
				si->name.s, si->address_str.s, si->port_no_str.s,
		                si->flags & SI_IS_MCAST ? " mcast" : "");
#endif
	}
	/* removing duplicate addresses*/
	for (si=*list;si; si=si->next){
		for (l=si->next;l;){
			next=l->next;
			if ((si->port_no==l->port_no) &&
				(si->address.af==l->address.af) &&
				(memcmp(si->address.u.addr, l->address.u.addr, si->address.len)
					== 0)
				){
#ifdef EXTRA_DEBUG
				printf("removing duplicate %s [%s] ==  %s [%s]\n",
						si->name.s, si->address_str.s,
						 l->name.s, l->address_str.s);
#endif
				/* add the name to the alias list*/
				if ((!(l->flags& SI_IS_IP)) && (
						(l->name.len!=si->name.len)||
						(strncmp(l->name.s, si->name.s, si->name.len)!=0))
					)
					add_alias(l->name.s, l->name.len, l->port_no, l->proto);
						
				/* remove l*/
				sock_listrm(list, l);
				free_sock_info(l);
			}
			l=next;
		}
	}

#ifdef USE_MCAST
	     /* Remove invalid multicast entries */
	si=*list;
	while(si){
		if ((si->flags & SI_IS_MCAST) && 
		    ((si->proto == PROTO_TCP)
#ifdef USE_TLS
		    || (si->proto == PROTO_TLS)
#endif /* USE_TLS */
		    )){
			LOG(L_WARN, "WARNING: removing entry %s:%s [%s]:%s\n",
			    get_proto_name(si->proto), si->name.s, 
			    si->address_str.s, si->port_no_str.s);
			l = si;
			si=si->next;
			sock_listrm(list, l);
			free_sock_info(l);
		} else {
			si=si->next;
		}
	}
#endif /* USE_MCAST */

	return 0;
error:
	return -1;
}
Beispiel #17
0
/* Find all the NetBIOS names associated using supplied host name */
struct NodeStatusInfo *
SMBGetNodeStatus(const char *hostName, uint32_t *outCount)
{
    struct NodeStatusInfo *outAddr = NULL, *listAddr;
    CFMutableArrayRef addressArray = NULL;
    CFMutableDataRef theData;
    CFMutableArrayRef nbrrArray;
    CFIndex ii;
    uint32_t jj;
    struct connectAddress *conn;
    struct nb_ctx ctx;
    struct smb_prefs prefs;
    int error;

    bzero(&ctx, sizeof(struct nb_ctx));
    /* Read the preference files */
    readPreferences(&prefs, NULL, NULL, FALSE, TRUE);
    /* Resolve the host name into a list of address */
    error = resolvehost(hostName, &addressArray, NULL, NBNS_UDP_PORT_137, TRUE, FALSE);
    if (error) {
        goto done;
    }
    /* Allocate the memory needed to hold the list of address and info */
    listAddr = outAddr = malloc(CFArrayGetCount(addressArray) * sizeof(struct NodeStatusInfo));
    if (outAddr == NULL) {
        error = ENOMEM;
        goto done;
    }

    for (ii=0; ii < CFArrayGetCount(addressArray); ii++) {
        theData = (CFMutableDataRef)CFArrayGetValueAtIndex(addressArray, ii);
        if (! theData) {
            continue;
        }
        conn = (struct connectAddress *)(void *)CFDataGetMutableBytePtr(theData);
        if (!conn) {
            continue;
        }
        memcpy(&listAddr->node_storage, &conn->storage, sizeof(conn->storage));
        listAddr->node_servername[0] = (char)0;
        listAddr->node_workgroupname[0] = (char)0;
        listAddr->node_nbrrArray = NULL;
        /* Creating the array causes nbns_getnodestatus to return a full list */
        nbrrArray = CFArrayCreateMutable(kCFAllocatorSystemDefault, 0,
                                         &kCFTypeArrayCallBacks );
        listAddr->node_errno = nbns_getnodestatus(&conn->addr, &ctx, &prefs, NULL,
                               listAddr->node_servername,
                               listAddr->node_workgroupname,
                               nbrrArray);

        if (nbrrArray && (listAddr->node_errno == 0)) {
            struct NBResourceRecord *nbrrDest;

            listAddr->node_nbrrArrayCnt = (uint32_t)CFArrayGetCount(nbrrArray);
            if (listAddr->node_nbrrArrayCnt) {
                listAddr->node_nbrrArray = malloc(listAddr->node_nbrrArrayCnt * sizeof(struct NBResourceRecord));
            }
            nbrrDest = listAddr->node_nbrrArray;
            if (listAddr->node_nbrrArray)
                for (jj=0; jj < listAddr->node_nbrrArrayCnt; jj++) {
                    struct NBResourceRecord *nbrrSrc = NULL;

                    theData = (CFMutableDataRef)CFArrayGetValueAtIndex(nbrrArray, jj);
                    if (theData) {
                        nbrrSrc = (struct NBResourceRecord *)(void *)CFDataGetMutableBytePtr(theData);
                    }
                    if (nbrrSrc == NULL) {
                        listAddr->node_errno = ENOMEM;
                        break;
                    }
                    memcpy(nbrrDest, nbrrSrc, sizeof(*nbrrSrc));
                    nbrrDest++;
                }
        }
        if ((listAddr->node_errno) && (listAddr->node_nbrrArray)) {
            free(listAddr->node_nbrrArray);
            listAddr->node_nbrrArray = NULL;
            listAddr->node_nbrrArrayCnt = 0;
        }
        /* Done release it */
        if (nbrrArray) {
            CFRelease(nbrrArray);
        }
        listAddr++;
        *outCount += 1;
    }

    if (*outCount == 0) {
        free(outAddr);
        outAddr = NULL; /* Didn't really find any */
        error = EHOSTUNREACH;
    }

done:
    if (addressArray) {
        CFRelease(addressArray);
    }
    releasePreferenceInfo(&prefs);
    errno = error;
    return outAddr;
}
Beispiel #18
0
/**
 * stats socket sould be an IP_address:port or unix://path/to_file
 * TODO handling unix sockets and IPv6 !!
 *
 * returns
 * 0 if no stats
 * 1 if stats properly started
 * -1 if error
 */
int start_stats_server(char *stats_socket)
{
   char *p,*port;
   unsigned short stats_port;
   struct hostent *he;
   /*use sockaddr_storage ??*/
   struct sockaddr_in su;
   int optval;

   use_stats=0;
   port=(char *)0;
   he=(struct hostent *)0;
   stats_fd=-1;
   p=stats_socket;

   if(p==0 || *p==0)
      return 0;

   if(!init_seas_stats_table()){
      LM_ERR("unable to init stats table, disabling statistics\n");
      return -1;
   }
   while(*p){
      if(*p == ':'){
	 *p=0;
	 port=p+1;
	 break;
      }
   }
   if(!(he=resolvehost(stats_socket,0)))
      goto error;
   if(port==(char*)0 || *port==0)
      stats_port=5088;
   else if(!(stats_port=str2s(port,strlen(port),0))){
	 LM_ERR("invalid port %s\n",port);
	 goto error;
      }
   if((stats_fd=socket(he->h_addrtype, SOCK_STREAM, 0))==-1){
      LM_ERR("trying to open server socket (%s)\n",strerror(errno));
      goto error;
   }
   optval=1;
   if (setsockopt(stats_fd, SOL_SOCKET, SO_REUSEADDR, (void*)&optval, sizeof(optval))==-1) {
      LM_ERR("setsockopt (%s)\n",strerror(errno));
      goto error;
   }
   su.sin_family = he->h_addrtype;
   su.sin_port=htons(stats_port);
   memcpy(&su.sin_addr,he->h_addr_list[0],4);
   if((bind(stats_fd,(struct sockaddr*)&su,sizeof(struct sockaddr_in)))==-1){
      LM_ERR( "bind (%s)\n",strerror(errno));
      goto error;
   }
   if(listen(stats_fd, 10)==-1){
      LM_ERR( "listen (%s)\n",strerror(errno));
      goto error;
   }
   if(!(pid=fork())){/*child*/
      signal(SIGTERM,sig_handler);
      serve_stats(stats_fd);
      printf("statistics Server Process exits !!\n");
      exit(0);
   }else if(pid>0){/*parent*/
      close(stats_fd);
   }else{/*error*/
      LM_ERR("failed to create stats server process\n");
      goto error;
   }
   use_stats=1;
   return 1;
error:
   if(stats_fd!=-1)
      close(stats_fd);
   destroy_seas_stats_table();
   return -1;
}
Beispiel #19
0
/*
 * This is the parsing function
 * The socket grammar should be:
 * 		 ip ':' port '/optional/path' ':' method
 */
static evi_reply_sock* xmlrpc_parse(str socket)
{
	evi_reply_sock *sock = NULL;
	unsigned short port = 0;
	char *p = NULL;
	str host, path=str_init(NULL);
	struct hostent *hentity;
	int len;
	struct xmlrpc_sock_param *params;

	int http_buf_len=0;

	if (!socket.len || !socket.s) {
		LM_ERR("no socket specified\n");
		return NULL;
	}

	if (!(params=shm_malloc(sizeof(struct xmlrpc_sock_param)))) {
		LM_ERR("no more pkg mem!\n");
		return NULL;
	}
	memset(params, 0, sizeof(struct xmlrpc_sock_param));

	/* extract host */
	host.s = socket.s;
	p = memchr(socket.s, COLON_C, socket.len);
	if (!p || p == socket.s) {
		LM_ERR("port not specified <%.*s>\n", socket.len, socket.s);
		return NULL;
	}
	host.len = p - socket.s;

	/* used to resolve host */
	*p = '\0';
	/* skip colon */
	socket.s += host.len + 1;
	socket.len -= host.len + 1;

	LM_DBG("host is %.*s - remains <%.*s>[%d]\n", host.len, host.s,
			socket.len, socket.s, socket.len);

	if (!socket.len || *socket.s == '\0') {
		LM_ERR("invalid port number\n");
		return NULL;
	}

	p = memchr(socket.s, COLON_C, socket.len);
	if (!p || p == socket.s) {
		LM_ERR("method not specified <%.*s>\n", socket.len, socket.s);
		return NULL;
	}

	port = str2s(socket.s, p - socket.s, 0);
	if (port == 0) {
		/* most probably we've got path */
		if ((path.s=(q_memchr(socket.s, SLASH_C, p-socket.s)))==NULL) {
			LM_ERR("malformed port: %.*s\n",(int)(p - socket.s), socket.s);
			return NULL;
		} else {
			port=str2s(socket.s, path.s-socket.s, 0);
			if (port == 0) {
				LM_ERR("malformed port: %.*s\n",(int)(p - socket.s), socket.s);
				return NULL;
			}

			path.len = p - path.s;

			socket.len -= ((path.s+path.len)-socket.s);
			socket.s = path.s+path.len;
		}

		/* will use this later for allocation */
		http_buf_len=LENOF(XMLRPC_HTTP_METHOD) +  path.len +
			LENOF(XMLRPC_HTTP_PROTO_HOST);
	}

	/* jump over ':' */
	socket.len = socket.len - (p - socket.s + 1);
	socket.s = p + 1;

	LM_DBG("port is %hu - remains <%.*s>[%d]\n",
			port, socket.len, socket.s, socket.len);

	if (socket.len <= 0 || *socket.s == '\0') {
		LM_ERR("invalid method name\n");
		return NULL;
	}

	len = sizeof(evi_reply_sock) + host.len
		+ sizeof(struct xmlrpc_sock_param)
		+ socket.len /* this is method */+ http_buf_len;
	sock = shm_malloc(len);
	if (!sock) {
		LM_ERR("no more memory for socket\n");
		return NULL;
	}

	memset(sock, 0, len);
	/* only UDP has port */
	sock->flags = EVI_PORT;
	sock->port = port;

	/* also build sockaddr */
	hentity = resolvehost(host.s, 0);
	if (!hentity) {
		LM_ERR("cannot resolve host %s\n", host.s);
		goto error;
	}
	if(hostent2su(&sock->src_addr.udp_addr, hentity, 0, port)){
		LM_ERR("failed to resolve %s\n", host.s);
		goto error;
	}
	sock->flags |= EVI_SOCKET;

	/* address */
	sock->address.s = (char*)(sock+1);
	sock->address.len = host.len;
	memcpy(sock->address.s, host.s, host.len);
	sock->flags |= EVI_ADDRESS;



	/* copy parameters: path and method */
	params = (struct xmlrpc_sock_param*)(sock->address.s + host.len);
	params->method.s = (char*)(params+1);

	memcpy(params->method.s, socket.s, socket.len);
	params->method.len = socket.len;

	if (http_buf_len) {
		/* build only once; not for every message */
		params->first_line.s = (char*)(params->method.s+socket.len);

		memcpy(params->method.s, socket.s, socket.len);

		params->first_line.len = 0;

		memcpy(params->first_line.s,
				XMLRPC_HTTP_METHOD, LENOF(XMLRPC_HTTP_METHOD));
		params->first_line.len = LENOF(XMLRPC_HTTP_METHOD);

		memcpy(params->first_line.s+params->first_line.len, path.s, path.len);
		params->first_line.len += path.len;

		memcpy(params->first_line.s+params->first_line.len, XMLRPC_HTTP_PROTO_HOST,
				LENOF(XMLRPC_HTTP_PROTO_HOST));
		params->first_line.len += LENOF(XMLRPC_HTTP_PROTO_HOST);
	} else {
		params->first_line.s = XMLRPC_HTTP_CONST;
		params->first_line.len = LENOF(XMLRPC_HTTP_CONST);
	}



	sock->flags |= EVI_PARAMS;

	/* needs expire */
	sock->flags |= EVI_EXPIRE|XMLRPC_FLAG;

	sock->params= params;

	return sock;
error:
	if (sock)
		shm_free(sock);
	return NULL;
}
Beispiel #20
0
/*! \brief Adds the proxies in the proxy list & resolves the hostnames 
 * \return 0 if ok, <0 on error */
static int fix_actions(struct action* a)
{
	struct action *t;
	int ret;
	cmd_export_t* cmd;
	struct hostent* he;
	struct ip_addr ip;
	struct socket_info* si;
	str host;
	int proto=PROTO_NONE, port;
	struct proxy_l *p;
	struct bl_head *blh;
	int i;
	str s;
	pv_elem_t *model=NULL;
	pv_elem_t *models[5]; 
	xl_level_p xlp;

	if (a==0){
		LM_CRIT("null pointer\n");
		return E_BUG;
	}
	for(t=a; t!=0; t=t->next){
		switch(t->type){
			case ROUTE_T:
				if (t->elem[0].type!=NUMBER_ST){
					LM_ALERT("BUG in route() type %d\n",
						t->elem[0].type);
					ret = E_BUG;
					goto error;
				}
				if ((t->elem[0].u.number>RT_NO)||(t->elem[0].u.number<0)){
					LM_ALERT("invalid routing table number in"
							"route(%lu)\n", t->elem[0].u.number);
					ret = E_CFG;
					goto error;
				}
				if ( rlist[t->elem[0].u.number].a==NULL ) {
					LM_ERR("called route %d is not defined\n",
						(int)t->elem[0].u.number);
					ret = E_CFG;
					goto error;
				}
				break;
			case FORWARD_T:
				if (sl_fwd_disabled>0) {
					LM_ERR("stateless forwarding disabled, but forward() "
						"is used!!\n");
					ret = E_CFG;
					goto error;
				}
				sl_fwd_disabled = 0;
				if (t->elem[0].type==NOSUBTYPE)
					break;
			case SEND_T:
				if (t->elem[0].type!=STRING_ST) {
					LM_CRIT("invalid type %d (should be string)\n", t->type);
					ret = E_BUG;
					goto error;
				}
				ret = parse_phostport( t->elem[0].u.string,
						strlen(t->elem[0].u.string),
						&host.s, &host.len, &port, &proto);
				if (ret!=0) {
					LM_ERR("ERROR:fix_actions: FORWARD/SEND bad "
						"argument\n");
					ret = E_CFG;
					goto error;
				}
				p = add_proxy( &host,(unsigned short)port, proto);
				if (p==0) {
					LM_ERR("forward/send failed to add proxy");
					ret = E_CFG;
					goto error;
				}
				t->elem[0].type = PROXY_ST;
				t->elem[0].u.data = (void*)p;
				break;
			case IF_T:
				if (t->elem[0].type!=EXPR_ST){
					LM_CRIT("invalid subtype %d for if (should be expr)\n",
								t->elem[0].type);
					ret = E_BUG;
					goto error;
				}else if( (t->elem[1].type!=ACTIONS_ST)
						&&(t->elem[1].type!=NOSUBTYPE) ){
					LM_CRIT("invalid subtype %d for if() {...} (should be"
								"action)\n", t->elem[1].type);
					ret = E_BUG;
					goto error;
				}else if( (t->elem[2].type!=ACTIONS_ST)
						&&(t->elem[2].type!=NOSUBTYPE) ){
					LM_CRIT("invalid subtype %d for if() {} else{...}(should"
							"be action)\n", t->elem[2].type);
					ret = E_BUG;
					goto error;
				}
				if (t->elem[0].u.data){
					if ((ret=fix_expr((struct expr*)t->elem[0].u.data))<0)
						return ret;
				}
				if ( (t->elem[1].type==ACTIONS_ST)&&(t->elem[1].u.data) ){
					if ((ret=fix_actions((struct action*)t->elem[1].u.data))<0)
						return ret;
				}
				if ( (t->elem[2].type==ACTIONS_ST)&&(t->elem[2].u.data) ){
					if((ret=fix_actions((struct action*)t->elem[2].u.data))<0)
						return ret;
				}
				break;
			case WHILE_T:
				if (t->elem[0].type!=EXPR_ST){
					LM_CRIT("invalid subtype %d for while (should be expr)\n",
								t->elem[0].type);
					ret = E_BUG;
					goto error;
				}else if( (t->elem[1].type!=ACTIONS_ST)
						&&(t->elem[1].type!=NOSUBTYPE) ){
					LM_CRIT("invalid subtype %d for while() {...} (should be"
								"action)\n", t->elem[1].type);
					ret = E_BUG;
					goto error;
				}
				if (t->elem[0].u.data){
					if ((ret=fix_expr((struct expr*)t->elem[0].u.data))<0)
						return ret;
				}
				if ( (t->elem[1].type==ACTIONS_ST)&&(t->elem[1].u.data) ){
					if ((ret=fix_actions((struct action*)t->elem[1].u.data))<0)
						return ret;
				}
				break;
			case SWITCH_T:
				if ( (t->elem[1].type==ACTIONS_ST)&&(t->elem[1].u.data) ){
					if ((ret=fix_actions((struct action*)t->elem[1].u.data))<0)
						return ret;
				}
				break;
			case CASE_T:
				if ( (t->elem[1].type==ACTIONS_ST)&&(t->elem[1].u.data) ){
					if ((ret=fix_actions((struct action*)t->elem[1].u.data))<0)
						return ret;
				}
				break;
			case DEFAULT_T:
				if ( (t->elem[0].type==ACTIONS_ST)&&(t->elem[0].u.data) ){
					if ((ret=fix_actions((struct action*)t->elem[0].u.data))<0)
						return ret;
				}
				break;
			case MODULE_T:
				cmd = (cmd_export_t*)t->elem[0].u.data;
				LM_DBG("fixing %s, line %d\n", cmd->name, t->line);
				if (cmd->fixup){
					if (cmd->param_no==0){
						ret=cmd->fixup( 0, 0);
						if (ret<0) goto error;
					}
					else {
						for (i=1; i<=cmd->param_no; i++) {
							ret=cmd->fixup(&t->elem[i].u.data, i);
							t->elem[i].type=MODFIXUP_ST;
							if (ret<0) goto error;
						}
					}
				}
				break;
			case FORCE_SEND_SOCKET_T:
				if (t->elem[0].type!=SOCKID_ST){
					LM_CRIT("invalid subtype %d for force_send_socket\n",
								t->elem[0].type);
					ret = E_BUG;
					goto error;
				}
				he=resolvehost(((struct socket_id*)t->elem[0].u.data)->name,0);
				if (he==0){
					LM_ERR(" could not resolve %s\n",
								((struct socket_id*)t->elem[0].u.data)->name);
					ret = E_BAD_ADDRESS;
					goto error;
				}
				hostent2ip_addr(&ip, he, 0);
				si=find_si(&ip, ((struct socket_id*)t->elem[0].u.data)->port,
								((struct socket_id*)t->elem[0].u.data)->proto);
				if (si==0){
					LM_ERR("bad force_send_socket"
						" argument: %s:%d (opensips doesn't listen on it)\n",
						((struct socket_id*)t->elem[0].u.data)->name,
						((struct socket_id*)t->elem[0].u.data)->port);
					ret = E_BAD_ADDRESS;
					goto error;
				}
				t->elem[0].u.data=si;
				t->elem[0].type=SOCKETINFO_ST;
				break;
			case SET_DEBUG_T:
				if (t->elem[0].type==NOSUBTYPE)
					break;
				if (t->elem[0].type!=NUMBER_ST) {
					LM_CRIT("fix_actions: BUG in setdebug() type %d\n",
						t->elem[0].type );
					ret=E_BUG;
					goto error;
				}
				/* normalize the value */
				if (t->elem[0].u.number>L_DBG)
					t->elem[0].u.number = L_DBG;
				else if (t->elem[0].u.number<L_ALERT)
					t->elem[0].u.number = L_ALERT;
				break;
			case SETFLAG_T:
			case RESETFLAG_T:
			case ISFLAGSET_T:
				if (t->elem[0].type!=NUMBER_ST) {
					LM_CRIT("bad xxxflag() type %d\n", t->elem[0].type );
					ret=E_BUG;
					goto error;
				}
				if (!flag_in_range( t->elem[0].u.number )) {
					ret=E_CFG;
					goto error;
				}
				break;
			case SETSFLAG_T:
			case RESETSFLAG_T:
			case ISSFLAGSET_T:
				if (t->elem[0].type!=NUMBER_ST) {
					LM_CRIT("bad xxxsflag() type %d\n", t->elem[0].type );
					ret=E_BUG;
					goto error;
				}
				t->elem[0].u.number = fixup_flag( t->elem[0].u.number );
				if (t->elem[0].u.data==0) {
					ret=E_CFG;
					goto error;
				}
				break;
			case SETBFLAG_T:
			case RESETBFLAG_T:
			case ISBFLAGSET_T:
				if (t->elem[0].type!=NUMBER_ST || t->elem[1].type!=NUMBER_ST) {
					LM_CRIT("bad xxxbflag() type "
						"%d,%d\n", t->elem[0].type, t->elem[0].type);
					ret=E_BUG;
					goto error;
				}
				t->elem[1].u.number = fixup_flag( t->elem[1].u.number );
				if (t->elem[1].u.data==0) {
					ret=E_CFG;
					goto error;
				}
				break;
			case EQ_T:
			case COLONEQ_T:
			case PLUSEQ_T:
			case MINUSEQ_T:
			case DIVEQ_T:
			case MULTEQ_T:
			case MODULOEQ_T:
			case BANDEQ_T:
			case BOREQ_T:
			case BXOREQ_T:
				if (t->elem[1].u.data){
					if ((ret=fix_expr((struct expr*)t->elem[1].u.data))<0)
						return ret;
				}
				break;
			case USE_BLACKLIST_T:
			case UNUSE_BLACKLIST_T:
				if (t->elem[0].type!=STRING_ST) {
					LM_CRIT("bad [UN]USE_BLACKLIST type %d\n",t->elem[0].type);
					ret=E_BUG;
					goto error;
				}
				host.s = t->elem[0].u.string;
				host.len = strlen(host.s);
				if ( strcasecmp(host.s,"all")==0 ) {
					blh = NULL;
				} else {
					blh = get_bl_head_by_name(&host);
					if (blh==NULL) {
						LM_ERR("[UN]USE_BLACKLIST - list "
							"%s not configured\n", t->elem[0].u.string);
						ret=E_CFG;
						goto error;
					}
				}
				t->elem[0].type = BLACKLIST_ST;
				t->elem[0].u.data = blh;
				break;
			case CACHE_STORE_T:
			case CACHE_FETCH_T:
			case CACHE_REMOVE_T:
				/* attr name */
				s.s = (char*)t->elem[1].u.data;
				s.len = strlen(s.s);
				if(s.len==0) {
					LM_ERR("param 2 is empty string!\n");
					return E_CFG;
				}

				if(pv_parse_format(&s ,&model) || model==NULL) {
						LM_ERR("wrong format [%s] for value param!\n", s.s);
						ret=E_BUG;
						goto error;
				}
				t->elem[1].u.data = (void*)model;

				if (t->type==CACHE_REMOVE_T)
					break;

				/* value */
				if (t->type==CACHE_FETCH_T) {
					if(((pv_spec_p)t->elem[2].u.data)->type!= PVT_AVP)
					{
						LM_ERR("Wrong type for the third argument - "
							"must be an AVP\n");
						ret=E_BUG;
						goto error;
					}
				} else {
					s.s = (char*)t->elem[2].u.data;
					s.len = strlen(s.s);
					if(s.len==0) {
						LM_ERR("param 2 is empty string!\n");
						return E_CFG;
					}

					if(pv_parse_format(&s ,&model) || model==NULL) {
						LM_ERR("wrong format [%s] for value param!\n",s.s);
						ret=E_BUG;
						goto error;
					}
					t->elem[2].u.data = (void*)model;
				}

				break;
			case XDBG_T:
			case XLOG_T:
				s.s = (char*)t->elem[1].u.data;
				if (s.s == NULL)
				{
					/* commands have only one parameter */
					s.s = (char *)t->elem[0].u.data;
					s.len = strlen(s.s);
					if(s.len==0)
					{
						LM_ERR("param is empty string!\n");
						return E_CFG;
					}

					if(pv_parse_format(&s ,&model) || model==NULL)
					{
						LM_ERR("wrong format [%s] for value param!\n", s.s);
						ret=E_BUG;
						goto error;
					}
					
					t->elem[0].u.data = (void*)model;
					t->elem[0].type = SCRIPTVAR_ELEM_ST;
				}
				else
				{
					/* there are two parameters */
					s.s = (char *)t->elem[0].u.data;
					s.len = strlen(s.s);
					if (s.len == 0)
					{
						LM_ERR("param is empty string\n");
						return E_CFG;
					}
					xlp = (xl_level_p)pkg_malloc(sizeof(xl_level_t));
					if(xlp == NULL)
					{
						LM_ERR("no more memory\n");
						return E_UNSPEC;
					}

					memset(xlp, 0, sizeof(xl_level_t));
					if(s.s[0]==PV_MARKER)
					{
						xlp->type = 1;
						if(pv_parse_spec(&s, &xlp->v.sp)==NULL)
						{
							LM_ERR("invalid level param\n");
							return E_UNSPEC;
						}
					} 
					else 
					{
						xlp->type = 0;
						switch(s.s[2])
						{
							case 'A': xlp->v.level = L_ALERT; break;
							case 'C': xlp->v.level = L_CRIT; break;
							case 'E': xlp->v.level = L_ERR; break;
							case 'W': xlp->v.level = L_WARN; break;
							case 'N': xlp->v.level = L_NOTICE; break;
							case 'I': xlp->v.level = L_INFO; break;
							case 'D': xlp->v.level = L_DBG; break;
							default:
								LM_ERR("unknown log level\n");
								return E_UNSPEC;
						}
					}
					t->elem[0].u.data = xlp;

					s.s = t->elem[1].u.data;
					s.len = strlen(s.s);
					if (pv_parse_format(&s, &model) || model == NULL)
					{
						LM_ERR("wrong fomat [%s] for value param\n",s.s);
						ret=E_BUG;
						goto error;
					}

					t->elem[1].u.data = model;
					t->elem[1].type = SCRIPTVAR_ELEM_ST;
				}
				break;
			case CONSTRUCT_URI_T:
				for (i=0;i<5;i++)
				{	
					s.s = (char*)t->elem[i].u.data;
					s.len = strlen(s.s);
					if(s.len==0) 
						continue;

					if(pv_parse_format(&s ,&(models[i])) || models[i]==NULL) 
					{
						LM_ERR("wrong format [%s] for value param!\n",s.s);
						ret=E_BUG;
						goto error;
					}

					t->elem[i].u.data = (void*)models[i];
				}
				
				if (((pv_spec_p)t->elem[5].u.data)->type != PVT_AVP)
				{
					LM_ERR("Wrong type for the third argument - "
						"must be an AVP\n");
					ret=E_BUG;
					goto error;
				}

				break;
		}
	}
	return 0;
error:
	LM_ERR("fixing failed (code=%d) at cfg line %d\n", ret, t->line);
	return ret;
}
Beispiel #21
0
/*! \brief eval_elem helping function, returns an op param */
inline static int comp_ip(struct sip_msg *msg, int op, struct ip_addr* ip,
		operand_t *opd)
{
	struct hostent* he;
	char ** h;
	int ret;
	str tmp;

	ret=-1;
	switch(opd->type){
		case NET_ST:
			switch(op){
				case EQUAL_OP:
					ret=(matchnet(ip, (struct net*)opd->v.data)==1);
					break;
				case DIFF_OP:
					ret=(matchnet(ip, (struct net*)opd->v.data)!=1);
					break;
				default:
					goto error_op;
			}
			break;
		case STR_ST:
		case RE_ST:
			switch(op){
				case EQUAL_OP:
				case MATCH_OP:
					/* 1: compare with ip2str*/
					ret=comp_str(ip_addr2a(ip), opd->v.data, op, opd->type);
					if (ret==1) break;
					/* 2: resolve (name) & compare w/ all the ips */
					if (opd->type==STR_ST){
						he=resolvehost((char*)opd->v.data,0);
						if (he==0){
							LM_DBG("could not resolve %s\n",(char*)opd->v.data);
						}else if (he->h_addrtype==(int)ip->af){
							for(h=he->h_addr_list;(ret!=1)&& (*h); h++){
								ret=(memcmp(ip->u.addr, *h, ip->len)==0);
							}
							if (ret==1) break;
						}
					}
					/* 3: (slow) rev dns the address
					* and compare with all the aliases
					* !!??!! review: remove this? */
					if(received_dns & DO_REV_DNS)
					{
						he=rev_resolvehost(ip);
						if (he==0){
							print_ip("comp_ip: could not rev_resolve ip"
									" address: ", ip, "\n");
						ret=0;
						}else{
							/*  compare with primary host name */
							ret=comp_str(he->h_name, opd->v.data, op,
									opd->type);
							/* compare with all the aliases */
							for(h=he->h_aliases; (ret!=1) && (*h); h++){
								ret=comp_str(*h, opd->v.data, op, opd->type);
							}
						}
					} else {
						return 0;
					}
					break;
				case DIFF_OP:
					ret=comp_ip(msg, op, ip, opd);
					if (ret>=0) ret=!ret;
					break;
				default:
					goto error_op;
			}
			break;
		case MYSELF_ST: /* check if it's one of our addresses*/
			tmp.s=ip_addr2a(ip);
			tmp.len=strlen(tmp.s);
			ret=check_self_op(op, &tmp, 0);
			break;
		default:
			LM_CRIT("invalid type for src_ip or dst_ip (%d)\n", opd->type);
			ret=-1;
	}
	return ret;
error_op:
	LM_CRIT("invalid operator %d\n", op);
	return -1;
	
}
Beispiel #22
0
/*
 * This is the parsing function
 * The socket grammar should be:
 * 		 ip ':' port ':' method
 */
static evi_reply_sock* xmlrpc_parse(str socket)
{
	evi_reply_sock *sock = NULL;
	unsigned short port = 0;
	char *p = NULL;
	str host, *method;
	struct hostent *hentity;
	int len;

	if (!socket.len || !socket.s) {
		LM_ERR("no socket specified\n");
		return NULL;
	}

	/* extract host */
	host.s = socket.s;
	p = memchr(socket.s, COLON_C, socket.len);
	if (!p || p == socket.s) {
		LM_ERR("port not specified <%.*s>\n", socket.len, socket.s);
		return NULL;
	}
	host.len = p - socket.s;
	/* used to resolve host */
	*p = '\0';
	/* skip colon */
	socket.s += host.len + 1;
	socket.len -= host.len + 1;

	LM_DBG("host is %.*s - remains <%.*s>[%d]\n", host.len, host.s,
			socket.len, socket.s, socket.len);
	
	if (!socket.len || *socket.s == '\0') {
		LM_ERR("invalid port number\n");
		return NULL;
	}

	p = memchr(socket.s, COLON_C, socket.len);
	if (!p || p == socket.s) {
		LM_ERR("method not specified <%.*s>\n", socket.len, socket.s);
		return NULL;
	}
	port = str2s(socket.s, p - socket.s, 0);
	if (port == 0) {
		LM_DBG("malformed port: %.*s\n",(int)(p - socket.s), socket.s);
		return NULL;
	}

	/* skip colon */
	socket.len = socket.len - (p - socket.s + 1);
	socket.s = p + 1;

	LM_DBG("port is %hu - remains <%.*s>[%d]\n",
			port, socket.len, socket.s, socket.len);

	if (socket.len <= 0 || *socket.s == '\0') {
		LM_ERR("invalid method name\n");
		return NULL;
	}
	
	LM_DBG("method is %.*s[%d]\n", socket.len, socket.s, socket.len);

	len = sizeof(evi_reply_sock) - sizeof(void*) + sizeof(str) + 
		host.len + socket.len;
	sock = shm_malloc(len);
	if (!sock) {
		LM_ERR("no more memory for socket\n");
		return NULL;
	}

	memset(sock, 0, len);
	/* only UDP has port */
	sock->flags = EVI_PORT;
	sock->port = port;

	/* also build sockaddr */
	hentity = resolvehost(host.s, 0);
	if (!hentity) {
		LM_ERR("cannot resolve host %s\n", host.s);
		goto error;
	}
	if(hostent2su(&sock->src_addr.udp_addr, hentity, 0, port)){
		LM_ERR("failed to resolve %s\n", host.s);
		goto error;
	}
	sock->flags |= EVI_SOCKET;

	/* copy method  - this should point to same address as params*/
	method = (str *) &sock->params;
	method->s = (char *) (method + 1);
	method->len = socket.len;
	memcpy(method->s, socket.s, socket.len);
	sock->flags |= EVI_PARAMS;

	/* address should point below method name */
	sock->address.s = method->s + method->len;
	sock->address.len = host.len;
	memcpy(sock->address.s, host.s, host.len);
	sock->flags |= EVI_ADDRESS;

	/* needs expire */
	sock->flags |= EVI_EXPIRE|XMLRPC_FLAG;

	return sock;
error:
	if (sock)
		shm_free(sock);
	return NULL;
}
Beispiel #23
0
/* fixes a socket list => resolve addresses, 
 * interface names, fills missing members, remove duplicates */
static int fix_socket_list(struct socket_info **list)
{
	struct socket_info* si;
	struct socket_info* l;
	struct socket_info* next;
	char* tmp;
	int len;
	struct hostent* he;
	char** h;
	
	/* try to change all the interface names into addresses
	 *  --ugly hack */
	
	for (si=*list;si;){
		next=si->next;
		if (add_interfaces(si->name.s, AF_INET, si->port_no,
							si->proto, list)!=-1){
			/* success => remove current entry (shift the entire array)*/
			sock_listrm(list, si);
			free_sock_info(si);
		}
		si=next;
	}
	/* get ips & fill the port numbers*/
#ifdef EXTRA_DEBUG
	LM_DBG("listening on \n");
#endif  
	LM_DBG("fix_socket_list");
	for (si=*list;si;si=si->next){
		/* fix the number of processes per interface */
		if (si->children==0 && (si->proto==PROTO_UDP || si->proto==PROTO_SCTP))
			si->children = children_no;
		/* fix port number, port_no should be !=0 here */
		if (si->port_no==0){
#ifdef USE_TLS
			si->port_no= (si->proto==PROTO_TLS)?tls_port_no:port_no;
#else
			si->port_no= port_no;
#endif
		}
		tmp=int2str(si->port_no, &len);
		if (len>=MAX_PORT_LEN){
			LM_ERR("bad port number: %d\n", si->port_no);
			goto error;
		}
		si->port_no_str.s=(char*)pkg_malloc(len+1);
		if (si->port_no_str.s==0){
			LM_ERR("out of pkg memory.\n");
			goto error;
		}
		strncpy(si->port_no_str.s, tmp, len+1);
		si->port_no_str.len=len;
		LM_DBG("resolvehost [%.*s] ",si->name.len,si->name.s);
		/* get "official hostnames", all the aliases etc. */
		he=resolvehost(si->name.s,0);
		if (he==0){
			LM_ERR("could not resolve %s\n", si->name.s);
			goto error;
		}
		LM_DBG("aliases [%.*s] == [%.*s] ",
			(int)strlen(he->h_name),he->h_name, si->name.len, si->name.s);
		/* check if we got the official name */
		if (strcasecmp(he->h_name, si->name.s)!=0){
			if (auto_aliases && add_alias(si->name.s, si->name.len,
							si->port_no, si->proto)<0){
				LM_ERR("add_alias failed\n");
			}
			/* change the official name */
			pkg_free(si->name.s);
			si->name.s=(char*)pkg_malloc(strlen(he->h_name)+1);
			if (si->name.s==0){
				LM_ERR("out of pkg memory.\n");
				goto error;
			}
			si->name.len=strlen(he->h_name);
			strncpy(si->name.s, he->h_name, si->name.len+1);
		}
		/* add the aliases*/
		if (auto_aliases) {
			for(h=he->h_aliases; h && *h; h++){
				LM_DBG("h_alias [%.*s] ",(int)strlen(*h),*h);
				if (add_alias(*h, strlen(*h), si->port_no, si->proto)<0){
					LM_ERR("add_alias failed\n");
				}
			}
		}
		hostent2ip_addr(&si->address, he, 0); /*convert to ip_addr 
														 format*/
		if ((tmp=ip_addr2a(&si->address))==0) goto error;
		if (si->address.af == AF_INET6) {
			si->address_str.s=(char*)pkg_malloc(strlen(tmp)+1+2);
			if (si->address_str.s==0){
				LM_ERR("out of pkg memory.\n");
				goto error;
			}
			si->address_str.s[0] = '[';
			strncpy( si->address_str.s+1 , tmp, strlen(tmp));
			si->address_str.s[1+strlen(tmp)] = ']';
			si->address_str.s[2+strlen(tmp)] = '\0';
			si->address_str.len=strlen(tmp) + 2;
		} else {
			si->address_str.s=(char*)pkg_malloc(strlen(tmp)+1);
			if (si->address_str.s==0){
				LM_ERR("out of pkg memory.\n");
				goto error;
			}
			strncpy(si->address_str.s, tmp, strlen(tmp)+1);
			si->address_str.len=strlen(tmp);
		}
		/* set is_ip (1 if name is an ip address, 0 otherwise) */
		if ( auto_aliases && (si->address_str.len==si->name.len) &&
				(strncasecmp(si->address_str.s, si->name.s,
								si->address_str.len)==0)
			){
				si->flags|=SI_IS_IP;
				/* do rev. DNS on it (for aliases)*/
				he=rev_resolvehost(&si->address);
				if (he==0){
					LM_WARN("could not rev. resolve %s\n", si->name.s);
				}else{
					/* add the aliases*/
					if (add_alias(he->h_name, strlen(he->h_name),
									si->port_no, si->proto)<0){
						LM_ERR("add_alias failed\n");
					}
					for(h=he->h_aliases; h && *h; h++)
						if (add_alias(*h,strlen(*h),si->port_no,si->proto)<0){
							LM_ERR(" add_alias failed\n");
						}
				}
		}

		/* Now build an ip_addr structure for the adv_name, if there is one
		 * so that find_si can find it later easily.  Doing this so that
		 * we can force_send_socket() on an advertised name.  Generally there
		 * is little interest in dealing with an advertised name as anything
		 * other than an opaque string that we blindly put into the SIP
		 * message.
		 */
        if(si->adv_name_str.len) {
			/* If adv_name_str is already an IP, this is kinda foolish cus it
			 * converts it to ip_addr, then to he, then here we go back to
			 * ip_addr, but it's either that, or we duplicate the logic to
			 * check for an ip address here, and still we might have to call
			 * resolvehost().
			 */
			he=resolvehost(si->adv_name_str.s,0);
			if (he==0){
				LM_ERR("ERROR: fix_socket_list: could not resolve "
						"advertised name %s\n", si->adv_name_str.s);
				goto error;
			}
			hostent2ip_addr(&si->adv_address, he, 0); /*convert to ip_addr */

			/* build and set string encoding for the adv socket info
			 * This is usefful for the usrloc module when it's generating
			 * or updating the socket on a location record, so we'll generate
			 * it up front just like the regular sock_str so we don't have
			 * to worry about it later.
			 */
			tmp = socket2str( si, 0, &si->adv_sock_str.len, 1);
			if (tmp==0) {
				LM_ERR("ERROR: fix_socket_list: failed to convert "
					    "socket to string (adv)\n");
				goto error;
			}
			si->adv_sock_str.s=(char*)pkg_malloc(si->adv_sock_str.len);
			if (si->adv_sock_str.s==0) {
				LM_ERR("ERROR: fix_socket_list: out of memory.\n");
				goto error;
			}
			memcpy(si->adv_sock_str.s, tmp, si->adv_sock_str.len);
		}

		/* build and set string encoding for the real socket info */
		tmp = socket2str( si, 0, &si->sock_str.len, 0);
		if (tmp==0) {
			LM_ERR("failed to convert socket to string");
			goto error;
		}
		si->sock_str.s=(char*)pkg_malloc(si->sock_str.len);
		if (si->sock_str.s==0) {
			LM_ERR("out of pkg memory.\n");
			goto error;
		}
		memcpy(si->sock_str.s, tmp, si->sock_str.len);

#ifdef USE_MCAST
		/* Check if it is an multicast address and
		 * set the flag if so
		 */
		if (is_mcast(&si->address)) {
			si->flags |= SI_IS_MCAST;
		}
#endif /* USE_MCAST */

#ifdef EXTRA_DEBUG
		printf("              %.*s [%s]:%s%s\n", si->name.len, 
				si->name.s, si->address_str.s, si->port_no_str.s,
		                si->flags & SI_IS_MCAST ? " mcast" : "");
#endif
	}
	/* removing duplicate addresses*/
	for (si=*list;si; si=si->next){
		for (l=si->next;l;){
			next=l->next;
			if ((si->port_no==l->port_no) &&
				(si->address.af==l->address.af) &&
				(memcmp(si->address.u.addr, l->address.u.addr, si->address.len)
					== 0)
				){
#ifdef EXTRA_DEBUG
				printf("removing duplicate %s [%s] ==  %s [%s]\n",
						si->name.s, si->address_str.s,
						 l->name.s, l->address_str.s);
#endif
				/* add the name to the alias list*/
				if ((!(l->flags& SI_IS_IP)) && (
						(l->name.len!=si->name.len)||
						(strncmp(l->name.s, si->name.s, si->name.len)!=0))
					)
					add_alias(l->name.s, l->name.len, l->port_no, l->proto);
						
				/* remove l*/
				sock_listrm(list, l);
				free_sock_info(l);
			}
			l=next;
		}
	}

#ifdef USE_MCAST
	     /* Remove invalid multicast entries */
	si=*list;
	while(si){
		if ((si->flags & SI_IS_MCAST) && 
		    ((si->proto == PROTO_TCP)
#ifdef USE_TLS
		    || (si->proto == PROTO_TLS)
#endif /* USE_TLS */
#ifdef USE_SCTP
			|| (si->proto == PROTO_SCTP)
#endif
		    )){
			LM_WARN("removing entry %s:%s [%s]:%s\n",
			    get_proto_name(si->proto), si->name.s, 
			    si->address_str.s, si->port_no_str.s);
			l = si;
			si=si->next;
			sock_listrm(list, l);
			free_sock_info(l);
		} else {
			si=si->next;
		}
	}
#endif /* USE_MCAST */

	return 0;
error:
	return -1;
}
Beispiel #24
0
int jsonrpc_dgram_mod_init(void)
{
	unsigned int port_no;
	int n;
	struct stat filestat;
	struct hostent *host;
	char *p, *host_s;
	str port_str;
	int len;
	int sep;

	/* checking the mi_socket module param */
	LM_DBG("testing socket existance...\n");

	if( jsonrpc_dgram_socket==NULL || *jsonrpc_dgram_socket == 0) {
		LM_ERR("no DATAGRAM_ socket configured\n");
		return -1;
	}

	LM_DBG("the socket's name/address is %s\n", jsonrpc_dgram_socket);

	memset( &jsonrpc_dgram_addr, 0, sizeof(jsonrpc_dgram_sockaddr_t) );

	if(strlen(jsonrpc_dgram_socket)<6) {
		LM_ERR("lenght of socket address is too short: %s\n",
				jsonrpc_dgram_socket);
		return -1;
	}
	if(strncmp(jsonrpc_dgram_socket, "udp:", 4) == 0) {
		/*for an UDP socket*/
		LM_DBG("udp socket provided\n");
		/*separate proto and host */
		p = jsonrpc_dgram_socket+4;
		if( (*(p)) == '\0') {
			LM_ERR("malformed ip address\n");
			return -1;
		}
		host_s=p;
		LM_DBG("remaining address after separating the protocol is %s\n", p);

		if( (p = strrchr(p+1, ':')) == 0 ) {
			LM_ERR("no port specified\n");
			return -1;
		}

		/*the address contains a port number*/
		*p = '\0';
		p++;
		port_str.s = p;
		port_str.len = strlen(p);
		LM_DBG("the port string is %s\n", p);
		if(str2int(&port_str, &port_no) != 0 ) {
			LM_ERR("there is not a valid number port\n");
			return -1;
		}
		*p = '\0';
		if (port_no<1024  || port_no>65535)
		{
			LM_ERR("invalid port number; must be in [1024,65535]\n");
			return -1;
		}

		if(! (host = resolvehost(host_s)) ) {
			LM_ERR("failed to resolve %s\n", host_s);
			return -1;
		}
		LM_DBG("the ip is %s\n",host_s);
		if(hostent2su( &(jsonrpc_dgram_addr.udp_addr), host, 0, port_no ) !=0) {
			LM_ERR("failed to resolve %s\n", jsonrpc_dgram_socket);
			return -1;
		}
		jsonrpc_dgram_socket_domain = host->h_addrtype;
		goto done;
	}
	/* in case of a Unix socket*/
	LM_DBG("UNIX socket provided\n");

	if(*jsonrpc_dgram_socket != '/') {
		if(runtime_dir!=NULL && *runtime_dir!=0) {
			len = strlen(runtime_dir);
			sep = 0;
			if(runtime_dir[len-1]!='/') {
				sep = 1;
			}
			len += sep + strlen(jsonrpc_dgram_socket);
			p = pkg_malloc(len + 1);
			if(p==NULL) {
				LM_ERR("no more pkg\n");
				return -1;
			}
			strcpy(p, runtime_dir);
			if(sep) strcat(p, "/");
			strcat(p, jsonrpc_dgram_socket);
			jsonrpc_dgram_socket = p;
			LM_DBG("unix socket path is [%s]\n", jsonrpc_dgram_socket);
		}
	}

	n=stat(jsonrpc_dgram_socket, &filestat);
	if( n==0) {
		LM_INFO("the socket %s already exists, trying to delete it...\n",
				jsonrpc_dgram_socket);
		if(config_check==0) {
			if (unlink(jsonrpc_dgram_socket)<0) {
				LM_ERR("cannot delete old socket: %s\n", strerror(errno));
				return -1;
			}
		}
	} else if (n<0 && errno!=ENOENT) {
		LM_ERR("socket stat failed:%s\n", strerror(errno));
		return -1;
	}

	/* check mi_unix_socket_mode */
	if(!jsonrpc_dgram_unix_socket_mode) {
		LM_WARN("cannot specify jsonrpc_dgram_unix_socket_mode = 0,"
				" forcing it to rw-------\n");
		jsonrpc_dgram_unix_socket_mode = S_IRUSR| S_IWUSR;
	}

	if (jsonrpc_dgram_unix_socket_uid_s) {
		if (user2uid(&jsonrpc_dgram_unix_socket_uid,
					&jsonrpc_dgram_unix_socket_gid,
					jsonrpc_dgram_unix_socket_uid_s)<0) {
			LM_ERR("bad user name %s\n", jsonrpc_dgram_unix_socket_uid_s);
			return -1;
		}
	}

	if (jsonrpc_dgram_unix_socket_gid_s) {
		if (group2gid(&jsonrpc_dgram_unix_socket_gid,
					jsonrpc_dgram_unix_socket_gid_s)<0) {
			LM_ERR("bad group name %s\n", jsonrpc_dgram_unix_socket_gid_s);
			return -1;
		}
	}

	/*create the unix socket address*/
	jsonrpc_dgram_addr.unix_addr.sun_family = AF_LOCAL;
	if(strlen(jsonrpc_dgram_socket)
			>= sizeof(jsonrpc_dgram_addr.unix_addr.sun_path)-1) {
		LM_ERR("socket path is too long\n");
		return -1;
	}
	memcpy(jsonrpc_dgram_addr.unix_addr.sun_path,
			jsonrpc_dgram_socket, strlen(jsonrpc_dgram_socket));

done:
	/* add space for extra processes */
	register_procs(jsonrpc_dgram_workers);
	/* add child to update local config framework structures */
	cfg_register_child(jsonrpc_dgram_workers);

	return 0;
}
Beispiel #25
0
static struct socket_info* find_socket(str* received)
{
	struct sip_uri puri;
	param_hooks_t hooks;
	struct hostent* he;
	struct ip_addr ip;
	struct socket_info* si;
	param_t* params;
	unsigned short port;
	char* buf;
	int error;

	if (!received) return 0;

	si = 0;
	if (parse_uri(received->s, received->len, &puri) < 0) {
		LOG(L_ERR, "find_socket: Error while parsing received URI\n");
		return 0;
	}
	
	if (parse_params(&puri.params, CLASS_URI, &hooks, &params) < 0) {
		LOG(L_ERR, "find_socket: Error while parsing received URI parameters\n");
		return 0;
	}

	if (!hooks.uri.dstip || !hooks.uri.dstip->body.s || !hooks.uri.dstip->body.len) goto end;

	buf = (char*)pkg_malloc(hooks.uri.dstip->body.len + 1);
	if (!buf) {
		LOG(L_ERR, "find_socket: No memory left\n");
		goto end;
	}
	memcpy(buf, hooks.uri.dstip->body.s, hooks.uri.dstip->body.len);
	buf[hooks.uri.dstip->body.len] = '\0';

	he = resolvehost(buf);
	if (he == 0) {
		LOG(L_ERR, "find_socket: Unable to resolve '%s'\n", buf);
		pkg_free(buf);
		goto end;
	}
	pkg_free(buf);

	if (hooks.uri.dstport && hooks.uri.dstport->body.s && hooks.uri.dstport->body.len) {
		port = str2s(hooks.uri.dstport->body.s, hooks.uri.dstport->body.len, &error);
		if (error != 0) {
			LOG(L_ERR, "find_socket: Unable to convert port number\n");		
			goto end;
		}
	} else {
		port = 0;
	}

	hostent2ip_addr(&ip, he, 0);
	si = find_si(&ip, port, puri.proto);
	if (si == 0) {
		LOG(L_ERR, "find_socket: Unable to find socket, using the default one\n");
		goto end;
	}
	
 end:
	if (params) free_params(params);
	return si;
}
Beispiel #26
0
/* opens, binds and listens-on a control tcp socket
 * returns socket fd or -1 on error */
int init_tcpudp_sock(union sockaddr_union* sa_un, char* address, int port,
						enum socket_protos type)
{
	union sockaddr_union su;
	struct hostent* he;
	int s;
	int optval;
	
	s=-1;
	if ((type!=UDP_SOCK) && (type!=TCP_SOCK)){
		LOG(L_CRIT, "BUG: init_tcpudp_sock called with bad type: %d\n",
				type);
		goto error;
	}
	memset(&su, 0, sizeof (su));
	/* if no address specified, or address=='*', listen on all
	 * ipv4 addresses */
	if ((address==0)||((*address)==0)||((*address=='*') && (*(address+1)==0))){
		su.sin.sin_family=AF_INET;
		su.sin.sin_port=htons(port);
		su.sin.sin_addr.s_addr=INADDR_ANY;
#ifdef HAVE_SOCKADDR_SA_LEN
		su.sin.sin_len=sizeof(struct sockaddr_in);
#endif
	}else{
		he=resolvehost(address);
		if (he==0){
			LOG(L_ERR, "ERROR: init_tcpudp_sock: bad address %s\n", address);
			goto error;
		}
		if (hostent2su(&su, he, 0, port)==-1) goto error;
	}
	s=socket(AF2PF(su.s.sa_family), (type==TCP_SOCK)?SOCK_STREAM:SOCK_DGRAM,0);
	if (s==-1){
		LOG(L_ERR, "ERROR: init_tcpudp_sock: cannot create tcp socket:"
				" %s [%d]\n", strerror(errno), errno);
		goto error;
	}
	/* REUSEADDR */
	optval=1;
	if (setsockopt(s, SOL_SOCKET, SO_REUSEADDR, &optval, sizeof(optval))==-1){
		LOG(L_ERR, "ERROR: init_tcpudp_sock: setsockopt: %s [%d]\n", 
				strerror(errno), errno);
		/* continue */
	}
	/* tos */
	optval=IPTOS_LOWDELAY;
	if (setsockopt(s, IPPROTO_IP, IP_TOS, (void*)&optval,sizeof(optval)) ==-1){
		LOG(L_WARN, "WARNING: init_tcpudp_sock: setsockopt tos: %s\n",
				strerror(errno));
		/* continue since this is not critical */
	}
	if (set_non_blocking(s)==-1){
		LOG(L_ERR, "ERROR: init_tcpudp_sock: set non blocking failed\n");
	}
	
	if (bind(s, &su.s, sockaddru_len(su))==-1){
		LOG(L_ERR, "ERROR: init_tcpudp_sock: bind: %s [%d]\n",
				strerror(errno), errno);
		goto error;
	}
	if ((type==TCP_SOCK) && (listen(s, 128)==-1)){
		LOG(L_ERR, "ERROR: init_tcpudp_sock: listen: %s [%d]\n",
				strerror(errno), errno);
		goto error;
	}
	*sa_un=su;
	return s;
error:
	if (s!=-1) close(s);
	return -1;
}
Beispiel #27
0
/** Initializes seas module. It first parses the listen_sockets parameter
 * which has the form "ip_address[:port]", creates the pipe to
 * communicate with the dispatcher.
 */
static int seas_init(void)
{
   char *p,*port;
   struct hostent *he;
   struct socket_info *si;
   int c_pipe[2],mierr,i;
   /** Populate seas_functions*/
   if (load_tm_api(&seas_f.tmb)!=0) {
      LM_ERR( "can't load TM API\n");
      return -1;
   }
   if(!(seas_f.t_check_orig_trans = find_export("t_check_trans", 0, 0))){
      LM_ERR( "Seas requires transaction module (t_check_trans not found)\n");
      return -1;
   }
   /** Populate seas_functions*/
   c_pipe[0]=c_pipe[1]=-1;
   p=seas_listen_socket;
   port=(char *)0;
   seas_listen_port=5080;
   /*if the seas_listen_socket configuration string is empty, use default values*/
   if(p==NULL || *p==0){
      si=get_first_socket();
      seas_listen_ip=&si->address;
   } else {/*if config string is not empty, then try to find host first, and maybe port..*/
      while(*p){
	 if(*p == ':'){
	    *p=0;
	    port=p+1;
	    break;
	 }
	 p++;
      }
      if(!(he=resolvehost(seas_listen_socket,0)))
	 goto error;
      if(!(seas_listen_ip=pkg_malloc(sizeof(struct ip_addr))))
	 goto error;
      hostent2ip_addr(seas_listen_ip, he, 0);
      if(port!=(char *)0 && (seas_listen_port=str2s(port,strlen(port),&mierr))==0){
	 LM_ERR("invalid port %s \n",port);
	 goto error;
      }
   }
   memset(unc_as_t,0,2*MAX_UNC_AS_NR*sizeof(struct unc_as));//useless because unc_as_t is in bss?
   if (pipe(c_pipe)==-1) {
      LM_ERR("cannot create pipe!\n");
      goto error;
   }
   read_pipe=c_pipe[0];
   write_pipe=c_pipe[1];
   seas_init_tags();
   if(0>start_stats_server(seas_stats_socket))
      goto error;
   if(0>prepare_ha())
      goto error;
   if(0>parse_cluster_cfg())
      goto error;
   return 0;
error:
   for(i=0;i<2;i++)
      if(c_pipe[i]!=-1)
	 close(c_pipe[i]);
   if(seas_listen_ip!=0)
      pkg_free(seas_listen_ip);
   if(use_stats)
      stop_stats_server();
   return -1;
}
Beispiel #28
0
/* returns 0 if ok, <0 on error */
static int fix_actions(struct action* a)
{
	struct action *t;
	int ret;
	cmd_export_t* cmd;
	struct hostent* he;
	struct ip_addr ip;
	struct socket_info* si;
	str host;
	int proto=PROTO_NONE, port;
	struct proxy_l *p;
	struct bl_head *blh;

	if (a==0){
		LM_CRIT("null pointer\n");
		return E_BUG;
	}
	for(t=a; t!=0; t=t->next){
		switch(t->type){
			case FORWARD_T:
				if (t->elem[0].type==NOSUBTYPE)
					break;
			case SEND_T:
				if (t->elem[0].type!=STRING_ST) {
					LM_CRIT("invalid type %d (should be string)\n", t->type);
					return E_BUG;
				}
				ret = parse_phostport( t->elem[0].u.string,
						strlen(t->elem[0].u.string),
						&host.s, &host.len, &port, &proto);
				if (ret!=0) {
					LM_ERR("ERROR:fix_actions: FORWARD/SEND bad "
						"argument\n");
					return E_CFG;
				}
				p = add_proxy( &host,(unsigned short)port, proto);
				if (p==0) {
					LM_ERR("forward/send failed to add proxy");
					return E_CFG;
				}
				t->elem[0].type = PROXY_ST;
				t->elem[0].u.data = (void*)p;
				break;
			case IF_T:
				if (t->elem[0].type!=EXPR_ST){
					LM_CRIT("invalid subtype %d for if (should be expr)\n",
								t->elem[0].type);
					return E_BUG;
				}else if( (t->elem[1].type!=ACTIONS_ST)
						&&(t->elem[1].type!=NOSUBTYPE) ){
					LM_CRIT("invalid subtype %d for if() {...} (should be"
								"action)\n", t->elem[1].type);
					return E_BUG;
				}else if( (t->elem[2].type!=ACTIONS_ST)
						&&(t->elem[2].type!=NOSUBTYPE) ){
					LM_CRIT("invalid subtype %d for if() {} else{...}(should"
							"be action)\n", t->elem[2].type);
					return E_BUG;
				}
				if (t->elem[0].u.data){
					if ((ret=fix_expr((struct expr*)t->elem[0].u.data))<0)
						return ret;
				}
				if ( (t->elem[1].type==ACTIONS_ST)&&(t->elem[1].u.data) ){
					if ((ret=fix_actions((struct action*)t->elem[1].u.data))<0)
						return ret;
				}
				if ( (t->elem[2].type==ACTIONS_ST)&&(t->elem[2].u.data) ){
					if((ret=fix_actions((struct action*)t->elem[2].u.data))<0)
						return ret;
				}
				break;
			case WHILE_T:
				if (t->elem[0].type!=EXPR_ST){
					LM_CRIT("invalid subtype %d for while (should be expr)\n",
								t->elem[0].type);
					return E_BUG;
				}else if( (t->elem[1].type!=ACTIONS_ST)
						&&(t->elem[1].type!=NOSUBTYPE) ){
					LM_CRIT("invalid subtype %d for while() {...} (should be"
								"action)\n", t->elem[1].type);
					return E_BUG;
				}
				if (t->elem[0].u.data){
					if ((ret=fix_expr((struct expr*)t->elem[0].u.data))<0)
						return ret;
				}
				if ( (t->elem[1].type==ACTIONS_ST)&&(t->elem[1].u.data) ){
					if ((ret=fix_actions((struct action*)t->elem[1].u.data))<0)
						return ret;
				}
				break;
			case SWITCH_T:
				if ( (t->elem[1].type==ACTIONS_ST)&&(t->elem[1].u.data) ){
					if ((ret=fix_actions((struct action*)t->elem[1].u.data))<0)
						return ret;
				}
				break;
			case CASE_T:
				if ( (t->elem[1].type==ACTIONS_ST)&&(t->elem[1].u.data) ){
					if ((ret=fix_actions((struct action*)t->elem[1].u.data))<0)
						return ret;
				}
				break;
			case DEFAULT_T:
				if ( (t->elem[0].type==ACTIONS_ST)&&(t->elem[0].u.data) ){
					if ((ret=fix_actions((struct action*)t->elem[0].u.data))<0)
						return ret;
				}
				break;
			case MODULE_T:
				cmd = (cmd_export_t*)t->elem[0].u.data;
				LM_DBG("fixing %s, line %d\n", cmd->name, t->line);
				if (cmd->fixup){
					if (cmd->param_no>0){
						ret=cmd->fixup(&t->elem[1].u.data, 1);
						t->elem[1].type=MODFIXUP_ST;
						if (ret<0) goto error;
					}
					if (cmd->param_no>1){
						ret=cmd->fixup(&t->elem[2].u.data, 2);
						t->elem[2].type=MODFIXUP_ST;
						if (ret<0) goto error;
					}
					if (cmd->param_no==0){
						ret=cmd->fixup( 0, 0);
						if (ret<0) goto error;
					}
				}
				break;
			case FORCE_SEND_SOCKET_T:
				if (t->elem[0].type!=SOCKID_ST){
					LM_CRIT("invalid subtype %d for force_send_socket\n",
								t->elem[0].type);
					return E_BUG;
				}
				he=resolvehost(((struct socket_id*)t->elem[0].u.data)->name,0);
				if (he==0){
					LM_ERR(" could not resolve %s\n",
								((struct socket_id*)t->elem[0].u.data)->name);
					ret = E_BAD_ADDRESS;
					goto error;
				}
				hostent2ip_addr(&ip, he, 0);
				si=find_si(&ip, ((struct socket_id*)t->elem[0].u.data)->port,
								((struct socket_id*)t->elem[0].u.data)->proto);
				if (si==0){
					LM_ERR("bad force_send_socket"
							" argument: %s:%d (ser doesn't listen on it)\n",
							((struct socket_id*)t->elem[0].u.data)->name,
							((struct socket_id*)t->elem[0].u.data)->port);
					ret = E_BAD_ADDRESS;
					goto error;
				}
				t->elem[0].u.data=si;
				t->elem[0].type=SOCKETINFO_ST;
				break;
			case SET_DEBUG_T:
				if (t->elem[0].type==NOSUBTYPE)
					break;
				if (t->elem[0].type!=NUMBER_ST) {
					LM_CRIT("fix_actions: BUG in setdebug() type %d\n",
						t->elem[0].type );
					ret=E_BUG;
					goto error;
				}
				/* normalize the value */
				if (t->elem[0].u.number>L_DBG)
					t->elem[0].u.number = L_DBG;
				else if (t->elem[0].u.number<L_ALERT)
					t->elem[0].u.number = L_ALERT;
				break;
			case SETFLAG_T:
			case RESETFLAG_T:
			case ISFLAGSET_T:
				if (t->elem[0].type!=NUMBER_ST) {
					LM_CRIT("bad xxxflag() type %d\n", t->elem[0].type );
					ret=E_BUG;
					goto error;
				}
				if (!flag_in_range( t->elem[0].u.number )) {
					ret=E_CFG;
					goto error;
				}
				break;
			case SETSFLAG_T:
			case RESETSFLAG_T:
			case ISSFLAGSET_T:
				if (t->elem[0].type!=NUMBER_ST) {
					LM_CRIT("bad xxxsflag() type %d\n", t->elem[0].type );
					ret=E_BUG;
					goto error;
				}
				t->elem[0].u.number = fixup_flag( t->elem[0].u.number );
				if (t->elem[0].u.data==0) {
					ret=E_CFG;
					goto error;
				}
				break;
			case SETBFLAG_T:
			case RESETBFLAG_T:
			case ISBFLAGSET_T:
				if (t->elem[0].type!=NUMBER_ST || t->elem[1].type!=NUMBER_ST) {
					LM_CRIT("bad xxxbflag() type "
						"%d,%d\n", t->elem[0].type, t->elem[0].type);
					ret=E_BUG;
					goto error;
				}
				t->elem[1].u.number = fixup_flag( t->elem[1].u.number );
				if (t->elem[1].u.data==0) {
					ret=E_CFG;
					goto error;
				}
				break;
			case EQ_T:
			case COLONEQ_T:
			case PLUSEQ_T:
			case MINUSEQ_T:
			case DIVEQ_T:
			case MULTEQ_T:
			case MODULOEQ_T:
			case BANDEQ_T:
			case BOREQ_T:
			case BXOREQ_T:
				if (t->elem[1].u.data){
					if ((ret=fix_expr((struct expr*)t->elem[1].u.data))<0)
						return ret;
				}
				break;
			case USE_BLACKLIST_T:
				if (t->elem[0].type!=STRING_ST) {
					LM_CRIT("bad USE_BLACKLIST type %d\n", t->elem[0].type);
					ret=E_BUG;
					goto error;
				}
				host.s = t->elem[0].u.string;
				host.len = strlen(host.s);
				blh = get_bl_head_by_name(&host);
				if (blh==NULL) {
					LM_ERR("USE_BLACKLIST - list "
						"%s not configured\n", t->elem[0].u.string);
					ret=E_CFG;
					goto error;
				}
				t->elem[0].type = BLACKLIST_ST;
				t->elem[0].u.data = blh;
				break;
		}
	}
	return 0;
error:
	LM_ERR("fixing failed (code=%d) at cfg line %d\n", ret, t->line);
	return ret;
}