-
Notifications
You must be signed in to change notification settings - Fork 174
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
Showing
4 changed files
with
322 additions
and
2 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,52 @@ | ||
From 404c424fa8dbc34a4273b5ad54b15091efa5d4b4 Mon Sep 17 00:00:00 2001 | ||
From: Jian Chang <[email protected]> | ||
Date: Sat, 7 Nov 2015 10:07:14 +0800 | ||
Subject: [PATCH 1/2] shorten timeout | ||
|
||
--- | ||
src/chinadns.c | 11 ++++------- | ||
1 file changed, 4 insertions(+), 7 deletions(-) | ||
|
||
diff --git a/src/chinadns.c b/src/chinadns.c | ||
index 6716554..930e6de 100644 | ||
--- a/src/chinadns.c | ||
+++ b/src/chinadns.c | ||
@@ -159,8 +159,7 @@ static void usage(void); | ||
#ifdef DEBUG | ||
#define DLOG(s...) LOG(s) | ||
void __gcov_flush(void); | ||
-static void gcov_handler(int signum) | ||
-{ | ||
+static void gcov_handler(int signum) { | ||
__gcov_flush(); | ||
exit(1); | ||
} | ||
@@ -199,8 +198,8 @@ int main(int argc, char **argv) { | ||
FD_SET(remote_sock, &readset); | ||
FD_SET(remote_sock, &errorset); | ||
struct timeval timeout = { | ||
- .tv_sec = 0, | ||
- .tv_usec = 50 * 1000, | ||
+ .tv_sec = 5, | ||
+ .tv_usec = 0, | ||
}; | ||
if (-1 == select(max_fd, &readset, NULL, &errorset, &timeout)) { | ||
ERR("select"); | ||
@@ -628,7 +627,7 @@ static void dns_handle_local() { | ||
dns_server_addrs[i].addrlen)) | ||
ERR("sendto"); | ||
} | ||
- for (i = has_chn_dns; i < dns_servers_len; i++) { | ||
+ for (i = has_chn_dns; i < dns_servers_len; i++) { | ||
if (-1 == sendto(remote_sock, compression_buf, len + 1, 0, | ||
dns_server_addrs[i].addr, | ||
dns_server_addrs[i].addrlen)) | ||
@@ -914,5 +913,3 @@ Forward DNS requests.\n\ | ||
\n\ | ||
Online help: <https://github.com/clowwindy/ChinaDNS>\n"); | ||
} | ||
- | ||
- | ||
-- | ||
2.6.2.windows.1 | ||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,268 @@ | ||
From 47c4bbc98be61a1e7738274f3adf0a403b3489a0 Mon Sep 17 00:00:00 2001 | ||
From: Jian Chang <[email protected]> | ||
Date: Sun, 8 Nov 2015 16:14:32 +0800 | ||
Subject: [PATCH 2/2] Use # to define trusted DNS | ||
|
||
--- | ||
src/chinadns.c | 140 ++++++++++++++++++++++++++++++++++++--------------------- | ||
1 file changed, 90 insertions(+), 50 deletions(-) | ||
|
||
diff --git a/src/chinadns.c b/src/chinadns.c | ||
index 930e6de..0955729 100644 | ||
--- a/src/chinadns.c | ||
+++ b/src/chinadns.c | ||
@@ -82,6 +82,10 @@ static int dns_servers_len; | ||
static int has_chn_dns; | ||
static id_addr_t *dns_server_addrs; | ||
|
||
+static int has_trusted_dns = 0; | ||
+static net_list_t trusted_dns_server_list; | ||
+static id_addr_t *trusted_dns_server_addrs; | ||
+ | ||
static int parse_args(int argc, char **argv); | ||
|
||
static int setnonblock(int sock); | ||
@@ -294,6 +298,27 @@ static int parse_args(int argc, char **argv) { | ||
return 0; | ||
} | ||
|
||
+static int cmp_in_addr(const void *a, const void *b) { | ||
+ struct in_addr *ina = (struct in_addr *)a; | ||
+ struct in_addr *inb = (struct in_addr *)b; | ||
+ if (ina->s_addr == inb->s_addr) | ||
+ return 0; | ||
+ if (ina->s_addr > inb->s_addr) | ||
+ return 1; | ||
+ return -1; | ||
+} | ||
+ | ||
+static int cmp_net_mask(const void *a, const void *b) { | ||
+ net_mask_t *neta = (net_mask_t *)a; | ||
+ net_mask_t *netb = (net_mask_t *)b; | ||
+ if (neta->net.s_addr == netb->net.s_addr) | ||
+ return 0; | ||
+ // TODO: pre ntohl | ||
+ if (ntohl(neta->net.s_addr) > ntohl(netb->net.s_addr)) | ||
+ return 1; | ||
+ return -1; | ||
+} | ||
+ | ||
static int resolve_dns_servers() { | ||
struct addrinfo hints; | ||
struct addrinfo *addr_ip; | ||
@@ -303,18 +328,25 @@ static int resolve_dns_servers() { | ||
char *pch = strchr(dns_servers, ','); | ||
has_chn_dns = 0; | ||
int has_foreign_dns = 0; | ||
+ trusted_dns_server_list.entries = 0; | ||
dns_servers_len = 1; | ||
- if (compression) { | ||
- if (!chnroute_file) { | ||
- VERR("Chnroutes are necessary when using DNS compression pointer mutation\n"); | ||
- return -1; | ||
- } | ||
- } | ||
while (pch != NULL) { | ||
dns_servers_len++; | ||
pch = strchr(pch + 1, ','); | ||
} | ||
+ char *rch = strchr(dns_servers, '#'); | ||
+ while (rch != NULL) { | ||
+ dns_servers_len--; | ||
+ trusted_dns_server_list.entries++; | ||
+ rch = strchr(rch + 1, '#'); | ||
+ } | ||
dns_server_addrs = calloc(dns_servers_len, sizeof(id_addr_t)); | ||
+ if (trusted_dns_server_list.entries) { | ||
+ trusted_dns_server_addrs = calloc(trusted_dns_server_list.entries, | ||
+ sizeof(id_addr_t)); | ||
+ trusted_dns_server_list.nets = calloc(trusted_dns_server_list.entries, | ||
+ sizeof(net_mask_t)); | ||
+ } | ||
|
||
memset(&hints, 0, sizeof(hints)); | ||
hints.ai_family = AF_INET; | ||
@@ -324,17 +356,32 @@ static int resolve_dns_servers() { | ||
char *port; | ||
memset(global_buf, 0, BUF_SIZE); | ||
strncpy(global_buf, token, BUF_SIZE - 1); | ||
- port = (strrchr(global_buf, ':')); | ||
- if (port) { | ||
+ | ||
+ if ((port = (strrchr(global_buf, '#')))) { | ||
+ *port = '\0'; | ||
+ port++; | ||
+ if ((r = getaddrinfo(global_buf, port, &hints, &addr_ip))) { | ||
+ VERR("%s:%s\n", gai_strerror(r), token); | ||
+ return -1; | ||
+ } | ||
+ trusted_dns_server_addrs[has_trusted_dns].addr = addr_ip->ai_addr; | ||
+ trusted_dns_server_addrs[has_trusted_dns].addrlen = addr_ip->ai_addrlen; | ||
+ trusted_dns_server_list.nets[has_trusted_dns].mask = 0; | ||
+ inet_aton(global_buf, &trusted_dns_server_list.nets[has_trusted_dns].net); | ||
+ has_trusted_dns++; | ||
+ token = strtok(0, ","); | ||
+ continue; | ||
+ } else if ((port = (strrchr(global_buf, ':')))) { | ||
*port = '\0'; | ||
port++; | ||
} else { | ||
port = "53"; | ||
} | ||
- if (0 != (r = getaddrinfo(global_buf, port, &hints, &addr_ip))) { | ||
+ if ((r = getaddrinfo(global_buf, port, &hints, &addr_ip))) { | ||
VERR("%s:%s\n", gai_strerror(r), token); | ||
return -1; | ||
} | ||
+ token = strtok(0, ","); | ||
if (compression) { | ||
if (test_ip_in_list(((struct sockaddr_in *)addr_ip->ai_addr)->sin_addr, | ||
&chnroute_list)) { | ||
@@ -346,12 +393,10 @@ static int resolve_dns_servers() { | ||
dns_server_addrs[dns_servers_len - has_foreign_dns].addr = addr_ip->ai_addr; | ||
dns_server_addrs[dns_servers_len - has_foreign_dns].addrlen = addr_ip->ai_addrlen; | ||
} | ||
- token = strtok(0, ","); | ||
} else { | ||
dns_server_addrs[i].addr = addr_ip->ai_addr; | ||
dns_server_addrs[i].addrlen = addr_ip->ai_addrlen; | ||
i++; | ||
- token = strtok(0, ","); | ||
if (chnroute_file) { | ||
if (test_ip_in_list(((struct sockaddr_in *)addr_ip->ai_addr)->sin_addr, | ||
&chnroute_list)) { | ||
@@ -362,8 +407,15 @@ static int resolve_dns_servers() { | ||
} | ||
} | ||
} | ||
+ if ((compression || has_trusted_dns) && !chnroute_file) { | ||
+ VERR("Chnroutes are necessary when using DNS compression pointer mutation\ | ||
+ or specifies trusted DNS\n"); | ||
+ return -1; | ||
+ } | ||
+ qsort(trusted_dns_server_list.nets, trusted_dns_server_list.entries, | ||
+ sizeof(net_mask_t), cmp_net_mask); | ||
if (chnroute_file) { | ||
- if (!(has_chn_dns && has_foreign_dns)) { | ||
+ if (!(has_chn_dns && has_foreign_dns || has_trusted_dns)) { | ||
if (compression) { | ||
VERR("You should have at least one Chinese DNS and one foreign DNS when " | ||
"using DNS compression pointer mutation\n"); | ||
@@ -378,16 +430,6 @@ static int resolve_dns_servers() { | ||
return 0; | ||
} | ||
|
||
-static int cmp_in_addr(const void *a, const void *b) { | ||
- struct in_addr *ina = (struct in_addr *)a; | ||
- struct in_addr *inb = (struct in_addr *)b; | ||
- if (ina->s_addr == inb->s_addr) | ||
- return 0; | ||
- if (ina->s_addr > inb->s_addr) | ||
- return 1; | ||
- return -1; | ||
-} | ||
- | ||
static int parse_ip_list() { | ||
FILE *fp; | ||
char line_buf[32]; | ||
@@ -430,17 +472,6 @@ static int parse_ip_list() { | ||
return 0; | ||
} | ||
|
||
-static int cmp_net_mask(const void *a, const void *b) { | ||
- net_mask_t *neta = (net_mask_t *)a; | ||
- net_mask_t *netb = (net_mask_t *)b; | ||
- if (neta->net.s_addr == netb->net.s_addr) | ||
- return 0; | ||
- // TODO: pre ntohl | ||
- if (ntohl(neta->net.s_addr) > ntohl(netb->net.s_addr)) | ||
- return 1; | ||
- return -1; | ||
-} | ||
- | ||
static int parse_chnroute() { | ||
FILE *fp; | ||
char line_buf[32]; | ||
@@ -567,7 +598,6 @@ static void dns_handle_local() { | ||
uint16_t query_id; | ||
ssize_t len; | ||
int i; | ||
- int sended = 0; | ||
const char *question_hostname; | ||
ns_msg msg; | ||
len = recvfrom(local_sock, global_buf, BUF_SIZE, 0, src_addr, &src_addrlen); | ||
@@ -602,7 +632,7 @@ static void dns_handle_local() { | ||
id_addr.addr = src_addr; | ||
id_addr.addrlen = src_addrlen; | ||
queue_add(id_addr); | ||
- if (compression) { | ||
+ if (compression || has_trusted_dns) { | ||
if (len > 16) { | ||
size_t off = 12; | ||
int ended = 0; | ||
@@ -617,27 +647,34 @@ static void dns_handle_local() { | ||
off += 1 + global_buf[off]; | ||
} | ||
if (ended) { | ||
- memcpy(compression_buf, global_buf, off-1); | ||
- memcpy(compression_buf + off + 1, global_buf + off, len - off); | ||
- compression_buf[off-1] = '\xc0'; | ||
- compression_buf[off] = '\x04'; | ||
for (i = 0; i < has_chn_dns; i++) { | ||
if (-1 == sendto(remote_sock, global_buf, len, 0, | ||
dns_server_addrs[i].addr, | ||
dns_server_addrs[i].addrlen)) | ||
ERR("sendto"); | ||
} | ||
- for (i = has_chn_dns; i < dns_servers_len; i++) { | ||
- if (-1 == sendto(remote_sock, compression_buf, len + 1, 0, | ||
- dns_server_addrs[i].addr, | ||
- dns_server_addrs[i].addrlen)) | ||
- ERR("sendto"); | ||
- sended = 1; | ||
+ if (has_trusted_dns) { | ||
+ for (i = 0; i < has_trusted_dns; i++) { | ||
+ if (-1 == sendto(remote_sock, global_buf, len, 0, | ||
+ trusted_dns_server_addrs[i].addr, | ||
+ trusted_dns_server_addrs[i].addrlen)) | ||
+ ERR("sendto"); | ||
+ } | ||
+ } else { | ||
+ memcpy(compression_buf, global_buf, off-1); | ||
+ memcpy(compression_buf + off + 1, global_buf + off, len - off); | ||
+ compression_buf[off-1] = '\xc0'; | ||
+ compression_buf[off] = '\x04'; | ||
+ for (i = has_chn_dns; i < dns_servers_len; i++) { | ||
+ if (-1 == sendto(remote_sock, compression_buf, len + 1, 0, | ||
+ dns_server_addrs[i].addr, | ||
+ dns_server_addrs[i].addrlen)) | ||
+ ERR("sendto"); | ||
+ } | ||
} | ||
} | ||
} | ||
- } | ||
- if (!sended) { | ||
+ } else { | ||
for (i = 0; i < dns_servers_len; i++) { | ||
if (-1 == sendto(remote_sock, global_buf, len, 0, | ||
dns_server_addrs[i].addr, | ||
@@ -755,9 +792,12 @@ static int should_filter_query(ns_msg msg, struct in_addr dns_addr) { | ||
// TODO cache result for each dns server | ||
int dns_is_chn = 0; | ||
int dns_is_foreign = 0; | ||
- if (chnroute_file && (dns_servers_len > 1)) { | ||
- dns_is_chn = test_ip_in_list(dns_addr, &chnroute_list); | ||
- dns_is_foreign = !dns_is_chn; | ||
+ if (chnroute_file && ((dns_servers_len > 1) || has_trusted_dns)) { | ||
+ dns_is_foreign = test_ip_in_list(dns_addr, &trusted_dns_server_list); | ||
+ if (!dns_is_foreign) { | ||
+ dns_is_chn = test_ip_in_list(dns_addr, &chnroute_list); | ||
+ dns_is_foreign = !dns_is_chn; | ||
+ } | ||
} | ||
rrmax = ns_msg_count(msg, ns_s_an); | ||
if (rrmax == 0) { | ||
-- | ||
2.6.2.windows.1 | ||
|