@@ -318,7 +318,11 @@ export default {
318318 return new Response ( 订阅内容 , { status : 200 , headers : responseHeaders } ) ;
319319 }
320320 return new Response ( '无效的订阅TOKEN' , { status : 403 } ) ;
321- } else if ( 访问路径 === 'locations' ) return fetch ( new Request ( 'https://speed.cloudflare.com/locations' , { headers : { 'Referer' : 'https://speed.cloudflare.com/' } } ) ) ;
321+ } else if ( 访问路径 === 'locations' ) { //反代locations列表
322+ const cookies = request . headers . get ( 'Cookie' ) || '' ;
323+ const authCookie = cookies . split ( ';' ) . find ( c => c . trim ( ) . startsWith ( 'auth=' ) ) ?. split ( '=' ) [ 1 ] ;
324+ if ( authCookie && authCookie == await MD5MD5 ( UA + 加密秘钥 + 管理员密码 ) ) return fetch ( new Request ( 'https://speed.cloudflare.com/locations' , { headers : { 'Referer' : 'https://speed.cloudflare.com/' } } ) ) ;
325+ }
322326 } else if ( 管理员密码 ) { // ws代理
323327 await 反代参数获取 ( request ) ;
324328 return await 处理WS请求 ( request , userID ) ;
@@ -495,8 +499,26 @@ function 解析魏烈思请求(chunk, token) {
495499}
496500async function forwardataTCP ( host , portNum , rawData , ws , respHeader , remoteConnWrapper ) {
497501 console . log ( JSON . stringify ( { configJSON : { 目标地址 : host , 目标端口 : portNum , 反代IP : 反代IP , 代理类型 : 启用SOCKS5反代 , 全局代理 : 启用SOCKS5全局反代 , 代理账号 : 我的SOCKS5账号 } } ) ) ;
498- async function connectDirect ( address , port , data ) {
499- const remoteSock = connect ( { hostname : address , port : port } ) ;
502+ async function connectDirect ( address , port , data , 所有反代数组 = null ) {
503+ let remoteSock ;
504+ if ( 所有反代数组 && 所有反代数组 . length > 0 ) {
505+ const 打乱后数组 = [ ...所有反代数组 ] . sort ( ( ) => Math . random ( ) - 0.5 ) ;
506+ const 最大尝试次数 = Math . min ( 8 , 打乱后数组 . length ) ;
507+ for ( let i = 0 ; i < 最大尝试次数 ; i ++ ) {
508+ const [ 反代地址 , 反代端口 ] = 打乱后数组 [ i ] ;
509+ try {
510+ remoteSock = connect ( { hostname : 反代地址 , port : 反代端口 } ) ;
511+ const testWriter = remoteSock . writable . getWriter ( ) ;
512+ await testWriter . write ( data ) ;
513+ testWriter . releaseLock ( ) ;
514+ return remoteSock ;
515+ } catch ( err ) {
516+ try { remoteSock ?. close ?. ( ) ; } catch ( e ) { }
517+ continue ;
518+ }
519+ }
520+ }
521+ remoteSock = connect ( { hostname : address , port : port } ) ;
500522 const writer = remoteSock . writable . getWriter ( ) ;
501523 await writer . write ( data ) ;
502524 writer . releaseLock ( ) ;
@@ -509,10 +531,8 @@ async function forwardataTCP(host, portNum, rawData, ws, respHeader, remoteConnW
509531 } else if ( 启用SOCKS5反代 === 'http' || 启用SOCKS5反代 === 'https' ) {
510532 newSocket = await httpConnect ( host , portNum , rawData ) ;
511533 } else {
512- try {
513- const [ 反代IP地址 , 反代IP端口 ] = await 解析地址端口 ( 反代IP ) ;
514- newSocket = await connectDirect ( 反代IP地址 , 反代IP端口 , rawData ) ;
515- } catch { newSocket = await connectDirect ( atob ( 'UFJPWFlJUC50cDEuMDkwMjI3Lnh5eg==' ) , 1 , rawData ) }
534+ const 所有反代数组 = await 解析地址端口 ( 反代IP ) ;
535+ newSocket = await connectDirect ( atob ( 'UFJPWFlJUC50cDEuMDkwMjI3Lnh5eg==' ) , 1 , rawData , 所有反代数组 ) ;
516536 }
517537 remoteConnWrapper . socket = newSocket ;
518538 newSocket . closed . catch ( ( ) => { } ) . finally ( ( ) => closeSocketQuietly ( ws ) ) ;
@@ -1295,42 +1315,84 @@ function sha224(s) {
12951315
12961316async function 解析地址端口 ( proxyIP ) {
12971317 proxyIP = proxyIP . toLowerCase ( ) ;
1298- if ( proxyIP . includes ( '.william' ) ) {
1299- const williamResult = await ( async function 解析William域名 ( william ) {
1300- try {
1301- const response = await fetch ( `https://1.1.1.1/dns-query?name=${ william } &type=TXT` , { headers : { 'Accept' : 'application/dns-json' } } ) ;
1302- if ( ! response . ok ) return null ;
1303- const data = await response . json ( ) ;
1304- const txtRecords = ( data . Answer || [ ] ) . filter ( record => record . type === 16 ) . map ( record => record . data ) ;
1305- if ( txtRecords . length === 0 ) return null ;
1306- let txtData = txtRecords [ 0 ] ;
1307- if ( txtData . startsWith ( '"' ) && txtData . endsWith ( '"' ) ) txtData = txtData . slice ( 1 , - 1 ) ;
1308- const prefixes = txtData . replace ( / \\ 0 1 0 / g, ',' ) . replace ( / \n / g, ',' ) . split ( ',' ) . map ( s => s . trim ( ) ) . filter ( Boolean ) ;
1309- if ( prefixes . length === 0 ) return null ;
1310- return prefixes [ Math . floor ( Math . random ( ) * prefixes . length ) ] ;
1311- } catch ( error ) {
1312- console . error ( '解析ProxyIP失败:' , error ) ;
1313- return null ;
1314- }
1315- } ) ( proxyIP ) ;
1316- proxyIP = williamResult || proxyIP ;
1318+ async function DoH查询 ( 域名 , 记录类型 ) {
1319+ try {
1320+ const response = await fetch ( `https://1.1.1.1/dns-query?name=${ 域名 } &type=${ 记录类型 } ` , {
1321+ headers : { 'Accept' : 'application/dns-json' }
1322+ } ) ;
1323+ if ( ! response . ok ) return [ ] ;
1324+ const data = await response . json ( ) ;
1325+ return data . Answer || [ ] ;
1326+ } catch ( error ) {
1327+ console . error ( `DoH查询失败 (${ 记录类型 } ):` , error ) ;
1328+ return [ ] ;
1329+ }
13171330 }
1318- let 地址 = proxyIP , 端口 = 443 ;
1319- if ( proxyIP . includes ( '.tp' ) ) {
1320- const tpMatch = proxyIP . match ( / \. t p ( \d + ) / ) ;
1321- if ( tpMatch ) 端口 = parseInt ( tpMatch [ 1 ] , 10 ) ;
1331+
1332+ function 解析地址端口字符串 ( str ) {
1333+ let 地址 = str , 端口 = 443 ;
1334+ if ( str . includes ( ']:' ) ) {
1335+ const parts = str . split ( ']:' ) ;
1336+ 地址 = parts [ 0 ] + ']' ;
1337+ 端口 = parseInt ( parts [ 1 ] , 10 ) || 端口 ;
1338+ } else if ( str . includes ( ':' ) && ! str . startsWith ( '[' ) ) {
1339+ const colonIndex = str . lastIndexOf ( ':' ) ;
1340+ 地址 = str . slice ( 0 , colonIndex ) ;
1341+ 端口 = parseInt ( str . slice ( colonIndex + 1 ) , 10 ) || 端口 ;
1342+ }
13221343 return [ 地址 , 端口 ] ;
13231344 }
1324- if ( proxyIP . includes ( ']:' ) ) {
1325- const parts = proxyIP . split ( ']:' ) ;
1326- 地址 = parts [ 0 ] + ']' ;
1327- 端口 = parseInt ( parts [ 1 ] , 10 ) || 端口 ;
1328- } else if ( proxyIP . includes ( ':' ) && ! proxyIP . startsWith ( '[' ) ) {
1329- const colonIndex = proxyIP . lastIndexOf ( ':' ) ;
1330- 地址 = proxyIP . slice ( 0 , colonIndex ) ;
1331- 端口 = parseInt ( proxyIP . slice ( colonIndex + 1 ) , 10 ) || 端口 ;
1345+
1346+ let 所有反代数组 = [ ] ;
1347+
1348+ if ( proxyIP . includes ( '.william' ) ) {
1349+ try {
1350+ const txtRecords = await DoH查询 ( proxyIP , 'TXT' ) ;
1351+ const txtData = txtRecords . filter ( r => r . type === 16 ) . map ( r => r . data ) ;
1352+ if ( txtData . length > 0 ) {
1353+ let data = txtData [ 0 ] ;
1354+ if ( data . startsWith ( '"' ) && data . endsWith ( '"' ) ) data = data . slice ( 1 , - 1 ) ;
1355+ const prefixes = data . replace ( / \\ 0 1 0 / g, ',' ) . replace ( / \n / g, ',' ) . split ( ',' ) . map ( s => s . trim ( ) ) . filter ( Boolean ) ;
1356+ 所有反代数组 = prefixes . map ( prefix => 解析地址端口字符串 ( prefix ) ) ;
1357+ }
1358+ } catch ( error ) {
1359+ console . error ( '解析William域名失败:' , error ) ;
1360+ }
1361+ } else {
1362+ let [ 地址 , 端口 ] = 解析地址端口字符串 ( proxyIP ) ;
1363+
1364+ if ( proxyIP . includes ( '.tp' ) ) {
1365+ const tpMatch = proxyIP . match ( / \. t p ( \d + ) / ) ;
1366+ if ( tpMatch ) 端口 = parseInt ( tpMatch [ 1 ] , 10 ) ;
1367+ }
1368+
1369+ // 判断是否是域名(非IP地址)
1370+ const ipv4Regex = / ^ ( 2 5 [ 0 - 5 ] | 2 [ 0 - 4 ] \d | [ 0 1 ] ? \d \d ? ) \. ( 2 5 [ 0 - 5 ] | 2 [ 0 - 4 ] \d | [ 0 1 ] ? \d \d ? ) \. ( 2 5 [ 0 - 5 ] | 2 [ 0 - 4 ] \d | [ 0 1 ] ? \d \d ? ) \. ( 2 5 [ 0 - 5 ] | 2 [ 0 - 4 ] \d | [ 0 1 ] ? \d \d ? ) $ / ;
1371+ const ipv6Regex = / ^ \[ ? ( [ a - f A - F 0 - 9 : ] + ) \] ? $ / ;
1372+
1373+ if ( ! ipv4Regex . test ( 地址 ) && ! ipv6Regex . test ( 地址 ) ) {
1374+ // 并行查询 A 和 AAAA 记录
1375+ const [ aRecords , aaaaRecords ] = await Promise . all ( [
1376+ DoH查询 ( 地址 , 'A' ) ,
1377+ DoH查询 ( 地址 , 'AAAA' )
1378+ ] ) ;
1379+
1380+ const ipv4List = aRecords . filter ( r => r . type === 1 ) . map ( r => r . data ) ;
1381+ const ipv6List = aaaaRecords . filter ( r => r . type === 28 ) . map ( r => `[${ r . data } ]` ) ;
1382+ const ipAddresses = [ ...ipv4List , ...ipv6List ] ;
1383+
1384+ 所有反代数组 = ipAddresses . length > 0
1385+ ? ipAddresses . map ( ip => [ ip , 端口 ] )
1386+ : [ [ 地址 , 端口 ] ] ;
1387+ } else {
1388+ 所有反代数组 = [ [ 地址 , 端口 ] ] ;
1389+ }
13321390 }
1333- return [ 地址 , 端口 ] ;
1391+
1392+ return 所有反代数组 ;
1393+ // low
1394+ const [ 选中地址 , 选中端口 ] = 所有反代数组 [ Math . floor ( Math . random ( ) * 所有反代数组 . length ) ] ;
1395+ return [ 选中地址 , 选中端口 ] ;
13341396}
13351397
13361398async function SOCKS5可用性验证 ( 代理协议 = 'socks5' , 代理参数 ) {
0 commit comments