@@ -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