Skip to content

Commit a2034c8

Browse files
committed
first version
0 parents  commit a2034c8

16 files changed

+1128
-0
lines changed

.eslintrc.json

+29
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,29 @@
1+
{
2+
"env": {
3+
"es6": true,
4+
"node": true
5+
},
6+
"extends": "eslint:recommended",
7+
"rules": {
8+
"indent": [
9+
"error",
10+
"tab",
11+
{
12+
"SwitchCase": 1
13+
}
14+
],
15+
"linebreak-style": [
16+
"error",
17+
"windows"
18+
],
19+
"quotes": [
20+
"error",
21+
"single"
22+
],
23+
"semi": [
24+
"error",
25+
"always"
26+
],
27+
"no-console": "off"
28+
}
29+
}

.gitignore

+6
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
node_modules/
2+
rules/*
3+
!rules/.gitkeep
4+
config.json
5+
*.bak
6+
*.bak.*

common/consts.js

+90
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,90 @@
1+
const { reverseFill } = require('./utils');
2+
3+
const DNSTYPE = reverseFill({
4+
A: 1,
5+
NS: 2,
6+
MD: 3,
7+
MF: 4,
8+
CNAME: 5,
9+
SOA: 6,
10+
MB: 7,
11+
MG: 8,
12+
MR: 9,
13+
NULL: 10,
14+
WKS: 11,
15+
PTR: 12,
16+
HINFO: 13,
17+
MINFO: 14,
18+
MX: 15,
19+
TXT: 16,
20+
RP: 17,
21+
AFSDB: 18,
22+
X25: 19,
23+
ISDN: 20,
24+
RT: 21,
25+
NSAP: 22,
26+
'NSAP-PTR': 23,
27+
SIG: 24,
28+
KEY: 25,
29+
PX: 26,
30+
GPOS: 27,
31+
AAAA: 28,
32+
LOC: 29,
33+
NXT: 30,
34+
EID: 31,
35+
NB: 32,
36+
NIMLOC: 32,
37+
SRV: 33,
38+
NBSTAT: 33,
39+
ATMA: 34,
40+
NAPTR: 35,
41+
KX: 36,
42+
CERT: 37,
43+
A6: 38,
44+
DNAME: 39,
45+
SINK: 40,
46+
OPT: 41,
47+
APL: 42,
48+
DS: 43,
49+
SSHFP: 44,
50+
IPSECKEY: 45,
51+
RRSIG: 46,
52+
NSEC: 47,
53+
DNSKEY: 48,
54+
DHCID: 49,
55+
NSEC3: 50,
56+
NSEC3PARAM: 51,
57+
TLSA: 52,
58+
HIP: 55,
59+
CDS: 59,
60+
CDNSKEY: 60,
61+
OPENPGPKEY: 61,
62+
SPF: 99,
63+
UINFO: 100,
64+
UID: 101,
65+
GID: 102,
66+
UNSPEC: 103,
67+
TKEY: 249,
68+
TSIG: 250,
69+
IXFR: 251,
70+
AXFR: 252,
71+
MAILB: 253,
72+
MAILA: 254,
73+
ANY: 255,
74+
URI: 256,
75+
CAA: 257,
76+
TA: 32768,
77+
DLV: 32769
78+
});
79+
80+
const DNSCLASS = reverseFill({
81+
IN: 1,
82+
CS: 2,
83+
CH: 3,
84+
HS: 4
85+
});
86+
87+
module.exports = {
88+
DNSTYPE,
89+
DNSCLASS
90+
};

common/convert.js

+33
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,33 @@
1+
const udpPacketToTcpPacket = (data) => {
2+
const length = data.byteLength;
3+
if (length > 512) {
4+
console.warn(`*UDP->TCP* Packet size is ${length}, which is larger than 512, request data maybe invalid.`);
5+
}
6+
return Buffer.concat([Buffer.from([length >> 8, length & 255]), data]);
7+
};
8+
9+
const tcpPacketToUdpPacket = (data, tc = false) => {
10+
const length = (data[0] << 8) + data[1];
11+
data = data.slice(2);
12+
const actualLength = data.byteLength;
13+
if (actualLength !== length) {
14+
console.warn(`*TCP->UDP* Packet size doesn't match, expected ${length} but got ${actualLength}, request data maybe invalid.`);
15+
}
16+
if (actualLength > 512) {
17+
if (tc) {
18+
data = data.split(0, 512);
19+
// set TC to 1
20+
data[3] |= 4;
21+
console.warn('*TCP->UDP* Packet size is larger than 512 bytes, data is truncated and TC is set to true.');
22+
}
23+
else {
24+
console.warn('*TCP->UDP* Packet size is larger than 512 bytes, data is not truncated but response data maybe not acceptable.');
25+
}
26+
}
27+
return data;
28+
};
29+
30+
module.exports = {
31+
udpPacketToTcpPacket,
32+
tcpPacketToUdpPacket
33+
};

common/load-config.js

+59
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,59 @@
1+
const fs = require('fs');
2+
const { parseServer } = require('./utils');
3+
4+
const defaultConfig = {
5+
tcp: {
6+
enable: false,
7+
host: '::',
8+
port: 53
9+
},
10+
udp: {
11+
enable: false,
12+
host: '::',
13+
port: 53
14+
},
15+
servers: {
16+
default: {
17+
host: '8.8.8.8',
18+
port: '53',
19+
type: 'udp'
20+
}
21+
},
22+
rules: []
23+
};
24+
25+
const loadConfig = (path) => {
26+
// require() cannot be reloaded until restart
27+
// const config = require(path);
28+
const config = JSON.parse(fs.readFileSync(path, 'utf8'));
29+
30+
// only merge the first level and second level config
31+
const result = Object.assign({}, defaultConfig, config);
32+
Object.keys(defaultConfig).forEach(key => {
33+
if (typeof defaultConfig[key] !== 'object' || defaultConfig[key] instanceof Array) {
34+
return;
35+
}
36+
result[key] = Object.assign({}, defaultConfig[key], result[key]);
37+
});
38+
39+
// parse servers
40+
const { servers, rules } = result;
41+
Object.keys(servers).forEach(key => {
42+
servers[key] = parseServer(servers[key]);
43+
});
44+
for (let rule of rules) {
45+
const { server } = rule;
46+
if (server) {
47+
if (typeof server === 'string' && servers[server]) {
48+
rule.server = servers[server];
49+
}
50+
else {
51+
rule.server = parseServer(server);
52+
}
53+
}
54+
}
55+
56+
return result;
57+
};
58+
59+
module.exports = loadConfig;

0 commit comments

Comments
 (0)