printf("-h this help\n");
printf("-p port the port to listen on\n");
printf("-v verbose (multiple times increase verbosity)\n");
+ printf("-f ip set forwarder address\n");
+ printf("-z port set forwarder port\n");
printf("Version %s\n", PACKAGE_VERSION);
printf("BSD licensed, see LICENSE file in source package.\n");
printf("Report bugs to %s.\n", PACKAGE_BUGREPORT);
log_init();
/* parse the options */
- while( (c=getopt(argc, argv, "hvp:")) != -1) {
+ while( (c=getopt(argc, argv, "f:hvp:z:")) != -1) {
switch(c) {
+ case 'f':
+ fwd = optarg;
+ break;
+ case 'z':
+ fwdport = optarg;
+ break;
case 'p':
if(!atoi(optarg))
fatal_exit("invalid port '%s'", optarg);
}
if(!worker_set_fwd(worker, fwd, fwdport)) {
worker_delete(worker);
- fatal_exit("could set forwarder address");
+ fatal_exit("could not set forwarder address");
}
/* drop user priviliges and chroot if needed */
int worker_set_fwd(struct worker* worker, const char* ip, const char* port)
{
- struct addrinfo *res = NULL;
- struct addrinfo hints;
- int r;
+ uint16_t p;
log_assert(worker && ip);
- memset(&hints, 0, sizeof(hints));
- hints.ai_family = AF_UNSPEC;
- hints.ai_socktype = SOCK_DGRAM;
- if(!port)
- port = UNBOUND_DNS_PORT;
- if((r=getaddrinfo(ip, port, &hints, &res)) != 0 || !res) {
- log_err("failed %s:%s getaddrinfo: %s %s",
- ip, port,
- gai_strerror(r), r==EAI_SYSTEM?strerror(errno):"");
+ if(port)
+ p = (uint16_t)atoi(port);
+ else p = (uint16_t)atoi(UNBOUND_DNS_PORT);
+ if(!p) {
+ log_err("Bad port number %s", port?port:"default_port");
return 0;
}
- worker->fwd_addrlen = res->ai_addrlen;
- memcpy(&worker->fwd_addr, &res->ai_addr, res->ai_addrlen);
- freeaddrinfo(res);
+ if(str_is_ip6(ip)) {
+ struct sockaddr_in6* sa =
+ (struct sockaddr_in6*)&worker->fwd_addr;
+ worker->fwd_addrlen = (socklen_t)sizeof(struct sockaddr_in6);
+ memset(sa, 0, worker->fwd_addrlen);
+ sa->sin6_family = AF_INET6;
+ sa->sin6_port = htons(p);
+ if(inet_pton((int)sa->sin6_family, ip, &sa->sin6_addr) <= 0) {
+ log_err("Bad ip6 address %s", ip);
+ return 0;
+ }
+ } else { /* ip4 */
+ struct sockaddr_in* sa =
+ (struct sockaddr_in*)&worker->fwd_addr;
+ worker->fwd_addrlen = (socklen_t)sizeof(struct sockaddr_in);
+ memset(sa, 0, worker->fwd_addrlen);
+ sa->sin_family = AF_INET;
+ sa->sin_port = htons(p);
+ if(inet_pton((int)sa->sin_family, ip, &sa->sin_addr) <= 0) {
+ log_err("Bad ip4 address %s", ip);
+ return 0;
+ }
+ }
+ verbose(VERB_ALGO, "fwd queries to: %s %d", ip, p);
return 1;
}
address families.
- uses IPV6_USE_MIN_MTU for udp6 ,IPV6_V6ONLY to make ip6 sockets.
- listens on both ip4 and ip6 ports to provide correct return address.
+ - worker fwder address filled correctly.
+ - fixup timer code.
1 February 2007: Wouter
- outside network more UDP work.
.Nm unbound
.Op Fl h
.Op Fl p Ar port
+.Op Fl f Ar ip
+.Op Fl z Ar port
.Op Fl v
.Sh DESCRIPTION
.It Fl p Ar port
Start listening on the given port. Default is port 53(DNS).
+.It Fl f Ar ip
+Set forwarder address. DNS queries will be forwarded to this server.
+
+.It Fl z Ar ip
+Set forwarder port. DNS queries will be forwarded to this port.
+
.It Fl v
Increase verbosity. If given multiple times, more information is logged.
}
comm_timer_disable(p->timer);
/* TODO handle it */
+ log_info("outnet handle udp reply");
return 0;
}
{
/* struct pending* p = (struct pending*)arg; */
/* it timed out . TODO handle it. */
+ log_info("timeout udp");
}
struct outside_network*
else pend->c = outnet->udp4_ports[chosen];
log_assert(pend->c);
- log_info("chose query %x outbound %d of %d",
- pend->id, chosen, nummax);
+ log_info("query %x outbound %d of %d", pend->id, chosen, nummax);
}
/* system calls to set timeout after sending UDP to make roundtrip
smaller. */
- tv.tv_sec = (int)time(NULL) + timeout;
+ tv.tv_sec = timeout;
tv.tv_usec = 0;
comm_timer_set(pend->timer, &tv);
}
}
tm->callback = cb;
tm->cb_arg = cb_arg;
- evtimer_set(&tm->ev_timer->ev, comm_timer_callback, tm);
+ /*evtimer_set(&tm->ev_timer->ev, comm_timer_callback, tm);*/
+ event_set(&tm->ev_timer->ev, -1, EV_PERSIST|EV_TIMEOUT,
+ comm_timer_callback, tm);
if(event_base_set(base->eb->base, &tm->ev_timer->ev) != 0) {
log_err("timer_create: event_base_set failed.");
free(tm->ev_timer);
{
if(timer->ev_timer->enabled)
comm_timer_disable(timer);
- memcpy((struct timeval*)&timer->timeout, tv, sizeof(struct timeval));
- evtimer_add(&timer->ev_timer->ev, (struct timeval*)&timer->timeout);
+ evtimer_add(&timer->ev_timer->ev, tv);
timer->ev_timer->enabled = 1;
}
/** the internal event stuff */
struct internal_timer* ev_timer;
- /**
- * the timeout, absolute value seconds.
- * Do not write to this, call comm_timer_set instead.
- */
- const struct timeval timeout;
-
/** callback function, takes user arg only */
void (*callback)(void*);