diff --git a/.gitignore b/.gitignore
index 7317422..87c0221 100644
--- a/.gitignore
+++ b/.gitignore
@@ -18,3 +18,4 @@ src/filter/trackers
test/src/fdnstress/fdnstress
test/src/ptest/ptest
gcov-dir
+src/cashpack-0.3
diff --git a/Makefile.in b/Makefile.in
index 2754c7b..b444566 100644
--- a/Makefile.in
+++ b/Makefile.in
@@ -1,5 +1,6 @@
all: apps man
APPS = src/fdns test/src/fdnstress
+LIBS = src/cashpack-0.3
MANPAGES = fdns.1
prefix=@prefix@
@@ -15,9 +16,14 @@ NAME=@PACKAGE_NAME@
PACKAGE_TARNAME=@PACKAGE_TARNAME@
DOCDIR=@docdir@
+.PHONY: libs $(LIBS)
+libs: $(LIBS)
+$(LIBS):
+ $(MAKE) -C $@
+
.PHONY: apps $(APPS)
apps: $(APPS)
-$(APPS):
+$(APPS): $(LIBS)
$(MAKE) -C $@
$(MANPAGES): $(wildcard src/man/*.txt)
@@ -30,6 +36,9 @@ clean:
for dir in $(APPS); do \
$(MAKE) -C $$dir clean; \
done
+ for dir in $(LIBS); do \
+ $(MAKE) -C $$dir clean; \
+ done
rm -f $(MANPAGES) $(MANPAGES:%=%.gz)
cd test/compile; ./compile.sh --clean; cd ../..
@@ -38,6 +47,7 @@ distclean: clean
$(MAKE) -C $$dir distclean; \
done
rm -fr Makefile autom4te.cache config.log config.status config.h dummy.o src/common.mk
+ rm -fr src/cashpack-0.3
realinstall:
# fdns executable
diff --git a/README b/README
index 18a2451..cc8b5c1 100644
--- a/README
+++ b/README
@@ -54,6 +54,9 @@ Daniel Schildt (https://github.com/d2s)
rcplab (https://github.com/rcplab)
- containerpi and twnic
+Incoporating cashpack library, https://github.com/Dridi/cashpack
+Copyright ©2016-2017 Dridi Boukelmoune, license MIT
+
Incorporating code from Firejail Security Sandbox, https://github.com/netblue30/firejail
Copyright © 2014-2020 Firejail Authors, license GPLv2
diff --git a/README.md b/README.md
index ab9653f..757784d 100644
--- a/README.md
+++ b/README.md
@@ -43,7 +43,12 @@ FDNS is a community project. We are not affiliated with any company, and we don
## Project Status
-Release `0.9.62.6` is out.
+Development version 0.9.63:
+
+- HTTP1.1 removed and replaced with HTTP2.
+- Adding support for https://commons.host network of DoH servers (20+ servers).
+- Replaced --allow-local-doh with --disable-local-doh.
+
diff --git a/configure b/configure
index 34b7f68..0c1df78 100755
--- a/configure
+++ b/configure
@@ -3952,6 +3952,8 @@ if test "$prefix" = /usr; then
test "$sysconfdir" = '${prefix}/etc' && sysconfdir="/etc"
fi
+cd src && tar -xzvf cashpack-0.3.tar.gz && cd cashpack-0.3 && ./configure && cd ../..
+
ac_config_files="$ac_config_files Makefile src/common.mk src/fdns/Makefile test/src/fdnstress/Makefile"
cat >confcache <<\_ACEOF
diff --git a/configure.ac b/configure.ac
index 63e1628..c302886 100644
--- a/configure.ac
+++ b/configure.ac
@@ -77,6 +77,8 @@ if test "$prefix" = /usr; then
test "$sysconfdir" = '${prefix}/etc' && sysconfdir="/etc"
fi
+cd src && tar -xzvf cashpack-0.3.tar.gz && cd cashpack-0.3 && ./configure && cd ../..
+
AC_OUTPUT(Makefile src/common.mk src/fdns/Makefile test/src/fdnstress/Makefile)
echo
diff --git a/etc/servers b/etc/servers
index c50124d..352032b 100644
--- a/etc/servers
+++ b/etc/servers
@@ -38,7 +38,7 @@ zone: Europe
tags: UK, Europe
address: 217.169.20.23:443
host: dns.aa.net.uk/dns-query
-keepalive: 7
+keepalive: 30
name: a-and-a2
website: https://www.aa.net.uk/legal/dohdot-disclaimer/
@@ -46,7 +46,7 @@ zone: Europe
tags: UK, Europe
address: 217.169.20.22:443
host: dns.aa.net.uk/dns-query
-keepalive: 7
+keepalive: 30
# server down
#name: aaflalo
@@ -98,13 +98,15 @@ address: 176.103.130.134:443
host: dns-family.adguard.com/dns-query
keepalive: 30
-name: alekberg
-website: https://github.com/DNSCrypt/dnscrypt-resolvers/blob/master/v2/public-resolvers.md
-zone: Europe
-tags: Netherlands, Europe
-address: 51.15.124.208:443
-host: dns.alekberg.net/
-keepalive: 7
+# server down
+#name: alekberg
+#website: https://github.com/DNSCrypt/dnscrypt-resolvers/blob/master/v2/public-resolvers.md
+#zone: Europe
+#tags: Netherlands, Europe
+#address: 51.15.124.208:443
+#host: dns.alekberg.net/
+#sni: yes
+#keepalive: 7
# server down
#name: alekberg-adblocker
@@ -149,44 +151,46 @@ tags: non-profit, Austria, Europe
address: 93.177.65.183:443
host: doh.appliedprivacy.net/query
sni: yes
-keepalive: 7
+keepalive: 20
-# very short keepalive, will work fine on Firefox!
-#name: blahdns-fi
-#website: https://blahdns.com
-#zone: Europe
-#tags: Finland, Europe, adblocker
-#address: 95.216.212.177:443
-#host: doh-fi.blahdns.com/dns-query
-#sni: yes
-#keepalive: 7
-#
-#name: blahdns-de
-#website: https://blahdns.com
-#zone: Europe
-#tags: Germany, Europe, adblocker
-#address: 159.69.198.101:443
-#host: doh-de.blahdns.com/dns-query
-#sni: yes
-#keepalive: 4
-#
-#name: blahdns-jp
-#website: https://blahdns.com
-#zone: Asia-Pacific
-#tags: Japan, Asia-Pacific, adblocker
-#address: 45.32.55.94:443
-#host: doh-jp.blahdns.com/dns-query
-#sni: yes
-#keepalive: 4
-#
-#name: blahdns-sg
-#website: https://blahdns.com
-#zone: Asia-Pacific
-#tags: Singapore, Asia-Pacific, adblocker
-#address: 139.180.141.57:443
-#host: doh-sg.blahdns.com/dns-query
-#sni: yes
-#keepalive: 4
+name: blahdns-fi
+website: https://blahdns.com
+zone: Europe
+tags: Finland, Europe, adblocker
+address: 95.216.212.177:443
+host: doh-fi.blahdns.com/dns-query
+sni: yes
+keepalive: 30
+
+# very short timeout; works fine on Firefox
+##name: blahdns-de
+##website: https://blahdns.com
+##zone: Europe
+##tags: Germany, Europe, adblocker
+##address: 159.69.198.101:443
+##host: doh-de.blahdns.com/dns-query
+##sni: yes
+##keepalive: 4
+
+# very short timeout; works fine on Firefox
+##name: blahdns-jp
+##website: https://blahdns.com
+##zone: Asia-Pacific
+##tags: Japan, Asia-Pacific, adblocker
+##address: 45.32.55.94:443
+##host: doh-jp.blahdns.com/dns-query
+##sni: yes
+##keepalive: 4
+
+# very short timeout; works fine on Firefox
+##name: blahdns-sg
+##website: https://blahdns.com
+##zone: Asia-Pacific
+##tags: Singapore, Asia-Pacific, adblocker
+##address: 139.180.141.57:443
+##host: doh-sg.blahdns.com/dns-query
+##sni: yes
+##keepalive: 4
name: bortzmeyer
website: https://www.bortzmeyer.org/doh-bortzmeyer-fr-policy.html
@@ -194,7 +198,7 @@ zone: Europe
tags: France, Europe
address: 193.70.85.11:443
host: doh.bortzmeyer.fr/
-keepalive: 7
+keepalive: 20
name: brahmaworld
website: https://dns.brahma.world/
@@ -274,7 +278,7 @@ zone: Americas-East, Americas-West, Asia-Pacific, Europe
tags: anycast, Americas, Americas-East, Americas-West, Asia-Pacific, Europe
address: 1.1.1.1:443
host: cloudflare-dns.com/dns-query
-keepalive: 180
+keepalive: 60
name: cloudflare2
website: https://www.cloudflare.com
@@ -282,7 +286,7 @@ zone: Americas-East, Americas-West, Asia-Pacific, Europe
tags: anycast, Americas, Americas-East, Americas-West, Asia-Pacific, Europe
address: 1.0.0.1:443
host: cloudflare-dns.com/dns-query
-keepalive: 180
+keepalive: 60
name: cloudflare-security
website: https://www.cloudflare.com
@@ -291,7 +295,7 @@ tags: anycast, security, Americas, Americas-East, Americas-West, Asia-Pacific, E
address: 1.1.1.2:443
host: security.cloudflare-dns.com/dns-query
sni: yes
-keepalive: 180
+keepalive: 60
name: cloudflare-security2
website: https://www.cloudflare.com
@@ -300,26 +304,34 @@ tags: anycast, security, Americas, Americas-East, Americas-West, Asia-Pacific, E
address: 1.0.0.2:443
host: security.cloudflare-dns.com/dns-query
sni: yes
-keepalive: 180
+keepalive: 60
name: cloudflare-family
website: https://www.cloudflare.com
zone: Americas-East, Americas-West, Asia-Pacific, Europe
-tags: family, Americas, Americas-East, Americas-West, Asia-Pacific, Europe
+tags: family
address: 1.0.0.3:443
host: family.cloudflare-dns.com/dns-query
sni: yes
-keepalive: 180
+keepalive: 60
name: cloudflare-family2
website: https://www.cloudflare.com
zone: Americas-East, Americas-West, Asia-Pacific, Europe
-tags: family, Americas, Americas-East, Americas-West, Asia-Pacific, Europe
+tags: family
address: 1.1.1.3:443
host: family.cloudflare-dns.com/dns-query
sni: yes
-keepalive: 180
+keepalive: 60
+name: commons-host
+website: https://dev.to/commonshost/how-we-built-a-doh-cdn-with-20-global-edge-servers-in-10-days-1man
+zone: Americas-East, Americas-West, Asia-Pacific, Europe
+tags: geocast, Americas, Americas-East, Americas-West, Asia-Pacific, Europe
+address: commons.host:443
+host: commons.host/
+sni: yes
+keepalive: 30
# uncensored server redirected to cloudflare
name: containerpi
@@ -330,21 +342,23 @@ address: 45.77.180.10:443
host: dns.containerpi.com/dns-query
keepalive: 30
-name: cznic
-website: https://www.nic.cz/odvr/
-zone: Europe
-tags: Czechia, Europe
-address: 185.43.135.1:443
-host: odvr.nic.cz/doh
-keepalive: 7
-
-name: cznic2
-website: https://www.nic.cz/odvr/
-zone: Europe
-tags: Czechia, Europe
-address: 193.17.47.1:443
-host: odvr.nic.cz/doh
-keepalive: 7
+# works fine on Firefox
+##name: cznic
+##website: https://www.nic.cz/odvr/
+##zone: Europe
+##tags: Czechia, Europe
+##address: 185.43.135.1:443
+##host: odvr.nic.cz/doh
+##keepalive: 7
+
+# works fine on Firefox
+##name: cznic2
+##website: https://www.nic.cz/odvr/
+##zone: Europe
+##tags: Czechia, Europe
+##address: 193.17.47.1:443
+##host: odvr.nic.cz/doh
+##keepalive: 7
name: defaultroutes
website: https://doh.defaultroutes.de/
@@ -371,6 +385,24 @@ address: 185.95.218.43:443
host: dns.digitale-gesellschaft.ch/dns-query
keepalive: 30
+name: dns-sb
+website: https://dns.sb/
+zone: Europe
+tags: Estonia, Germany, Europe
+address: 185.222.222.222:443
+host: doh.dns.sb/dns-query
+sni: yes
+keepalive: 30
+
+name: dns-sb2
+website: https://dns.sb/
+zone: Europe
+tags: Estonia, Germany, Europe
+address: 185.184.222.222:443
+host: doh.dns.sb/dns-query
+sni: yes
+keepalive: 30
+
name: dnscrypt-ca
website: https://dnscrypt.ca/
zone: Americas-East
@@ -387,14 +419,29 @@ address: 149.56.228.45:453
host: dns2.dnscrypt.ca:453/dns-query
keepalive: 30
-# very short keepalive, works fine on Firefox
-#name: dnsforge
-#website: https://dnsforge.de
-#zone: Europe
-#tags: Germany, Europe, adblocker
-#address: 176.9.93.198:443
-#host: dnsforge.de/dns-query
-#keepalive: 2
+name: dnsforge
+website: https://dnsforge.de
+zone: Europe
+tags: Germany, Europe, adblocker
+address: 176.9.93.198:443
+host: dnsforge.de/dns-query
+keepalive: 30
+
+name: dnshome
+website: https://www.dnshome.de/doh-dot-public-resolver.php
+zone: Europe
+tags: Germany, Europe
+address: 185.233.106.232:443
+host: dns.dnshome.de/dns-query
+keepalive: 20
+
+name: dnshome2
+website: https://www.dnshome.de/doh-dot-public-resolver.php
+zone: Europe
+tags: Germany, Europe
+address: 185.233.107.4:443
+host: dns.dnshome.de/dns-query
+keepalive: 20
name: dnslify
website: https://www.dnslify.com/
@@ -402,7 +449,7 @@ zone: Asia-Pacific, Americas-East, Americas-West, Asia-Pacific, Europe
tags: Americas, Americas-East, Americas-West, Asia-Pacific, Europe, Netherlands, Germany, UK, NY, Califronia, Singapore
address: 185.235.81.1:443
host: doh.dnslify.com/dns-query
-keepalive: 7
+keepalive: 20
name: faelix
website: https://faelix.net/ref/dns/#privacy-dns
@@ -410,7 +457,7 @@ zone: Europe
tags: UK, Europe, adblocker
address: 46.227.200.52:443
host: pdns.faelix.net/
-keepalive: 7
+keepalive: 20
name: faelix2
website: https://faelix.net/ref/dns/#privacy-dns
@@ -418,7 +465,7 @@ zone: Europe
tags: Switzerland, Europe, adblocker
address: 185.134.196.52:443
host: pdns.faelix.net/
-keepalive: 7
+keepalive: 20
name: faelix3
website: https://faelix.net/ref/dns
@@ -426,7 +473,7 @@ zone: Europe
tags: UK, Europe
address: 46.227.200.54:443
host: rdns.faelix.net/
-keepalive: 7
+keepalive: 20
name: ffmuc
website: https://ffmuc.net/
@@ -466,7 +513,7 @@ zone: Europe
tags: Switzerland, Europe, OpenNIC
address: 85.5.93.230:443
host: ibksturm.synology.me/dns-query
-keepalive: 7
+keepalive: 30
name: ibuki
website: https://ibuki.cgnat.net/
@@ -474,7 +521,7 @@ zone: Americas-West
tags: California, Americas, Americas-West
address: 35.198.2.76:443
host: ibuki.cgnat.net/dns-query
-keepalive: 7
+keepalive: 20
name: jcdns
website: https://jcdns.fun/
@@ -516,14 +563,14 @@ address: 116.203.115.192:443
host: doh.libredns.gr/ads
keepalive: 30
-# very short keepalive; works fine in Firefox
-#name: meganerd
-#website: https://meganerd.nl/encrypted-dns-server
-#zone: Europe
-#tags: Netherlands, Europe
-#address: 209.250.241.25:443
-#host: jarjar.meganerd.nl/doh
-#keepalive: 3
+# very short timeout; works fine on Firefox
+##name: meganerd
+##website: https://meganerd.nl/encrypted-dns-server
+##zone: Europe
+##tags: Netherlands, Europe
+##address: 209.250.241.25:443
+##host: jarjar.meganerd.nl/doh
+##keepalive: 3
name: nixnet
website: https://nixnet.services/dns/
@@ -588,7 +635,7 @@ zone: Europe
tags: Netherlands, Europe
address: 136.144.215.158:443
host: doh.powerdns.org/dns-query
-keepalive: 7
+keepalive: 20
name: quad9
website: https://quad9.net
@@ -637,7 +684,7 @@ zone: Asia-Pacific
tags: Australia, Asia-Pacific, OpenNIC
address: 45.76.113.31:8443
host: dns.seby.io/dns-query
-keepalive: 7
+keepalive: 20
name: seby2
website: https://dns.seby.io
@@ -645,7 +692,7 @@ zone: Asia-Pacific
tags: Australia, Asia-Pacific, OpenNIC
address: 139.99.222.72:443
host: doh-2.seby.io/dns-query
-keepalive: 7
+keepalive: 20
name: snopyta
website: https://snopyta.org
@@ -662,7 +709,7 @@ zone: Europe
tags: non-profit, Switzerland, Europe
address: 130.59.31.248:443
host: dns.switch.ch/dns-query
-keepalive: 7
+keepalive: 20
name: switch2
website: https://www.switch.ch/security/info/public-dns/
@@ -670,7 +717,7 @@ zone: Europe
tags: non-profit, Switzerland, Europe
address: 130.59.31.251:443
host: dns.switch.ch/dns-query
-keepalive: 7
+keepalive: 20
# tiarapp servers: https://github.com/pengelana
name: tiarapp-sg
diff --git a/src/cashpack-0.3.tar.gz b/src/cashpack-0.3.tar.gz
new file mode 100644
index 0000000..f6776aa
Binary files /dev/null and b/src/cashpack-0.3.tar.gz differ
diff --git a/src/fdns/Makefile.in b/src/fdns/Makefile.in
index f75f749..917e68f 100644
--- a/src/fdns/Makefile.in
+++ b/src/fdns/Makefile.in
@@ -5,8 +5,8 @@ include ../common.mk
%.o : %.c $(H_FILE_LIST)
$(CC) $(CFLAGS) $(EXTRA_CFLAGS) $(INCLUDE) -c $< -o $@
-fdns: $(OBJS)
- $(CC) $(LDFLAGS) -o $@ $(OBJS) -lssl -lcrypto -lrt -lseccomp $(LIBS) $(EXTRA_LDFLAGS)
+fdns: $(OBJS) ../cashpack-0.3/lib/.libs/libhpack.a
+ $(CC) $(LDFLAGS) -o $@ $(OBJS) ../cashpack-0.3/lib/.libs/libhpack.a -lssl -lcrypto -lrt -lseccomp $(LIBS) $(EXTRA_LDFLAGS)
clean:; rm -f *.o fdns *.gcov *.gcda *.gcno
diff --git a/src/fdns/dns.c b/src/fdns/dns.c
index 7fdeb60..f3c36bb 100644
--- a/src/fdns/dns.c
+++ b/src/fdns/dns.c
@@ -205,14 +205,60 @@ uint8_t *dns_parser(uint8_t *buf, ssize_t *lenptr, DnsDestination *dest) {
}
void dns_keepalive(void) {
+ if (ssl_state == SSL_CLOSED)
+ return;
+
if (arg_debug)
printf("(%d) send keepalive\n", arg_id);
- uint8_t msg[33] = { // www.example.com
- 0x00, 0x00, 0x01, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0x77, 0x77, 0x77,
- 0x07, 0x65, 0x78, 0x61, 0x6d, 0x70, 0x6c, 0x65, 0x03, 0x63, 0x6f, 0x6d, 0x00, 0x00, 0x01, 0x00,
- 0x01
- };
- uint8_t buf[MAXBUF];
- memcpy(buf, msg, sizeof(msg));
- ssl_rxtx_dns(buf, sizeof(msg));
+ h2_send_ping();
}
+
+// returns the length of the response,,0 if failed
+// the response is copied back in msg
+int dns_query(uint8_t *msg, int cnt) {
+ assert(msg);
+ assert(cnt);
+
+
+ int datalen = h2_send_query(msg, cnt);
+ if (datalen == 0)
+ goto errout;
+
+ if (arg_debug) {
+ printf("(%d) DNS data:\n", arg_id);
+ print_mem(msg, datalen);
+ printf("(%d) *** SSL transaction end ***\n", arg_id);
+ }
+
+ //
+ // partial response parsing
+ //
+ if (lint_rx(msg, datalen)) {
+ if (lint_error() == DNSERR_NXDOMAIN) {
+ // NXDOMAIN or similar received, cache for 10 minutes
+ cache_set_reply(msg, datalen, CACHE_TTL_ERROR);
+ return datalen;
+ }
+
+ // serveral adblocker/family services return addresses of 0.0.0.0 or 127.0.0.1 for blocked domains
+ const char *str = lint_err2str();
+ if (strstr(str, "0.0.0.0") || strstr(str, "127.0.0.1")) {
+ // set NXDOMAIN bytes in the packet
+ msg[3] = 3;
+ rlogprintf("%s refused by service provider\n", cache_get_name());
+ return datalen;
+ }
+ else
+ rlogprintf("Error: %s %s\n", lint_err2str(), cache_get_name());
+ return 0;
+ }
+
+ // cache the response and exit
+ cache_set_reply(msg, datalen, arg_cache_ttl);
+ return datalen;
+
+errout:
+ ssl_close();
+ return 0;
+}
+
diff --git a/src/fdns/fdns.h b/src/fdns/fdns.h
index c8db469..9068648 100644
--- a/src/fdns/fdns.h
+++ b/src/fdns/fdns.h
@@ -72,10 +72,9 @@ static inline int check_addr_port(const char *str) {
#define RESOLVER_KEEPALIVE_AFTER_SLEEP (RESOLVER_KEEPALIVE_TIMER * 1.2) // after sleep detection
#define MONITOR_WAIT_TIMER 2 // wait for this number of seconds before restarting a failed resolver process
#define CONSOLE_PRINTOUT_TIMER 5 // transfer stats from resolver to frontend
-#define SSL_REOPEN_TIMER 5 // try to reopen a failed SSL connection after this time
-#define OUT_OF_SLEEP (RESOLVER_KEEPALIVE_SHUTDOWN + 5)
- // detect computer going out of sleep/hibernation, reinitialize SSL connections
- // it should be greater than RESOLVER_KEEPALIVE_SHUTDOWN
+#define SSL_REOPEN_TIMER 2 // try to reopen a failed SSL connection after this time
+#define OUT_OF_SLEEP 10 // attempting to detect the computer coming out of sleep mode
+
#define CACHE_TTL_DEFAULT (40 * 60) // default DNS cache ttl in seconds
#define CACHE_TTL_MIN (1 * 60)
#define CACHE_TTL_MAX (60 * 60)
@@ -131,7 +130,8 @@ typedef struct dnsserver_t {
char *zone; // geographical zone
char *tags; // description
char *address; // IP address
- char *host; // POST request first line
+ char *host; // authority in http2
+ char *path;
char *request; // full POST request
int sni; // 1 or 0
int keepalive; // keepalive in seconds
@@ -180,6 +180,7 @@ static inline void print_mem(unsigned char *msg, int len) {
// main.c
extern int arg_argc;
extern int arg_debug;
+extern int arg_debug_h2;
extern int arg_resolvers;
extern int arg_id;
extern int arg_fd;
@@ -195,7 +196,7 @@ extern char *arg_forwarder;
extern int arg_test_hosts;
extern char *arg_zone;
extern int arg_cache_ttl;
-extern int arg_allow_local_doh;
+extern int arg_disable_local_doh;
extern char *arg_whitelist_file;
extern int arg_fallback_only;
extern Stats stats;
@@ -216,8 +217,10 @@ extern SSLState ssl_state;
void ssl_init(void);
void ssl_open(void);
void ssl_close(void);
-int ssl_rxtx_dns(uint8_t *msg, int cnt);
int ssl_status_check(void);
+int ssl_rx(uint8_t *buf);
+int ssl_tx(uint8_t *buf, int len);
+int ssl_get_socket(void);
// frontend.c
extern int encrypted[RESOLVERS_CNT_MAX];
@@ -239,6 +242,7 @@ typedef enum {
} DnsDestination;
uint8_t *dns_parser(uint8_t *buf, ssize_t *len, DnsDestination *dest);
void dns_keepalive(void);
+int dns_query(uint8_t *msg, int cnt);
// filter.c
void filter_init(void);
@@ -336,4 +340,15 @@ int whitelist_blocked(const char *domain);
void procs_add(void);
void procs_list(void);
+// h2.c
+void h2_init(void);
+void h2_close(void);
+void h2_connect(void);
+void h2_send_exampledotcom(void);
+int h2_send_query(uint8_t *req, int cnt);
+void h2_send_ping(void);
+int h2_exchange(uint8_t *response);
+
+
+
#endif
diff --git a/src/fdns/filter.c b/src/fdns/filter.c
index 28292d8..b1f8ffb 100644
--- a/src/fdns/filter.c
+++ b/src/fdns/filter.c
@@ -127,7 +127,7 @@ static DFilter default_filter[] = {
// hardcoded DoH servers
// this is the last section before the NULL entry
- // the NULL entry is moved up for --allow-local-doh
+ // the NULL entry is moved up if --disable-local-doh is not present
{'D', "$dnscrypt-cert.oszx.co", 0},
{'D', "$cloudflare-dns.com", 0},
{'D', "$anycast.censurfridns.dk", 0},
@@ -161,8 +161,8 @@ void filter_init(void) {
void filter_postinit(void) {
int i = 0;
- // --allow-local-doh: move the NULL entry up
- if (arg_allow_local_doh) {
+ // move the NULL entry up
+ if (!arg_disable_local_doh) {
while (default_filter[i].label != 'D' && default_filter[i].label != 0)
i++;
assert(default_filter[i].label == 'D');
@@ -295,7 +295,7 @@ void filter_load_all_lists(void) {
filter_load_list('F', PATH_ETC_FP_TRACKERS_LIST);
filter_load_list('A', PATH_ETC_ADBLOCKER_LIST);
filter_load_list('M', PATH_ETC_COINBLOCKER_LIST);
- if (!arg_allow_local_doh)
+ if (arg_disable_local_doh)
filter_load_list('D', PATH_ETC_DOH_LIST);
filter_load_list('H', PATH_ETC_HOSTS_LIST);
}
diff --git a/src/fdns/frontend.c b/src/fdns/frontend.c
index aa4aa9b..ac2f62f 100644
--- a/src/fdns/frontend.c
+++ b/src/fdns/frontend.c
@@ -95,6 +95,8 @@ static int sandbox(void *sandbox_arg) {
int last = 3;
if (arg_debug)
a[last++] = "--debug";
+ if (arg_debug_h2)
+ a[last++] = "--debug-h2";
if (arg_nofilter)
a[last++] = "--nofilter";
if (arg_ipv6)
@@ -123,8 +125,8 @@ static int sandbox(void *sandbox_arg) {
}
if (arg_allow_all_queries)
a[last++] = "--allow-all-queries";
- if (arg_allow_local_doh)
- a[last++] = "--allow-local-doh";
+ if (arg_disable_local_doh)
+ a[last++] = "--disable-local-doh";
if (arg_cache_ttl != CACHE_TTL_DEFAULT) {
char *cmd;
diff --git a/src/fdns/h2.c b/src/fdns/h2.c
new file mode 100644
index 0000000..81e2540
--- /dev/null
+++ b/src/fdns/h2.c
@@ -0,0 +1,427 @@
+// gcc -lhpack -o cashbld cashbld.c
+#include
+#include
+#include
+#include
+#include
+#include
+
+#include "../cashpack-0.3/inc/hpack.h"
+#include "h2frame.h"
+#include "fdns.h"
+
+static uint32_t stream_id;
+
+#define MAX_HEADER_FIELDS 64
+#define HEADER(name, value) fields[pos++] = (struct hpack_field){ \
+ .nam = (name), \
+ .val = (value), \
+ .flg = HPACK_FLG_TYP_LIT | HPACK_FLG_NAM_HUF | HPACK_FLG_VAL_HUF \
+ }
+
+
+struct tmp_buf {
+ char *data;
+ size_t offset;
+};
+
+static void header_encode_cb(enum hpack_event_e evt, const char *buf, size_t len, void *priv) {
+ struct tmp_buf *out = priv;
+ switch (evt) {
+ case HPACK_EVT_DATA:
+ memcpy(out->data + out->offset, buf, len);
+ out->offset += len;
+ break;
+ default:
+ break;
+ }
+}
+
+static void print_headers(enum hpack_event_e evt, const char *buf, size_t len, void *priv) {
+ (void)priv;
+ if (!arg_debug)
+ return;
+
+ /* print "\n${name}: ${value}" for each header field */
+
+ switch (evt) {
+ case HPACK_EVT_FIELD:
+ printf("\n");
+ break;
+ case HPACK_EVT_VALUE:
+ printf(": ");
+ /* fall through */
+ case HPACK_EVT_NAME:
+ printf("%s", buf);
+ (void)len;
+ /* fall through */
+ default:
+ /* ignore other events */
+ break;
+ }
+}
+
+
+struct hpack *hpe = NULL;
+struct hpack *hpd = NULL;
+void h2_init(void) {
+ hpe = hpack_encoder(4096, -1, hpack_default_alloc);
+ hpd = hpack_decoder(4096, -1, hpack_default_alloc);
+}
+
+void h2_close(void) {
+ if (hpe != NULL) {
+ hpack_free(&hpe);
+ hpe = NULL;
+ }
+ if (hpd != NULL) {
+ hpack_free(&hpd);
+ hpd = NULL;
+ }
+
+}
+
+// encode a header frame
+// frame - http2 frame
+// return offset for the end of frame
+static uint32_t h2_encode_header(uint8_t *frame, int len) {
+ assert(frame);
+
+ char slen[20];
+ sprintf(slen, "%d", len);
+
+ // extract server data
+ DnsServer *srv = server_get();
+ assert(srv);
+ assert(srv->path);
+ assert(srv->host);
+
+
+ // hpack encode
+ struct hpack_field fields[MAX_HEADER_FIELDS];
+ size_t pos = 0;
+
+ HEADER(":method", "POST");
+ HEADER(":path", srv->path);
+ HEADER(":authority", srv->host);
+ HEADER(":scheme", "https");
+ HEADER("accept", "application/dns-message");
+ HEADER("content-type", "application/dns-message");
+ HEADER("content-length", slen); //"48");
+ HEADER("pragma", "no-cache");
+// HEADER("te", "trailers");
+
+ // encoding structure
+ char hpack_buf[MAXBUF];
+ struct tmp_buf buf = {
+ frame + 9, // frame header size 9
+ 0,
+ };
+ struct hpack_encoding enc;
+ enc.fld = fields;
+ enc.fld_cnt = pos;
+ enc.buf = hpack_buf;
+ enc.buf_len = MAXBUF;
+ enc.cb = header_encode_cb,
+ enc.priv = &buf,
+ enc.cut = 0;
+
+ // encoding
+ int rv = hpack_encode(hpe, &enc);
+ if (rv != HPACK_RES_OK) {
+ fprintf(stderr, "hpack encoding error: %s\n", hpack_strerror(rv));
+ exit(1);
+ }
+
+ // build header
+ H2Frame *frm = (H2Frame *) frame;
+ uint32_t length = buf.offset;
+ h2frame_set_length(frm, length);
+ frm->type = H2_TYPE_HEADERS;
+ frm->flag = H2_FLAG_END_HEADERS;// | H2_FLAG_END_STREAM;
+ h2frame_set_stream(frm, stream_id);
+
+ return sizeof(H2Frame) + length;
+}
+
+// decode a header frame
+// frame - http2 frame
+// return offset for the end of frame
+static uint32_t h2_decode_header(uint8_t *frame) {
+ // http2 frame
+ H2Frame frm;
+ memcpy(&frm, frame, sizeof(H2Frame));
+ int offset = sizeof(H2Frame);
+ if (frm.type != H2_TYPE_HEADERS) {
+ fprintf(stderr, "Not a header header\n");
+ return 0;
+ }
+
+ uint8_t flg = frm.flag;
+ uint8_t pad = 0;
+ uint32_t str = h2frame_extract_stream(&frm);
+ size_t len = h2frame_extract_length(&frm);
+//todo if (len > sizeof blk)
+// return (EXIT_FAILURE); /* DIY */
+
+ uint8_t blk[4096];
+ uint8_t buf[1024];
+ struct hpack_decoding dec;
+ dec.blk = blk;
+ dec.blk_len = 0;
+ dec.buf = buf;
+ dec.buf_len = sizeof buf;
+ dec.cb = print_headers;
+ dec.priv = NULL;
+
+ if (flg & H2_FLAG_PADDED)
+ offset += 1;
+ if (flg & H2_FLAG_PRIORITY)
+ offset += 5;
+
+ memcpy(blk, frame + offset, len);
+ offset += len;
+
+ /* decode the HPACK block */
+ if (flg & H2_FLAG_END_HEADERS && arg_debug)
+ printf("=== stream %u", str);
+
+ dec.cut = ~flg & H2_FLAG_END_HEADERS;
+ dec.blk_len = len;
+
+ int rv = hpack_decode(hpd, &dec);
+ if (rv < 0)
+ return 0;
+
+ if (flg & H2_FLAG_PADDED)
+ offset += pad;
+ if (arg_debug)
+ printf("\n");
+ return offset;
+}
+
+// encode a data frame
+// frame - http2 frame
+// data and length
+// using the same session id as the last encoded header frame; ending the stream
+// return offset for the end of the frame
+static uint32_t h2_encode_data(uint8_t *frame, uint8_t *data, unsigned length) {
+ assert(frame);
+ assert(data);
+ assert(length);
+
+ // build header
+ H2Frame *frm = (H2Frame *) frame;
+ h2frame_set_length(frm, length);
+ frm->type = H2_TYPE_DATA;
+ frm->flag = H2_FLAG_END_STREAM;
+ h2frame_set_stream(frm, stream_id);
+ memcpy(frame + sizeof(H2Frame), data, length);
+
+ return length + sizeof(H2Frame);
+}
+
+// decode a data frame
+// frame - http2 frame
+// offset - offset to data section in frame
+// length - length of data section
+// return offset for the end of the frame
+uint32_t h2_decode_data(uint8_t *frame, uint32_t *offset, uint32_t *length) {
+ assert(frame);
+ assert(length);
+
+ // decode header
+ // http2 frame
+ H2Frame frm;
+ memcpy(&frm, frame, sizeof(H2Frame));
+ int rv = sizeof(H2Frame);
+ if (frm.type != H2_TYPE_DATA) {
+ fprintf(stderr, "Not a data frame\n");
+ return 0;
+ }
+
+ uint8_t flg = frm.flag;
+ uint8_t pad = 0;
+ uint32_t stream = h2frame_extract_stream(&frm);
+//todo: check the current streamid
+ *length = h2frame_extract_length(&frm);
+ *offset = rv;
+
+ if (flg & H2_FLAG_PADDED)
+ rv += 1;
+
+ *offset = rv;
+ return rv + *length + pad;
+}
+
+
+static uint8_t buf_query[MAXBUF];
+void h2_connect(void) {
+ stream_id = 0;
+ uint8_t connect[] = {
+ 0x50, 0x52, 0x49, 0x20, 0x2a, 0x20, 0x48, 0x54, 0x54, 0x50, 0x2f, 0x32, 0x2e, 0x30, 0x0d, 0x0a,
+ 0x0d, 0x0a, 0x53, 0x4d, 0x0d, 0x0a, 0x0d, 0x0a, 0x00, 0x00, 0x12, 0x04, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x01, 0x00, 0x01, 0x00, 0x00, 0x00, 0x04, 0x00, 0x02, 0x00, 0x00, 0x00, 0x05, 0x00,
+ 0x00, 0x40, 0x00, 0x00, 0x00, 0x04, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xbf, 0x00, 0x01,
+ 0x00, 0x00, 0x05, 0x02, 0x00, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x00, 0xc8, 0x00, 0x00,
+ 0x05, 0x02, 0x00, 0x00, 0x00, 0x00, 0x05, 0x00, 0x00, 0x00, 0x00, 0x64, 0x00, 0x00, 0x05, 0x02,
+ 0x00, 0x00, 0x00, 0x00, 0x07, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x05, 0x02, 0x00, 0x00,
+ 0x00, 0x00, 0x09, 0x00, 0x00, 0x00, 0x07, 0x00, 0x00, 0x00, 0x05, 0x02, 0x00, 0x00, 0x00, 0x00,
+ 0x0b, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x05, 0x02, 0x00, 0x00, 0x00, 0x00, 0x0d, 0x00,
+ 0x00, 0x00, 0x00, 0xf0
+ };
+
+ if (arg_debug)
+ printf("(%d) h2 send connect\n", arg_id);
+ ssl_tx(connect, sizeof(connect));
+ h2_exchange(buf_query);
+ stream_id = 13;
+}
+
+void h2_send_exampledotcom(void) {
+ stream_id += 2;
+
+ uint8_t req[] = {
+ 0x00, 0x00, 0x01, 0x00, 0x00, 0x01, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x01, 0x07, 0x65, 0x78, 0x61, 0x6d, 0x70, 0x6c, 0x65, 0x03, 0x63, 0x6f,
+ 0x6d, 0x00, 0x00, 0x02, 0x00, 0x01, 0x00, 0x00, 0x29, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x08, 0x00, 0x08, 0x00, 0x04, 0x00, 0x01, 0x00, 0x00
+ };
+ uint32_t len = h2_encode_header(buf_query, sizeof(req));
+ if (arg_debug || arg_debug_h2) {
+ printf("(%d) h2 tx ", arg_id);
+ h2frame_print((H2Frame *) buf_query);
+ }
+
+ int len2 = h2_encode_data(buf_query + len, req, sizeof(req));
+ if (arg_debug || arg_debug_h2) {
+ printf("(%d) h2 tx query example.com ", arg_id);
+ h2frame_print((H2Frame *) (buf_query + len));
+ }
+
+ ssl_tx(buf_query, len + len2);
+ int rv = h2_exchange(buf_query);
+ if (arg_debug) {
+ printf("DNS response (%d bytes):\n", rv);
+ print_mem(buf_query, rv);
+ }
+}
+
+
+
+int h2_send_query(uint8_t *req, int cnt) {
+ stream_id += 2;
+ uint32_t len = h2_encode_header(buf_query, cnt);
+ if (arg_debug || arg_debug_h2) {
+ printf("(%d) h2 tx ", arg_id);
+ h2frame_print((H2Frame *) buf_query);
+ }
+
+ int len2 = h2_encode_data(buf_query + len, req, cnt);
+ if (arg_debug || arg_debug_h2) {
+ printf("(%d) h2 tx query ", arg_id);
+ h2frame_print((H2Frame *) (buf_query + len));
+ }
+ ssl_tx(buf_query, len + len2);
+
+ return h2_exchange(req);
+}
+
+void h2_send_ping(void) {
+ uint8_t frame[] = {0, 0, 8, 6, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 };
+ if (arg_debug || arg_debug_h2) {
+ printf("(%d) h2 tx ", arg_id);
+ h2frame_print((H2Frame *) frame);
+ }
+
+ ssl_tx(frame, sizeof(frame));
+ h2_exchange(buf_query);
+}
+
+// copy rx data in response and return the length
+int h2_exchange(uint8_t *response) {
+ assert(response);
+ int retval = 0;
+
+ uint8_t buf[MAXBUF];
+ while (1) {
+ fd_set readfds;
+ FD_ZERO(&readfds);
+ int fd = ssl_get_socket();
+ FD_SET(fd, &readfds);
+ struct timeval timeout;
+ timeout.tv_sec = 5;
+ timeout.tv_usec = 0;
+
+ int rv = select(fd + 1, &readfds, NULL, NULL, &timeout);
+ if (rv <= 0)
+ return 0;
+ if (rv == 0)
+ return 0;
+
+ if (FD_ISSET(fd, &readfds)) {
+ int rv = ssl_rx(buf);
+ if (rv == 0) {
+ if (ssl_state == SSL_OPEN)
+ ssl_close();
+ return 0;
+ }
+
+ if (arg_debug) {
+ printf("(%d) h2 rx %d bytes\n", arg_id, rv);
+ print_mem(buf, rv);
+ }
+
+ int offset = 0;
+ while (offset < rv) {
+ H2Frame *frm = (H2Frame *) (buf + offset);
+
+ if (arg_debug || arg_debug_h2) {
+ printf("(%d) h2 rx ", arg_id);
+ h2frame_print(frm);
+ }
+
+ if (frm->type == H2_TYPE_HEADERS) {
+ h2_decode_header((uint8_t *) frm);
+ }
+ else if (frm->type == H2_TYPE_DATA) {
+ uint32_t offset;
+ uint32_t length;
+ h2_decode_data((uint8_t *) frm, &offset, &length);
+ if (arg_debug)
+ print_mem((uint8_t *) frm + offset, length);
+
+ // copy response in buf_query_data
+ if (length != 0) {
+ memcpy(response, (uint8_t *) frm + offset, length);
+ retval = length;
+ }
+ }
+ // ping response - do nothing
+ else if (frm->type == H2_TYPE_PING && frm->flag & H2_FLAG_END_STREAM)
+ return 0;
+ // ping request - set end stream flag and return the packet
+ else if (frm->type == H2_TYPE_PING && frm->flag & H2_FLAG_END_STREAM == 0) {
+ frm->flag |= H2_FLAG_END_STREAM;
+ ssl_tx((uint8_t *) frm, rv - offset);
+ return 0;
+ }
+ else if (frm->type == H2_TYPE_GOAWAY) {
+ ssl_close();
+ return 0;
+ }
+
+ if (frm->flag & H2_FLAG_END_STREAM)
+ return retval; // disregard the rest!
+ offset += sizeof(H2Frame) + h2frame_extract_length(frm);
+ if (arg_debug)
+ printf("(%d) h2 rx data offset %d\n", arg_id, offset);
+ }
+ }
+ }
+
+ return retval;
+}
+
+
+
diff --git a/src/fdns/h2frame.h b/src/fdns/h2frame.h
new file mode 100644
index 0000000..c82140d
--- /dev/null
+++ b/src/fdns/h2frame.h
@@ -0,0 +1,94 @@
+#ifndef H2FRAME_H
+#define H2FRAME_H
+#include
+#include
+
+//
+// http2 header definitions
+//
+typedef struct h2frame_t {
+ uint8_t len[3];
+
+#define H2_TYPE_DATA 0x00
+#define H2_TYPE_HEADERS 0x01
+#define H2_TYPE_PRIORITY 0x02
+#define H2_TYPE_RESET 0x03
+#define H2_TYPE_SETTINGS 0x04
+#define H2_TYPE_PING 0x06
+#define H2_TYPE_GOAWAY 0x07
+ uint8_t type;
+
+#define H2_FLAG_END_STREAM 0x01
+#define H2_FLAG_END_HEADERS 0x04
+#define H2_FLAG_PADDED 0x08
+#define H2_FLAG_PRIORITY 0x20
+ uint8_t flag;
+
+ uint8_t stream[4];
+} H2Frame;
+
+static inline char *h2frame_type2str(uint8_t type) {
+ switch (type) {
+ case H2_TYPE_DATA:
+ return "DATA";
+ case H2_TYPE_HEADERS:
+ return "HEADERS";
+ case H2_TYPE_PRIORITY:
+ return "PRIORITY";
+ case H2_TYPE_RESET:
+ return "RESET";
+ case H2_TYPE_SETTINGS:
+ return "SETTINGS";
+ case H2_TYPE_PING:
+ return "PING";
+ case H2_TYPE_GOAWAY:
+ return "GOAWAY";
+ };
+ return "UNKNOWN";
+}
+
+static inline uint32_t h2frame_extract_stream(H2Frame *frm) {
+ uint32_t rv = frm->stream[0] << 24 | frm->stream[1] << 16 | frm->stream[2] << 8 | frm->stream[3];
+ return rv;
+}
+
+static inline uint32_t h2frame_extract_length(H2Frame *frm) {
+ uint32_t rv = frm->len[0] << 16 | frm->len[1] << 8 | frm->len[2];
+ return rv;
+}
+
+static inline void h2frame_set_stream(H2Frame *frm, uint32_t stream) {
+ frm->stream[3] = stream & 0xFF;
+ frm->stream[2] = (stream >> 8) & 0xFF;
+ frm->stream[1] = (stream >> 16) & 0xFF;
+ frm->stream[0] = (stream >> 24) & 0x7F;
+}
+
+static inline void h2frame_set_length(H2Frame *frm, uint32_t length) {
+ frm->len[2] = length & 0xFF;
+ frm->len[1] = (length >> 8) & 0xFF;
+ frm->len[0] = (length >> 16) & 0xFF;
+}
+
+static inline void h2frame_print(H2Frame *frm) {
+ uint32_t len = h2frame_extract_length(frm);
+ uint32_t stream = h2frame_extract_stream(frm);
+ printf("stream %u, len %u, type 0x%02u %s, flags 0x%02u (",
+ stream,
+ len,
+ frm->type, h2frame_type2str(frm->type),
+ frm->flag);
+
+ if (frm->flag & H2_FLAG_END_STREAM)
+ printf("end stream,");
+ if (frm->flag & H2_FLAG_END_HEADERS)
+ printf("end headers,");
+ if (frm->flag & H2_FLAG_PADDED)
+ printf("padded,");
+ if (frm->flag & H2_FLAG_PRIORITY)
+ printf("priority,");
+ printf(")\n");
+ fflush(0);
+}
+
+#endif
diff --git a/src/fdns/main.c b/src/fdns/main.c
index 0be1939..8bc400b 100644
--- a/src/fdns/main.c
+++ b/src/fdns/main.c
@@ -20,6 +20,7 @@
#include
int arg_argc = 0;
int arg_debug = 0;
+int arg_debug_h2 = 0;
int arg_resolvers = RESOLVERS_CNT_DEFAULT;
int arg_id = -1;
int arg_fd = -1;
@@ -34,7 +35,7 @@ char *arg_certfile = NULL;
int arg_test_hosts = 0;
char *arg_zone = NULL;
int arg_cache_ttl = CACHE_TTL_DEFAULT;
-int arg_allow_local_doh = 0;
+int arg_disable_local_doh = 0;
char *arg_whitelist_file = NULL;
int arg_fallback_only = 0;
@@ -49,13 +50,15 @@ static void usage(void) {
printf("Options:\n");
printf(" --allow-all-queries - allow all DNS query types; by default only\n"
"\tA queries are allowed.\n");
- printf(" --allow-local-doh - allow applications on local network to connect to DoH\n"
- "\tservices; disabled by default.\n");
printf(" --cache-ttl=seconds - change DNS cache TTL (default %ds).\n", CACHE_TTL_DEFAULT);
printf(" --certfile=filename - SSL certificate file in PEM format.\n");
printf(" --daemonize - detach from the controlling terminal and run as a Unix\n"
"\tdaemon.\n");
printf(" --debug - print debug messages.\n");
+ printf(" --debug-h2 - print HTTP2 debug messages.\n");
+ printf(" --disable-local-doh - blacklist DoH services for applications running on\n"
+ "\tlocal network.\n");
+
#ifdef HAVE_GCOV
printf(" --fallback-only - operate strictly in fallback mode.\n");
#endif
@@ -113,6 +116,8 @@ int main(int argc, char **argv) {
}
else if (strcmp(argv[i], "--debug") == 0)
arg_debug = 1;
+ else if (strcmp(argv[i], "--debug-h2") == 0)
+ arg_debug_h2 = 1;
}
}
@@ -136,6 +141,8 @@ int main(int argc, char **argv) {
// already processed
else if (strcmp(argv[i], "--debug") == 0) // already processed
;
+ else if (strcmp(argv[i], "--debug-h2") == 0) // already processed
+ ;
else if (strcmp(argv[i], "--daemonize") == 0)
;
else if (strncmp(argv[i], "--zone=", 7) == 0)
@@ -158,8 +165,8 @@ int main(int argc, char **argv) {
arg_certfile = argv[i] + 11;
else if (strcmp(argv[i], "--allow-all-queries") == 0)
arg_allow_all_queries = 1;
- else if (strcmp(argv[i], "--allow-local-doh") == 0) {
- arg_allow_local_doh = 1;
+ else if (strcmp(argv[i], "--disable-local-doh") == 0) {
+ arg_disable_local_doh = 1;
filter_postinit();
}
else if (strcmp(argv[i], "--nofilter") == 0)
diff --git a/src/fdns/resolver.c b/src/fdns/resolver.c
index ff1e51d..b5c5f77 100644
--- a/src/fdns/resolver.c
+++ b/src/fdns/resolver.c
@@ -38,7 +38,6 @@ void resolver(void) {
// connect SSL/DNS server
ssl_init();
ssl_open();
- dns_keepalive();
// start the local DNS server on 127.0.0.1 only
// in order to mitigate DDoS amplification attacks
@@ -122,14 +121,13 @@ void resolver(void) {
// one second timeout
//***********************************************
else if (rv == 0) {
+ // attempting to detect the computer coming out of sleep mode
time_t ts = time(NULL);
if (ts - timestamp > OUT_OF_SLEEP) {
rlogprintf("Suspend detected, restarting SSL connection\n");
cache_init();
- if (!arg_fallback_only) {
- ssl_close();
- ssl_open();
- }
+ // force a PING - if the connection is already down, close SSL
+ dns_keepalive();
}
timestamp = ts;
query_second = 0;
@@ -157,9 +155,15 @@ void resolver(void) {
}
// ssl keepalive:
- // if any incoming data, probably is the session going down - force a keepalive
- if (ssl_status_check())
- dns_keepalive_cnt = 0;
+ // if any incoming data, probably is the session going down
+ if (ssl_status_check()) {
+ h2_exchange(buf);
+ if (ssl_state == SSL_CLOSED) {
+ ssl_open();
+ ssl_reopen_cnt = SSL_REOPEN_TIMER;
+ }
+ }
+
if (--dns_keepalive_cnt <= 0) {
dns_keepalive();
dns_keepalive_cnt = srv->keepalive;
@@ -302,7 +306,7 @@ void resolver(void) {
int ssl_len;
timetrace_start();
if (ssl_state == SSL_OPEN)
- ssl_len = ssl_rxtx_dns(buf, len);
+ ssl_len = dns_query(buf, len);
// a HTTP error from SSL, with no DNS data comming back
if (ssl_state == SSL_OPEN && ssl_len == 0)
diff --git a/src/fdns/server.c b/src/fdns/server.c
index 9c2bdd8..85c61d2 100644
--- a/src/fdns/server.c
+++ b/src/fdns/server.c
@@ -142,11 +142,14 @@ static DnsServer *read_one_server(FILE *fp, int *linecnt, const char *fname) {
if (!s->address)
errExit("strdup");
-// todo: accept a server name in parallel with IP addresses
// check address:port
- if (check_addr_port(s->address)) {
- fprintf(stderr, "Error: file %s, line %d, invalid address:port\n", fname, *linecnt);
- exit(1);
+ // commons.host is a geocast host
+ // OpenSSL will find out the IP address using regular DNS over UDP
+ if (strcmp(s->name, "commons-host") != 0) {
+ if (check_addr_port(s->address)) {
+ fprintf(stderr, "Error: file %s, line %d, invalid address:port\n", fname, *linecnt);
+ exit(1);
+ }
}
found = 1;
}
@@ -158,6 +161,7 @@ static DnsServer *read_one_server(FILE *fp, int *linecnt, const char *fname) {
errExit("strdup");
found = 1;
+
// build the DNS/HTTP request
char *str = strchr(s->host, '/');
if (!str) {
@@ -165,9 +169,10 @@ static DnsServer *read_one_server(FILE *fp, int *linecnt, const char *fname) {
fprintf(stderr, "Error: file %s, line %d, invalid host\n", fname, *linecnt);
exit(1);
}
+ s->path = strdup(str);
+ if (!s->path)
+ errExit("strdup");
*str++ = '\0';
- if (asprintf(&s->request, "POST /%s HTTP/1.1\r\nHost: %s\r\n%s", str, s->host, push_request_tail) == -1)
- errExit("asprintf");
}
else if (strncmp(buf, "sni: ", 5) == 0) {
if (s->sni)
@@ -188,15 +193,16 @@ static DnsServer *read_one_server(FILE *fp, int *linecnt, const char *fname) {
fprintf(stderr, "Error: file %s, line %d, invalid keepalive\n", fname, *linecnt);
exit(1);
}
+// s->keepalive = 25;
// check server data
- if (!s->name || !s->website || !s->zone || !s->tags || !s->address || !s->host || !s->request) {
+ if (!s->name || !s->website || !s->zone || !s->tags || !s->address || !s->host) {
fprintf(stderr, "Error: file %s, line %d, one of the server fields is missing\n", fname, *linecnt);
exit(1);
}
// add host to filter
- if (!arg_allow_local_doh)
+ if (arg_disable_local_doh)
filter_add('D', s->host);
return s;
@@ -276,11 +282,11 @@ int test_server(const char *server_name) {
fflush(0);
timetrace_start();
- dns_keepalive();
- dns_keepalive();
- dns_keepalive();
- dns_keepalive();
- dns_keepalive();
+ h2_send_exampledotcom();
+ h2_send_exampledotcom();
+ h2_send_exampledotcom();
+ h2_send_exampledotcom();
+ h2_send_exampledotcom();
ms = timetrace_end();
if (ssl_state == SSL_CLOSED) {
diff --git a/src/fdns/ssl.c b/src/fdns/ssl.c
index c635718..87dd730 100644
--- a/src/fdns/ssl.c
+++ b/src/fdns/ssl.c
@@ -144,6 +144,8 @@ void ssl_open(void) {
}
}
}
+ // inform the server we are using http2
+ SSL_CTX_set_alpn_protos(ctx, (const unsigned char *)"\x02h2", 3);
bio = BIO_new_ssl_connect(ctx);
BIO_get_ssl(bio, &ssl);
@@ -171,9 +173,14 @@ void ssl_open(void) {
ssl_state = SSL_OPEN;
rlogprintf("SSL connection opened\n");
+
+ h2_init();
+ h2_connect();
+ h2_send_exampledotcom();
}
void ssl_close(void) {
+ h2_close();
if (ssl) {
int rv = SSL_shutdown(ssl);
if (rv == 0)
@@ -186,30 +193,28 @@ void ssl_close(void) {
rlogprintf("SSL connection closed\n");
}
-// returns the length of the response,0 if failed
-int ssl_rxtx_dns(uint8_t *msg, int cnt) {
- assert(msg);
+int ssl_get_socket(void) {
+ return SSL_get_fd(ssl);
+}
- DnsServer *srv = server_get();
- assert(srv);
+int ssl_tx(uint8_t *buf, int len) {
+ assert(buf);
+ assert(len);
- if (ssl == NULL || ssl_state != SSL_OPEN)
- return 0;
+ if (ctx == NULL || ssl == NULL || ssl_state != SSL_OPEN)
+ goto errout;
assert(bio);
assert(ctx);
assert(ssl);
- char buf[MAXBUF];
- sprintf(buf, srv->request, cnt);
- int len = strlen(buf);
- assert(cnt < MAXBUF - len);
+ if (arg_debug)
+ printf("(%d) *** SSL transaction len %d***\n", arg_id, len);
+
+//print_mem(buf, len);
+
- memcpy(buf + len, msg, cnt);
- len += cnt;
- if (arg_debug)
- printf("(%d) *** SSL transaction ***\n", arg_id);
int lentx;
if((lentx = BIO_write(bio, buf, len)) <= 0) {
@@ -218,15 +223,25 @@ int ssl_rxtx_dns(uint8_t *msg, int cnt) {
goto errout;
}
if((lentx = BIO_write(bio, buf, len)) <= 0) {
- rlogprintf("Error: failed SSL write, retval %d\n", lentx);
+ rlogprintf("Error: failed SSL write, retval %d\n", lentx);\
goto errout;
}
}
if (arg_debug)
printf("(%d) SSL write %d/%d bytes\n", arg_id, len, lentx);
+ return lentx;
+errout:
+ ssl_close();
+ return 0;
+}
+
+int ssl_rx(uint8_t *buf) {
+ assert(buf);
+ if (ctx == NULL || ssl == NULL || ssl_state != SSL_OPEN)
+ goto errout;
- len = BIO_read(bio, buf, MAXBUF);
+ int len = BIO_read(bio, buf, MAXBUF);
if(len <= 0) {
if(! BIO_should_retry(bio)) {
rlogprintf("Error: failed SSL read, retval %d\n", len);
@@ -238,116 +253,16 @@ int ssl_rxtx_dns(uint8_t *msg, int cnt) {
goto errout;
}
}
- buf[len] = '\0';
-
- // check 200 OK
- char *ptr = strstr(buf, "200 OK");
- if (!ptr) {
- rlogprintf("Warning: HTTP error, 200 OK not received\n");
- printf("**************\n%s\n**************\n", buf);
- fflush(0);
- goto errout;
- }
-
- // look for the end of http header
- ptr = strstr(buf, "\r\n\r\n");
- if (!ptr) {
- rlogprintf("Warning: cannot parse HTTPS response, didn't recieve a full http header\n");
- printf("**************\n%s\n**************\n", buf);
- fflush(0);
- goto errout;
- }
- ptr += 4; // length of "\r\n\r\n"
- ptrdiff_t hlen = ptr - buf; // +4 is the length of \r\n\r\n
- *(ptr - 1) = 0;
if (arg_debug)
- printf("(%d) http header:\n%s", arg_id, buf);
-
- // look for Content-Length:
- char *contlen = "Content-Length: ";
- ptr = strcasestr(buf, contlen);
- int datalen = 0;
- if (!ptr) {
- rlogprintf("Warning: cannot parse HTTPS response, content-length missing\n");
- print_mem((uint8_t *) buf, len);
- goto errout;
- }
- else {
- ptr += strlen(contlen);
- sscanf(ptr, "%d", &datalen);
- if (datalen == 0) // we got a "Content-lenght: 0"; this is probably a HTTP error
- return 0;
- }
-
- // do we need to read more data?
- int totallen = (int) hlen + datalen;
- if (arg_debug)
- printf("(%d) SSL read len %d, totallen %d, datalen %d\n",
- arg_id, len, totallen, datalen);
- if (totallen >= MAXBUF) {
- rlogprintf("Warning: cannot parse HTTPS response, invalid length\n");
- print_mem((uint8_t *) buf, len);
- goto errout;
- }
-
- while (len < totallen) {
- int rv = BIO_read(bio, buf + len, totallen - len);
- if (arg_debug)
- printf("(%d) SSL read + %d\n", arg_id, rv);
- if(rv <= 0) {
- if(! BIO_should_retry(bio)) {
- rlogprintf("Error: failed SSL read\n");
- goto errout;
- }
- rv = BIO_read(bio, buf, MAXBUF);
- if (arg_debug)
- printf("(%d) SSL read + %d\n", arg_id, rv);
- if(rv <= 0) {
- rlogprintf("Error: SSL connection is probably closed\n");
- goto errout;
- }
- }
-
- len += rv;
- }
+ printf("(%d) SSL read %d bytes\n", arg_id, len);
+ return len;
+errout:
+ ssl_close();
+ return 0;
+}
- // copy the response in buf
- memcpy(msg, buf + len - datalen, datalen);
- if (arg_debug) {
- printf("(%d) DNS data:\n", arg_id);
- print_mem((uint8_t *) buf, datalen);
- printf("(%d) *** SSL transaction end ***\n", arg_id);
- }
- //
- // partial response parsing
- //
- if (lint_rx(msg, datalen)) {
- if (lint_error() == DNSERR_NXDOMAIN) {
- // NXDOMAIN or similar received, cache for 10 minutes
- cache_set_reply(msg, datalen, CACHE_TTL_ERROR);
- return datalen;
- }
- // serveral adblocker/family services return addresses of 0.0.0.0 or 127.0.0.1 for blocked domains
- const char *str = lint_err2str();
- if (strstr(str, "0.0.0.0") || strstr(str, "127.0.0.1")) {
- // set NXDOMAIN bytes in the packet
- msg[3] = 3;
- rlogprintf("%s refused by service provider\n", cache_get_name());
- return datalen;
- }
- else
- rlogprintf("Error: %s %s\n", lint_err2str(), cache_get_name());
- return 0;
- }
- // cache the response and exit
- cache_set_reply(msg, datalen, arg_cache_ttl);
- return datalen;
-errout:
- ssl_close();
- return 0;
-}
diff --git a/src/man/fdns.txt b/src/man/fdns.txt
index 5082818..6feadf1 100644
--- a/src/man/fdns.txt
+++ b/src/man/fdns.txt
@@ -41,11 +41,6 @@ Asia-Pacific and Europe. Use --list=all option to print all the servers and the
Allow all DNS query types; by default only A queries are allowed. In case --ipv6 is set,
AAAA queries are also allowed.
.TP
-\fB\-\-allow-local-doh
-Allow applications on local network to connect to DoH services; disabled by default.
-NOTE: Applications can still use DoH-Server if they have a hardcoded IP-Address.
-If you realy want to block other DoH connection you must use your firewall.
-.TP
\fB\-\-cache-ttl=seconds
Change DNS cache TTL, in seconds. By default we use a fixed cache TTL of 40 minutes.
.TP
@@ -73,6 +68,14 @@ $ sudo fdns --proxy-addr-any --daemonize
\fB\-\-debug
Print debug messages.
.TP
+\fB\-\-debug-h2
+Print debug messages for HTTP2 protocol.
+.TP
+\fB\-\-disable-local-doh
+Blacklist DoH services for applications running on the local network.
+NOTE: Applications can still use DoH-Server if they have a hardcoded IP-Address.
+If you realy want to block other DoH connection you must use your firewall.
+.TP
\fB\-\-forwarder=domain@address
Conditional domain forwarding to a different DNS server.
.br
diff --git a/src/tools/wordpress.c b/src/tools/wordpress.c
index 0b67596..dbb46f9 100644
--- a/src/tools/wordpress.c
+++ b/src/tools/wordpress.c
@@ -19,67 +19,21 @@
/*
Simple tool to extract the server list for wordpress site
-
-Add to anycast list:
-cira-family (family, Canada)
-family.canadianshield.cira.ca/dns-query (149.112.121.30)
-cira-family2 (family, Canada)
-family.canadianshield.cira.ca/dns-query (149.112.122.30)
-
-Add to Asia-Pacific
-blahdns-jp (Japan, adblocker)
-doh-jp.blahdns.com/dns-query (45.32.55.94)
-blahdns-sg (Singapore, adblocker)
-doh-sg.blahdns.com/dns-query (139.180.141.57)
-
-Add to Europe
-blahdns-de (Germany, adblocker)
-doh-de.blahdns.com/dns-query (159.69.198.101)
-blahdns-fi (Finland, adblocker)
-doh-fi.blahdns.com/dns-query (95.216.212.177)
-
-Remove Luxembourg from nixnet/nixnet-adblocker Americas
-clean up dnslify: Netherlands, Germany, UK, NY, Califronia, Singapore
-
*/
-#define _GNU_SOURCE
-#include
-#include
-#include
-#include
-#define errExit(msg) do { char msgout[500]; snprintf(msgout, 500, "Error %s: %s:%d %s", msg, __FILE__, __LINE__, __FUNCTION__); perror(msgout); exit(1);} while (0)
-// check ip:port
-// return -1 if error
-static inline int check_addr_port(const char *str) {
- unsigned a, b, c, d, e;
-
- // extract ip
- int rv = sscanf(str, "%u.%u.%u.%u:%u", &a, &b, &c, &d, &e);
- if (rv != 5 || a > 255 || b > 255 || c > 255 || d > 255 || e > 0xffffffff)
- return -1;
- return 0;
-}
+#include "../fdns/fdns.h"
+// stub
+int arg_disable_local_doh = 0;
+void filter_add(char label, const char *domain) {(void) label; (void) domain;}
-typedef struct dnsserver_t {
- struct dnsserver_t *next;// linked list
- int active; // flag for random purposes
-
- // server data
- char *name; // name
- char *website; // website
- char *zone; // geographical zone
- char *tags; // description
- char *address; // IP address
- char *host; // POST request first line
- char *request; // full POST request
- int sni; // 1 or 0
- int keepalive; // keepalive in seconds
-} DnsServer;
static DnsServer *slist_americas = NULL;
static DnsServer *slist_asiapac = NULL;
static DnsServer *slist_europe = NULL;
static DnsServer *slist_anycast = NULL;
+static int arg_anycast = 0;
+static int arg_americas = 0;
+static int arg_asia_pacific = 0;
+static int arg_europe = 0;
// returns NULL for end of list
static DnsServer *read_one_server(FILE *fp, int *linecnt, const char *fname) {
@@ -96,91 +50,112 @@ static DnsServer *read_one_server(FILE *fp, int *linecnt, const char *fname) {
buf[0] = '\0';
int found = 0;
while (fgets(buf, 4096, fp)) {
+ char *start = buf;
(*linecnt)++;
+ if (strncmp(start, "##", 2) == 0)
+ start += 2;
+
// comments
- if (*buf == '#')
+ if (*start == '#')
continue;
// remove \n
- char *ptr = strchr(buf, '\n');
+ char *ptr = strchr(start, '\n');
if (ptr)
*ptr = '\0';
- if (strncmp(buf, "name: ", 6) == 0) {
+ if (strncmp(start, "name: ", 6) == 0) {
if (s->name)
goto errout;
- s->name = strdup(buf + 6);
+ s->name = strdup(start + 6);
if (!s->name)
errExit("strdup");
found = 1;
}
- else if (strncmp(buf, "website: ", 9) == 0) {
+ else if (strncmp(start, "website: ", 9) == 0) {
if (s->website)
goto errout;
- s->website = strdup(buf + 9);
+ s->website = strdup(start + 9);
if (!s->website)
errExit("strdup");
found = 1;
}
- else if (strncmp(buf, "zone: ", 6) == 0) {
+ else if (strncmp(start, "zone: ", 6) == 0) {
if (s->zone)
goto errout;
- s->zone = strdup(buf + 6);
+ s->zone = strdup(start + 6);
if (!s->zone)
errExit("strdup");
found = 1;
}
- else if (strncmp(buf, "tags: ", 6) == 0) {
+ else if (strncmp(start, "tags: ", 6) == 0) {
if (s->tags)
goto errout;
- s->tags = strdup(buf + 6);
+ s->tags = strdup(start + 6);
if (!s->tags)
errExit("strdup");
found = 1;
}
- else if (strncmp(buf, "address: ", 9) == 0) {
+ else if (strncmp(start, "address: ", 9) == 0) {
if (s->address)
goto errout;
- s->address = strdup(buf + 9);
+ s->address = strdup(start + 9);
if (!s->address)
errExit("strdup");
-// todo: accept a server name in parallel with IP addresses
// check address:port
- if (check_addr_port(s->address)) {
- fprintf(stderr, "Error: file %s, line %d, invalid address:port\n", fname, *linecnt);
- exit(1);
+ // commons.host is a geocast host
+ // OpenSSL will find out the IP address using regular DNS over UDP
+ if (strcmp(s->name, "commons-host") != 0) {
+ if (check_addr_port(s->address)) {
+ fprintf(stderr, "Error: file %s, line %d, invalid address:port\n", fname, *linecnt);
+ exit(1);
+ }
}
found = 1;
}
- else if (strncmp(buf, "host: ", 6) == 0) {
+ else if (strncmp(start, "host: ", 6) == 0) {
if (s->host)
goto errout;
- s->host = strdup(buf + 6);
+ s->host = strdup(start + 6);
if (!s->host)
errExit("strdup");
found = 1;
+
+
+ // build the DNS/HTTP request
+ char *str = strchr(s->host, '/');
+ if (!str) {
+ free(s);
+ fprintf(stderr, "Error: file %s, line %d, invalid host\n", fname, *linecnt);
+ exit(1);
+ }
+ s->path = strdup(str);
+ if (!s->path)
+ errExit("strdup");
+ *str++ = '\0';
}
- else if (strncmp(buf, "sni: ", 5) == 0) {
+ else if (strncmp(start, "sni: ", 5) == 0) {
if (s->sni)
goto errout;
- if (strcmp(buf + 5, "yes") == 0)
+ if (strcmp(start + 5, "yes") == 0)
s->sni = 1;
- else if (strcmp(buf + 5, "no") == 0)
+ else if (strcmp(start + 5, "no") == 0)
s->sni = 0;
else {
fprintf(stderr, "Error: file %s, line %d, wrong SNI setting\n", fname, *linecnt);
exit(1);
}
}
- else if (strncmp(buf, "keepalive: ", 11) == 0) {
+ else if (strncmp(start, "keepalive: ", 11) == 0) {
if (s->keepalive)
goto errout;
- if (sscanf(buf + 11, "%d", &s->keepalive) != 1 || s->keepalive <= 0) {
+ if (sscanf(start + 11, "%d", &s->keepalive) != 1 || s->keepalive <= 0) {
fprintf(stderr, "Error: file %s, line %d, invalid keepalive\n", fname, *linecnt);
exit(1);
}
+// s->keepalive = 25;
// check server data
if (!s->name || !s->website || !s->zone || !s->tags || !s->address || !s->host) {
@@ -188,6 +163,10 @@ static DnsServer *read_one_server(FILE *fp, int *linecnt, const char *fname) {
exit(1);
}
+ // add host to filter
+ if (arg_disable_local_doh)
+ filter_add('D', s->host);
+
return s;
}
}
@@ -270,7 +249,6 @@ static void load_list(void) {
}
}
- printf("total %d\n", cnt);
fclose(fp);
}
@@ -329,10 +307,26 @@ void print_server(DnsServer *ptr) {
if (c)
*c = '\0';
printf("%s ", ptr->website, ptr->name);
- if (*ptr->tags)
- printf("(%s)", ptr->tags);
+ int geocast = 0;
+ if (*ptr->tags) {
+ if (strstr(ptr->tags, "geocast")) {
+ ptr->tags += 7;
+ if (*ptr->tags == ',')
+ ptr->tags++;
+ if (*ptr->tags == ' ')
+ ptr->tags++;
+ geocast = 1;
+ }
+
+ if (ptr)
+ printf("(%s)", ptr->tags);
+ }
+
printf("
\n");
- printf("%s (%s)\n", ptr->host, ptr->address);
+ if (geocast)
+ printf("%s%s (geocast)\n", ptr->host, ptr->path);
+ else
+ printf("%s%s (%s)\n", ptr->host, ptr->path, ptr->address);
}
void print_start(void) {
@@ -344,51 +338,88 @@ void print_end(void) {
void print_list(void) {
+ DnsServer *ptr;
+
// anycast table
- printf("\n\n");
- DnsServer *ptr = slist_anycast;
- while (ptr) {
- print_server(ptr);
- ptr = ptr->next;
+ if (arg_anycast) {
+ printf("\n\n");
+ ptr = slist_anycast;
+ while (ptr) {
+ print_server(ptr);
+ ptr = ptr->next;
+ }
+ printf(" | \n\n\n");
}
- printf(" |
\n\n\n");
-
- printf("\n");
// Americas
- printf("Americas \n");
- ptr = slist_americas;
- while (ptr) {
- print_server(ptr);
- ptr = ptr->next;
+ if (arg_americas) {
+ printf("\n");
+ // Americas
+ printf("Americas \n");
+ ptr = slist_americas;
+ while (ptr) {
+ print_server(ptr);
+ ptr = ptr->next;
+ }
+ printf(" \n");
}
- printf("\n");
// Asia-Pacific
- printf("Asia-Pacific \n");
- ptr = slist_asiapac;
- while (ptr) {
- print_server(ptr);
- ptr = ptr->next;
+ if (arg_asia_pacific) {
+ printf("Asia-Pacific \n");
+ ptr = slist_asiapac;
+ while (ptr) {
+ print_server(ptr);
+ ptr = ptr->next;
+ }
+ printf(" \n");
}
- printf(" \n");
-
// Europe
- printf("Europe, Middle-East, Africa \n");
- ptr = slist_europe;
- int i = 0;
- while (ptr) {
- if (i == 5)
- printf(" | Europe, Middle-East, Africa (cont.) \n");
- print_server(ptr);
- ptr = ptr->next;
- i++;
+ if (arg_europe) {
+ printf("Europe, Middle-East, Africa \n");
+ ptr = slist_europe;
+ int i = 0;
+ while (ptr) {
+ if (i == 5)
+ printf(" | Europe, Middle-East, Africa (cont.) \n");
+ print_server(ptr);
+ ptr = ptr->next;
+ i++;
+ }
+ printf(" \n");
}
- printf(" | \n\n\n");
+
+ printf(" |
\n\n\n");
+}
+
+void usage(void) {
+ printf("Usage: wordpress options\n");
+ printf("Options:\n");
+ printf(" --anycast\n");
+ printf(" --americas\n");
+ printf(" --asia-pacific\n");
+ printf(" --europe\n");
}
+int main(int argc, char **argv) {
+ if (argc < 2) {
+ printf("Error: invalid params\n");
+ usage();
+ return -1;
+ }
+
+ int i;
+ for (i = 1; i < argc; i++) {
+ if (strcmp(argv[i], "--anycast") == 0)
+ arg_anycast = 1;
+ else if (strcmp(argv[i], "--americas") == 0)
+ arg_americas = 1;
+ else if (strcmp(argv[i], "--asia-pacific") == 0)
+ arg_asia_pacific = 1;
+ else if (strcmp(argv[i], "--europe") == 0)
+ arg_europe = 1;
+ }
-int main(void) {
load_list();
print_list();
return 0;
diff --git a/test/stress/test-server.exp b/test/stress/test-server.exp
index 5389271..b585f34 100755
--- a/test/stress/test-server.exp
+++ b/test/stress/test-server.exp
@@ -3,13 +3,13 @@
# Copyright (C) 2019-2020 FDNS Authors
# License GPL v2
-set timeout 30
+set timeout 10
spawn $env(SHELL)
match_max 100000
if { $argc != 1 } {
puts "TESTING ERROR: argument missing"
- puts "Usage: wget.exp server-name"
+ puts "Usage: test-server.exp server-name"
exit
}
@@ -19,19 +19,19 @@ send -- "pkill fdns\r"
sleep 1
+puts " TESTING: --test-server\n"
send -- "fdns --test-server=$argv 2>&1\r"
expect {
timeout {puts "TESTING ERROR 0\n";exit 1}
- "Error:" {puts "TESTING ERROR 1\n";exit 1}
- "no such server available" {puts "TESTING ERROR 2\n";exit 1}
"response average"
}
expect {
- timeout {puts "TESTING ERROR 3\n";exit 1}
+ timeout {puts "TESTING ERROR 2\n";exit 1}
"Testing completed"
}
sleep 1
+puts " TESTING: starting proxy111\n"
send -- "fdns --server=$argv 2>&1\r"
expect {
timeout {puts "TESTING ERROR 10\n";exit 1}
@@ -50,76 +50,66 @@ expect {
timeout {puts "TESTING ERROR 14\n";exit 1}
"SSL connection opened"
}
-
-# wait 10 seconds to detect any kind of connection problems
-#expect {
-# timeout {puts "connection OK\n"}
-# "Error:" {puts "TESTING ERROR 2\n";exit 1}
-# "SSL connection closed" {puts "TESTING ERROR 3\n";exit 1}
-#}
-sleep 1
-
-spawn $env(SHELL)
-send "rm /tmp/index.html\r"
after 100
-send -- "firejail --dns=127.1.1.1 wget -O /tmp/index.html google.com\r"
+spawn $env(SHELL)
+
+puts " TESTING: starting proxy222\n"
+#send -- "fdns --server=$argv --proxy-addr=127.2.2.2 2>&1\r"
+send -- "fdns --server=blahdns-de --proxy-addr=127.2.2.2 2>&1\r"
expect {
timeout {puts "TESTING ERROR 20\n";exit 1}
- "Connecting to www.google.com"
-}
-expect {
- timeout {puts "TESTING ERROR 21\n";exit 1}
- "index.html"
+ "Error:" {puts "TESTING ERROR 21\n";exit 1}
+ "fdns starting"
}
expect {
timeout {puts "TESTING ERROR 22\n";exit 1}
- "saved"
+ "SSL connection opened"
}
-after 100
-
-# do it again!
-send "rm /tmp/index.html\r"
-after 100
-send -- "firejail --dns=127.1.1.1 wget -O /tmp/index.html wordpress.com\r"
expect {
timeout {puts "TESTING ERROR 23\n";exit 1}
- "Connecting to wordpress.com"
+ "SSL connection opened"
}
expect {
timeout {puts "TESTING ERROR 24\n";exit 1}
- "index.html"
-}
-expect {
- timeout {puts "TESTING ERROR 25\n";exit 1}
- "saved"
+ "SSL connection opened"
}
+
after 100
-send "rm /tmp/index.html\r"
-after 100
+spawn $env(SHELL)
-# under development
+puts " TESTING: queries\n"
send -- "cp ../src/fdnstress/fdnstress /transfer/.\r"
send -- "cp list20 /transfer/.\r"
after 100
send -- "firejail --dns=127.1.1.1 /transfer/fdnstress --threads=1 /transfer/list20\r"
expect {
timeout {puts "TESTING ERROR 30\n";exit 1}
+ "Error:" {puts "TESTING ERROR 30.1\n";exit 1}
+ "SSL connection closed" {puts "TESTING ERROR 30.2\n";exit 1}
"wordpress.com"
}
expect {
timeout {puts "TESTING ERROR 31\n";exit 1}
+ "Error:" {puts "TESTING ERROR 30.1\n";exit 1}
+ "SSL connection closed" {puts "TESTING ERROR 30.2\n";exit 1}
"linux.org"
}
expect {
timeout {puts "TESTING ERROR 32\n";exit 1}
+ "Error:" {puts "TESTING ERROR 30.1\n";exit 1}
+ "SSL connection closed" {puts "TESTING ERROR 30.2\n";exit 1}
"google.com"
}
expect {
timeout {puts "TESTING ERROR 33\n";exit 1}
+ "Error:" {puts "TESTING ERROR 30.1\n";exit 1}
+ "SSL connection closed" {puts "TESTING ERROR 30.2\n";exit 1}
"youtube.com"
}
expect {
timeout {puts "TESTING ERROR 34\n";exit}
+ "Error:" {puts "TESTING ERROR 30.1\n";exit 1}
+ "SSL connection closed" {puts "TESTING ERROR 30.2\n";exit 1}
"fedoraproject.org"
}
after 100