Skip to content

Commit a834984

Browse files
committed
feat: 添加UDP处理功能,优化DNS查询逻辑
1 parent bfbfd08 commit a834984

1 file changed

Lines changed: 83 additions & 5 deletions

File tree

_worker.js

Lines changed: 83 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -294,14 +294,16 @@ async function 维列斯OverWSHandler(request) {
294294
value: null,
295295
};
296296
// 标记是否为 DNS 查询
297+
let udpStreamWrite = null;
297298
let isDns = false;
298299

299300
// WebSocket 数据流向远程服务器的管道
300301
readableWebSocketStream.pipeTo(new WritableStream({
301302
async write(chunk, controller) {
302-
if (isDns) {
303+
if (isDns && udpStreamWrite) {
303304
// 如果是 DNS 查询,调用 DNS 处理函数
304-
return await handleDNSQuery(chunk, webSocket, null, log);
305+
//return await handleDNSQuery(chunk, webSocket, null, log);
306+
return udpStreamWrite(chunk);
305307
}
306308
if (remoteSocketWapper.value) {
307309
// 如果已有远程 Socket,直接写入数据
@@ -346,7 +348,11 @@ async function 维列斯OverWSHandler(request) {
346348

347349
if (isDns) {
348350
// 如果是 DNS 查询,调用 DNS 处理函数
349-
return handleDNSQuery(rawClientData, webSocket, 维列斯ResponseHeader, log);
351+
//return handleDNSQuery(rawClientData, webSocket, 维列斯ResponseHeader, log);
352+
const { write } = await handleUDPOutBound(webSocket, 维列斯ResponseHeader, log);
353+
udpStreamWrite = write;
354+
udpStreamWrite(rawClientData);
355+
return;
350356
}
351357
// 处理 TCP 出站连接
352358
if (!banHosts.includes(addressRemote)) {
@@ -875,6 +881,78 @@ function stringify(arr, offset = 0) {
875881
return uuid;
876882
}
877883

884+
/**
885+
*
886+
* @param {import("@cloudflare/workers-types").WebSocket} webSocket
887+
* @param {ArrayBuffer} 维列斯ResponseHeader
888+
* @param {(string)=> void} log
889+
*/
890+
async function handleUDPOutBound(webSocket, 维列斯ResponseHeader, log) {
891+
892+
let is维列斯HeaderSent = false;
893+
const transformStream = new TransformStream({
894+
start(controller) {
895+
896+
},
897+
transform(chunk, controller) {
898+
// udp message 2 byte is the the length of udp data
899+
// TODO: this should have bug, beacsue maybe udp chunk can be in two websocket message
900+
for (let index = 0; index < chunk.byteLength;) {
901+
const lengthBuffer = chunk.slice(index, index + 2);
902+
const udpPakcetLength = new DataView(lengthBuffer).getUint16(0);
903+
const udpData = new Uint8Array(
904+
chunk.slice(index + 2, index + 2 + udpPakcetLength)
905+
);
906+
index = index + 2 + udpPakcetLength;
907+
controller.enqueue(udpData);
908+
}
909+
},
910+
flush(controller) {
911+
}
912+
});
913+
914+
// only handle dns udp for now
915+
transformStream.readable.pipeTo(new WritableStream({
916+
async write(chunk) {
917+
const resp = await fetch('https://1.1.1.1/dns-query',
918+
{
919+
method: 'POST',
920+
headers: {
921+
'content-type': 'application/dns-message',
922+
},
923+
body: chunk,
924+
})
925+
const dnsQueryResult = await resp.arrayBuffer();
926+
const udpSize = dnsQueryResult.byteLength;
927+
// console.log([...new Uint8Array(dnsQueryResult)].map((x) => x.toString(16)));
928+
const udpSizeBuffer = new Uint8Array([(udpSize >> 8) & 0xff, udpSize & 0xff]);
929+
if (webSocket.readyState === WS_READY_STATE_OPEN) {
930+
log(`doh success and dns message length is ${udpSize}`);
931+
if (is维列斯HeaderSent) {
932+
webSocket.send(await new Blob([udpSizeBuffer, dnsQueryResult]).arrayBuffer());
933+
} else {
934+
webSocket.send(await new Blob([维列斯ResponseHeader, udpSizeBuffer, dnsQueryResult]).arrayBuffer());
935+
is维列斯HeaderSent = true;
936+
}
937+
}
938+
}
939+
})).catch((error) => {
940+
log('dns udp has error' + error)
941+
});
942+
943+
const writer = transformStream.writable.getWriter();
944+
945+
return {
946+
/**
947+
*
948+
* @param {Uint8Array} chunk
949+
*/
950+
write(chunk) {
951+
writer.write(chunk);
952+
}
953+
};
954+
}
955+
878956
/**
879957
* 处理 DNS 查询的函数
880958
* @param {ArrayBuffer} udpChunk - 客户端发送的 DNS 查询数据
@@ -2409,7 +2487,7 @@ async function resolveToIPv6(target) {
24092487

24102488
// 获取域名的IPv4地址
24112489
async function fetchIPv4(domain) {
2412-
const url = `https://cloudflare-dns.com/dns-query?name=${domain}&type=A`;
2490+
const url = `https://1.1.1.1/dns-query?name=${domain}&type=A`;
24132491
const response = await fetch(url, {
24142492
headers: { 'Accept': 'application/dns-json' }
24152493
});
@@ -2599,7 +2677,7 @@ async function bestIP(request, env, txt = 'ADD.txt') {
25992677
'Accept': 'application/dns-json'
26002678
}
26012679
});
2602-
2680+
26032681
if (response.ok) {
26042682
const data = await response.json();
26052683
if (data.Status === 0 && data.Answer && data.Answer.length > 0) {

0 commit comments

Comments
 (0)