Skip to content

Commit 7578b3b

Browse files
authored
Update _worker.src.js
1 parent 3286680 commit 7578b3b

File tree

1 file changed

+129
-106
lines changed

1 file changed

+129
-106
lines changed

_worker.src.js

Lines changed: 129 additions & 106 deletions
Original file line numberDiff line numberDiff line change
@@ -78,7 +78,7 @@ let fakeHostName;
7878
let subProtocol = 'https';
7979
let subConverter = atob('dXJsLnYxLm1r'); // Subscription conversion backend using Sheep's function
8080
let subConfig = atob('aHR0cHM6Ly9yYXcuZ2l0aHVidXNlcmNvbnRlbnQuY29tL2FtY2x1YnMvQUNMNFNTUi9tYWluL0NsYXNoL2NvbmZpZy9BQ0w0U1NSX09ubGluZV9GdWxsX011bHRpTW9kZS5pbmk='); // Subscription profile
81-
let fileName = atob('5pWw5a2X5aWX5Yip');
81+
let fileName = atob('5pWw5a2X5aWX5Yip');
8282
let isBase64 = true;
8383

8484
let botToken = '';
@@ -97,9 +97,14 @@ let nat64Domain = [
9797
// 'twitch.tv'
9898
];
9999
let nat64 = false;
100+
let nat64Prefix;
101+
let nat64Prefixs = [
102+
'2602:fc59:b0:64::'
103+
];
104+
100105
let hostRemark = false;
101106

102-
const ENABLE_LOG = true;
107+
const ENABLE_LOG = true;
103108

104109
if (!isValidUUID(userID)) {
105110
throw new Error('uuid is invalid');
@@ -138,6 +143,7 @@ export default {
138143
ADDRESSESAPI,
139144
NAT64,
140145
NAT64_DOM_URL_TXT,
146+
NAT64_PREFIX,
141147
HOST_REAMRK,
142148
} = env;
143149
const kvCheckResponse = await checkKVNamespaceBinding(env);
@@ -249,6 +255,23 @@ export default {
249255
let proxyDomainAll = await getIpUrlTxtAndCsv(noTLS, proxyDomainTxt, null);
250256
proxyDomain = [...new Set([...proxyDomainAll.txt])];
251257
}
258+
nat64Prefix = url.searchParams.get('NAT64_PREFIX') || NAT64_PREFIX;
259+
if (NAT64_PREFIX) {
260+
if (httpPattern.test(NAT64_PREFIX)) {
261+
let proxyIpTxt = await addIpText(NAT64_PREFIX);
262+
let ipUrlTxtAndCsv;
263+
if (NAT64_PREFIX.endsWith('.csv')) {
264+
ipUrlTxtAndCsv = await getIpUrlTxtAndCsv(noTLS, null, proxyIpTxt);
265+
} else {
266+
ipUrlTxtAndCsv = await getIpUrlTxtAndCsv(noTLS, proxyIpTxt, null);
267+
}
268+
const uniqueIpTxt = [...new Set([...ipUrlTxtAndCsv.txt, ...ipUrlTxtAndCsv.csv])];
269+
nat64Prefix = uniqueIpTxt[Math.floor(Math.random() * uniqueIpTxt.length)];
270+
} else {
271+
nat64Prefixs = await addIpText(NAT64_PREFIX);
272+
nat64Prefix = nat64Prefixs[Math.floor(Math.random() * nat64Prefixs.length)];
273+
}
274+
}
252275

253276
// Unified protocol for handling subconverters
254277
const [subProtocol, subConverterWithoutProtocol] = (subConverter.startsWith("http://") || subConverter.startsWith("https://"))
@@ -410,11 +433,11 @@ async function resolveProxyIP(PROXYIP, noTLS, proxyIpTxt, fallbackIPs = []) {
410433
/** ---------------------Tools------------------------------ */
411434

412435
function log(...args) {
413-
if (ENABLE_LOG) console.log(...args);
436+
if (ENABLE_LOG) console.log(...args);
414437
}
415438

416439
function error(...args) {
417-
if (ENABLE_LOG) console.error(...args);
440+
if (ENABLE_LOG) console.error(...args);
418441
}
419442

420443
export async function hashHex_f(string) {
@@ -1124,86 +1147,86 @@ function getRandomItems(arr, count) {
11241147
})();
11251148

11261149
async function resolveDomainToNAT64IPv6(domain) {
1127-
try {
1128-
log(`[DNS] Starting domain resolution: ${domain}`);
1150+
try {
1151+
log(`[DNS] Starting domain resolution: ${domain}`);
11291152

1130-
const response = await fetch(`${dnsResolver}?name=${domain}&type=A`, {
1131-
headers: {
1132-
Accept: "application/dns-json",
1133-
},
1134-
});
1153+
const response = await fetch(`${dnsResolver}?name=${domain}&type=A`, {
1154+
headers: {
1155+
Accept: "application/dns-json",
1156+
},
1157+
});
11351158

1136-
if (!response.ok) {
1137-
throw new Error(`DNS request failed with status code: ${response.status}`);
1138-
}
1159+
if (!response.ok) {
1160+
throw new Error(`DNS request failed with status code: ${response.status}`);
1161+
}
11391162

1140-
const result = await response.json();
1141-
log(`[DNS] Query result: ${JSON.stringify(result, null, 2)}`);
1163+
const result = await response.json();
1164+
log(`[DNS] Query result: ${JSON.stringify(result, null, 2)}`);
11421165

1143-
const aRecord = result?.Answer?.find(record => record.type === 1 && record.data);
1144-
if (!aRecord) {
1145-
throw new Error("No valid A record found");
1146-
}
1166+
const aRecord = result?.Answer?.find(record => record.type === 1 && record.data);
1167+
if (!aRecord) {
1168+
throw new Error("No valid A record found");
1169+
}
11471170

1148-
const ipv4 = aRecord.data;
1149-
log(`[DNS] Found IPv4 address: ${ipv4}`);
1171+
const ipv4 = aRecord.data;
1172+
log(`[DNS] Found IPv4 address: ${ipv4}`);
11501173

1151-
const ipv6 = convertIPv4ToNAT64IPv6(ipv4);
1152-
log(`[NAT64] Converted IPv6 address: ${ipv6}`);
1174+
const ipv6 = convertIPv4ToNAT64IPv6(ipv4);
1175+
log(`[NAT64] Converted IPv6 address: ${ipv6}`);
11531176

1154-
return ipv6;
1177+
return ipv6;
11551178

1156-
} catch (err) {
1157-
error(`[Error] Failed to get NAT64 address: ${err.message}`);
1158-
throw new Error(`DNS resolution failed: ${err.message}`);
1159-
}
1179+
} catch (err) {
1180+
error(`[Error] Failed to get NAT64 address: ${err.message}`);
1181+
throw new Error(`DNS resolution failed: ${err.message}`);
1182+
}
11601183
}
11611184

11621185
function convertIPv4ToNAT64IPv6(ipv4Address, options = {}) {
1163-
const {
1164-
prefixType = 'custom', // Options: 'standard', 'custom', 'private', 'random', 'manual'
1165-
withBrackets = true,
1166-
prefix = '' // Used only when prefixType is 'manual'
1167-
} = options;
1168-
1169-
// Validate and parse IPv4 address
1170-
const parts = ipv4Address.trim().split('.');
1171-
if (parts.length !== 4) throw new Error('Invalid IPv4 address');
1172-
const hexParts = parts.map(part => {
1173-
const num = Number(part);
1174-
if (!/^\d+$/.test(part) || isNaN(num) || num < 0 || num > 255) {
1175-
throw new Error(`Invalid IPv4 segment: ${part}`);
1176-
}
1177-
return num.toString(16).padStart(2, '0');
1178-
});
1179-
1180-
// Built-in NAT64 prefixes
1181-
const predefinedPrefixes = {
1182-
standard: ['64:ff9b::'],
1183-
custom: ['2001:67c:2960:6464::'],
1184-
private: ['fd00:abcd::', 'fd00:1234::'],
1185-
random: ['64:ff9b::', '2001:67c:2960:6464::', 'fd00:abcd::']
1186-
};
1187-
1188-
// Select prefix
1189-
let selectedPrefix;
1190-
if (prefixType === 'manual') {
1191-
if (!prefix || typeof prefix !== 'string' || !prefix.includes('::')) {
1192-
throw new Error('Invalid manual prefix; must be a valid IPv6 prefix');
1193-
}
1194-
selectedPrefix = prefix;
1195-
} else if (predefinedPrefixes[prefixType]) {
1196-
const prefixList = predefinedPrefixes[prefixType];
1197-
selectedPrefix = prefixList[Math.floor(Math.random() * prefixList.length)];
1198-
} else {
1199-
throw new Error(`Unsupported prefixType: ${prefixType}`);
1200-
}
1201-
1202-
// Construct IPv6 suffix
1203-
const ipv6Tail = `${hexParts[0]}${hexParts[1]}:${hexParts[2]}${hexParts[3]}`.toLowerCase();
1204-
const fullIPv6 = `${selectedPrefix}${ipv6Tail}`;
1205-
1206-
return withBrackets ? `[${fullIPv6}]` : fullIPv6;
1186+
const {
1187+
prefixType = nat64Prefix ? 'manual' : 'custom', // Options: 'standard', 'custom', 'private', 'random', 'manual'
1188+
prefix = nat64Prefix || '', // Used only when prefixType is 'manual'
1189+
withBrackets = true
1190+
} = options;
1191+
1192+
// Validate and parse IPv4 address
1193+
const parts = ipv4Address.trim().split('.');
1194+
if (parts.length !== 4) throw new Error('Invalid IPv4 address');
1195+
const hexParts = parts.map(part => {
1196+
const num = Number(part);
1197+
if (!/^\d+$/.test(part) || isNaN(num) || num < 0 || num > 255) {
1198+
throw new Error(`Invalid IPv4 segment: ${part}`);
1199+
}
1200+
return num.toString(16).padStart(2, '0');
1201+
});
1202+
1203+
// Built-in NAT64 prefixes
1204+
const predefinedPrefixes = {
1205+
standard: ['64:ff9b::'],
1206+
custom: ['2602:fc59:b0:64::'],
1207+
private: ['fd00:abcd::', 'fd00:1234::'],
1208+
random: ['64:ff9b::', '2001:67c:2960:6464::', 'fd00:abcd::']
1209+
};
1210+
1211+
// Select prefix
1212+
let selectedPrefix;
1213+
if (prefixType === 'manual') {
1214+
if (!prefix || typeof prefix !== 'string' || !prefix.includes('::')) {
1215+
throw new Error('Invalid manual prefix; must be a valid IPv6 prefix');
1216+
}
1217+
selectedPrefix = prefix;
1218+
} else if (predefinedPrefixes[prefixType]) {
1219+
const prefixList = predefinedPrefixes[prefixType];
1220+
selectedPrefix = prefixList[Math.floor(Math.random() * prefixList.length)];
1221+
} else {
1222+
throw new Error(`Unsupported prefixType: ${prefixType}`);
1223+
}
1224+
1225+
// Construct IPv6 suffix
1226+
const ipv6Tail = `${hexParts[0]}${hexParts[1]}:${hexParts[2]}${hexParts[3]}`.toLowerCase();
1227+
const fullIPv6 = `${selectedPrefix}${ipv6Tail}`;
1228+
1229+
return withBrackets ? `[${fullIPv6}]` : fullIPv6;
12071230
}
12081231

12091232
/**
@@ -1218,33 +1241,33 @@ function convertIPv4ToNAT64IPv6(ipv4Address, options = {}) {
12181241
* @returns {boolean} Whether the hostname matches the pattern
12191242
*/
12201243
function matchesDomainPattern(hostname, pattern) {
1221-
if (!hostname || !pattern) return false;
1244+
if (!hostname || !pattern) return false;
12221245

1223-
// Normalize to lowercase; domain names are case-insensitive
1224-
hostname = hostname.toLowerCase();
1225-
pattern = pattern.toLowerCase();
1246+
// Normalize to lowercase; domain names are case-insensitive
1247+
hostname = hostname.toLowerCase();
1248+
pattern = pattern.toLowerCase();
12261249

1227-
// Exclude IP addresses (both IPv4 and IPv6)
1228-
// IPv4: consists of digits and dots; IPv6: contains colons and may be wrapped in brackets
1229-
const ipv4Regex = /^(\d{1,3}\.){3}\d{1,3}$/;
1230-
const ipv6Regex = /^\[?([a-f0-9:]+)\]?$/i;
1231-
if (ipv4Regex.test(hostname) || ipv6Regex.test(hostname)) {
1232-
return false;
1233-
}
1250+
// Exclude IP addresses (both IPv4 and IPv6)
1251+
// IPv4: consists of digits and dots; IPv6: contains colons and may be wrapped in brackets
1252+
const ipv4Regex = /^(\d{1,3}\.){3}\d{1,3}$/;
1253+
const ipv6Regex = /^\[?([a-f0-9:]+)\]?$/i;
1254+
if (ipv4Regex.test(hostname) || ipv6Regex.test(hostname)) {
1255+
return false;
1256+
}
12341257

1235-
const hostParts = hostname.split('.');
1236-
const patternParts = pattern.split('.');
1258+
const hostParts = hostname.split('.');
1259+
const patternParts = pattern.split('.');
12371260

1238-
if (hostParts.length < patternParts.length) return false;
1261+
if (hostParts.length < patternParts.length) return false;
12391262

1240-
// Match segments from right to left; all corresponding segments must match
1241-
for (let i = 1; i <= patternParts.length; i++) {
1242-
if (hostParts[hostParts.length - i] !== patternParts[patternParts.length - i]) {
1243-
return false;
1244-
}
1245-
}
1263+
// Match segments from right to left; all corresponding segments must match
1264+
for (let i = 1; i <= patternParts.length; i++) {
1265+
if (hostParts[hostParts.length - i] !== patternParts[patternParts.length - i]) {
1266+
return false;
1267+
}
1268+
}
12461269

1247-
return true;
1270+
return true;
12481271
}
12491272

12501273
/**
@@ -1261,17 +1284,17 @@ async function resolveNAT64IfNeeded(address, addressRemote, port, nat64, forceNA
12611284
log(`resolveNAT64IfNeeded: address = ${address}, addressRemote = ${addressRemote}, port = ${port}, nat64 = ${nat64}`);
12621285
log(`resolveNAT64IfNeeded: proxyDomain = ${proxyDomain}, nat64Domain = ${nat64Domain}`);
12631286

1264-
if(proxyDomain.some(domain => matchesDomainPattern(address, domain))){
1287+
if (proxyDomain.some(domain => matchesDomainPattern(address, domain))) {
12651288
log(`resolveNAT64IfNeeded: proxyIP = ${proxyIP}`);
12661289
return proxyIP;
12671290
}
12681291

12691292
const shouldUseNAT64 = nat64 && (forceNAT64 || nat64Domain.some(domain => matchesDomainPattern(address, domain)));
12701293
if (shouldUseNAT64) {
1271-
const nat64IP = await resolveDomainToNAT64IPv6(addressRemote);
1272-
log(`resolveNAT64IfNeeded Using NAT64 IPv6: nat64IP = ${nat64IP}`);
1273-
return nat64IP;
1274-
}
1294+
const nat64IP = await resolveDomainToNAT64IPv6(addressRemote);
1295+
log(`resolveNAT64IfNeeded Using NAT64 IPv6: nat64IP = ${nat64IP}`);
1296+
return nat64IP;
1297+
}
12751298

12761299
return address;
12771300
}
@@ -1862,7 +1885,7 @@ function splitNodeData(uniqueIpTxt, noTLS, host, uuid, userAgent, protType, nat6
18621885
if (match && !ipTxt.includes('@am_clubs')) {
18631886
address = match[1];
18641887
port = match[2] || port;
1865-
remarks = hostRemark?host:(match[3] || address || host);
1888+
remarks = hostRemark ? host : (match[3] || address || host);
18661889
proxyip = match[4] || '';
18671890
// console.log(`splitNodeData--match-> \n address: ${address} \n port: ${port} \n remarks: ${remarks} \n proxyip: ${proxyip}`);
18681891
} else {
@@ -1886,7 +1909,7 @@ function splitNodeData(uniqueIpTxt, noTLS, host, uuid, userAgent, protType, nat6
18861909

18871910
address = ip;
18881911
port = newPort || port;
1889-
remarks = hostRemark?host:(extra || address || host);
1912+
remarks = hostRemark ? host : (extra || address || host);
18901913
// console.log(`splitNodeData---> \n address: ${address} \n port: ${port} \n remarks: ${remarks} \n proxyip: ${proxyip}`);
18911914
}
18921915

@@ -2422,7 +2445,7 @@ async function handleTCPOutBound(remoteSocket, addressRemote, portRemote, rawCli
24222445
*/
24232446
async function connectAndWrite(address, port, socks = false) {
24242447
//
2425-
address = await resolveNAT64IfNeeded(address,addressRemote,port,nat64);
2448+
address = await resolveNAT64IfNeeded(address, addressRemote, port, nat64);
24262449

24272450
/** @type {import("@cloudflare/workers-types").Socket} */
24282451
const tcpSocket = socks ? await socks5Connect(addressType, address, port, log)
@@ -2444,12 +2467,12 @@ async function handleTCPOutBound(remoteSocket, addressRemote, portRemote, rawCli
24442467
*/
24452468
async function retry() {
24462469
//
2447-
const resolvedTarget = await resolveNAT64IfNeeded(proxyIP,addressRemote,portRemote,nat64,true);
2470+
const resolvedTarget = await resolveNAT64IfNeeded(proxyIP, addressRemote, portRemote, nat64, true);
24482471
const finalTargetHost = resolvedTarget || addressRemote;
24492472
const finalTargetPort = proxyPort || portRemote;
24502473

2451-
const tcpSocket = socks5Enable
2452-
? await connectAndWrite(addressRemote, portRemote, true)
2474+
const tcpSocket = socks5Enable
2475+
? await connectAndWrite(addressRemote, portRemote, true)
24532476
: await connectAndWrite(finalTargetHost, finalTargetPort);
24542477

24552478
log(`retry-${socks5Enable} connected to ${addressRemote}:${portRemote}`);
@@ -3079,4 +3102,4 @@ async function nginx() {
30793102
</html>
30803103
`
30813104
return text;
3082-
}
3105+
}

0 commit comments

Comments
 (0)