Exemplo n.º 1
0
int netblockstrtoaddr(const char* str, int port, struct sockaddr_storage* addr,
        socklen_t* addrlen, int* net)
{
	char buf[64];
	char* s;
	*net = (str_is_ip6(str)?128:32);
	if((s=strchr(str, '/'))) {
		if(atoi(s+1) > *net) {
			log_err("netblock too large: %s", str);
			return 0;
		}
		*net = atoi(s+1);
		if(*net == 0 && strcmp(s+1, "0") != 0) {
			log_err("cannot parse netblock: '%s'", str);
			return 0;
		}
		strlcpy(buf, str, sizeof(buf));
		s = strchr(buf, '/');
		if(s) *s = 0;
		s = buf;
	}
	if(!ipstrtoaddr(s?s:str, port, addr, addrlen)) {
		log_err("cannot parse ip address: '%s'", str);
		return 0;
	}
	if(s) {
		addr_mask(addr, *addrlen, *net);
	}
	return 1;
}
Exemplo n.º 2
0
/** check interface strings */
static void
interfacechecks(struct config_file* cfg)
{
	struct sockaddr_storage a;
	socklen_t alen;
	int i, j;
	for(i=0; i<cfg->num_ifs; i++) {
		if(!extstrtoaddr(cfg->ifs[i], &a, &alen)) {
			fatal_exit("cannot parse interface specified as '%s'",
				cfg->ifs[i]);
		}
		for(j=0; j<cfg->num_ifs; j++) {
			if(i!=j && strcmp(cfg->ifs[i], cfg->ifs[j])==0)
				fatal_exit("interface: %s present twice, "
					"cannot bind same ports twice.",
					cfg->ifs[i]);
		}
	}
	for(i=0; i<cfg->num_out_ifs; i++) {
		if(!ipstrtoaddr(cfg->out_ifs[i], UNBOUND_DNS_PORT, 
			&a, &alen)) {
			fatal_exit("cannot parse outgoing-interface "
				"specified as '%s'", cfg->out_ifs[i]);
		}
		for(j=0; j<cfg->num_out_ifs; j++) {
			if(i!=j && strcmp(cfg->out_ifs[i], cfg->out_ifs[j])==0)
				fatal_exit("outgoing-interface: %s present "
					"twice, cannot bind same ports twice.",
					cfg->out_ifs[i]);
		}
	}
}
Exemplo n.º 3
0
int netblockstrtoaddr(const char* str, int port, struct sockaddr_storage* addr,
        socklen_t* addrlen, int* net)
{
	char* s = NULL;
	*net = (str_is_ip6(str)?128:32);
	if((s=strchr(str, '/'))) {
		if(atoi(s+1) > *net) {
			log_err("netblock too large: %s", str);
			return 0;
		}
		*net = atoi(s+1);
		if(*net == 0 && strcmp(s+1, "0") != 0) {
			log_err("cannot parse netblock: '%s'", str);
			return 0;
		}
		if(!(s = strdup(str))) {
			log_err("out of memory");
			return 0;
		}
		*strchr(s, '/') = '\0';
	}
	if(!ipstrtoaddr(s?s:str, port, addr, addrlen)) {
		free(s);
		log_err("cannot parse ip address: '%s'", str);
		return 0;
	}
	if(s) {
		free(s);
		addr_mask(addr, *addrlen, *net);
	}
	return 1;
}
Exemplo n.º 4
0
int authextstrtoaddr(char* str, struct sockaddr_storage* addr, 
	socklen_t* addrlen, char** auth_name)
{
	char* s;
	int port = UNBOUND_DNS_PORT;
	if((s=strchr(str, '@'))) {
		char buf[MAX_ADDR_STRLEN];
		size_t len = (size_t)(s-str);
		char* hash = strchr(s+1, '#');
		if(hash) {
			*auth_name = hash+1;
		} else {
			*auth_name = NULL;
		}
		if(len >= MAX_ADDR_STRLEN) {
			return 0;
		}
		(void)strlcpy(buf, str, sizeof(buf));
		buf[len] = 0;
		port = atoi(s+1);
		if(port == 0) {
			if(!hash && strcmp(s+1,"0")!=0)
				return 0;
			if(hash && strncmp(s+1,"0#",2)!=0)
				return 0;
		}
		return ipstrtoaddr(buf, port, addr, addrlen);
	}
	if((s=strchr(str, '#'))) {
		char buf[MAX_ADDR_STRLEN];
		size_t len = (size_t)(s-str);
		if(len >= MAX_ADDR_STRLEN) {
			return 0;
		}
		(void)strlcpy(buf, str, sizeof(buf));
		buf[len] = 0;
		port = UNBOUND_DNS_OVER_TLS_PORT;
		*auth_name = s+1;
		return ipstrtoaddr(buf, port, addr, addrlen);
	}
	*auth_name = NULL;
	return ipstrtoaddr(str, port, addr, addrlen);
}
Exemplo n.º 5
0
/** contact the server with TCP connect */
static int
contact_server(const char* svr, struct config_file* cfg, int statuscmd)
{
	struct sockaddr_storage addr;
	socklen_t addrlen;
	int fd;
	/* use svr or the first config entry */
	if(!svr) {
		if(cfg->control_ifs)
			svr = cfg->control_ifs->str;
		else	svr = "127.0.0.1";
		/* config 0 addr (everything), means ask localhost */
		if(strcmp(svr, "0.0.0.0") == 0)
			svr = "127.0.0.1";
		else if(strcmp(svr, "::0") == 0 ||
			strcmp(svr, "0::0") == 0 ||
			strcmp(svr, "0::") == 0 ||
			strcmp(svr, "::") == 0)
			svr = "::1";
	}
	if(strchr(svr, '@')) {
		if(!extstrtoaddr(svr, &addr, &addrlen))
			fatal_exit("could not parse IP@port: %s", svr);
	} else {
		if(!ipstrtoaddr(svr, cfg->control_port, &addr, &addrlen))
			fatal_exit("could not parse IP: %s", svr);
	}
	fd = socket(addr_is_ip6(&addr, addrlen)?AF_INET6:AF_INET, 
		SOCK_STREAM, 0);
	if(fd == -1) {
#ifndef USE_WINSOCK
		fatal_exit("socket: %s", strerror(errno));
#else
		fatal_exit("socket: %s", wsa_strerror(WSAGetLastError()));
#endif
	}
	if(connect(fd, (struct sockaddr*)&addr, addrlen) < 0) {
		log_addr(0, "address", &addr, addrlen);
#ifndef USE_WINSOCK
		log_err("connect: %s", strerror(errno));
		if(errno == ECONNREFUSED && statuscmd) {
			printf("unbound is stopped\n");
			exit(3);
		}
#else
		log_err("connect: %s", wsa_strerror(WSAGetLastError()));
		if(WSAGetLastError() == WSAECONNREFUSED && statuscmd) {
			printf("unbound is stopped\n");
			exit(3);
		}
#endif
		exit(1);
	}
	return fd;
}
Exemplo n.º 6
0
int 
extstrtoaddr(const char* str, struct sockaddr_storage* addr,
	socklen_t* addrlen)
{
	char* s;
	int port = UNBOUND_DNS_PORT;
	if((s=strchr(str, '@'))) {
		char buf[MAX_ADDR_STRLEN];
		if(s-str >= MAX_ADDR_STRLEN) {
			return 0;
		}
		(void)strlcpy(buf, str, sizeof(buf));
		buf[s-str] = 0;
		port = atoi(s+1);
		if(port == 0 && strcmp(s+1,"0")!=0) {
			return 0;
		}
		return ipstrtoaddr(buf, port, addr, addrlen);
	}
	return ipstrtoaddr(str, port, addr, addrlen);
}
Exemplo n.º 7
0
/** contact the server with TCP connect */
static int
contact_server(const char* svr, struct config_file* cfg, int statuscmd)
{
	struct sockaddr_storage addr;
	socklen_t addrlen;
	int addrfamily = 0;
	int fd;
	/* use svr or the first config entry */
	if(!svr) {
		if(cfg->control_ifs)
			svr = cfg->control_ifs->str;
		else	svr = "127.0.0.1";
		/* config 0 addr (everything), means ask localhost */
		if(strcmp(svr, "0.0.0.0") == 0)
			svr = "127.0.0.1";
		else if(strcmp(svr, "::0") == 0 ||
			strcmp(svr, "0::0") == 0 ||
			strcmp(svr, "0::") == 0 ||
			strcmp(svr, "::") == 0)
			svr = "::1";
	}
	if(strchr(svr, '@')) {
		if(!extstrtoaddr(svr, &addr, &addrlen))
			fatal_exit("could not parse IP@port: %s", svr);
#ifdef HAVE_SYS_UN_H
	} else if(svr[0] == '/') {
		struct sockaddr_un* usock = (struct sockaddr_un *) &addr;
		usock->sun_family = AF_LOCAL;
#ifdef HAVE_STRUCT_SOCKADDR_UN_SUN_LEN
		usock->sun_len = (socklen_t)sizeof(usock);
#endif
		(void)strlcpy(usock->sun_path, svr, sizeof(usock->sun_path));
		addrlen = (socklen_t)sizeof(struct sockaddr_un);
		addrfamily = AF_LOCAL;
#endif
	} else {
		if(!ipstrtoaddr(svr, cfg->control_port, &addr, &addrlen))
			fatal_exit("could not parse IP: %s", svr);
	}

	if(addrfamily == 0)
		addrfamily = addr_is_ip6(&addr, addrlen)?AF_INET6:AF_INET;
	fd = socket(addrfamily, SOCK_STREAM, 0);
	if(fd == -1) {
#ifndef USE_WINSOCK
		fatal_exit("socket: %s", strerror(errno));
#else
		fatal_exit("socket: %s", wsa_strerror(WSAGetLastError()));
#endif
	}
	if(connect(fd, (struct sockaddr*)&addr, addrlen) < 0) {
#ifndef USE_WINSOCK
		log_err_addr("connect", strerror(errno), &addr, addrlen);
		if(errno == ECONNREFUSED && statuscmd) {
			printf("unbound is stopped\n");
			exit(3);
		}
#else
		log_err_addr("connect", wsa_strerror(WSAGetLastError()), &addr, addrlen);
		if(WSAGetLastError() == WSAECONNREFUSED && statuscmd) {
			printf("unbound is stopped\n");
			exit(3);
		}
#endif
		exit(1);
	}
	return fd;
}
Exemplo n.º 8
0
/** delayer main service routine */
static void
service(const char* bind_str, int bindport, const char* serv_str, 
	size_t memsize, int delay_msec)
{
	struct sockaddr_storage bind_addr, srv_addr;
	socklen_t bind_len, srv_len;
	struct ringbuf* ring = ring_create(memsize);
	struct timeval delay, reuse;
	sldns_buffer* pkt;
	int i, s, listen_s;
#ifndef S_SPLINT_S
	delay.tv_sec = delay_msec / 1000;
	delay.tv_usec = (delay_msec % 1000)*1000;
#endif
	reuse = delay; /* reuse is max(4*delay, 1 second) */
	dl_tv_add(&reuse, &delay);
	dl_tv_add(&reuse, &delay);
	dl_tv_add(&reuse, &delay);
	if(reuse.tv_sec == 0)
		reuse.tv_sec = 1;
	if(!extstrtoaddr(serv_str, &srv_addr, &srv_len)) {
		printf("cannot parse forward address: %s\n", serv_str);
		exit(1);
	}
	pkt = sldns_buffer_new(65535);
	if(!pkt)
		fatal_exit("out of memory");
	if( signal(SIGINT, delayer_sigh) == SIG_ERR ||
#ifdef SIGHUP
		signal(SIGHUP, delayer_sigh) == SIG_ERR ||
#endif
#ifdef SIGQUIT
		signal(SIGQUIT, delayer_sigh) == SIG_ERR ||
#endif
#ifdef SIGBREAK
		signal(SIGBREAK, delayer_sigh) == SIG_ERR ||
#endif
#ifdef SIGALRM
		signal(SIGALRM, delayer_sigh) == SIG_ERR ||
#endif
		signal(SIGTERM, delayer_sigh) == SIG_ERR)
		fatal_exit("could not bind to signal");
	/* bind UDP port */
	if((s = socket(str_is_ip6(bind_str)?AF_INET6:AF_INET,
		SOCK_DGRAM, 0)) == -1) {
#ifndef USE_WINSOCK
		fatal_exit("socket: %s", strerror(errno));
#else
		fatal_exit("socket: %s", wsa_strerror(WSAGetLastError()));
#endif
	}
	i=0;
	if(bindport == 0) {
		bindport = 1024 + random()%64000;
		i = 100;
	}
	while(1) {
		if(!ipstrtoaddr(bind_str, bindport, &bind_addr, &bind_len)) {
			printf("cannot parse listen address: %s\n", bind_str);
			exit(1);
		}
		if(bind(s, (struct sockaddr*)&bind_addr, bind_len) == -1) {
#ifndef USE_WINSOCK
			log_err("bind: %s", strerror(errno));
#else
			log_err("bind: %s", wsa_strerror(WSAGetLastError()));
#endif
			if(i--==0)
				fatal_exit("cannot bind any port");
			bindport = 1024 + random()%64000;
		} else break;
	}
	fd_set_nonblock(s);
	/* and TCP port */
	if((listen_s = socket(str_is_ip6(bind_str)?AF_INET6:AF_INET,
		SOCK_STREAM, 0)) == -1) {
#ifndef USE_WINSOCK
		fatal_exit("tcp socket: %s", strerror(errno));
#else
		fatal_exit("tcp socket: %s", wsa_strerror(WSAGetLastError()));
#endif
	}
#ifdef SO_REUSEADDR
	if(1) {
		int on = 1;
		if(setsockopt(listen_s, SOL_SOCKET, SO_REUSEADDR, (void*)&on,
			(socklen_t)sizeof(on)) < 0)
#ifndef USE_WINSOCK
			fatal_exit("setsockopt(.. SO_REUSEADDR ..) failed: %s",
				strerror(errno));
#else
			fatal_exit("setsockopt(.. SO_REUSEADDR ..) failed: %s",
				wsa_strerror(WSAGetLastError()));
#endif
	}
#endif
	if(bind(listen_s, (struct sockaddr*)&bind_addr, bind_len) == -1) {
#ifndef USE_WINSOCK
		fatal_exit("tcp bind: %s", strerror(errno));
#else
		fatal_exit("tcp bind: %s", wsa_strerror(WSAGetLastError()));
#endif
	}
	if(listen(listen_s, 5) == -1) {
#ifndef USE_WINSOCK
		fatal_exit("tcp listen: %s", strerror(errno));
#else
		fatal_exit("tcp listen: %s", wsa_strerror(WSAGetLastError()));
#endif
	}
	fd_set_nonblock(listen_s);
	printf("listening on port: %d\n", bindport);

	/* process loop */
	do_quit = 0;
	service_loop(s, listen_s, ring, &delay, &reuse, &srv_addr, srv_len, 
		pkt);

	/* cleanup */
	verbose(1, "cleanup");
#ifndef USE_WINSOCK
	close(s);
	close(listen_s);
#else
	closesocket(s);
	closesocket(listen_s);
#endif
	sldns_buffer_free(pkt);
	ring_delete(ring);
}