Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with
or
.
Download ZIP
Browse files

Rewrite using libevent instead of libuv.

  • Loading branch information...
commit d33ce14302c828c8ea283b5c4b0a3860f4ba14be 1 parent c622fd0
@jedisct1 jedisct1 authored
Showing with 35,289 additions and 1,328 deletions.
  1. +32 −4 .gitignore
  2. +4 −4 AUTHORS
  3. +2 −2 COPYING
  4. +3 −0  NEWS
  5. +11 −11 README.markdown
  6. +7 −8 TECHNOTES
  7. +6 −0 autogen.sh
  8. +34 −27 configure.ac
  9. +3 −3 iphone.sh
  10. +5 −5 man/dnscrypt-proxy.8
  11. +7 −5 man/dnscrypt-proxy.8.markdown
  12. +4 −3 src/Makefile.am
  13. +5 −13 src/dnscrypt-proxy/Makefile.am
  14. +35 −26 src/dnscrypt-proxy/app.c
  15. +98 −77 src/dnscrypt-proxy/cert.c
  16. +10 −9 src/dnscrypt-proxy/cert.h
  17. +36 −3 src/dnscrypt-proxy/dnscrypt.c
  18. +5 −0 src/dnscrypt-proxy/dnscrypt.h
  19. +9 −22 src/dnscrypt-proxy/dnscrypt_client.c
  20. +27 −25 src/dnscrypt-proxy/dnscrypt_proxy.h
  21. +3 −1 src/dnscrypt-proxy/logger.c
  22. +4 −4 src/dnscrypt-proxy/options.c
  23. +4 −2 src/dnscrypt-proxy/pid_file.c
  24. +2 −0  src/dnscrypt-proxy/probes_dnscrypt_proxy.d
  25. +104 −94 src/dnscrypt-proxy/probes_no_dtrace.h
  26. +2 −3 src/dnscrypt-proxy/salsa20_random.c
  27. +327 −358 src/dnscrypt-proxy/tcp_request.c
  28. +1 −1  src/dnscrypt-proxy/tcp_request.h
  29. +12 −26 src/dnscrypt-proxy/tcp_request_p.h
  30. +254 −239 src/dnscrypt-proxy/udp_request.c
  31. +8 −18 src/dnscrypt-proxy/udp_request_p.h
  32. +20 −0 src/dnscrypt-proxy/utils.c
  33. +4 −0 src/dnscrypt-proxy/utils.h
  34. +0 −49 src/dnscrypt-proxy/uv_alloc.c
  35. +0 −18 src/dnscrypt-proxy/uv_alloc.h
  36. +0 −207 src/dnscrypt-proxy/uv_helpers.c
  37. +0 −61 src/dnscrypt-proxy/uv_helpers.h
  38. +3 −0  src/ext/Makefile.am
  39. +568 −0 src/ext/queue.h
  40. +1,279 −0 src/libevent/ChangeLog
  41. +257 −0 src/libevent/Doxyfile
  42. +74 −0 src/libevent/LICENSE
  43. +241 −0 src/libevent/Makefile.am
  44. +47 −0 src/libevent/Makefile.nmake
  45. +191 −0 src/libevent/README
  46. +363 −0 src/libevent/WIN32-Code/event2/event-config.h
  47. +1,354 −0 src/libevent/WIN32-Code/tree.h
  48. +539 −0 src/libevent/arc4random.c
  49. +15 −0 src/libevent/autogen.sh
  50. +3,064 −0 src/libevent/buffer.c
  51. +325 −0 src/libevent/buffer_iocp.c
  52. +410 −0 src/libevent/bufferevent-internal.h
  53. +875 −0 src/libevent/bufferevent.c
  54. +690 −0 src/libevent/bufferevent_async.c
  55. +511 −0 src/libevent/bufferevent_filter.c
  56. +1,435 −0 src/libevent/bufferevent_openssl.c
  57. +333 −0 src/libevent/bufferevent_pair.c
  58. +1,011 −0 src/libevent/bufferevent_ratelim.c
  59. +693 −0 src/libevent/bufferevent_sock.c
  60. +101 −0 src/libevent/changelist-internal.h
  61. +488 −0 src/libevent/compat/sys/queue.h
  62. +803 −0 src/libevent/configure.in
  63. +100 −0 src/libevent/defer-internal.h
  64. +306 −0 src/libevent/devpoll.c
  65. +473 −0 src/libevent/epoll.c
  66. +52 −0 src/libevent/epoll_sub.c
  67. +281 −0 src/libevent/evbuffer-internal.h
  68. +4,692 −0 src/libevent/evdns.c
  69. +45 −0 src/libevent/evdns.h
  70. +368 −0 src/libevent/event-internal.h
  71. +2,913 −0 src/libevent/event.c
  72. +85 −0 src/libevent/event.h
  73. +290 −0 src/libevent/event_iocp.c
  74. +1,717 −0 src/libevent/event_rpcgen.py
  75. +590 −0 src/libevent/event_tagging.c
  76. +45 −0 src/libevent/evhttp.h
  77. +92 −0 src/libevent/evmap-internal.h
  78. +799 −0 src/libevent/evmap.c
  79. +473 −0 src/libevent/evport.c
  80. +204 −0 src/libevent/evrpc-internal.h
  81. +1,174 −0 src/libevent/evrpc.c
  82. +45 −0 src/libevent/evrpc.h
  83. +64 −0 src/libevent/evsignal-internal.h
  84. +382 −0 src/libevent/evthread-internal.h
  85. +445 −0 src/libevent/evthread.c
  86. +191 −0 src/libevent/evthread_pthread.c
  87. +339 −0 src/libevent/evthread_win32.c
  88. +2,180 −0 src/libevent/evutil.c
  89. +39 −0 src/libevent/evutil.h
  90. +147 −0 src/libevent/evutil_rand.c
Sorry, we could not display the entire diff because too many files (508) changed.
View
36 .gitignore
@@ -1,5 +1,5 @@
-*.dSYM
*.cmake
+*.dSYM
*.log
*.o
*.s
@@ -24,19 +24,47 @@ depcomp
install-sh
libtool
ltmain.sh
+m4/libtool.m4
+m4/ltoptions.m4
+m4/ltsugar.m4
+m4/ltversion.m4
+m4/lt~obsolete.m4
man/*.html
man/Makefile.in
missing
probes.h
probes_dnscrypt_proxy.h
-src/*.la
-src/*.lo
src/*.o
src/.deps
-src/.libs
src/Makefile.in
src/dnscrypt-proxy/Makefile.in
src/dnscrypt-proxy/dnscrypt-proxy
+src/libevent/*.la
+src/libevent/*.lo
+src/libevent/*.pc
+src/libevent/.libs
+src/libevent/include/event2/event-config.h
+src/libevent/sample/.libs
+src/libevent/sample/dns-example
+src/libevent/sample/event-test
+src/libevent/sample/hello-world
+src/libevent/sample/http-server
+src/libevent/sample/le-proxy
+src/libevent/sample/signal-test
+src/libevent/sample/time-test
+src/libevent/test/.libs
+src/libevent/test/bench
+src/libevent/test/bench_cascade
+src/libevent/test/bench_http
+src/libevent/test/bench_httpclient
+src/libevent/test/regress
+src/libevent/test/rpcgen-attempted
+src/libevent/test/test-changelist
+src/libevent/test/test-eof
+src/libevent/test/test-init
+src/libevent/test/test-ratelim
+src/libevent/test/test-time
+src/libevent/test/test-weof
src/libnacl/okcompilers/c
src/libnacl/okcompilers/do
stamp-*
View
8 AUTHORS
@@ -3,10 +3,10 @@ NaCl
see http://nacl.cr.yp.to/ for more info about this library and the
list of contributors.
-libuv
------
-see https://github.com/joyent/libuv for more info about this library
-and the src/libuv/AUTHORS file for the list of contributors.
+libevent
+--------
+see https://http://libevent.org/ for more info about this library
+and the src/libevent/README file for the list of contributors.
dnscrypt
--------
View
4 COPYING
@@ -26,8 +26,8 @@ The externally maintained libraries used by dnscrypt-proxy are:
- NaCl (http://nacl.cr.yp.to/). Public domain.
- - libuv (https://github.com/joyent/libuv). MIT license.
- + libuv dependencies, see src/libuv/LICENSE.
+ - libevent (http://libevent.org/). 3-clause BSD license.
+ See src/libevent/LICENSE.
- salsa20_random.c reuses code from OpenBSD written by Damien Miller.
BSD license.
View
3  NEWS
@@ -1,4 +1,7 @@
+* Version 0.10:
+ - Almost a complete rewrite, with libuv being replaced by libevent.
+
* Version 0.9.5:
- Full IPv6 support.
View
22 README.markdown
@@ -33,8 +33,7 @@ Installation
------------
The daemon is known to work on recent versions of OSX, OpenBSD,
-NetBSD, Dragonfly BSD, FreeBSD, Linux, Windows (MingW or Cygwin), and iOS
-(requires a jailbroken device).
+NetBSD, Dragonfly BSD, FreeBSD, Linux and iOS (requires a jailbroken device).
Download the
[latest version](https://github.com/opendns/dnscrypt-proxy/downloads)
@@ -54,9 +53,6 @@ compilation process.
Running `make -j2 test` in the `src/libnacl` directory is also highly
recommended.
-On BSD systems, _GNU Make_ should be installed prior to running the
-`./configure` script.
-
The proxy will be installed as `/usr/local/sbin/dnscrypt-proxy` by default.
Command-line switches are documented in the `dnscrypt-proxy(8)` man page.
@@ -73,8 +69,9 @@ The easiest way to start the daemon is:
# dnscrypt-proxy --daemonize
-The proxy will accept incoming requests on 127.0.0.1 and
-encrypt/decrypt them from/to OpenDNS resolvers.
+The proxy will accept incoming requests on 127.0.0.1, tag them with an
+authentication code, forward them to OpenDNS resolvers, and validate
+each answer before passing it to the client.
Given such a setup, in order to actually start using DNSCrypt, you
need to update your `/etc/resolv.conf` file and replace your current
@@ -143,6 +140,8 @@ As a workaround, the port number can be changed using
the `--resolver-port=<port>` option. For example, OpenDNS servers
reply to queries sent to ports 53, 443 and 5353.
+By default, dnscrypt-proxy sends outgoing queries to UDP port 443.
+
In addition, the DNSCrypt proxy can force outgoing queries to be
sent over TCP. For example, TCP port 443, which is commonly used for
communication over HTTPS, may not be filtered.
@@ -150,7 +149,7 @@ communication over HTTPS, may not be filtered.
The `--tcp-only` command-line switch forces this behavior. When
an incoming query is received, the daemon immediately replies with a
"response truncated" message, forcing the client to retry over TCP.
-The daemon then encrypts and signs the query and forwards it over TCP
+The daemon then authenticates the query and forwards it over TCP
to the resolver.
TCP is slower than UDP, and this workaround should never be used
@@ -174,7 +173,7 @@ adding `options edns0` to the `/etc/resolv.conf` file on most
Unix-like operating systems.
`dnscrypt-proxy` can transparently rewrite outgoing packets before
-signing and encrypting them, in order to add the EDNS0 mechanism. By
+authenticating them, in order to add the EDNS0 mechanism. By
default, a conservative payload size of 1280 bytes is advertised.
This size can be made larger by starting the proxy with the
@@ -197,8 +196,9 @@ DNS settings. OSX only, written in Objective C. 64-bit CPU required.
Experimental.
- [DNSCrypt WinClient](https://github.com/Noxwizard/dnscrypt-winclient):
-Easily enable/disable DNSCrypt on multiple adapters. Windows only,
-written in .NET.
+Easily enable/disable DNSCrypt on multiple adapters. Supports
+different ports and protocols, IPv6, parental controls and the proxy
+can act as a gateway service. Windows only, written in .NET.
- [DNSCrypt Win Client](https://github.com/opendns/dnscrypt-win-client):
Official GUI for Windows, by OpenDNS.
View
15 TECHNOTES
@@ -16,7 +16,7 @@ Cryptographic library
so that portable packages can be built. CPU-specific implementations are
used server-side.
-- crypto_box_curve25519xsalsa20poly1305_*() for signing/encrypting
+- crypto_box_curve25519xsalsa20poly1305_*() for authenticating/encrypting
queries and replies, crypto_sign_ed25519_*() for signing certificates, and
crypto_stream_salsa20() as a PRNG.
@@ -25,15 +25,14 @@ Cryptographic library
Event-notification library
--------------------------
-- Uses NodeJS' libuv, which wraps libev and native Windows functions, and
- provides nice cross-platform wrappers for common functions. Unbound's
- boilerplate is also excellent, but it hasn't been packaged as a
- standalone library yet.
+- Uses libevent. Unbound's boilerplate is also excellent, but it hasn't been
+ packaged as a standalone library yet.
-- Because it is totally awesome for writing software that has to
- eventually work on Windows.
+- Because it is totally awesome for writing portable software.
-- Bundled with dnscrypt, for now, because it's still a moving target.
+- Bundled with dnscrypt, for now, because it's a modified version (so
+ that evdns can cope with TXT records) and because some distributions
+ are still shipping dead old versions.
Certificates
------------
View
6 autogen.sh
@@ -1,5 +1,11 @@
#! /bin/sh
+if glibtoolize --version > /dev/null 2>&1; then
+ LIBTOOLIZE='glibtoolize'
+else
+ LIBTOOLIZE='libtoolize'
+fi
+$LIBTOOLIZE && \
aclocal -I m4 && \
autoheader && \
automake --gnu --add-missing --include-deps && \
View
61 configure.ac
@@ -1,8 +1,9 @@
AC_PREREQ(2.61)
-AC_INIT(dnscrypt-proxy, 0.9.5, https://github.com/opendns/dnscrypt-proxy/issues)
+AC_INIT(dnscrypt-proxy, 0.10, 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])
+AC_CONFIG_SUBDIRS([src/libevent])
AM_INIT_AUTOMAKE([1.9 dist-bzip2])
AM_MAINTAINER_MODE
AM_DEP_TRACK
@@ -11,27 +12,11 @@ AC_SUBST(VERSION)
ISODATE=`date +%Y-%m-%d`
AC_SUBST(ISODATE)
-# Checks for programs.
-AX_CHECK_GNU_MAKE
-AS_IF([test -n "${ifGNUmake}"],[
- AC_MSG_ERROR([
-Found: ${MAKE}
-GNU make is required and was not found. If GNU make is not installed,
-please install it. www.gnu.org. If GNU make is installed, please adjust
-your PATH to make sure that GNU make is found before any other version
-of make that is installed on your system. rm config.cache and then
-re-run configure again.])
-],[
- AC_SUBST(MAKE, $_cv_gnu_make_command)
-])
-
LX_CFLAGS=${CFLAGS-NONE}
AC_PROG_CC_C99
AC_USE_SYSTEM_EXTENSIONS
CPPFLAGS="$CPPFLAGS -D_XPG4_2=1 -D_GNU_SOURCE=1"
-AX_PTHREAD
-
AS_IF([test "$cross_compiling" != no],
AC_DEFINE(CROSS_COMPILING,,[define if you are cross-compiling])
)
@@ -80,6 +65,7 @@ AX_CHECK_COMPILE_FLAG([-Wwrite-strings], [CFLAGS="$CFLAGS -Wwrite-strings"])
AX_CHECK_COMPILE_FLAG([-Wdiv-by-zero], [CFLAGS="$CFLAGS -Wdiv-by-zero"])
AC_ARG_VAR([CWFLAGS], [define to compilation flags for generating extra warnings])
+AX_CHECK_COMPILE_FLAG([-Wno-unknown-warning-option], [CWFLAGS="$CWFLAGS -Wno-unknown-warning-option"])
AX_CHECK_COMPILE_FLAG([-Wall], [CWFLAGS="$CWFLAGS -Wall"])
AX_CHECK_COMPILE_FLAG([-Wbad-function-cast], [CWFLAGS="$CWFLAGS -Wbad-function-cast"])
AX_CHECK_COMPILE_FLAG([-Wcast-align], [CWFLAGS="$CWFLAGS -Wcast-align"])
@@ -91,7 +77,6 @@ AX_CHECK_COMPILE_FLAG([-Wfloat-equal], [CWFLAGS="$CWFLAGS -Wfloat-equal"])
AX_CHECK_COMPILE_FLAG([-Wformat=2], [CWFLAGS="$CWFLAGS -Wformat=2"])
AX_CHECK_COMPILE_FLAG([-Wimplicit], [CWFLAGS="$CWFLAGS -Wimplicit"])
AX_CHECK_COMPILE_FLAG([-Wmissing-declarations], [CWFLAGS="$CWFLAGS -Wmissing-declarations"])
-AX_CHECK_COMPILE_FLAG([-Wmissing-noreturn], [CWFLAGS="$CWFLAGS -Wmissing-noreturn"])
AX_CHECK_COMPILE_FLAG([-Wmissing-prototypes], [CWFLAGS="$CWFLAGS -Wmissing-prototypes"])
AX_CHECK_COMPILE_FLAG([-Wnormalized=id], [CWFLAGS="$CWFLAGS -Wnormalized=id"])
AX_CHECK_COMPILE_FLAG([-Woverride-init], [CWFLAGS="$CWFLAGS -Woverride-init"])
@@ -135,15 +120,14 @@ AS_IF([test -d /usr/local/lib], [
LDFLAGS="$LDFLAGS -L/usr/local/lib"
])
-LIBS="$PTHREAD_LIBS $LIBS"
-CFLAGS="$CFLAGS $PTHREAD_CFLAGS"
-CC="$PTHREAD_CC"
+dnl Checks for header files.
-# Checks for header files.
AC_SYS_LARGEFILE
-AC_CHECK_HEADERS([execinfo.h paths.h sys/cdefs.h sys/feature_tests.h])
+AC_CHECK_HEADERS([sys/cdefs.h sys/feature_tests.h])
+AC_CHECK_HEADERS([execinfo.h paths.h pwd.h])
+
+dnl Checks for typedefs, structures, and compiler characteristics.
-# Checks for typedefs, structures, and compiler characteristics.
AC_C_RESTRICT
AC_CHECK_TYPE([in_port_t], , [AC_DEFINE(in_port_t, uint16_t,
@@ -238,7 +222,8 @@ do {
AC_MSG_RESULT(no)
])
-# Checks for library functions.
+dnl Checks for library functions.
+
AC_SEARCH_LIBS(pow, [m])
AC_SEARCH_LIBS(dlopen, [dl])
AC_SEARCH_LIBS(clock_gettime, [rt],
@@ -260,7 +245,8 @@ AS_IF([echo `(uname -s) 2>/dev/null` | $GREP "CYGWIN" > /dev/null], [
AC_CHECK_HEADER([CoreServices/CoreServices.h],
[LIBS="$LIBS -framework CoreFoundation -framework CoreServices"])
-# Switches
+dnl Switches.
+
AC_HEADER_ASSERT
AC_ARG_ENABLE(blocking-random,
@@ -303,15 +289,36 @@ AC_SUBST([MAINT])
AC_SUBST([NACL_PATH])
AC_SUBST([PROBES_SOURCE])
+dnl Libtool.
+
+LT_INIT([disable-shared])
+
+dnl Subconfig.
+
+ac_configure_args="$ac_configure_args --disable-dependency-tracking"
+ac_configure_args="$ac_configure_args --disable-openssl"
+ac_configure_args="$ac_configure_args --disable-shared"
+ac_configure_args="$ac_configure_args --disable-thread-support"
+ac_configure_args="$ac_configure_args --enable-function-sections"
+ac_configure_args="$ac_configure_args --with-pic"
+export CC
+export CFLAGS
+export CPP
+export CPPFLAGS
+export LDFLAGS
+export LIBS
+
+dnl Output.
+
AC_CONFIG_FILES([Makefile
man/Makefile
src/Makefile
src/dnscrypt-proxy/Makefile
+ src/ext/Makefile
src/libnacl/Makefile
src/libnacl/tests/Makefile
src/libnacl/okcompilers/c
src/libnacl/okcompilers/do
- src/libuv/Makefile
test/Makefile])
AC_OUTPUT
View
6 iphone.sh
@@ -3,9 +3,9 @@
export XCODEDIR="/Applications/Xcode45-DP1.app/Contents/Developer"
export BASEDIR="${XCODEDIR}/Platforms/iPhoneOS.platform/Developer"
export PATH="${BASEDIR}/usr/bin:$BASEDIR/usr/sbin:$PATH"
-export SDK="${BASEDIR}/SDKs/iPhoneOS5.1.sdk"
-export CFLAGS="-pthread -mthumb -arch armv6 -isysroot ${SDK}"
-export LDFLAGS="-pthread -mthumb -arch armv6 -isysroot ${SDK}"
+export SDK="${BASEDIR}/SDKs/iPhoneOS6.0.sdk"
+export CFLAGS="-pthread -mthumb -arch armv7 -isysroot ${SDK}"
+export LDFLAGS="-pthread -mthumb -arch armv7 -isysroot ${SDK}"
./configure --host=arm-apple-darwin10 && make -j2
View
10 man/dnscrypt-proxy.8
@@ -1,7 +1,7 @@
.\" generated with Ronn/v0.7.3
.\" http://github.com/rtomayko/ronn/tree/0.7.3
.
-.TH "DNSCRYPT\-PROXY" "8" "May 2012" "" ""
+.TH "DNSCRYPT\-PROXY" "8" "June 2012" "" ""
.
.SH "NAME"
\fBdnscrypt\-proxy\fR \- A DNSCrypt forwarder
@@ -10,13 +10,13 @@
\fBdnscrypt\-proxy\fR [\fIoptions\fR]
.
.SH "DESCRIPTION"
-\fBdnscrypt\-proxy\fR accepts DNS requests, encrypts and signs them using dnscrypt and forwards them to a remote dnscrypt\-enabled resolver\.
+\fBdnscrypt\-proxy\fR accepts DNS requests, authenticates and encrypts them using dnscrypt and forwards them to a remote dnscrypt\-enabled resolver\.
.
.P
-Replies from the resolver are expected also to be encrypted and signed\.
+Replies from the resolver are expected to be authenticated and encrypted or else they will be discarded\.
.
.P
-The proxy verifies the signature of replies, decrypts them, and transparently forwards them to the local stub resolver\.
+The proxy verifies the replies, decrypts them, and transparently forwards them to the local stub resolver\.
.
.P
\fBdnscrypt\-proxy\fR listens to \fB127\.0\.0\.1\fR / port \fB53\fR by default\.
@@ -57,7 +57,7 @@ Intead, run a DNS cache like \fBUnbound\fR, and configure it to use \fBdnscrypt\
\fB\-r\fR, \fB\-\-resolver\-address=<ip>\fR: a DNSCrypt\-capable resolver IP address\.
.
.IP "\(bu" 4
-\fB\-t\fR, \fB\-\-resolver\-port=<port>\fR: connect to the resolver on port \fIport\fR, as a workaround if UDP over port 53 is filtered\.
+\fB\-t\fR, \fB\-\-resolver\-port=<port>\fR: connect to the resolver on port \fIport\fR, as a workaround if UDP over port 53 is filtered\. The default port is 443\.
.
.IP "\(bu" 4
\fB\-u\fR, \fB\-\-user=<user name>\fR: chroot(2) to this user\'s home directory and drop privileges\.
View
12 man/dnscrypt-proxy.8.markdown
@@ -7,12 +7,14 @@ dnscrypt-proxy(8) -- A DNSCrypt forwarder
## DESCRIPTION
-**dnscrypt-proxy** accepts DNS requests, encrypts and signs them using
-dnscrypt and forwards them to a remote dnscrypt-enabled resolver.
+**dnscrypt-proxy** accepts DNS requests, authenticates and encrypts
+them using dnscrypt and forwards them to a remote dnscrypt-enabled
+resolver.
-Replies from the resolver are expected also to be encrypted and signed.
+Replies from the resolver are expected to be authenticated and
+encrypted or else they will be discarded.
-The proxy verifies the signature of replies, decrypts them, and transparently
+The proxy verifies the replies, decrypts them, and transparently
forwards them to the local stub resolver.
`dnscrypt-proxy` listens to `127.0.0.1` / port `53` by default.
@@ -58,7 +60,7 @@ ports.
address.
* `-t`, `--resolver-port=<port>`: connect to the resolver on port <port>,
- as a workaround if UDP over port 53 is filtered.
+ as a workaround if UDP over port 53 is filtered. The default port is 443.
* `-u`, `--user=<user name>`: chroot(2) to this user's home directory
and drop privileges.
View
7 src/Makefile.am
@@ -1,5 +1,6 @@
SUBDIRS = \
- dnscrypt-proxy \
- libuv \
- libnacl
+ ext \
+ libevent \
+ libnacl \
+ dnscrypt-proxy
View
18 src/dnscrypt-proxy/Makefile.am
@@ -37,25 +37,20 @@ dnscrypt_proxy_SOURCES = \
udp_request.h \
udp_request_p.h \
utils.c \
- utils.h \
- uv_alloc.c \
- uv_alloc.h \
- uv_helpers.c \
- uv_helpers.h
+ utils.h
AM_CFLAGS = @CWFLAGS@
AM_CPPFLAGS = \
- -I../libuv/include \
+ -I../ext \
+ -I../libevent/include \
-I../@NACL_PATH@/include/local
dnscrypt_proxy_LDADD = \
- ../libuv/uv.a \
+ ../libevent/libevent_core.la \
+ ../libevent/libevent_extra.la \
../@NACL_PATH@/lib/local/libnacl.a
-dnscrypt_proxy_DEPENDENCIES = \
- ../libuv/.done
-
BUILT_SOURCES = \
../libnacl/.done \
probes.h
@@ -63,9 +58,6 @@ BUILT_SOURCES = \
../libnacl/.done:
cd ../libnacl && $(MAKE) $(AM_MAKEFLAGS)
-../libuv/.done:
- cd ../libuv && $(MAKE) $(AM_MAKEFLAGS)
-
probes.h: @PROBES_SOURCE@
cat @PROBES_SOURCE@ > $@
View
61 src/dnscrypt-proxy/app.c
@@ -1,11 +1,6 @@
#include <config.h>
#include <sys/types.h>
-#ifdef _WIN32
-# include <winsock2.h>
-#else
-# include <sys/socket.h>
-#endif
#include <errno.h>
#include <signal.h>
@@ -15,6 +10,9 @@
#include <time.h>
#include <unistd.h>
+#include <event2/event.h>
+#include <event2/util.h>
+
#include "app.h"
#include "dnscrypt_client.h"
#include "dnscrypt_proxy.h"
@@ -24,36 +22,48 @@
#include "stack_trace.h"
#include "tcp_request.h"
#include "udp_request.h"
-#include "uv.h"
-#include "uv_alloc.h"
-#include "uv_helpers.h"
static AppContext app_context;
static int
proxy_context_init(ProxyContext * const proxy_context, int argc, char *argv[])
{
- struct sockaddr_storage resolver_addr;
+ char sockaddr_port[256U];
+ int sockaddr_len_int;
memset(proxy_context, 0, sizeof *proxy_context);
proxy_context->event_loop = NULL;
+ proxy_context->tcp_accept_timer = NULL;
+ proxy_context->tcp_conn_listener = NULL;
+ proxy_context->udp_listener_event = NULL;
+ proxy_context->udp_proxy_resolver_event = NULL;
+ proxy_context->udp_proxy_resolver_handle = -1;
+ proxy_context->udp_listener_handle = -1;
if (options_parse(&app_context, proxy_context, argc, argv) != 0) {
return -1;
}
- if ((proxy_context->event_loop = uv_loop_new()) == NULL) {
- logger(NULL, LOG_ERR, "Unable to initialize the UV event loop");
+ if ((proxy_context->event_loop = event_base_new()) == NULL) {
+ logger(NULL, LOG_ERR, "Unable to initialize the event loop");
return -1;
}
- if (uv_addr_any(&resolver_addr, proxy_context->resolver_ip,
- proxy_context->resolver_port,
- SOCK_DGRAM, IPPROTO_UDP, 0) != 0) {
- logger(NULL, LOG_ERR, "Unsupported socket address: [%s (%s)]",
- proxy_context->resolver_ip, proxy_context->resolver_port);
+ if (strchr(proxy_context->resolver_ip, ':') != NULL &&
+ *proxy_context->resolver_ip != '[') {
+ evutil_snprintf(sockaddr_port, sizeof sockaddr_port, "[%s]:%s",
+ proxy_context->resolver_ip, proxy_context->resolver_port);
+ } else {
+ evutil_snprintf(sockaddr_port, sizeof sockaddr_port, "%s:%s",
+ proxy_context->resolver_ip, proxy_context->resolver_port);
+ }
+ sockaddr_len_int = (int) sizeof proxy_context->resolver_sockaddr;
+ if (evutil_parse_sockaddr_port(sockaddr_port,
+ (struct sockaddr *)
+ &proxy_context->resolver_sockaddr,
+ &sockaddr_len_int) != 0) {
+ logger(NULL, LOG_ERR, "Unsupported resolver address: %s",
+ sockaddr_port);
return -1;
}
- memcpy(&proxy_context->resolver_addr, &resolver_addr,
- STORAGE_LEN(resolver_addr));
- uv_alloc_init(proxy_context);
+ proxy_context->resolver_sockaddr_len = (ev_socklen_t) sockaddr_len_int;
return 0;
}
@@ -64,7 +74,6 @@ proxy_context_free(ProxyContext * const proxy_context)
if (proxy_context == NULL) {
return;
}
- uv_alloc_free(proxy_context);
options_free(proxy_context);
logger_close(proxy_context);
}
@@ -81,9 +90,9 @@ int init_tz(void)
time(&now);
if ((tm = localtime(&now)) != NULL &&
strftime(stbuf, sizeof stbuf, "%z", tm) == (size_t) 5U) {
- snprintf(default_tz_for_putenv, sizeof default_tz_for_putenv,
- "TZ=UTC%c%c%c:%c%c", (*stbuf == '-' ? '+' : '-'),
- stbuf[1], stbuf[2], stbuf[3], stbuf[4]);
+ evutil_snprintf(default_tz_for_putenv, sizeof default_tz_for_putenv,
+ "TZ=UTC%c%c%c:%c%c", (*stbuf == '-' ? '+' : '-'),
+ stbuf[1], stbuf[2], stbuf[3], stbuf[4]);
}
putenv(default_tz_for_putenv);
(void) localtime(&now);
@@ -171,13 +180,13 @@ main(int argc, char *argv[])
if (cert_updater_start(&proxy_context) != 0) {
exit(1);
}
- uv_run(proxy_context.event_loop);
+ event_base_dispatch(proxy_context.event_loop);
logger_noformat(&proxy_context, LOG_INFO, "Stopping proxy");
- cert_updater_stop(&proxy_context);
+ cert_updater_free(&proxy_context);
tcp_listener_stop(&proxy_context);
udp_listener_stop(&proxy_context);
- uv_loop_delete(proxy_context.event_loop);
+ event_base_free(proxy_context.event_loop);
proxy_context_free(&proxy_context);
app_context.proxy_context = NULL;
salsa20_random_close();
View
175 src/dnscrypt-proxy/cert.c
@@ -1,26 +1,26 @@
#include <config.h>
#include <sys/types.h>
-#ifdef _WIN32
-# include <winsock2.h>
-#else
-# include <sys/socket.h>
-# include <arpa/inet.h>
-#endif
#include <assert.h>
+#include <stdint.h>
#include <stdlib.h>
#include <string.h>
#include <time.h>
+#include <event2/dns.h>
+#include <event2/event.h>
+
#include "cert.h"
#include "cert_p.h"
#include "crypto_sign_ed25519.h"
#include "dnscrypt_proxy.h"
#include "logger.h"
#include "probes.h"
+#include "salsa20_random.h"
#include "utils.h"
-#include "uv_helpers.h"
+
+static int cert_updater_update(ProxyContext * const proxy_context);
static int
cert_parse_version(ProxyContext * const proxy_context,
@@ -92,6 +92,7 @@ cert_parse_bincert(ProxyContext * const proxy_context,
logger(proxy_context, LOG_INFO,
"This certificates supersedes certificate #%lu",
(unsigned long) previous_serial);
+
return 0;
}
@@ -157,46 +158,43 @@ cert_print_server_key(ProxyContext * const proxy_context)
}
static void
-cert_timer_cb(uv_timer_t *handle, int status)
+cert_timer_cb(evutil_socket_t handle, const short event,
+ void * const proxy_context_)
{
- ProxyContext * const proxy_context = handle->data;
- CertUpdater * const cert_updater = &proxy_context->cert_updater;
+ ProxyContext * const proxy_context = proxy_context_;
- (void) status;
- cert_updater->has_cert_timer = 0;
+ (void) handle;
+ (void) event;
logger_noformat(proxy_context, LOG_INFO,
"Refetching server certificates");
- cert_updater_start(proxy_context);
+ cert_updater_update(proxy_context);
}
static void
cert_reschedule_query(ProxyContext * const proxy_context,
- const int64_t query_retry_delay)
+ const time_t query_retry_delay)
{
CertUpdater *cert_updater = &proxy_context->cert_updater;
- if (cert_updater->has_cert_timer != 0) {
+ if (evtimer_pending(cert_updater->cert_timer, NULL)) {
return;
}
- uv_timer_init(proxy_context->event_loop, &cert_updater->cert_timer);
- cert_updater->has_cert_timer = 1;
- cert_updater->cert_timer.data = proxy_context;
- uv_timer_start(&cert_updater->cert_timer, cert_timer_cb,
- query_retry_delay, (int64_t) 0);
+ const struct timeval tv = { .tv_sec = query_retry_delay, .tv_usec = 0 };
+ evtimer_add(cert_updater->cert_timer, &tv);
}
static void
cert_reschedule_query_after_failure(ProxyContext * const proxy_context)
{
CertUpdater *cert_updater = &proxy_context->cert_updater;
- int64_t query_retry_delay;
+ time_t query_retry_delay;
- if (cert_updater->has_cert_timer != 0) {
+ if (evtimer_pending(cert_updater->cert_timer, NULL)) {
return;
}
- query_retry_delay = (int64_t)
+ query_retry_delay = (time_t)
(CERT_QUERY_RETRY_MIN_DELAY +
- (int64_t) cert_updater->query_retry_step *
+ (time_t) cert_updater->query_retry_step *
(CERT_QUERY_RETRY_MAX_DELAY - CERT_QUERY_RETRY_MIN_DELAY) /
CERT_QUERY_RETRY_STEPS);
if (cert_updater->query_retry_step < CERT_QUERY_RETRY_STEPS) {
@@ -209,40 +207,43 @@ cert_reschedule_query_after_failure(ProxyContext * const proxy_context)
static void
cert_reschedule_query_after_success(ProxyContext * const proxy_context)
{
- if (proxy_context->cert_updater.has_cert_timer != 0) {
+ if (evtimer_pending(proxy_context->cert_updater.cert_timer, NULL)) {
return;
}
- cert_reschedule_query(proxy_context,
- (int64_t) CERT_QUERY_RETRY_DELAY_AFTER_SUCCESS);
+ cert_reschedule_query(proxy_context, (time_t)
+ CERT_QUERY_RETRY_DELAY_AFTER_SUCCESS_MIN_DELAY
+ + (time_t) salsa20_random_uniform
+ (CERT_QUERY_RETRY_DELAY_AFTER_SUCCESS_JITTER));
}
static void
-cert_query_cb(void *arg, int status, int timeouts, unsigned char *abuf,
- int alen)
+cert_query_cb(int result, char type, int count, int ttl,
+ void * const txt_records_, void * const arg)
{
- Bincert *bincert = NULL;
- ProxyContext *proxy_context = arg;
- struct ares_txt_reply *txt_out;
- struct ares_txt_reply *txt_out_current;
+ Bincert *bincert = NULL;
+ ProxyContext *proxy_context = arg;
+ const struct txt_record *txt_records = txt_records_;
+ int i = 0;
- (void) timeouts;
+ (void) type;
+ (void) ttl;
DNSCRYPT_PROXY_CERTS_UPDATE_RECEIVED();
- if (status != ARES_SUCCESS ||
- ares_parse_txt_reply(abuf, alen, &txt_out) != ARES_SUCCESS) {
+ evdns_base_free(proxy_context->cert_updater.evdns_base, 0);
+ proxy_context->cert_updater.evdns_base = NULL;
+ if (result != DNS_ERR_NONE) {
logger_noformat(proxy_context, LOG_ERR,
"Unable to retrieve server certificates");
cert_reschedule_query_after_failure(proxy_context);
DNSCRYPT_PROXY_CERTS_UPDATE_ERROR_COMMUNICATION();
return;
}
- txt_out_current = txt_out;
- while (txt_out_current != NULL) {
+ assert(count == 0 || count == 1);
+ while (i < count) {
cert_open_bincert(proxy_context,
- (const SignedBincert *) txt_out_current->txt,
- txt_out_current->length, &bincert);
- txt_out_current = txt_out_current->next;
+ (const SignedBincert *) txt_records[i].txt,
+ txt_records[i].len, &bincert);
+ i++;
}
- ares_free_data(txt_out);
if (bincert == NULL) {
logger_noformat(proxy_context, LOG_ERR,
"No useable certificates found");
@@ -272,42 +273,56 @@ cert_query_cb(void *arg, int status, int timeouts, unsigned char *abuf,
proxy_context->resolver_publickey);
}
-static int
-cert_set_servers(ProxyContext * const proxy_context,
- CertUpdater * const cert_updater)
-{
- return ares_set_servers_any(cert_updater->ar_channel,
- & (const ares_ss_node) {
- .next = NULL,
- .ss = &proxy_context->resolver_addr
- });
-}
-
int
cert_updater_init(ProxyContext * const proxy_context)
{
CertUpdater *cert_updater = &proxy_context->cert_updater;
- int ar_options_mask;
memset(cert_updater, 0, sizeof *cert_updater);
- if (ares_library_init(ARES_LIB_INIT_ALL) != ARES_SUCCESS) {
+ assert(proxy_context->event_loop != NULL);
+ assert(cert_updater->cert_timer == NULL);
+ if ((cert_updater->cert_timer =
+ evtimer_new(proxy_context->event_loop,
+ cert_timer_cb, proxy_context)) == NULL) {
return -1;
}
- assert(proxy_context->event_loop != NULL);
- cert_updater->has_cert_timer = 0;
cert_updater->query_retry_step = 0U;
- ar_options_mask = ARES_OPT_UDP_PORT | ARES_OPT_TCP_PORT;
- cert_updater->ar_options.udp_port = cert_updater->ar_options.tcp_port =
- STORAGE_PORT_ANY(proxy_context->resolver_addr);
- if (proxy_context->tcp_only != 0) {
- ar_options_mask |= ARES_OPT_FLAGS;
- cert_updater->ar_options.flags = ARES_FLAG_USEVC;
+ cert_updater->evdns_base = NULL;
+
+ return 0;
+}
+
+static int
+cert_updater_update(ProxyContext * const proxy_context)
+{
+ CertUpdater *cert_updater = &proxy_context->cert_updater;
+
+ DNSCRYPT_PROXY_CERTS_UPDATE_START();
+ if (cert_updater->evdns_base != NULL) {
+ evdns_base_free(cert_updater->evdns_base, 0);
+ }
+ if ((cert_updater->evdns_base =
+ evdns_base_new(proxy_context->event_loop, 0)) == NULL) {
+ return -1;
}
- if (uv_ares_init_options(proxy_context->event_loop,
- &cert_updater->ar_channel,
- &cert_updater->ar_options,
- ar_options_mask) != ARES_SUCCESS ||
- cert_set_servers(proxy_context, cert_updater) != ARES_SUCCESS) {
+ if (evdns_base_nameserver_sockaddr_add(cert_updater->evdns_base,
+ (struct sockaddr *)
+ &proxy_context->resolver_sockaddr,
+ proxy_context->resolver_sockaddr_len,
+ DNS_QUERY_NO_SEARCH) != 0) {
+ return -1;
+ }
+ if (proxy_context->tcp_only != 0 &&
+ strcmp(proxy_context->resolver_port,
+ DNS_DEFAULT_STANDARD_DNS_PORT) != 0) {
+ (void) evdns_base_nameserver_ip_add(cert_updater->evdns_base,
+ proxy_context->resolver_ip);
+ }
+ if (evdns_base_resolve_txt(cert_updater->evdns_base,
+ proxy_context->provider_name,
+ DNS_QUERY_NO_SEARCH,
+ cert_query_cb,
+ proxy_context) == NULL) {
return -1;
}
return 0;
@@ -316,11 +331,8 @@ cert_updater_init(ProxyContext * const proxy_context)
int
cert_updater_start(ProxyContext * const proxy_context)
{
- CertUpdater *cert_updater = &proxy_context->cert_updater;
+ cert_updater_update(proxy_context);
- DNSCRYPT_PROXY_CERTS_UPDATE_START();
- ares_query(cert_updater->ar_channel, proxy_context->provider_name,
- DNS_CLASS_IN, DNS_TYPE_TXT, cert_query_cb, proxy_context);
return 0;
}
@@ -329,10 +341,19 @@ cert_updater_stop(ProxyContext * const proxy_context)
{
CertUpdater * const cert_updater = &proxy_context->cert_updater;
- if (cert_updater->has_cert_timer) {
- cert_updater->has_cert_timer = 0;
- uv_timer_stop(&cert_updater->cert_timer);
+ assert(cert_updater->cert_timer != NULL);
+ evtimer_del(cert_updater->cert_timer);
+}
+
+void
+cert_updater_free(ProxyContext * const proxy_context)
+{
+ CertUpdater * const cert_updater = &proxy_context->cert_updater;
+
+ event_free(cert_updater->cert_timer);
+ cert_updater->cert_timer = NULL;
+ if (cert_updater->evdns_base != NULL) {
+ evdns_base_free(cert_updater->evdns_base, 0);
+ cert_updater->evdns_base = NULL;
}
- uv_ares_destroy(proxy_context->event_loop, cert_updater->ar_channel);
- ares_destroy_options(&cert_updater->ar_options);
}
View
19 src/dnscrypt-proxy/cert.h
@@ -2,24 +2,25 @@
#ifndef __CERT_H__
#define __CERT_H__ 1
-#include "uv.h"
+#include <event2/dns.h>
+#include <event2/event.h>
-#define CERT_QUERY_RETRY_MIN_DELAY (1 * 1000)
-#define CERT_QUERY_RETRY_MAX_DELAY (5 * 60 * 1000)
+#define CERT_QUERY_RETRY_MIN_DELAY 1
+#define CERT_QUERY_RETRY_MAX_DELAY (5 * 60)
#define CERT_QUERY_RETRY_STEPS 100
-#define CERT_QUERY_RETRY_DELAY_AFTER_SUCCESS (60 * 60 * 1000)
+#define CERT_QUERY_RETRY_DELAY_AFTER_SUCCESS_MIN_DELAY (60 * 60)
+#define CERT_QUERY_RETRY_DELAY_AFTER_SUCCESS_JITTER 100
typedef struct CertUpdater_ {
- struct ares_options ar_options;
- ares_channel ar_channel;
- uv_timer_t cert_timer;
- unsigned int query_retry_step;
- _Bool has_cert_timer;
+ struct evdns_base *evdns_base;
+ struct event *cert_timer;
+ unsigned int query_retry_step;
} CertUpdater;
struct ProxyContext_;
int cert_updater_init(struct ProxyContext_ * const proxy_context);
int cert_updater_start(struct ProxyContext_ * const proxy_context);
void cert_updater_stop(struct ProxyContext_ * const proxy_context);
+void cert_updater_free(struct ProxyContext_ * const proxy_context);
#endif
View
39 src/dnscrypt-proxy/dnscrypt.c
@@ -11,6 +11,8 @@
#include <stdlib.h>
#include <string.h>
+#include <event2/util.h>
+
#include "dnscrypt.h"
#include "salsa20_random.h"
#include "randombytes.h"
@@ -31,6 +33,37 @@ dnscrypt_query_header_size(void)
+ crypto_box_MACBYTES;
}
+static int
+dnscrypt_memcmp(const void * const b1_, const void * const b2_,
+ const size_t size)
+{
+ const uint8_t *b1 = b1_;
+ const uint8_t *b2 = b2_;
+ size_t i = (size_t) 0U;
+ uint8_t d = (uint8_t) 0U;
+
+ assert(size > (size_t) 0U);
+ do {
+ d |= b1[i] ^ b2[i];
+ } while (++i < size);
+
+ return (int) d;
+}
+
+int
+dnscrypt_cmp_client_nonce(const uint8_t client_nonce[crypto_box_HALF_NONCEBYTES],
+ const uint8_t * const buf, const size_t len)
+{
+ const size_t client_nonce_offset = sizeof DNSCRYPT_MAGIC_RESPONSE - 1U;
+
+ if (len < client_nonce_offset + crypto_box_HALF_NONCEBYTES ||
+ dnscrypt_memcmp(client_nonce, buf + client_nonce_offset,
+ crypto_box_HALF_NONCEBYTES) != 0) {
+ return -1;
+ }
+ return 0;
+}
+
size_t
dnscrypt_pad(uint8_t *buf, const size_t len, const size_t max_len)
{
@@ -73,9 +106,9 @@ dnscrypt_key_to_fingerprint(char fingerprint[80U], const uint8_t * const key)
COMPILER_ASSERT(crypto_box_SECRETKEYBYTES == 32U);
for (;;) {
assert(fingerprint_size > fingerprint_pos);
- snprintf(&fingerprint[fingerprint_pos],
- fingerprint_size - fingerprint_pos, "%02X%02X",
- key[key_pos], key[key_pos + 1U]);
+ evutil_snprintf(&fingerprint[fingerprint_pos],
+ fingerprint_size - fingerprint_pos, "%02X%02X",
+ key[key_pos], key[key_pos + 1U]);
key_pos += 2U;
if (key_pos >= crypto_box_PUBLICKEYBYTES) {
break;
View
5 src/dnscrypt-proxy/dnscrypt.h
@@ -26,6 +26,11 @@
size_t dnscrypt_response_header_size(void);
size_t dnscrypt_query_header_size(void);
+
+int dnscrypt_cmp_client_nonce(const uint8_t
+ client_nonce[crypto_box_HALF_NONCEBYTES],
+ const uint8_t * const buf, const size_t len);
+
size_t dnscrypt_pad(uint8_t *buf, const size_t len, const size_t max_len);
void dnscrypt_key_to_fingerprint(char fingerprint[80U],
View
31 src/dnscrypt-proxy/dnscrypt_client.c
@@ -1,5 +1,6 @@
#include <config.h>
+#include <sys/time.h>
#include <sys/types.h>
#include <assert.h>
@@ -8,10 +9,12 @@
#include <stdlib.h>
#include <string.h>
+#include <event2/event.h>
+
+#include "dnscrypt.h"
#include "dnscrypt_client.h"
#include "salsa20_random.h"
#include "utils.h"
-#include "uv.h"
static void
dnscrypt_make_client_nonce(DNSCryptClient * const client,
@@ -20,9 +23,9 @@ dnscrypt_make_client_nonce(DNSCryptClient * const client,
uint64_t ts;
uint32_t suffix;
- ts = uv_hrtime();
+ ts = dnscrypt_hrtime();
if (ts <= client->nonce_ts_last) {
- ts = client->nonce_ts_last + 1U;
+ ts = client->nonce_ts_last + (uint64_t) 1U;
}
client->nonce_ts_last = ts;
@@ -76,22 +79,6 @@ dnscrypt_client_curve(DNSCryptClient * const client,
return (ssize_t) (len + dnscrypt_query_header_size());
}
-static int
-dnscrypt_memcmp(const void * const b1_, const void * const b2_,
- const size_t size)
-{
- const uint8_t *b1 = b1_;
- const uint8_t *b2 = b2_;
- size_t i = (size_t) 0U;
- uint8_t d = (uint8_t) 0U;
-
- do {
- d |= b1[i] ^ b2[i];
- } while (++i < size);
-
- return (int) d;
-}
-
// 8 bytes: the string r6fnvWJ8 (DNSCRYPT_MAGIC_RESPONSE)
// 12 bytes: the client's nonce (crypto_box_NONCEBYTES / 2)
// 12 bytes: a server-selected nonce extension (crypto_box_NONCEBYTES / 2)
@@ -113,11 +100,11 @@ dnscrypt_client_uncurve(const DNSCryptClient * const client,
sizeof DNSCRYPT_MAGIC_RESPONSE - 1U)) {
return 1;
}
- memcpy(nonce, buf + sizeof DNSCRYPT_MAGIC_RESPONSE - 1U,
- crypto_box_NONCEBYTES);
- if (dnscrypt_memcmp(client_nonce, nonce, crypto_box_HALF_NONCEBYTES)) {
+ if (dnscrypt_cmp_client_nonce(client_nonce, buf, len) != 0) {
return -1;
}
+ memcpy(nonce, buf + sizeof DNSCRYPT_MAGIC_RESPONSE - 1U,
+ crypto_box_NONCEBYTES);
memset(buf + DNSCRYPT_SERVER_BOX_OFFSET - crypto_box_BOXZEROBYTES, 0,
crypto_box_BOXZEROBYTES);
if (crypto_box_open_afternm
View
52 src/dnscrypt-proxy/dnscrypt_proxy.h
@@ -3,30 +3,24 @@
#define __DNSCRYPT_PROXY_H__ 1
#include <sys/types.h>
-#ifdef _WIN32
-# include <winsock2.h>
-#else
-# include <sys/socket.h>
-#endif
#include <stdint.h>
+#include <event2/event.h>
+#include <event2/listener.h>
+
#include "app.h"
#include "cert.h"
#include "crypto_box.h"
#include "crypto_sign_ed25519.h"
#include "dnscrypt_client.h"
-#include "uv.h"
-
-#ifdef _WIN32
-# include "uv-private/ngx-queue.h"
-#endif
+#include "queue.h"
#ifndef DNS_QUERY_TIMEOUT
-# define DNS_QUERY_TIMEOUT (10 * 1000)
+# define DNS_QUERY_TIMEOUT 10
#endif
-#define DNS_MAX_PACKET_SIZE_UDP_RECV (65535U - 20U - 8U)
+#define DNS_MAX_PACKET_SIZE_UDP_RECV (65536U - 20U - 8U)
#define DNS_MAX_PACKET_SIZE_UDP_SEND 512U
#if DNS_MAX_PACKET_SIZE_UDP_RECV > NS_MAX_PACKET_SIZE_UDP_SEND
@@ -35,8 +29,14 @@
# define DNS_MAX_PACKET_SIZE DNS_MAX_PACKET_SIZE_UDP_SEND
#endif
-#ifndef DNS_DEFAULT_PORT
-# define DNS_DEFAULT_PORT "53"
+#ifndef DNS_DEFAULT_LOCAL_PORT
+# define DNS_DEFAULT_LOCAL_PORT "53"
+#endif
+#ifndef DNS_DEFAULT_RESOLVER_PORT
+# define DNS_DEFAULT_RESOLVER_PORT "443"
+#endif
+#ifndef DNS_DEFAULT_STANDARD_DNS_PORT
+# define DNS_DEFAULT_STANDARD_DNS_PORT "53"
#endif
#define DNS_HEADER_SIZE 12U
@@ -61,10 +61,8 @@
#define DNS_DEFAULT_EDNS_PAYLOAD_SIZE 1280U
-typedef struct SockAddr_ {
- struct sockaddr_storage ss;
- const char *str;
-} SockAddr;
+typedef TAILQ_HEAD(TCPRequestQueue_, TCPRequest_) TCPRequestQueue;
+typedef TAILQ_HEAD(UDPRequestQueue_, UDPRequest_) UDPRequestQueue;
typedef struct ProxyContext_ {
uint8_t dnscrypt_magic_query[DNSCRYPT_MAGIC_QUERY_LEN];
@@ -72,13 +70,11 @@ typedef struct ProxyContext_ {
uint8_t resolver_publickey[crypto_box_PUBLICKEYBYTES];
DNSCryptClient dnscrypt_client;
CertUpdater cert_updater;
- struct sockaddr_storage resolver_addr;
- uv_tcp_t tcp_listener_handle;
- uv_udp_t udp_listener_handle;
- ngx_queue_t tcp_request_queue;
- ngx_queue_t udp_request_queue;
+ struct sockaddr_storage resolver_sockaddr;
+ TCPRequestQueue tcp_request_queue;
+ UDPRequestQueue udp_request_queue;
AppContext *app_context;
- uv_loop_t *event_loop;
+ struct event_base *event_loop;
const char *local_ip;
const char *local_port;
const char *log_file;
@@ -87,10 +83,16 @@ typedef struct ProxyContext_ {
const char *provider_publickey_s;
const char *resolver_ip;
const char *resolver_port;
+ struct evconnlistener *tcp_conn_listener;
+ struct event *tcp_accept_timer;
+ struct event *udp_listener_event;
+ struct event *udp_proxy_resolver_event;
char *user_dir;
- void *uv_alloc_buffer;
+ ev_socklen_t resolver_sockaddr_len;
size_t uv_alloc_buffer_size;
size_t edns_payload_size;
+ evutil_socket_t udp_proxy_resolver_handle;
+ evutil_socket_t udp_listener_handle;
#ifndef _WIN32
uid_t user_id;
gid_t user_group;
View
4 src/dnscrypt-proxy/logger.c
@@ -13,6 +13,8 @@
#include <time.h>
#include <unistd.h>
+#include <event2/util.h>
+
#include "dnscrypt_proxy.h"
#include "logger.h"
#include "safe_rw.h"
@@ -66,7 +68,7 @@ logger(struct ProxyContext_ * const context,
urgency = "";
}
va_start(va, format);
- len = (size_t) vsnprintf(line, sizeof line, format, va);
+ len = (size_t) evutil_vsnprintf(line, sizeof line, format, va);
va_end(va);
if (len >= sizeof line) {
View
8 src/dnscrypt-proxy/options.c
@@ -11,7 +11,7 @@
#include <fcntl.h>
#include <getopt.h>
#include <limits.h>
-#ifndef _WIN32
+#ifdef HAVE_PWD_H
# include <pwd.h>
#endif
#include <stdio.h>
@@ -103,14 +103,14 @@ void options_init_with_default(AppContext * const app_context,
proxy_context->connections_count_max = DEFAULT_CONNECTIONS_COUNT_MAX;
proxy_context->edns_payload_size = (size_t) DNS_DEFAULT_EDNS_PAYLOAD_SIZE;
proxy_context->local_ip = "127.0.0.1";
- proxy_context->local_port = DNS_DEFAULT_PORT;
+ proxy_context->local_port = DNS_DEFAULT_LOCAL_PORT;
proxy_context->log_fd = -1;
proxy_context->log_file = NULL;
proxy_context->pid_file = NULL;
proxy_context->provider_name = DEFAULT_PROVIDER_NAME;
proxy_context->provider_publickey_s = DEFAULT_PROVIDER_PUBLICKEY;
proxy_context->resolver_ip = DEFAULT_RESOLVER_IP;
- proxy_context->resolver_port = DNS_DEFAULT_PORT;
+ proxy_context->resolver_port = DNS_DEFAULT_RESOLVER_PORT;
#ifndef _WIN32
proxy_context->user_id = (uid_t) 0;
proxy_context->user_group = (uid_t) 0;
@@ -233,7 +233,7 @@ options_parse(AppContext * const app_context,
case 't':
proxy_context->resolver_port = optarg;
break;
-#ifndef _WIN32
+#ifdef HAVE_PWD_H
case 'u': {
const struct passwd * const pw = getpwnam(optarg);
if (pw == NULL) {
View
6 src/dnscrypt-proxy/pid_file.c
@@ -12,6 +12,8 @@
#include <stdlib.h>
#include <unistd.h>
+#include <event2/util.h>
+
#include "logger.h"
#include "pid_file.h"
#include "safe_rw.h"
@@ -92,8 +94,8 @@ pid_file_write(const int fd, const pid_t child)
char pid_buf[50U];
int pid_buf_len;
- pid_buf_len = snprintf(pid_buf, sizeof pid_buf, "%llu",
- (unsigned long long) child);
+ pid_buf_len = evutil_snprintf(pid_buf, sizeof pid_buf, "%llu",
+ (unsigned long long) child);
assert((size_t) pid_buf_len < sizeof pid_buf);
if (safe_write(fd, pid_buf, pid_buf_len, -1) != pid_buf_len) {
(void) ftruncate(fd, (off_t) 0);
View
2  src/dnscrypt-proxy/probes_dnscrypt_proxy.d
@@ -12,6 +12,7 @@ provider dnscrypt_proxy {
probe request__udp__replied(void *);
probe request__udp__truncated(void *);
probe request__udp__overloaded();
+ probe request__udp__network_error(void *);
probe request__udp__done(void *);
probe request__udp__proxy_resolver__start(void *);
@@ -24,6 +25,7 @@ provider dnscrypt_proxy {
probe request__tcp__start(void *);
probe request__tcp__replied(void *);
probe request__tcp__overloaded();
+ probe request__tcp__network_error(void *);
probe request__tcp__done(void *);
probe request__tcp__proxy_resolver__start(void *);
View
198 src/dnscrypt-proxy/probes_no_dtrace.h
@@ -1,130 +1,140 @@
#ifndef __PROBES_NO_DTRACE_H__
-#define __PROBES_NO_DTRACE_H__ 1
+# define __PROBES_NO_DTRACE_H__ 1
-#define DNSCRYPT_PROXY_CERTS_UPDATE_DONE(arg0) \
+# define DNSCRYPT_PROXY_CERTS_UPDATE_DONE(arg0) \
do { \
- } while (0)
-#define DNSCRYPT_PROXY_CERTS_UPDATE_DONE_ENABLED() (0)
-#define DNSCRYPT_PROXY_CERTS_UPDATE_ERROR_COMMUNICATION() \
+ } while (0)
+#define DNSCRYPT_PROXY_CERTS_UPDATE_DONE_ENABLED() (0)
+#define DNSCRYPT_PROXY_CERTS_UPDATE_ERROR_COMMUNICATION() \
do { \
- } while (0)
-#define DNSCRYPT_PROXY_CERTS_UPDATE_ERROR_COMMUNICATION_ENABLED() (0)
-#define DNSCRYPT_PROXY_CERTS_UPDATE_ERROR_NOCERTS() \
+ } while (0)
+#define DNSCRYPT_PROXY_CERTS_UPDATE_ERROR_COMMUNICATION_ENABLED() (0)
+#define DNSCRYPT_PROXY_CERTS_UPDATE_ERROR_NOCERTS() \
do { \
- } while (0)
-#define DNSCRYPT_PROXY_CERTS_UPDATE_ERROR_NOCERTS_ENABLED() (0)
-#define DNSCRYPT_PROXY_CERTS_UPDATE_ERROR_SECURITY() \
+ } while (0)
+#define DNSCRYPT_PROXY_CERTS_UPDATE_ERROR_NOCERTS_ENABLED() (0)
+#define DNSCRYPT_PROXY_CERTS_UPDATE_ERROR_SECURITY() \
do { \
- } while (0)
-#define DNSCRYPT_PROXY_CERTS_UPDATE_ERROR_SECURITY_ENABLED() (0)
-#define DNSCRYPT_PROXY_CERTS_UPDATE_RECEIVED() \
+ } while (0)
+#define DNSCRYPT_PROXY_CERTS_UPDATE_ERROR_SECURITY_ENABLED() (0)
+#define DNSCRYPT_PROXY_CERTS_UPDATE_RECEIVED() \
do { \
- } while (0)
-#define DNSCRYPT_PROXY_CERTS_UPDATE_RECEIVED_ENABLED() (0)
-#define DNSCRYPT_PROXY_CERTS_UPDATE_RETRY() \
+ } while (0)
+#define DNSCRYPT_PROXY_CERTS_UPDATE_RECEIVED_ENABLED() (0)
+#define DNSCRYPT_PROXY_CERTS_UPDATE_RETRY() \
do { \
- } while (0)
-#define DNSCRYPT_PROXY_CERTS_UPDATE_RETRY_ENABLED() (0)
-#define DNSCRYPT_PROXY_CERTS_UPDATE_START() \
+ } while (0)
+#define DNSCRYPT_PROXY_CERTS_UPDATE_RETRY_ENABLED() (0)
+#define DNSCRYPT_PROXY_CERTS_UPDATE_START() \
do { \
- } while (0)
-#define DNSCRYPT_PROXY_CERTS_UPDATE_START_ENABLED() (0)
-#define DNSCRYPT_PROXY_REQUEST_CURVE_DONE(arg0, arg1) \
+ } while (0)
+#define DNSCRYPT_PROXY_CERTS_UPDATE_START_ENABLED() (0)
+#define DNSCRYPT_PROXY_REQUEST_CURVE_DONE(arg0, arg1) \
do { \
- } while (0)
-#define DNSCRYPT_PROXY_REQUEST_CURVE_DONE_ENABLED() (0)
-#define DNSCRYPT_PROXY_REQUEST_CURVE_START(arg0, arg1) \
+ } while (0)
+#define DNSCRYPT_PROXY_REQUEST_CURVE_DONE_ENABLED() (0)
+#define DNSCRYPT_PROXY_REQUEST_CURVE_START(arg0, arg1) \
do { \
- } while (0)
-#define DNSCRYPT_PROXY_REQUEST_CURVE_START_ENABLED() (0)
-#define DNSCRYPT_PROXY_REQUEST_TCP_DONE(arg0) \
+ } while (0)
+#define DNSCRYPT_PROXY_REQUEST_CURVE_START_ENABLED() (0)
+#define DNSCRYPT_PROXY_REQUEST_TCP_DONE(arg0) \
do { \
- } while (0)
-#define DNSCRYPT_PROXY_REQUEST_TCP_DONE_ENABLED() (0)
-#define DNSCRYPT_PROXY_REQUEST_TCP_OVERLOADED() \
+ } while (0)
+#define DNSCRYPT_PROXY_REQUEST_TCP_DONE_ENABLED() (0)
+#define DNSCRYPT_PROXY_REQUEST_TCP_NETWORK_ERROR(arg0) \
do { \
- } while (0)
-#define DNSCRYPT_PROXY_REQUEST_TCP_OVERLOADED_ENABLED() (0)
-#define DNSCRYPT_PROXY_REQUEST_TCP_PROXY_RESOLVER_DONE(arg0) \
+ } while (0)
+#define DNSCRYPT_PROXY_REQUEST_TCP_NETWORK_ERROR_ENABLED() (0)
+#define DNSCRYPT_PROXY_REQUEST_TCP_OVERLOADED() \
do { \
- } while (0)
-#define DNSCRYPT_PROXY_REQUEST_TCP_PROXY_RESOLVER_DONE_ENABLED() (0)
-#define DNSCRYPT_PROXY_REQUEST_TCP_PROXY_RESOLVER_GOT_INVALID_REPLY(arg0) \
+ } while (0)
+#define DNSCRYPT_PROXY_REQUEST_TCP_OVERLOADED_ENABLED() (0)
+#define DNSCRYPT_PROXY_REQUEST_TCP_PROXY_RESOLVER_DONE(arg0) \
do { \
- } while (0)
-#define DNSCRYPT_PROXY_REQUEST_TCP_PROXY_RESOLVER_GOT_INVALID_REPLY_ENABLED() (0)
-#define DNSCRYPT_PROXY_REQUEST_TCP_PROXY_RESOLVER_REPLIED(arg0) \
+ } while (0)
+#define DNSCRYPT_PROXY_REQUEST_TCP_PROXY_RESOLVER_DONE_ENABLED() (0)
+#define DNSCRYPT_PROXY_REQUEST_TCP_PROXY_RESOLVER_GOT_INVALID_REPLY(arg0) \
do { \
- } while (0)
-#define DNSCRYPT_PROXY_REQUEST_TCP_PROXY_RESOLVER_REPLIED_ENABLED() (0)
-#define DNSCRYPT_PROXY_REQUEST_TCP_PROXY_RESOLVER_START(arg0) \
+ } while (0)
+#define DNSCRYPT_PROXY_REQUEST_TCP_PROXY_RESOLVER_GOT_INVALID_REPLY_ENABLED() (0)
+#define DNSCRYPT_PROXY_REQUEST_TCP_PROXY_RESOLVER_REPLIED(arg0) \
do { \
- } while (0)
-#define DNSCRYPT_PROXY_REQUEST_TCP_PROXY_RESOLVER_START_ENABLED() (0)
-#define DNSCRYPT_PROXY_REQUEST_TCP_REPLIED(arg0) \
+ } while (0)
+#define DNSCRYPT_PROXY_REQUEST_TCP_PROXY_RESOLVER_REPLIED_ENABLED() (0)
+#define DNSCRYPT_PROXY_REQUEST_TCP_PROXY_RESOLVER_START(arg0) \
do { \
- } while (0)
-#define DNSCRYPT_PROXY_REQUEST_TCP_REPLIED_ENABLED() (0)
-#define DNSCRYPT_PROXY_REQUEST_TCP_START(arg0) \
+ } while (0)
+#define DNSCRYPT_PROXY_REQUEST_TCP_PROXY_RESOLVER_START_ENABLED() (0)
+#define DNSCRYPT_PROXY_REQUEST_TCP_REPLIED(arg0) \
do { \
- } while (0)
-#define DNSCRYPT_PROXY_REQUEST_TCP_START_ENABLED() (0)
-#define DNSCRYPT_PROXY_REQUEST_TCP_TIMEOUT(arg0) \
+ } while (0)
+#define DNSCRYPT_PROXY_REQUEST_TCP_REPLIED_ENABLED() (0)
+#define DNSCRYPT_PROXY_REQUEST_TCP_START(arg0) \
do { \
- } while (0)
-#define DNSCRYPT_PROXY_REQUEST_TCP_TIMEOUT_ENABLED() (0)
-#define DNSCRYPT_PROXY_REQUEST_UDP_DONE(arg0) \
+ } while (0)
+#define DNSCRYPT_PROXY_REQUEST_TCP_START_ENABLED() (0)
+#define DNSCRYPT_PROXY_REQUEST_TCP_TIMEOUT(arg0) \
do { \
- } while (0)
-#define DNSCRYPT_PROXY_REQUEST_UDP_DONE_ENABLED() (0)
-#define DNSCRYPT_PROXY_REQUEST_UDP_OVERLOADED() \
+ } while (0)
+#define DNSCRYPT_PROXY_REQUEST_TCP_TIMEOUT_ENABLED() (0)
+#define DNSCRYPT_PROXY_REQUEST_UDP_DONE(arg0) \
do { \
- } while (0)
-#define DNSCRYPT_PROXY_REQUEST_UDP_OVERLOADED_ENABLED() (0)
-#define DNSCRYPT_PROXY_REQUEST_UDP_PROXY_RESOLVER_DONE(arg0) \
+ } while (0)
+#define DNSCRYPT_PROXY_REQUEST_UDP_DONE_ENABLED() (0)
+#define DNSCRYPT_PROXY_REQUEST_UDP_NETWORK_ERROR(arg0) \
do { \
- } while (0)
-#define DNSCRYPT_PROXY_REQUEST_UDP_PROXY_RESOLVER_DONE_ENABLED() (0)
-#define DNSCRYPT_PROXY_REQUEST_UDP_PROXY_RESOLVER_GOT_INVALID_REPLY(arg0) \
+ } while (0)
+#define DNSCRYPT_PROXY_REQUEST_UDP_NETWORK_ERROR_ENABLED() (0)
+#define DNSCRYPT_PROXY_REQUEST_UDP_OVERLOADED() \
do { \
- } while (0)
-#define DNSCRYPT_PROXY_REQUEST_UDP_PROXY_RESOLVER_GOT_INVALID_REPLY_ENABLED() (0)
-#define DNSCRYPT_PROXY_REQUEST_UDP_PROXY_RESOLVER_REPLIED(arg0) \
+ } while (0)
+#define DNSCRYPT_PROXY_REQUEST_UDP_OVERLOADED_ENABLED() (0)
+#define DNSCRYPT_PROXY_REQUEST_UDP_PROXY_RESOLVER_DONE(arg0) \
do { \
- } while (0)
-#define DNSCRYPT_PROXY_REQUEST_UDP_PROXY_RESOLVER_REPLIED_ENABLED() (0)
-#define DNSCRYPT_PROXY_REQUEST_UDP_PROXY_RESOLVER_START(arg0) \
+ } while (0)
+#define DNSCRYPT_PROXY_REQUEST_UDP_PROXY_RESOLVER_DONE_ENABLED() (0)
+#define DNSCRYPT_PROXY_REQUEST_UDP_PROXY_RESOLVER_GOT_INVALID_REPLY(arg0) \
do { \
- } while (0)
-#define DNSCRYPT_PROXY_REQUEST_UDP_PROXY_RESOLVER_START_ENABLED() (0)
-#define DNSCRYPT_PROXY_REQUEST_UDP_REPLIED(arg0) \
+ } while (0)
+#define DNSCRYPT_PROXY_REQUEST_UDP_PROXY_RESOLVER_GOT_INVALID_REPLY_ENABLED() (0)
+#define DNSCRYPT_PROXY_REQUEST_UDP_PROXY_RESOLVER_REPLIED(arg0) \
do { \
- } while (0)
-#define DNSCRYPT_PROXY_REQUEST_UDP_REPLIED_ENABLED() (0)
-#define DNSCRYPT_PROXY_REQUEST_UDP_START(arg0) \
+ } while (0)
+#define DNSCRYPT_PROXY_REQUEST_UDP_PROXY_RESOLVER_REPLIED_ENABLED() (0)
+#define DNSCRYPT_PROXY_REQUEST_UDP_PROXY_RESOLVER_START(arg0) \
do { \
- } while (0)
-#define DNSCRYPT_PROXY_REQUEST_UDP_START_ENABLED() (0)
-#define DNSCRYPT_PROXY_REQUEST_UDP_TIMEOUT(arg0) \
+ } while (0)
+#define DNSCRYPT_PROXY_REQUEST_UDP_PROXY_RESOLVER_START_ENABLED() (0)
+#define DNSCRYPT_PROXY_REQUEST_UDP_REPLIED(arg0) \
do { \
- } while (0)
-#define DNSCRYPT_PROXY_REQUEST_UDP_TIMEOUT_ENABLED() (0)
-#define DNSCRYPT_PROXY_REQUEST_UDP_TRUNCATED(arg0) \
+ } while (0)
+#define DNSCRYPT_PROXY_REQUEST_UDP_REPLIED_ENABLED() (0)
+#define DNSCRYPT_PROXY_REQUEST_UDP_START(arg0) \
do { \
- } while (0)
-#define DNSCRYPT_PROXY_REQUEST_UDP_TRUNCATED_ENABLED() (0)
-#define DNSCRYPT_PROXY_REQUEST_UNCURVE_DONE(arg0, arg1) \
+ } while (0)
+#define DNSCRYPT_PROXY_REQUEST_UDP_START_ENABLED() (0)
+#define DNSCRYPT_PROXY_REQUEST_UDP_TIMEOUT(arg0) \
do { \
- } while (0)
-#define DNSCRYPT_PROXY_REQUEST_UNCURVE_DONE_ENABLED() (0)
-#define DNSCRYPT_PROXY_REQUEST_UNCURVE_START(arg0, arg1) \
+ } while (0)
+#define DNSCRYPT_PROXY_REQUEST_UDP_TIMEOUT_ENABLED() (0)
+#define DNSCRYPT_PROXY_REQUEST_UDP_TRUNCATED(arg0) \
do { \
- } while (0)
-#define DNSCRYPT_PROXY_REQUEST_UNCURVE_START_ENABLED() (0)
-#define DNSCRYPT_PROXY_STATUS_REQUESTS_ACTIVE(arg0, arg1) \
+ } while (0)
+#define DNSCRYPT_PROXY_REQUEST_UDP_TRUNCATED_ENABLED() (0)
+#define DNSCRYPT_PROXY_REQUEST_UNCURVE_DONE(arg0, arg1) \
do { \
- } while (0)
-#define DNSCRYPT_PROXY_STATUS_REQUESTS_ACTIVE_ENABLED() (0)
+ } while (0)
+#define DNSCRYPT_PROXY_REQUEST_UNCURVE_DONE_ENABLED() (0)
+#define DNSCRYPT_PROXY_REQUEST_UNCURVE_START(arg0, arg1) \
+do { \
+ } while (0)
+#define DNSCRYPT_PROXY_REQUEST_UNCURVE_START_ENABLED() (0)
+#define DNSCRYPT_PROXY_STATUS_REQUESTS_ACTIVE(arg0, arg1) \
+do { \
+ } while (0)
+#define DNSCRYPT_PROXY_STATUS_REQUESTS_ACTIVE_ENABLED() (0)
+
+#endif /* !defined(DTRACE_PROBES_DISABLED) || !DTRACE_PROBES_DISABLED */
#endif
View
5 src/dnscrypt-proxy/salsa20_random.c
@@ -15,7 +15,6 @@
#include "salsa20_random.h"
#include "safe_rw.h"
#include "utils.h"
-#include "uv.h"
#ifdef _WIN32
# include <Wincrypt.h>
@@ -67,7 +66,7 @@ salsa20_random_random_dev_open(void)
static void
salsa20_random_init(void)
{
- stream.nonce = (uint64_t) uv_hrtime();
+ stream.nonce = dnscrypt_hrtime();
assert(stream.nonce != (uint64_t) 0U);
if ((stream.random_data_source_fd =
@@ -81,7 +80,7 @@ salsa20_random_init(void)
static void
salsa20_random_init(void)
{
- stream.nonce = (uint64_t) uv_hrtime();
+ stream.nonce = dnscrypt_hrtime();
assert(stream.nonce != (uint64_t) 0U);
if (! CryptAcquireContext(&stream.hcrypt_prov, NULL, NULL,
View
685 src/dnscrypt-proxy/tcp_request.c
@@ -1,18 +1,21 @@
#include <config.h>
+
#include <sys/types.h>
-#ifdef _WIN32
-# include <winsock2.h>
-#else
-# include <sys/socket.h>
-# include <arpa/inet.h>
-#endif
#include <assert.h>
#include <limits.h>
#include <signal.h>
+#include <stdint.h>
#include <stdlib.h>
#include <string.h>
+#include <unistd.h>
+
+#include <event2/buffer.h>
+#include <event2/bufferevent.h>
+#include <event2/event.h>
+#include <event2/listener.h>
+#include <event2/util.h>
#include "dnscrypt_client.h"
#include "dnscrypt_proxy.h"
@@ -20,79 +23,32 @@
#include "probes.h"
#include "tcp_request.h"
#include "tcp_request_p.h"
-#include "uv.h"
-#include "uv_alloc.h"
-#include "uv_helpers.h"
-
-static uv_buf_t
-tcp_alloc_cb(uv_handle_t *handle, size_t size)
-{
- TCPRequest * const tcp_request = handle->data;
-
- return uv_alloc_get_buffer(tcp_request->proxy_context, size);
-}
-
-static void tcp_request_free(TCPRequest * const tcp_request);
-
-static void
-proxy_resolver_close_cb(uv_handle_t *handle)
-{
- (void) handle;
-}
-
-static void
-proxy_resolver_close_and_free_cb(uv_handle_t *handle)
-{
- TCPRequest * const tcp_request = handle->data;
-
- assert(tcp_request->status.has_proxy_resolver_handle == 0);
- proxy_resolver_close_cb(handle);
- tcp_request_free(tcp_request);
-}
-
-static void
-client_proxy_close_cb(uv_handle_t *handle)
-{
- (void) handle;
-}
-
-static void
-client_proxy_close_and_free_cb(uv_handle_t *handle)
-{
- TCPRequest * const tcp_request = handle->data;
-
- assert(tcp_request->status.has_client_proxy_handle == 0);
- client_proxy_close_cb(handle);
- tcp_request_free(tcp_request);
-}
static void
tcp_request_free(TCPRequest * const tcp_request)
{
ProxyContext *proxy_context;
- if (tcp_request->status.has_timeout_timer) {
- tcp_request->status.has_timeout_timer = 0;
- uv_timer_stop(&tcp_request->timeout_timer);
+ if (tcp_request->timeout_timer != NULL) {
+ event_free(tcp_request->timeout_timer);
+ tcp_request->timeout_timer = NULL;
}
- if (tcp_request->status.has_client_proxy_handle) {
- tcp_request->status.has_client_proxy_handle = 0;
- uv_close((uv_handle_t *) &tcp_request->client_proxy_handle,
- client_proxy_close_and_free_cb);
- return;
+ if (tcp_request->client_proxy_bev != NULL) {
+ bufferevent_free(tcp_request->client_proxy_bev);
+ tcp_request->client_proxy_bev = NULL;
}
- if (tcp_request->status.has_proxy_resolver_handle) {
- tcp_request->status.has_proxy_resolver_handle = 0;
- uv_close((uv_handle_t *) &tcp_request->proxy_resolver_handle,
- proxy_resolver_close_and_free_cb);
- logger(tcp_request->proxy_context, LOG_DEBUG,
- "Resolver is unreachable over TCP");
- return;
+ if (tcp_request->proxy_resolver_bev != NULL) {
+ bufferevent_free(tcp_request->proxy_resolver_bev);
+ tcp_request->proxy_resolver_bev = NULL;
+ }
+ if (tcp_request->proxy_resolver_query_evbuf != NULL) {
+ evbuffer_free(tcp_request->proxy_resolver_query_evbuf);
+ tcp_request->proxy_resolver_query_evbuf = NULL;
}
DNSCRYPT_PROXY_REQUEST_TCP_DONE(tcp_request);
proxy_context = tcp_request->proxy_context;
- ngx_queue_remove(tcp_request);
- tcp_request->dns_packet_len = (size_t) 0U;
+ assert(! TAILQ_EMPTY(&proxy_context->tcp_request_queue));
+ TAILQ_REMOVE(&proxy_context->tcp_request_queue, tcp_request, queue);
tcp_request->proxy_context = NULL;
free(tcp_request);
assert(proxy_context->connections_count > 0U);
@@ -112,388 +68,401 @@ tcp_request_kill(TCPRequest * const tcp_request)
}
static void
-timeout_timer_cb(uv_timer_t *handle, int status)
+timeout_timer_cb(evutil_socket_t timeout_timer_handle, short ev_flags,
+ void * const tcp_request_)
{
- TCPRequest * const tcp_request = handle->data;
+ TCPRequest * const tcp_request = tcp_request_;
- (void) status;
+ (void) ev_flags;
+ (void) timeout_timer_handle;
DNSCRYPT_PROXY_REQUEST_TCP_TIMEOUT(tcp_request);
- logger_noformat(tcp_request->proxy_context,
- LOG_DEBUG, "resolver timeout (TCP)");
+ logger_noformat(tcp_request->proxy_context, LOG_DEBUG,
+ "resolver timeout (TCP)");
tcp_request_kill(tcp_request);
}
-static int
-read_packet_size(TCPRequest * const tcp_request, ssize_t * const nread_p,
- const uint8_t **packet_itr_p)
-{
- assert(*nread_p > (ssize_t) 0);
- tcp_request->dns_packet_expected_len = (size_t) (**packet_itr_p << 8);
- (*packet_itr_p)++;
- (*nread_p)--;
- tcp_request->status.has_expected_size_partial = 1;
- if (*nread_p <= (ssize_t) 0) {
- return 1;
- }
- assert((tcp_request->dns_packet_expected_len & 0xff) == 0U);
- tcp_request->dns_packet_expected_len |= (size_t) **packet_itr_p;
- (*packet_itr_p)++;
- (*nread_p)--;
- tcp_request->status.has_expected_size_partial = 0;
- tcp_request->status.has_expected_size = 1;
-
- return 2;
-}
-
static void
-proxy_to_client_cb(uv_write_t *req, int status)
+proxy_resolver_event_cb(struct bufferevent * const proxy_resolver_bev,
+ const short events, void * const tcp_request_)
{
- TCPRequest * const tcp_request = req->data;
+ TCPRequest * const tcp_request = tcp_request_;
- (void) status;
- DNSCRYPT_PROXY_REQUEST_TCP_REPLIED(tcp_request);
- assert(req == &tcp_request->proxy_to_client_send_query);
- tcp_request_kill(tcp_request);
+ (void) proxy_resolver_bev;
+ if ((events & BEV_EVENT_ERROR) != 0) {
+ tcp_request_kill(tcp_request);
+ return;
+ }
+ if ((events & BEV_EVENT_CONNECTED) == 0) {
+ return;
+ }
}
static void
-resolver_to_proxy_cb(uv_stream_t *handle, ssize_t nread, uv_buf_t buf)
+resolver_proxy_read_cb(struct bufferevent * const proxy_resolver_bev,
+ void * const tcp_request_)
{
- TCPRequest *tcp_request = handle->data;
- const uint8_t *packet_itr;
- size_t uncurved_len;
-
- assert((uv_tcp_t *) handle == &tcp_request->proxy_resolver_handle);
- if (nread == (ssize_t) 0) {
- goto bye;
+ uint8_t dns_reply_len_buf[2];
+ uint8_t dns_uncurved_reply_len_buf[2];
+ uint8_t *dns_reply;
+ TCPRequest *tcp_request = tcp_request_;
+ ProxyContext *proxy_context = tcp_request->proxy_context;
+ struct evbuffer *input = bufferevent_get_input(proxy_resolver_bev);
+ size_t available_size;
+ size_t uncurved_len;
+
+ if (tcp_request->status.has_dns_reply_len == 0) {
+ assert(evbuffer_get_length(input) >= (size_t) 2U);
+ evbuffer_remove(input, dns_reply_len_buf, sizeof dns_reply_len_buf);
+ tcp_request->dns_reply_len = (size_t)
+ ((dns_reply_len_buf[0] << 8) | dns_reply_len_buf[1]);
+ tcp_request->status.has_dns_reply_len = 1;
}
- if (nread == (ssize_t) -1) {
+ assert(tcp_request->status.has_dns_reply_len != 0);
+ if (tcp_request->dns_reply_len <
+ (size_t) DNS_HEADER_SIZE + dnscrypt_response_header_size()) {
+ logger_noformat(proxy_context, LOG_WARNING, "Short reply received");
tcp_request_kill(tcp_request);
- goto bye;
- }
- packet_itr = (const uint8_t *) buf.base;
- if (tcp_request->status.has_expected_size == 0) {
- read_packet_size(tcp_request, &nread, &packet_itr);
- }
- if (nread <= (ssize_t) 0) {
- goto bye;
- }
- assert(nread > (ssize_t) 0);
- assert(tcp_request->status.has_expected_size_partial == 0);
- assert(tcp_request->status.has_expected_size == 1);
- assert(tcp_request->dns_packet_expected_len <= 0xffff);
- assert(tcp_request->dns_packet_len <= tcp_request->dns_packet_expected_len);
- if ((size_t) nread >
- tcp_request->dns_packet_expected_len - tcp_request->dns_packet_len) {
- nread = (ssize_t) (tcp_request->dns_packet_expected_len -
- tcp_request->dns_packet_len);
- }
- assert(sizeof tcp_request->dns_packet >= (size_t) nread);
- assert(sizeof tcp_request->dns_packet - (size_t) nread
- >= tcp_request->dns_packet_len);
- memcpy(&tcp_request->dns_packet[tcp_request->dns_packet_len],
- packet_itr, (size_t) nread);
- tcp_request->dns_packet_len += (size_t) nread;
- if (tcp_request->dns_packet_len < tcp_request->dns_packet_expected_len) {
- goto bye;
- }
- if (tcp_request->dns_packet_len
- < (size_t) DNS_HEADER_SIZE + dnscrypt_response_header_size()) {
- logger_noformat(tcp_request->proxy_context, LOG_WARNING,
- "Short query received");
+ return;
+ }
+ available_size = evbuffer_get_length(input);
+ if (available_size < tcp_request->dns_reply_len) {
+ bufferevent_setwatermark(tcp_request->proxy_resolver_bev,
+ EV_READ, tcp_request->dns_reply_len,
+ tcp_request->dns_reply_len);
+ return;
+ }
+ assert(available_size >= tcp_request->dns_reply_len);
+ uncurved_len = tcp_request->dns_reply_len;
+ dns_reply = evbuffer_pullup(input, uncurved_len);
+ if (dns_reply == NULL) {
tcp_request_kill(tcp_request);
- goto bye;
+ return;
}
- uncurved_len = tcp_request->dns_packet_len;
DNSCRYPT_PROXY_REQUEST_UNCURVE_START(tcp_request, uncurved_len);
- if (dnscrypt_client_uncurve
- (&tcp_request->proxy_context->dnscrypt_client,
- tcp_request->client_nonce,
- (uint8_t *) tcp_request->dns_packet, &uncurved_len) != 0) {
+ if (dnscrypt_client_uncurve(&proxy_context->dnscrypt_client,
+ tcp_request->client_nonce,
+ dns_reply, &uncurved_len) != 0) {
DNSCRYPT_PROXY_REQUEST_UNCURVE_DONE(tcp_request, uncurved_len);
DNSCRYPT_PROXY_REQUEST_TCP_PROXY_RESOLVER_GOT_INVALID_REPLY(tcp_request);
logger_noformat(tcp_request->proxy_context, LOG_WARNING,
"Received a suspicious reply from the resolver");
tcp_request_kill(tcp_request);
- goto bye;
+ return;
}
DNSCRYPT_PROXY_REQUEST_UNCURVE_DONE(tcp_request, uncurved_len);
- memset(tcp_request->client_nonce, 0, sizeof tcp_request->client_nonce);
- assert(uncurved_len <= tcp_request->dns_packet_len);
- tcp_request->dns_packet_len = uncurved_len;
- assert(tcp_request->dns_packet_len <= 0xffff);
- tcp_request->dns_packet_nlen =
- htons((uint16_t) tcp_request->dns_packet_len);
- uv_write(&tcp_request->proxy_to_client_send_query,
- (uv_stream_t *) &tcp_request->client_proxy_handle,
- (uv_buf_t[]) {
- { .base = (void *) &tcp_request->dns_packet_nlen,
- .len = sizeof tcp_request->dns_packet_nlen },
- { .base = (void *) tcp_request->dns_packet,
- .len = tcp_request->dns_packet_len }
- }, 2, proxy_to_client_cb);
- tcp_request->proxy_to_client_send_query.data = tcp_request;
-
- tcp_request->status.has_proxy_resolver_handle = 0;
- uv_close((uv_handle_t *) &tcp_request->proxy_resolver_handle,
- proxy_resolver_close_cb);
- DNSCRYPT_PROXY_REQUEST_TCP_PROXY_RESOLVER_DONE(tcp_request);
-
-bye:
- uv_alloc_release_buffer(tcp_request->proxy_context, &buf);
+ assert(uncurved_len <= tcp_request->dns_reply_len);
+ dns_uncurved_reply_len_buf[0] = (uncurved_len >> 8) & 0xff;
+ dns_uncurved_reply_len_buf[1] = uncurved_len & 0xff;
+ if (bufferevent_write(tcp_request->client_proxy_bev,
+ dns_uncurved_reply_len_buf, (size_t) 2U) != 0 ||
+ bufferevent_write(tcp_request->client_proxy_bev, dns_reply,
+ uncurved_len) != 0) {
+ tcp_request_kill(tcp_request);
+ return;
+ }
+ bufferevent_enable(tcp_request->client_proxy_bev, EV_WRITE);
+ bufferevent_free(tcp_request->proxy_resolver_bev);
+ tcp_request->proxy_resolver_bev = NULL;
}
static void
-proxy_to_resolver_cb(uv_write_t *req, int status)
+client_proxy_event_cb(struct bufferevent * const client_proxy_bev,
+ const short events, void * const tcp_request_)
{
- TCPRequest * const tcp_request = req->data;
+ TCPRequest * const tcp_request = tcp_request_;
- assert(req == &tcp_request->proxy_to_resolver_send_query);
- if (status < 0) {
- tcp_request_kill(tcp_request);
- return;
- }
- tcp_request->dns_packet_len = (size_t) 0U;
- tcp_request->dns_packet_expected_len = (size_t) 0U;
- tcp_request->status.has_expected_size = 0;
- tcp_request->status.has_expected_size_partial = 0;
- uv_read_start((uv_stream_t *) &tcp_request->proxy_resolver_handle,
- tcp_alloc_cb, resolver_to_proxy_cb);
+ (void) client_proxy_bev;
+ (void) events;
+ tcp_request_kill(tcp_request);
}
static void
-proxy_to_resolver_connect_cb(uv_connect_t *handle, int status)
+client_proxy_write_cb(struct bufferevent * const client_proxy_bev,
+ void * const tcp_request_)
{
- TCPRequest *tcp_request = handle->data;
- ssize_t curve_ret;
+ TCPRequest * const tcp_request = tcp_request_;
+
+ (void) client_proxy_bev;
+ DNSCRYPT_PROXY_REQUEST_TCP_REPLIED(tcp_request);
+ tcp_request_kill(tcp_request);
+}
- if (status < 0) {
+static void
+client_proxy_read_cb(struct bufferevent * const client_proxy_bev,
+ void * const tcp_request_)
+{
+ uint8_t dns_query[DNS_MAX_PACKET_SIZE];
+ uint8_t dns_query_len_buf[2];
+ uint8_t dns_curved_query_len_buf[2];
+ TCPRequest *tcp_request = tcp_request_;
+ ProxyContext *proxy_context = tcp_request->proxy_context;
+ struct evbuffer *input = bufferevent_get_input(client_proxy_bev);
+ ssize_t curve_ret;
+ size_t available_size;
+ size_t max_len;
+
+ if (tcp_request->status.has_dns_query_len == 0) {
+ assert(evbuffer_get_length(input) >= (size_t) 2U);
+ evbuffer_remove(input, dns_query_len_buf, sizeof dns_query_len_buf);
+ tcp_request->dns_query_len = (size_t)
+ ((dns_query_len_buf[0] << 8) | dns_query_len_buf[1]);
+ tcp_request->status.has_dns_query_len = 1;
+ }
+ assert(tcp_request->status.has_dns_query_len != 0);
+ if (tcp_request->dns_query_len < (size_t) DNS_HEADER_SIZE) {
+ logger_noformat(proxy_context, LOG_WARNING, "Short query received");
tcp_request_kill(tcp_request);
return;
}
- assert(SIZE_MAX - DNSCRYPT_MAX_PADDING - dnscrypt_query_header_size()
- > tcp_request->dns_packet_len);
- size_t max_len = tcp_request->dns_packet_len + DNSCRYPT_MAX_PADDING +
+ available_size = evbuffer_get_length(input);
+ if (available_size < tcp_request->dns_query_len) {
+ bufferevent_setwatermark(tcp_request->client_proxy_bev,
+ EV_READ, tcp_request->dns_query_len,
+ tcp_request->dns_query_len);
+ return;
+ }
+ assert(available_size >= tcp_request->dns_query_len);
+ bufferevent_disable(tcp_request->client_proxy_bev, EV_READ);
+ max_len = tcp_request->dns_query_len + DNSCRYPT_MAX_PADDING +
dnscrypt_query_header_size();
- if (max_len > TCP_MAX_PACKET_SIZE) {
- max_len = TCP_MAX_PACKET_SIZE;
+ if (max_len > sizeof dns_query) {
+ max_len = sizeof dns_query;
}
- if (tcp_request->dns_packet_len + dnscrypt_query_header_size() > max_len) {
+ assert(max_len <= DNS_MAX_PACKET_SIZE);
+ if (tcp_request->dns_query_len + dnscrypt_query_header_size() > max_len) {
+ tcp_request_kill(tcp_request);
+ return;
+ }
+ assert(tcp_request->proxy_resolver_query_evbuf == NULL);
+ if ((tcp_request->proxy_resolver_query_evbuf = evbuffer_new()) == NULL) {
+ tcp_request_kill(tcp_request);
+ return;
+ }
+ if ((ssize_t)
+ evbuffer_remove_buffer(input, tcp_request->proxy_resolver_query_evbuf,
+ tcp_request->dns_query_len)
+ != (ssize_t) tcp_request->dns_query_len) {
+ tcp_request_kill(tcp_request);
+ return;
+ }
+ assert(tcp_request->dns_query_len <= sizeof dns_query);
+ if ((ssize_t) evbuffer_remove(tcp_request->proxy_resolver_query_evbuf,
+ dns_query, tcp_request->dns_query_len)
+ != (ssize_t) tcp_request->dns_query_len) {
+ free(dns_query);
+ tcp_request_kill(tcp_request);
return;
}
DNSCRYPT_PROXY_REQUEST_CURVE_START(tcp_request,
- tcp_request->dns_packet_len);
+ tcp_request->dns_query_len);
+ assert(max_len <= sizeof dns_query);
curve_ret =
- dnscrypt_client_curve(&tcp_request->proxy_context->dnscrypt_client,
+ dnscrypt_client_curve(&proxy_context->dnscrypt_client,
tcp_request->client_nonce,
- tcp_request->dns_packet,
- tcp_request->dns_packet_len, max_len);
+ dns_query, tcp_request->dns_query_len, max_len);
if (curve_ret <= (ssize_t) 0) {
+ tcp_request_kill(tcp_request);
return;
}
- tcp_request->dns_packet_len = (size_t) curve_ret;
- assert(tcp_request->dns_packet_len >= dnscrypt_query_header_size());
- DNSCRYPT_PROXY_REQUEST_CURVE_DONE(tcp_request, tcp_request->dns_packet_len);
- assert(tcp_request->dns_packet_len <= sizeof tcp_request->dns_packet);
- assert(tcp_request->dns_packet_len <= 0xffff);
- tcp_request->dns_packet_nlen =
- htons((uint16_t) tcp_request->dns_packet_len);
- uv_write(&tcp_request->proxy_to_resolver_send_query,
- (uv_stream_t *) &tcp_request->proxy_resolver_handle,
- (uv_buf_t[]) {
- { .base = (void *) &tcp_request->dns_packet_nlen,
- .len = sizeof tcp_request->dns_packet_nlen },
- { .base = (void *) tcp_request->dns_packet,
- .len = tcp_request->dns_packet_len }
- }, 2, proxy_to_resolver_cb);
- tcp_request->proxy_to_resolver_send_query.data = tcp_request;
-}
-
-#ifndef SO_RCVBUFFORCE
-# define SO_RCVBUFFORCE SO_RCVBUF
-#endif
-#ifndef SO_SNDBUFFORCE
-# define SO_SNDBUFFORCE SO_SNDBUF
-#endif
-
-static void
-tcp_tune(const uv_tcp_t * const handle)
-{
-#ifdef _WIN32
- (void) handle;