From 7282098ec016c8a50361880ee568ac9dbc94fc98 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?=E7=8E=8B=E8=89=AF?= <841369634@qq.com>
Date: Wed, 5 Mar 2025 21:39:03 +0800
Subject: [PATCH] =?UTF-8?q?feature:=201=EF=BC=89=E6=96=B0=E5=A2=9E=20`UDP`?=
=?UTF-8?q?=20=E5=92=8C=20`TCP`=20=E7=B1=BB=E5=9E=8B=E7=9A=84DNS=E6=9C=8D?=
=?UTF-8?q?=E5=8A=A1=EF=BC=9B2=EF=BC=89=E4=BF=AE=E5=A4=8D=20`TLS`=20?=
=?UTF-8?q?=E7=B1=BB=E5=9E=8B=E7=9A=84DNS=E6=9C=8D=E5=8A=A1=E5=9C=B0?=
=?UTF-8?q?=E5=9D=80=E9=85=8D=E7=BD=AE=E4=B8=8D=E7=94=9F=E6=95=88=E7=9A=84?=
=?UTF-8?q?=E9=97=AE=E9=A2=98=EF=BC=9B3=EF=BC=89=E5=88=A0=E9=99=A4=20`ipad?=
=?UTF-8?q?dress`=20=E7=B1=BB=E5=9E=8B=E7=9A=84DNS=E3=80=82?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
---
packages/mitmproxy/src/lib/dns/base.js | 68 +++++-
packages/mitmproxy/src/lib/dns/https.js | 56 +----
packages/mitmproxy/src/lib/dns/index.js | 77 +++++--
packages/mitmproxy/src/lib/dns/ipaddress.js | 38 ----
packages/mitmproxy/src/lib/dns/lookup.js | 4 -
packages/mitmproxy/src/lib/dns/preset.js | 33 +--
packages/mitmproxy/src/lib/dns/tcp.js | 51 +++++
packages/mitmproxy/src/lib/dns/tls.js | 25 ++-
packages/mitmproxy/src/lib/dns/udp.js | 44 ++++
.../proxy/mitmproxy/createConnectHandler.js | 4 +-
.../proxy/mitmproxy/createRequestHandler.js | 6 +-
.../src/lib/proxy/mitmproxy/dnsLookup.js | 6 +-
.../mitmproxy/src/lib/speed/SpeedTester.js | 2 +-
packages/mitmproxy/test/dnsSpeedTest.js | 5 -
packages/mitmproxy/test/dnsTest.mjs | 209 ++++++++++++++----
15 files changed, 414 insertions(+), 214 deletions(-)
delete mode 100644 packages/mitmproxy/src/lib/dns/ipaddress.js
delete mode 100644 packages/mitmproxy/src/lib/dns/lookup.js
create mode 100644 packages/mitmproxy/src/lib/dns/tcp.js
create mode 100644 packages/mitmproxy/src/lib/dns/udp.js
diff --git a/packages/mitmproxy/src/lib/dns/base.js b/packages/mitmproxy/src/lib/dns/base.js
index d44b1a5..fb44844 100644
--- a/packages/mitmproxy/src/lib/dns/base.js
+++ b/packages/mitmproxy/src/lib/dns/base.js
@@ -1,8 +1,19 @@
const LRUCache = require('lru-cache')
const log = require('../../utils/util.log.server')
+const matchUtil = require('../../utils/util.match')
const { DynamicChoice } = require('../choice/index')
-const cacheSize = 1024
+function mapToList (ipMap) {
+ const ipList = []
+ for (const key in ipMap) {
+ if (ipMap[key]) { // 配置为 ture 时才生效
+ ipList.push(key)
+ }
+ }
+ return ipList
+}
+
+const defaultCacheSize = 1024
class IpCache extends DynamicChoice {
constructor (hostname) {
@@ -22,10 +33,12 @@ class IpCache extends DynamicChoice {
}
module.exports = class BaseDNS {
- constructor (dnsName) {
+ constructor (dnsName, dnsType, cacheSize, preSetIpList) {
this.dnsName = dnsName
+ this.dnsType = dnsType
+ this.preSetIpList = preSetIpList
this.cache = new LRUCache({
- maxSize: cacheSize,
+ maxSize: (cacheSize > 0 ? cacheSize : defaultCacheSize),
sizeCalculation: () => {
return 1
},
@@ -53,7 +66,7 @@ module.exports = class BaseDNS {
}
const t = new Date()
- let ipList = await this._lookup(hostname)
+ let ipList = await this._lookupInternal(hostname)
if (ipList == null) {
// 没有获取到ipv4地址
ipList = []
@@ -61,12 +74,55 @@ module.exports = class BaseDNS {
ipList.push(hostname) // 把原域名加入到统计里去
ipCache.setBackupList(ipList)
- log.info(`[DNS '${this.dnsName}']: ${hostname} ➜ ${ipCache.value} (${new Date() - t} ms), ipList: ${JSON.stringify(ipList)}, ipCache:`, JSON.stringify(ipCache))
+ log.info(`[DNS-over-${this.dnsType} '${this.dnsName}'] ${hostname} ➜ ${ipCache.value} (${new Date() - t} ms), ipList: ${JSON.stringify(ipList)}, ipCache:`, JSON.stringify(ipCache))
return ipCache.value
} catch (error) {
- log.error(`[DNS '${this.dnsName}'] cannot resolve hostname ${hostname}, error:`, error)
+ log.error(`[DNS-over-${this.dnsType} '${this.dnsName}'] cannot resolve hostname ${hostname}, error:`, error)
return hostname
}
}
+
+ async _lookupInternal (hostname) {
+ // 获取当前域名的预设IP列表
+ let hostnamePreSetIpList = matchUtil.matchHostname(this.preSetIpList, hostname, `matched preSetIpList(${this.dnsName})`)
+ if (hostnamePreSetIpList && (hostnamePreSetIpList.length > 0 || hostnamePreSetIpList.length === undefined)) {
+ if (hostnamePreSetIpList.length > 0) {
+ hostnamePreSetIpList = hostnamePreSetIpList.slice()
+ } else {
+ hostnamePreSetIpList = mapToList(hostnamePreSetIpList)
+ }
+
+ if (hostnamePreSetIpList.length > 0) {
+ hostnamePreSetIpList.isPreSet = true
+ log.info(`[DNS-over-${this.dnsType} '${this.dnsName}'] 获取到该域名的预设IP列表: ${hostname} - ${JSON.stringify(hostnamePreSetIpList)}`)
+ return hostnamePreSetIpList
+ }
+ }
+
+ return await this._lookup(hostname)
+ }
+
+ async _lookup (hostname) {
+ const start = Date.now()
+ try {
+ const response = await this._doDnsQuery(hostname)
+ const cost = Date.now() - start
+ if (response == null || response.answers == null || response.answers.length == null || response.answers.length === 0) {
+ // 说明没有获取到ip
+ log.warn(`[DNS-over-${this.dnsType} '${this.dnsName}'] 没有该域名的IP地址: ${hostname}, cost: ${cost} ms, response:`, response)
+ return []
+ }
+ const ret = response.answers.filter(item => item.type === 'A').map(item => item.data)
+ if (ret.length === 0) {
+ log.info(`[DNS-over-${this.dnsType} '${this.dnsName}'] 没有该域名的IPv4地址: ${hostname}, cost: ${cost} ms`)
+ } else {
+ log.info(`[DNS-over-${this.dnsType} '${this.dnsName}'] 获取到该域名的IPv4地址: ${hostname} - ${JSON.stringify(ret)}, cost: ${cost} ms`)
+ }
+ return ret
+ } catch (e) {
+ log.error(`[DNS-over-${this.dnsType} '${this.dnsName}'] DNS query error, hostname: ${hostname}${this.dnsServer ? `, dnsServer: ${this.dnsServer}` : ''}, cost: ${Date.now() - start} ms, error:`, e)
+ return []
+ }
+ }
}
diff --git a/packages/mitmproxy/src/lib/dns/https.js b/packages/mitmproxy/src/lib/dns/https.js
index 1031af0..3ab889c 100644
--- a/packages/mitmproxy/src/lib/dns/https.js
+++ b/packages/mitmproxy/src/lib/dns/https.js
@@ -1,64 +1,16 @@
const { promisify } = require('node:util')
const doh = require('dns-over-http')
-const log = require('../../utils/util.log.server')
-const matchUtil = require('../../utils/util.match')
const BaseDNS = require('./base')
const dohQueryAsync = promisify(doh.query)
-function mapToList (ipMap) {
- const ipList = []
- for (const key in ipMap) {
- if (ipMap[key]) { // 配置为 ture 时才生效
- ipList.push(key)
- }
- }
- return ipList
-}
-
module.exports = class DNSOverHTTPS extends BaseDNS {
- constructor (dnsName, dnsServer, preSetIpList) {
- super(dnsName)
+ constructor (dnsName, cacheSize, preSetIpList, dnsServer) {
+ super(dnsName, 'HTTPS', cacheSize, preSetIpList)
this.dnsServer = dnsServer
- this.preSetIpList = preSetIpList
}
- async _lookup (hostname) {
- // 获取当前域名的预设IP列表
- let hostnamePreSetIpList = matchUtil.matchHostname(this.preSetIpList, hostname, 'matched preSetIpList')
- if (hostnamePreSetIpList && (hostnamePreSetIpList.length > 0 || hostnamePreSetIpList.length === undefined)) {
- if (hostnamePreSetIpList.length > 0) {
- hostnamePreSetIpList = hostnamePreSetIpList.slice()
- } else {
- hostnamePreSetIpList = mapToList(hostnamePreSetIpList)
- }
-
- if (hostnamePreSetIpList.length > 0) {
- hostnamePreSetIpList.isPreSet = true
- return hostnamePreSetIpList
- }
- }
-
- // 未预设当前域名的IP列表,则从dns服务器获取
- const start = new Date()
- try {
- const result = await dohQueryAsync({ url: this.dnsServer }, [{ type: 'A', name: hostname }])
- const cost = new Date() - start
- if (result.answers.length === 0) {
- // 说明没有获取到ip
- log.info(`DNS '${this.dnsName}' 没有该域名的IP地址: ${hostname}, cost: ${cost} ms`)
- return []
- }
- const ret = result.answers.filter(item => item.type === 'A').map(item => item.data)
- if (ret.length === 0) {
- log.info(`DNS '${this.dnsName}' 没有该域名的IPv4地址: ${hostname}, cost: ${cost} ms`)
- } else {
- log.info(`DNS '${this.dnsName}' 获取到该域名的IPv4地址: ${hostname} ${JSON.stringify(ret)}, cost: ${cost} ms`)
- }
- return ret
- } catch (e) {
- log.warn(`DNS query error: ${hostname}, dns: ${this.dnsName}, dnsServer: ${this.dnsServer}, cost: ${new Date() - start} ms, error:`, e)
- return []
- }
+ async _doDnsQuery (hostname) {
+ return await dohQueryAsync({ url: this.dnsServer }, [{ type: 'A', name: hostname }])
}
}
diff --git a/packages/mitmproxy/src/lib/dns/index.js b/packages/mitmproxy/src/lib/dns/index.js
index e153a0c..ee3e40c 100644
--- a/packages/mitmproxy/src/lib/dns/index.js
+++ b/packages/mitmproxy/src/lib/dns/index.js
@@ -1,8 +1,9 @@
const matchUtil = require('../../utils/util.match')
-const DNSOverHTTPS = require('./https.js')
-const DNSOverIpAddress = require('./ipaddress.js')
const DNSOverPreSetIpList = require('./preset.js')
+const DNSOverHTTPS = require('./https.js')
const DNSOverTLS = require('./tls.js')
+const DNSOverTCP = require('./tcp.js')
+const DNSOverUDP = require('./udp.js')
module.exports = {
initDNS (dnsProviders, preSetIpList) {
@@ -12,17 +13,65 @@ module.exports = {
for (const provider in dnsProviders) {
const conf = dnsProviders[provider]
- if (conf.type === 'ipaddress') {
- dnsMap[provider] = new DNSOverIpAddress(provider)
- } else if (conf.type === 'https') {
- dnsMap[provider] = new DNSOverHTTPS(provider, conf.server, preSetIpList)
- } else {
- dnsMap[provider] = new DNSOverTLS(provider)
+ // 获取DNS服务器
+ let server = conf.server || conf.host
+ if (server != null) {
+ server = server.replace(/\s+/, '')
+ }
+ if (!server) {
+ continue
}
- // 设置DNS名称到name属性中
- dnsMap[provider].name = provider
- dnsMap[provider].type = conf.type
+ // 获取DNS类型
+ let type = conf.type
+ if (type == null) {
+ if (server.startsWith('https://') || server.startsWith('http://')) {
+ type = 'https'
+ } else if (server.startsWith('tls://')) {
+ type = 'tls'
+ } else if (server.startsWith('tcp://')) {
+ type = 'tcp'
+ } else if (server.includes('://') && !server.startsWith('udp://')) {
+ throw new Error(`Unknown type DNS: ${server}, provider: ${provider}`)
+ } else {
+ type = 'udp'
+ }
+ } else {
+ type = type.replace(/\s+/, '').toLowerCase()
+ }
+
+ // 创建DNS对象
+ if (type === 'https' || type === 'doh' || type === 'dns-over-https') {
+ if (!server.includes('/')) {
+ server = `https://${server}/dns-query`
+ }
+
+ // 基于 https
+ dnsMap[provider] = new DNSOverHTTPS(provider, conf.cacheSize, preSetIpList, server)
+ } else {
+ // 获取DNS端口
+ let port = conf.port
+
+ // 处理带协议的DNS服务地址
+ if (server.includes('://')) {
+ server = server.split('://')[1]
+ }
+ // 处理带端口的DNS服务地址
+ if (port == null && server.includes(':')) {
+ [server, port] = server.split(':')
+ }
+
+ if (type === 'tls' || type === 'dot' || type === 'dns-over-tls') {
+ // 基于 tls
+ dnsMap[provider] = new DNSOverTLS(provider, conf.cacheSize, preSetIpList, server, port, conf.servername)
+ } else if (type === 'tcp' || type === 'dns-over-tcp') {
+ // 基于 tcp
+ dnsMap[provider] = new DNSOverTCP(provider, conf.cacheSize, preSetIpList, server, port)
+ } else {
+ // 基于 udp
+ dnsMap[provider] = new DNSOverUDP(provider, conf.cacheSize, preSetIpList, server, port)
+ }
+ }
}
// 创建预设IP的DNS
@@ -31,16 +80,14 @@ module.exports = {
return dnsMap
},
hasDnsLookup (dnsConfig, hostname) {
- let providerName = null
-
// 先匹配 预设IP配置
- const hostnamePreSetIpList = matchUtil.matchHostname(dnsConfig.preSetIpList, hostname, 'matched preSetIpList')
+ const hostnamePreSetIpList = matchUtil.matchHostname(dnsConfig.preSetIpList, hostname, 'matched preSetIpList(hasDnsLookup)')
if (hostnamePreSetIpList) {
return dnsConfig.dnsMap.PreSet
}
// 再匹配 DNS映射配置
- providerName = matchUtil.matchHostname(dnsConfig.mapping, hostname, 'get dns providerName')
+ const providerName = matchUtil.matchHostname(dnsConfig.mapping, hostname, 'get dns providerName')
// 由于DNS中的usa已重命名为cloudflare,所以做以下处理,为了向下兼容
if (providerName === 'usa' && dnsConfig.dnsMap.usa == null && dnsConfig.dnsMap.cloudflare != null) {
diff --git a/packages/mitmproxy/src/lib/dns/ipaddress.js b/packages/mitmproxy/src/lib/dns/ipaddress.js
deleted file mode 100644
index ab4d85d..0000000
--- a/packages/mitmproxy/src/lib/dns/ipaddress.js
+++ /dev/null
@@ -1,38 +0,0 @@
-const axios = require('axios')
-const log = require('../../utils/util.log.server')
-const BaseDNS = require('./base')
-
-module.exports = class DNSOverIpAddress extends BaseDNS {
- async _lookup (hostname) {
- const url = `https://${hostname}.ipaddress.com`
-
- // const res = fs.readFileSync(path.resolve(__dirname, './data.txt')).toString()
- const res = await axios.get(url)
- if (res.status !== 200 && res.status !== 201) {
- log.error(`[dns] get ${hostname} ipaddress: error: ${res}`)
- return
- }
- const ret = res.data
-
- const regexp = /
IP Address<\/th> | - ([^<]*)<\/li><\/ul><\/td><\/tr>/g
- const matched = regexp.exec(ret)
- let ip = null
-
- if (matched && matched.length >= 1) {
- ip = matched[1]
- log.info(`[dns] get ${hostname} ipaddress:${ip}`)
- return [ip]
- }
- log.warn(`[dns] get ${hostname} ipaddress: error`)
- return null
-
- // const { answers } = await dnstls.query(hostname)
- //
- // const answer = answers.find(answer => answer.type === 'A' && answer.class === 'IN')
- //
- // log.info('dns lookup:', hostname, answer)
- // if (answer) {
- // return answer.data
- // }
- }
-}
diff --git a/packages/mitmproxy/src/lib/dns/lookup.js b/packages/mitmproxy/src/lib/dns/lookup.js
deleted file mode 100644
index 108d106..0000000
--- a/packages/mitmproxy/src/lib/dns/lookup.js
+++ /dev/null
@@ -1,4 +0,0 @@
-module.exports = {
- lookup () {
- },
-}
diff --git a/packages/mitmproxy/src/lib/dns/preset.js b/packages/mitmproxy/src/lib/dns/preset.js
index 37b86e3..b992990 100644
--- a/packages/mitmproxy/src/lib/dns/preset.js
+++ b/packages/mitmproxy/src/lib/dns/preset.js
@@ -1,40 +1,11 @@
-const matchUtil = require('../../utils/util.match')
const BaseDNS = require('./base')
-function mapToList (ipMap) {
- const ipList = []
- for (const key in ipMap) {
- if (ipMap[key]) { // 配置为 ture 时才生效
- ipList.push(key)
- }
- }
- return ipList
-}
-
module.exports = class DNSOverPreSetIpList extends BaseDNS {
constructor (preSetIpList) {
- super()
- this.preSetIpList = preSetIpList
- this.name = 'PreSet'
- this.type = 'PreSet'
+ super('PreSet', 'PreSet', null, preSetIpList)
}
- async _lookup (hostname) {
- // 获取当前域名的预设IP列表
- let hostnamePreSetIpList = matchUtil.matchHostname(this.preSetIpList, hostname, 'matched preSetIpList')
- if (hostnamePreSetIpList && (hostnamePreSetIpList.length > 0 || hostnamePreSetIpList.length === undefined)) {
- if (hostnamePreSetIpList.length > 0) {
- hostnamePreSetIpList = hostnamePreSetIpList.slice()
- } else {
- hostnamePreSetIpList = mapToList(hostnamePreSetIpList)
- }
-
- if (hostnamePreSetIpList.length > 0) {
- return hostnamePreSetIpList
- }
- }
-
- // 未预设当前域名的IP列表
+ async _lookup (_hostname) {
return []
}
}
diff --git a/packages/mitmproxy/src/lib/dns/tcp.js b/packages/mitmproxy/src/lib/dns/tcp.js
new file mode 100644
index 0000000..779e75e
--- /dev/null
+++ b/packages/mitmproxy/src/lib/dns/tcp.js
@@ -0,0 +1,51 @@
+const net = require('node:net')
+const { Buffer } = require('node:buffer')
+const dnsPacket = require('dns-packet')
+const randi = require('random-int')
+const BaseDNS = require('./base')
+
+const defaultPort = 53 // UDP类型的DNS服务默认端口号
+
+module.exports = class DNSOverTCP extends BaseDNS {
+ constructor (dnsName, cacheSize, preSetIpList, dnsServer, dnsServerPort) {
+ super(dnsName, 'TCP', cacheSize, preSetIpList)
+ this.dnsServer = dnsServer
+ this.dnsServerPort = Number.parseInt(dnsServerPort) || defaultPort
+ }
+
+ _doDnsQuery (hostname) {
+ return new Promise((resolve, reject) => {
+ // 构造 DNS 查询报文
+ const packet = dnsPacket.encode({
+ flags: dnsPacket.RECURSION_DESIRED,
+ type: 'query',
+ id: randi(0x0, 0xFFFF),
+ questions: [{
+ type: 'A',
+ name: hostname,
+ }],
+ })
+
+ // --- TCP 查询 ---
+ const tcpClient = net.createConnection({
+ host: this.dnsServer,
+ port: this.dnsServerPort,
+ }, () => {
+ // TCP DNS 报文前需添加 2 字节长度头
+ const lengthBuffer = Buffer.alloc(2)
+ lengthBuffer.writeUInt16BE(packet.length)
+ tcpClient.write(Buffer.concat([lengthBuffer, packet]))
+ })
+
+ tcpClient.on('data', (data) => {
+ const length = data.readUInt16BE(0)
+ const response = dnsPacket.decode(data.subarray(2, 2 + length))
+ resolve(response)
+ })
+
+ tcpClient.on('error', (err) => {
+ reject(err)
+ })
+ })
+ }
+}
diff --git a/packages/mitmproxy/src/lib/dns/tls.js b/packages/mitmproxy/src/lib/dns/tls.js
index 0247c3e..b4b5d99 100644
--- a/packages/mitmproxy/src/lib/dns/tls.js
+++ b/packages/mitmproxy/src/lib/dns/tls.js
@@ -1,16 +1,27 @@
const dnstls = require('dns-over-tls')
-const log = require('../../utils/util.log.server')
const BaseDNS = require('./base')
+const defaultPort = 853
+
module.exports = class DNSOverTLS extends BaseDNS {
- async _lookup (hostname) {
- const { answers } = await dnstls.query(hostname)
+ constructor (dnsName, cacheSize, preSetIpList, dnsServer, dnsServerPort, dnsServerName) {
+ super(dnsName, 'TLS', cacheSize, preSetIpList)
+ this.dnsServer = dnsServer
+ this.dnsServerPort = Number.parseInt(dnsServerPort) || defaultPort
+ this.dnsServerName = dnsServerName
+ }
- const answer = answers.find(answer => answer.type === 'A' && answer.class === 'IN')
+ async _doDnsQuery (hostname) {
+ const options = {
+ host: this.dnsServer,
+ port: this.dnsServerPort,
+ servername: this.dnsServerName || this.dnsServer,
- log.info('DNS lookup:', hostname, answer)
- if (answer) {
- return answer.data
+ name: hostname,
+ klass: 'IN',
+ type: 'A',
}
+
+ return await dnstls.query(options)
}
}
diff --git a/packages/mitmproxy/src/lib/dns/udp.js b/packages/mitmproxy/src/lib/dns/udp.js
new file mode 100644
index 0000000..10464c3
--- /dev/null
+++ b/packages/mitmproxy/src/lib/dns/udp.js
@@ -0,0 +1,44 @@
+const dgram = require('node:dgram')
+const dnsPacket = require('dns-packet')
+const randi = require('random-int')
+const BaseDNS = require('./base')
+
+const udpClient = dgram.createSocket('udp4')
+
+const defaultPort = 53 // UDP类型的DNS服务默认端口号
+
+module.exports = class DNSOverUDP extends BaseDNS {
+ constructor (dnsName, cacheSize, preSetIpList, dnsServer, dnsServerPort) {
+ super(dnsName, 'UDP', cacheSize, preSetIpList)
+ this.dnsServer = dnsServer
+ this.dnsServerPort = Number.parseInt(dnsServerPort) || defaultPort
+ }
+
+ _doDnsQuery (hostname) {
+ return new Promise((resolve, reject) => {
+ // 构造 DNS 查询报文
+ const packet = dnsPacket.encode({
+ flags: dnsPacket.RECURSION_DESIRED,
+ type: 'query',
+ id: randi(0x0, 0xFFFF),
+ questions: [{
+ type: 'A',
+ name: hostname,
+ }],
+ })
+
+ // 发送 UDP 查询
+ udpClient.send(packet, 0, packet.length, this.dnsServerPort, this.dnsServer, (err) => {
+ if (err) {
+ reject(err)
+ }
+ })
+
+ // 接收 UDP 响应
+ udpClient.on('message', (msg) => {
+ const response = dnsPacket.decode(msg)
+ resolve(response)
+ })
+ })
+ }
+}
diff --git a/packages/mitmproxy/src/lib/proxy/mitmproxy/createConnectHandler.js b/packages/mitmproxy/src/lib/proxy/mitmproxy/createConnectHandler.js
index 49fa2fe..0ac8f4b 100644
--- a/packages/mitmproxy/src/lib/proxy/mitmproxy/createConnectHandler.js
+++ b/packages/mitmproxy/src/lib/proxy/mitmproxy/createConnectHandler.js
@@ -143,7 +143,7 @@ function connect (req, cltSocket, head, hostname, port, dnsConfig = null, isDire
if (isDnsIntercept && isDnsIntercept.dns && isDnsIntercept.ip !== isDnsIntercept.hostname) {
const { dns, ip, hostname } = isDnsIntercept
dns.count(hostname, ip, true)
- log.error(`记录ip失败次数,用于优选ip! hostname: ${hostname}, ip: ${ip}, reason: ${errorMsg}, dns: ${dns.name}`)
+ log.error(`记录ip失败次数,用于优选ip! hostname: ${hostname}, ip: ${ip}, reason: ${errorMsg}, dns: ${dns.dnsName}`)
}
})
proxySocket.on('error', (e) => {
@@ -157,7 +157,7 @@ function connect (req, cltSocket, head, hostname, port, dnsConfig = null, isDire
if (isDnsIntercept && isDnsIntercept.dns && isDnsIntercept.ip !== isDnsIntercept.hostname) {
const { dns, ip, hostname } = isDnsIntercept
dns.count(hostname, ip, true)
- log.error(`记录ip失败次数,用于优选ip! hostname: ${hostname}, ip: ${ip}, reason: ${errorMsg}, dns: ${dns.name}`)
+ log.error(`记录ip失败次数,用于优选ip! hostname: ${hostname}, ip: ${ip}, reason: ${errorMsg}, dns: ${dns.dnsName}`)
}
})
diff --git a/packages/mitmproxy/src/lib/proxy/mitmproxy/createRequestHandler.js b/packages/mitmproxy/src/lib/proxy/mitmproxy/createRequestHandler.js
index 516591a..b3c27f9 100644
--- a/packages/mitmproxy/src/lib/proxy/mitmproxy/createRequestHandler.js
+++ b/packages/mitmproxy/src/lib/proxy/mitmproxy/createRequestHandler.js
@@ -84,7 +84,7 @@ module.exports = function createRequestHandler (createIntercepts, middlewares, e
if (isDnsIntercept && isDnsIntercept.dns && isDnsIntercept.ip !== isDnsIntercept.hostname) {
const { dns, ip, hostname } = isDnsIntercept
dns.count(hostname, ip, true)
- log.error(`记录ip失败次数,用于优选ip! hostname: ${hostname}, ip: ${ip}, reason: ${reason}, dns: ${dns.name}`)
+ log.error(`记录ip失败次数,用于优选ip! hostname: ${hostname}, ip: ${ip}, reason: ${reason}, dns: ${dns.dnsName}`)
}
const counter = context.requestCount
if (counter != null) {
@@ -123,8 +123,8 @@ module.exports = function createRequestHandler (createIntercepts, middlewares, e
}
if (dns) {
rOptions.lookup = dnsLookup.createLookupFunc(res, dns, 'request url', url, isDnsIntercept)
- log.debug(`域名 ${rOptions.hostname} DNS: ${dns.name}`)
- res.setHeader('DS-DNS', dns.name)
+ log.debug(`域名 ${rOptions.hostname} DNS: ${dns.dnsName}`)
+ res.setHeader('DS-DNS', dns.dnsName)
} else {
log.info(`域名 ${rOptions.hostname} 在DNS中未配置`)
}
diff --git a/packages/mitmproxy/src/lib/proxy/mitmproxy/dnsLookup.js b/packages/mitmproxy/src/lib/proxy/mitmproxy/dnsLookup.js
index 466d543..6668ac0 100644
--- a/packages/mitmproxy/src/lib/proxy/mitmproxy/dnsLookup.js
+++ b/packages/mitmproxy/src/lib/proxy/mitmproxy/dnsLookup.js
@@ -43,15 +43,15 @@ module.exports = {
}
}
if (isTestFailedIp === false) {
- log.info(`----- ${action}: ${hostname}, use ip from dns '${dns.name}': ${ip}${target} -----`)
+ log.info(`----- ${action}: ${hostname}, use ip from dns '${dns.dnsName}': ${ip}${target} -----`)
if (res) {
- res.setHeader('DS-DNS-Lookup', `DNS: ${ip} ${dns.name === '预设IP' ? 'PreSet' : dns.name}`)
+ res.setHeader('DS-DNS-Lookup', `DNS: ${ip} ${dns.dnsName === '预设IP' ? 'PreSet' : dns.dnsName}`)
}
callback(null, ip, 4)
return
} else {
// 使用默认dns
- log.info(`----- ${action}: ${hostname}, use hostname by default DNS: ${hostname}, skip test failed ip from dns '${dns.name}: ${ip}'${target}, options:`, options)
+ log.info(`----- ${action}: ${hostname}, use hostname by default DNS: ${hostname}, skip test failed ip from dns '${dns.dnsName}: ${ip}'${target}, options:`, options)
}
} else {
// 使用默认dns
diff --git a/packages/mitmproxy/src/lib/speed/SpeedTester.js b/packages/mitmproxy/src/lib/speed/SpeedTester.js
index fc35825..59f4995 100644
--- a/packages/mitmproxy/src/lib/speed/SpeedTester.js
+++ b/packages/mitmproxy/src/lib/speed/SpeedTester.js
@@ -79,7 +79,7 @@ class SpeedTester {
}
async getFromOneDns (dns) {
- return await dns._lookup(this.hostname)
+ return await dns._lookupInternal(this.hostname)
}
async test () {
diff --git a/packages/mitmproxy/test/dnsSpeedTest.js b/packages/mitmproxy/test/dnsSpeedTest.js
index 8fc7667..80d8c78 100644
--- a/packages/mitmproxy/test/dnsSpeedTest.js
+++ b/packages/mitmproxy/test/dnsSpeedTest.js
@@ -3,11 +3,6 @@ const SpeedTest = require('../src/lib/speed/index.js')
const SpeedTester = require('../src/lib/speed/SpeedTester.js')
const dnsMap = dns.initDNS({
- // ipaddress: {
- // type: 'ipaddress',
- // server: 'ipaddress',
- // cacheSize: 1000
- // },
cloudflare: {
type: 'https',
server: 'https://1.1.1.1/dns-query',
diff --git a/packages/mitmproxy/test/dnsTest.mjs b/packages/mitmproxy/test/dnsTest.mjs
index bf0cbac..cb50beb 100644
--- a/packages/mitmproxy/test/dnsTest.mjs
+++ b/packages/mitmproxy/test/dnsTest.mjs
@@ -1,56 +1,99 @@
+import assert from 'node:assert'
import dns from '../src/lib/dns/index.js'
+import matchUtil from '../src/utils/util.match.js'
+
+const presetIp = '100.100.100.100'
+const preSetIpList = matchUtil.domainMapRegexply({
+ 'xxx.com': [
+ presetIp
+ ]
+})
const dnsProviders = dns.initDNS({
- aliyun: {
- type: 'https',
- server: 'https://dns.alidns.com/dns-query',
- cacheSize: 1000,
- },
+ // https
cloudflare: {
type: 'https',
server: 'https://1.1.1.1/dns-query',
cacheSize: 1000,
},
- ipaddress: {
- type: 'ipaddress',
- server: 'ipaddress',
- cacheSize: 1000,
- },
quad9: {
- type: 'https',
server: 'https://9.9.9.9/dns-query',
cacheSize: 1000,
},
- rubyfish: {
+ aliyun: {
type: 'https',
+ server: 'https://dns.alidns.com/dns-query',
+ cacheSize: 1000,
+ },
+ aliyun2: {
+ type: 'https',
+ server: 'dns.alidns.com', // 会自动补上 `https://` 和 `/dns-query`
+ cacheSize: 1000,
+ },
+ safe360: {
+ server: 'https://doh.360.cn/dns-query',
+ cacheSize: 1000,
+ },
+ rubyfish: {
server: 'https://rubyfish.cn/dns-query',
cacheSize: 1000,
},
py233: {
- type: 'https',
server: ' https://i.233py.com/dns-query',
cacheSize: 1000,
},
- // sb: {
- // type: 'https',
- // server: 'https://doh.dns.sb/dns-query',
- // cacheSize: 1000
- // },
- // adguard: {
- // type: 'https',
- // server: ' https://dns.adguard.com/dns-query',
- // cacheSize: 1000
- // }
-})
+ // tls
+ cloudflareTLS: {
+ type: 'tls',
+ server: '1.1.1.1',
+ servername: 'cloudflare-dns.com',
+ cacheSize: 1000,
+ },
+ quad9TLS: {
+ server: 'tls://9.9.9.9',
+ servername: 'dns.quad9.net',
+ cacheSize: 1000,
+ },
+ aliyunTLS: {
+ server: 'tls://223.5.5.5:853',
+ cacheSize: 1000,
+ },
+ aliyunTLS2: {
+ server: 'tls://223.6.6.6',
+ cacheSize: 1000,
+ },
+ safe360TLS: {
+ server: 'tls://dot.360.cn',
+ cacheSize: 1000,
+ },
-// const test = '111
IP Address | | 2222'
-// // IP Address | |
-// // IP Address | |
-// const regexp = /IP Address<\/th> | - (.*)<\/li><\/ul><\/td><\/tr>/
-// const matched = regexp.exec(test)
-// console.log('data:', matched)
+ // tcp
+ googleTCP: {
+ type: 'tcp',
+ server: '8.8.8.8',
+ port: 53,
+ cacheSize: 1000,
+ },
+ aliyunTCP: {
+ server: 'tcp://223.5.5.5',
+ cacheSize: 1000,
+ },
+ // udp
+ googleUDP: {
+ // type: 'udp', // 默认是udp可以不用标
+ server: '8.8.8.8',
+ cacheSize: 1000,
+ },
+ aliyunUDP: {
+ server: 'udp://223.5.5.5',
+ cacheSize: 1000,
+ },
+}, preSetIpList)
+
+
+const presetHostname = 'xxx.com'
const hostname1 = 'github.com'
const hostname2 = 'api.github.com'
const hostname3 = 'hk.docmirror.cn'
@@ -61,24 +104,96 @@ const hostname6 = 'gh2.docmirror.top'
let ip
-// console.log('test cloudflare')
+console.log('\n--------------- test PreSet ---------------\n')
+ip = await dnsProviders.PreSet.lookup(presetHostname)
+assert.strictEqual(ip, presetIp) // test preset
+console.log('===> test PreSet:', ip, '\n\n')
+console.log('\n\n')
+
+
+console.log('\n--------------- test https ---------------\n')
+ip = await dnsProviders.cloudflare.lookup(presetHostname)
+assert.strictEqual(ip, presetIp) // test preset
+console.log('\n\n')
+
+assert.strictEqual(dnsProviders.cloudflare.dnsType, 'HTTPS')
// ip = await dnsProviders.cloudflare.lookup(hostname1)
-// console.log('ip:', ip)
-// ip = await dnsProviders.cloudflare.lookup(hostname2)
-// console.log('ip:', ip)
-// ip = await dnsProviders.cloudflare.lookup(hostname3)
-// console.log('ip:', ip)
-// ip = await dnsProviders.cloudflare.lookup(hostname4)
-// console.log('ip:', ip)
-// ip = await dnsProviders.cloudflare.lookup(hostname5)
-// console.log('ip:', ip)
-// ip = await dnsProviders.cloudflare.lookup(hostname6)
-// console.log('ip:', ip)
+// console.log('===> test cloudflare:', ip, '\n\n')
-// console.log('test py233')
+assert.strictEqual(dnsProviders.quad9.dnsType, 'HTTPS')
+// ip = await dnsProviders.quad9.lookup(hostname1)
+// console.log('===> test quad9:', ip, '\n\n')
+
+assert.strictEqual(dnsProviders.aliyun.dnsType, 'HTTPS')
+// ip = await dnsProviders.aliyun.lookup(hostname1)
+// console.log('===> test aliyun:', ip, '\n\n')
+
+assert.strictEqual(dnsProviders.aliyun2.dnsType, 'HTTPS')
+// ip = await dnsProviders.aliyun2.lookup(hostname1)
+// console.log('===> test aliyun2:', ip, '\n\n')
+
+assert.strictEqual(dnsProviders.safe360.dnsType, 'HTTPS')
+// ip = await dnsProviders.safe360.lookup(hostname1)
+// console.log('===> test safe360:', ip, '\n\n')
+
+assert.strictEqual(dnsProviders.rubyfish.dnsType, 'HTTPS')
+// ip = await dnsProviders.rubyfish.lookup(hostname1)
+// console.log('===> test rubyfish:', ip, '\n\n')
+
+assert.strictEqual(dnsProviders.py233.dnsType, 'HTTPS')
// ip = await dnsProviders.py233.lookup(hostname1)
-// console.log('ip:', ip)
+// console.log('===> test py233:', ip, '\n\n')
-// console.log('test ipaddress')
-// ip = await dnsProviders.ipaddress.lookup(hostname0)
-// console.log('ip:', ip)
+
+console.log('\n--------------- test TLS ---------------\n')
+ip = await dnsProviders.cloudflareTLS.lookup(presetHostname)
+assert.strictEqual(ip, presetIp) // test preset
+console.log('\n\n')
+
+assert.strictEqual(dnsProviders.cloudflareTLS.dnsType, 'TLS')
+// ip = await dnsProviders.cloudflareTLS.lookup(hostname1)
+// console.log('===> test cloudflareTLS:', ip, '\n\n')
+
+assert.strictEqual(dnsProviders.quad9TLS.dnsType, 'TLS')
+// ip = await dnsProviders.quad9TLS.lookup(hostname1)
+// console.log('===> test quad9TLS:', ip, '\n\n')
+
+assert.strictEqual(dnsProviders.aliyunTLS.dnsType, 'TLS')
+// ip = await dnsProviders.aliyunTLS.lookup(hostname1)
+// console.log('===> test aliyunTLS:', ip, '\n\n')
+
+assert.strictEqual(dnsProviders.aliyunTLS2.dnsType, 'TLS')
+// ip = await dnsProviders.aliyunTLS2.lookup(hostname1)
+// console.log('===> test aliyunTLS2:', ip, '\n\n')
+
+assert.strictEqual(dnsProviders.safe360TLS.dnsType, 'TLS')
+// ip = await dnsProviders.safe360TLS.lookup(hostname1)
+// console.log('===> test safe360TLS:', ip, '\n\n')
+
+
+console.log('\n--------------- test TCP ---------------\n')
+ip = await dnsProviders.googleTCP.lookup(presetHostname)
+assert.strictEqual(ip, presetIp) // test preset
+console.log('\n\n')
+
+assert.strictEqual(dnsProviders.googleTCP.dnsType, 'TCP')
+// ip = await dnsProviders.googleTCP.lookup(hostname1)
+// console.log('===> test googleTCP:', ip, '\n\n')
+
+assert.strictEqual(dnsProviders.aliyunTCP.dnsType, 'TCP')
+// ip = await dnsProviders.aliyunTCP.lookup(hostname1)
+// console.log('===> test aliyunTCP:', ip, '\n\n')
+
+
+console.log('\n--------------- test UDP ---------------\n')
+ip = await dnsProviders.googleUDP.lookup(presetHostname)
+assert.strictEqual(ip, presetIp) // test preset
+console.log('\n\n')
+
+assert.strictEqual(dnsProviders.googleUDP.dnsType, 'UDP')
+// ip = await dnsProviders.googleUDP.lookup(hostname1)
+// console.log('===> test googleUDP:', ip, '\n\n')
+
+assert.strictEqual(dnsProviders.aliyunUDP.dnsType, 'UDP')
+// ip = await dnsProviders.aliyunUDP.lookup(hostname1)
+// console.log('===> test aliyunUDP:', ip, '\n\n')
|
---|
|
---|