Skip to content

Commit

Permalink
Introduce hostip(8), a tool for resolving a name before dnscrypt-prox…
Browse files Browse the repository at this point in the history
…y starts.

It should help fighting the chicken-and-egg issue seen on routers, where
dnscrypt-proxy requires a working NTP server, but the NTP server requires
a working resolver.
  • Loading branch information
jedisct1 committed Jul 7, 2012
1 parent 7744d53 commit a8a3ad5
Show file tree
Hide file tree
Showing 16 changed files with 436 additions and 6 deletions.
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,7 @@ src/.deps
src/Makefile.in
src/dnscrypt-proxy/Makefile.in
src/dnscrypt-proxy/dnscrypt-proxy
src/hostip/hostip
src/libevent/*.la
src/libevent/*.lo
src/libevent/*.pc
Expand Down
28 changes: 28 additions & 0 deletions ChangeLog
Original file line number Diff line number Diff line change
@@ -1,3 +1,31 @@
Date: 2012-07-06

Useless indentation nits.

Date: 2012-07-02

Use ioctl() instead of fnctl(fnctl()) as much as possible. Saves 1 syscall.

Date: 2012-07-02

Define getpwnam() and struct passwd if getpwnam(3) exists but the headers don't.

Date: 2012-06-26

Xcode 4.5 DP2

Date: 2012-06-24

Bump Linux packages to 10.0.1

Date: 2012-06-24

Update ChangeLog

Date: 2012-06-24

Current dev version is 0.10.1

Date: 2012-06-24

chroot() as soon as we can again. Drop libevent2's evdns arc4random() to use
Expand Down
5 changes: 5 additions & 0 deletions NEWS
Original file line number Diff line number Diff line change
@@ -1,4 +1,9 @@

* Version 0.11:
- A new tool, hostip, can resolve host names before dnscrypt-proxy is
started. This should help resolving chicken-and-egg problems on
routers, as reported by LanceThePants.

* Version 0.10.1:
- The daemon didn't start on some Linux distributions lacking the
RANDOM_UUID sysctl. This has been fixed.
Expand Down
11 changes: 11 additions & 0 deletions README.markdown
Original file line number Diff line number Diff line change
Expand Up @@ -184,6 +184,17 @@ are usually safe.
A value below or equal to 512 will disable this mechanism, unless a
client sends a packet with an OPT section providing a payload size.

The `hostip` utility
--------------------

The DNSCrypt proxy ships with a simple tool named `hostip` that
resolves a name to IPv4 or IPv6 addresses.

This tool can be useful for starting some services before
`dnscrypt-proxy`.

Queries made by `hostip` are not authenticated.

GUIs for dnscrypt-proxy
-----------------------

Expand Down
4 changes: 2 additions & 2 deletions configure.ac
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
AC_PREREQ(2.61)
AC_INIT(dnscrypt-proxy, 0.10.1, https://github.com/opendns/dnscrypt-proxy/issues)
AC_INIT(dnscrypt-proxy, 0.11, https://github.com/opendns/dnscrypt-proxy/issues)
AC_CONFIG_MACRO_DIR([m4])
AC_CONFIG_SRCDIR([src/dnscrypt-proxy/app.c])
AC_CONFIG_HEADER([config.h])
Expand Down Expand Up @@ -325,6 +325,7 @@ dnl Output.
AC_CONFIG_FILES([Makefile
man/Makefile
src/Makefile
src/hostip/Makefile
src/dnscrypt-proxy/Makefile
src/ext/Makefile
src/libnacl/Makefile
Expand All @@ -336,4 +337,3 @@ AC_CONFIG_FILES([Makefile
AC_OUTPUT

chmod +x src/libnacl/okcompilers/do

10 changes: 8 additions & 2 deletions man/Makefile.am
Original file line number Diff line number Diff line change
@@ -1,9 +1,15 @@
man_MANS = \
dnscrypt-proxy.8
dnscrypt-proxy.8 \
hostip.8

EXTRA_DIST= \
dnscrypt-proxy.8 \
dnscrypt-proxy.8.markdown
dnscrypt-proxy.8.markdown \
hostip.8 \
hostip.8.markdown

dnscrypt-proxy.8: dnscrypt-proxy.8.markdown
@RONN@ dnscrypt-proxy.8.markdown

hostip.8: hostip.8.markdown
@RONN@ hostip.8.markdown
5 changes: 4 additions & 1 deletion man/dnscrypt-proxy.8
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
.\" generated with Ronn/v0.7.3
.\" http://github.com/rtomayko/ronn/tree/0.7.3
.
.TH "DNSCRYPT\-PROXY" "8" "June 2012" "" ""
.TH "DNSCRYPT\-PROXY" "8" "July 2012" "" ""
.
.SH "NAME"
\fBdnscrypt\-proxy\fR \- A DNSCrypt forwarder
Expand Down Expand Up @@ -95,5 +95,8 @@ $ dnscrypt\-proxy \-\-provider\-key=B735:1140:206F:225D:3E2B:D822:D7FD:691E:A1C3
.
.fi
.
.SH "SEE ALSO"
hostip(8)
.
.SH "COPYRIGHT"
dnscrypt\-proxy is Copyright (C) 2011\-2012 OpenDNS, Inc\. \fBhttp://www\.opendns\.com/\fR
5 changes: 4 additions & 1 deletion man/dnscrypt-proxy.8.markdown
Original file line number Diff line number Diff line change
Expand Up @@ -87,8 +87,11 @@ string, with optional columns.

$ dnscrypt-proxy --provider-key=B735:1140:206F:225D:3E2B:D822:D7FD:691E:A1C3:3CC8:D666:8D0C:BE04:BFAB:CA43:FB79 --provider-name=2.dnscrypt-cert.dnscrypt.org. --resolver-ip=208.67.220.220 --daemonize

## SEE ALSO

hostip(8)

## COPYRIGHT

dnscrypt-proxy is Copyright (C) 2011-2012 OpenDNS, Inc.
`http://www.opendns.com/`

57 changes: 57 additions & 0 deletions man/hostip.8
Original file line number Diff line number Diff line change
@@ -0,0 +1,57 @@
.\" generated with Ronn/v0.7.3
.\" http://github.com/rtomayko/ronn/tree/0.7.3
.
.TH "HOSTIP" "8" "July 2012" "" ""
.
.SH "NAME"
\fBhostip\fR \- Resolve a host name to an IP address
.
.SH "SYNOPSIS"
\fBhostip\fR [\fIoptions\fR] host_name
.
.SH "DESCRIPTION"
\fBhostip\fR sends a DNS query to a resolver, and prints the IP addresses for the given host name\.
.
.P
It can be useful in order to retrieve IP addresses before dnscrypt\-proxy(8) is started\.
.
.SH "OPTIONS"
.
.IP "\(bu" 4
\fB\-6\fR, \fB\-\-ipv6\fR: ask for AAAA records\.
.
.IP "\(bu" 4
\fB\-h\fR, \fB\-\-help\fR: show usage\.
.
.IP "\(bu" 4
\fB\-r\fR, \fB\-\-resolver\-address=<ip>\fR: the resolver IP address (default: 208\.67\.222\.222, OpenDNS)\.
.
.IP "\(bu" 4
\fB\-V\fR, \fB\-\-version\fR: show version number\.
.
.IP "" 0
.
.SH "SIMPLE USAGE EXAMPLE"
.
.nf

$ hostip www\.example\.com
.
.fi
.
.SH "ADVANCED USAGE EXAMPLE"
.
.nf

$ hostip \-6 \-r 213\.154\.224\.3 www\.google\.com
.
.fi
.
.SH "EXIT STATUS"
The \fBhostip\fR utility exits 0 on success, and > 0 if an error occurs\.
.
.SH "SEE ALSO"
dnscrypt\-proxy(8)
.
.SH "COPYRIGHT"
hostip is Copyright (C) 2012 OpenDNS, Inc\. \fBhttp://www\.opendns\.com/\fR
47 changes: 47 additions & 0 deletions man/hostip.8.markdown
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
hostip(8) -- Resolve a host name to an IP address
=================================================

## SYNOPSIS

`hostip` [<options>] host_name

## DESCRIPTION

**hostip** sends a DNS query to a resolver, and prints the IP
addresses for the given host name.

It can be useful in order to retrieve IP addresses before
dnscrypt-proxy(8) is started.

## OPTIONS

* `-6`, `--ipv6`: ask for AAAA records.

* `-h`, `--help`: show usage.

* `-r`, `--resolver-address=<ip>`: the resolver IP address (default:
208.67.222.222, OpenDNS).

* `-V`, `--version`: show version number.

## SIMPLE USAGE EXAMPLE

$ hostip www.example.com

## ADVANCED USAGE EXAMPLE

$ hostip -6 -r 213.154.224.3 www.google.com

## EXIT STATUS

The `hostip` utility exits 0 on success, and > 0 if an error occurs.

## SEE ALSO

dnscrypt-proxy(8)

## COPYRIGHT

hostip is Copyright (C) 2012 OpenDNS, Inc.
`http://www.opendns.com/`

1 change: 1 addition & 0 deletions src/Makefile.am
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@

SUBDIRS = \
ext \
hostip \
libevent \
libnacl \
dnscrypt-proxy
18 changes: 18 additions & 0 deletions src/hostip/Makefile.am
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@

bin_PROGRAMS = \
hostip

hostip_SOURCES = \
app.c \
app.h \
options.c \
options.h

AM_CFLAGS = @CWFLAGS@

AM_CPPFLAGS = \
-I../libevent/include

hostip_LDADD = \
../libevent/libevent_extra.la \
../libevent/libevent_core.la
125 changes: 125 additions & 0 deletions src/hostip/app.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,125 @@

#include <config.h>
#include <sys/types.h>
#ifdef _WIN32
# include <winsock2.h>
#else
# include <sys/socket.h>
# include <netinet/in.h>
# include <arpa/inet.h>
#endif
#include <assert.h>
#include <stdio.h>
#include <stdlib.h>

#include <event2/event.h>
#include <event2/dns.h>
#include <event2/util.h>

#include "app.h"
#include "options.h"

static AppContext app_context;

#ifndef INET6_ADDRSTRLEN
# define INET6_ADDRSTRLEN 46U
#endif

static void
query_cb_err_print(const int err)
{
fprintf(stderr, "[%s]\n", evdns_err_to_string(err));
exit(1);
}

static void
ipv4_query_cb(int result, char type, int count, int ttl,
void * const ips_, void * const app_context_)
{
char ip_s_buf[INET6_ADDRSTRLEN + 1U];
AppContext *app_context = app_context_;
struct in_addr *ips = ips_;
const char *ip_s;
int i = 0;

(void) ttl;
if (result != DNS_ERR_NONE) {
query_cb_err_print(result);
}
assert(type == DNS_IPv4_A);
assert(count >= 0);
while (i < count) {
ip_s = evutil_inet_ntop(AF_INET, &ips[i], ip_s_buf, sizeof ip_s_buf);
if (ip_s != NULL) {
puts(ip_s);
}
i++;
}
event_base_loopexit(app_context->event_loop, NULL);
}

static void
ipv6_query_cb(int result, char type, int count, int ttl,
void * const ips_, void * const app_context_)
{
char ip_s_buf[INET6_ADDRSTRLEN + 1U];
AppContext *app_context = app_context_;
struct in6_addr *ips = ips_;
const char *ip_s;
int i = 0;

(void) ttl;
if (result != DNS_ERR_NONE) {
query_cb_err_print(result);
}
assert(type == DNS_IPv6_AAAA);
assert(count >= 0);
while (i < count) {
ip_s = evutil_inet_ntop(AF_INET6, &ips[i], ip_s_buf, sizeof ip_s_buf);
if (ip_s != NULL) {
puts(ip_s);
}
i++;
}
event_base_loopexit(app_context->event_loop, NULL);
}

int main(int argc, char *argv[])
{
struct evdns_base *evdns_base;

if (options_parse(&app_context, argc, argv) != 0) {
return 1;
}
#ifdef _WIN32
WSADATA wsa_data;
WSAStartup(MAKEWORD(2, 2), &wsa_data);
#endif
if ((app_context.event_loop = event_base_new()) == NULL) {
perror("event_base_new");
return 1;
}
if ((evdns_base = evdns_base_new(app_context.event_loop, 0)) == NULL) {
perror("evdns_base");
return 1;
}
if (evdns_base_nameserver_ip_add(evdns_base,
app_context.resolver_ip) != 0) {
fprintf(stderr, "Unable to use [%s] as a resolver\n",
app_context.resolver_ip);
return 1;
}
if (app_context.want_ipv6 != 0) {
evdns_base_resolve_ipv6(evdns_base, app_context.host_name,
DNS_QUERY_NO_SEARCH,
ipv6_query_cb, &app_context);
} else {
evdns_base_resolve_ipv4(evdns_base, app_context.host_name,
DNS_QUERY_NO_SEARCH,
ipv4_query_cb, &app_context);
}
event_base_dispatch(app_context.event_loop);
event_base_free(app_context.event_loop);

return 0;
}
Loading

0 comments on commit a8a3ad5

Please sign in to comment.