Add in custom subdomain lookups and connection management
This commit is contained in:
109
worker-server.js
109
worker-server.js
@@ -6,6 +6,7 @@ const http = require('http');
|
|||||||
const httpProxy = require('http-proxy');
|
const httpProxy = require('http-proxy');
|
||||||
const HyperDHTServer = require('hyperdht');
|
const HyperDHTServer = require('hyperdht');
|
||||||
const b32 = require('hi-base32');
|
const b32 = require('hi-base32');
|
||||||
|
const fetch = require('node-fetch');
|
||||||
|
|
||||||
// Configuration constants
|
// Configuration constants
|
||||||
const CONFIG = {
|
const CONFIG = {
|
||||||
@@ -13,7 +14,7 @@ const CONFIG = {
|
|||||||
WORKER_MULTIPLIER: 4,
|
WORKER_MULTIPLIER: 4,
|
||||||
PROXY_TIMEOUT: 360000, // 6 minutes
|
PROXY_TIMEOUT: 360000, // 6 minutes
|
||||||
TUNNEL_TIMEOUT: 3600000, // Increased to 1 hour for long-lived WebSocket connections
|
TUNNEL_TIMEOUT: 3600000, // Increased to 1 hour for long-lived WebSocket connections
|
||||||
DEBUG: false, // Keep enabled for diagnostics
|
DEBUG: true, // Enabled for diagnostics
|
||||||
CONINFO: false,
|
CONINFO: false,
|
||||||
MAX_SOCKETS: 500,
|
MAX_SOCKETS: 500,
|
||||||
MAX_TUNNELS: 1000, // Increased to handle high load
|
MAX_TUNNELS: 1000, // Increased to handle high load
|
||||||
@@ -22,6 +23,7 @@ const CONFIG = {
|
|||||||
CONNECT_RETRY_MS: 100,
|
CONNECT_RETRY_MS: 100,
|
||||||
MAX_CONNECT_RETRIES: 3,
|
MAX_CONNECT_RETRIES: 3,
|
||||||
TUNNEL_FORCE_CLOSE_MS: 10000, // Used for HTTP requests
|
TUNNEL_FORCE_CLOSE_MS: 10000, // Used for HTTP requests
|
||||||
|
LOOKUP_API: 'https://sub-api.my-mc.link',
|
||||||
};
|
};
|
||||||
|
|
||||||
// Shared HTTP agent
|
// Shared HTTP agent
|
||||||
@@ -73,12 +75,55 @@ if (cluster.isMaster) {
|
|||||||
res.end('Invalid host header');
|
res.end('Invalid host header');
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
const publicKey = Buffer.from(b32.decode.asBytes(split[0].toUpperCase()));
|
let subdomain = split[0].toLowerCase();
|
||||||
if (publicKey.length < 32) {
|
let publicKey;
|
||||||
console.log('Invalid public key');
|
|
||||||
res.writeHead(418, { 'Content-Type': 'text/html' });
|
// Try decoding subdomain as base32 hash
|
||||||
res.end(content);
|
try {
|
||||||
return;
|
publicKey = Buffer.from(b32.decode.asBytes(subdomain.toUpperCase()));
|
||||||
|
if (publicKey.length !== 32) throw new Error('Invalid public key length');
|
||||||
|
if (CONFIG.DEBUG) console.log(`Subdomain ${subdomain} is a valid hash, using directly`);
|
||||||
|
} catch (e) {
|
||||||
|
// Not a valid hash, perform API lookup
|
||||||
|
if (CONFIG.DEBUG) console.log(`Subdomain ${subdomain} is not a valid hash, performing API lookup`);
|
||||||
|
const isMapRequest = subdomain.endsWith('-map');
|
||||||
|
const baseSubdomain = isMapRequest ? subdomain.replace(/-map$/, '') : subdomain;
|
||||||
|
const lookupUrl = `${CONFIG.LOOKUP_API}/${baseSubdomain}`;
|
||||||
|
|
||||||
|
try {
|
||||||
|
if (CONFIG.DEBUG) console.log(`Fetching from ${lookupUrl} for ${isMapRequest ? 'map' : 'website'} request`);
|
||||||
|
const response = await fetch(lookupUrl);
|
||||||
|
const data = await response.json();
|
||||||
|
|
||||||
|
if (!data.success || !data.data) {
|
||||||
|
console.log(`No record found for subdomain ${baseSubdomain}`);
|
||||||
|
res.writeHead(404, { 'Content-Type': 'text/html' });
|
||||||
|
res.end(content);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
const hash = isMapRequest ? data.data.connectionHashMap : data.data.connectionHash;
|
||||||
|
if (CONFIG.DEBUG) console.log(`Using hash: ${hash} for ${isMapRequest ? 'connectionHashMap' : 'connectionHash'}`);
|
||||||
|
if (!hash) {
|
||||||
|
console.log(`No ${isMapRequest ? 'map' : 'website'} hash found for ${baseSubdomain}`);
|
||||||
|
res.writeHead(404, { 'Content-Type': 'text/html' });
|
||||||
|
res.end(content);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
publicKey = Buffer.from(b32.decode.asBytes(hash.toUpperCase()));
|
||||||
|
if (publicKey.length !== 32) {
|
||||||
|
console.log(`Invalid public key from API for ${baseSubdomain}: ${hash}`);
|
||||||
|
res.writeHead(404, { 'Content-Type': 'text/html' });
|
||||||
|
res.end(content);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
} catch (apiErr) {
|
||||||
|
console.error(`API lookup error for ${baseSubdomain}:`, apiErr.message);
|
||||||
|
res.writeHead(404, { 'Content-Type': 'text/html' });
|
||||||
|
res.end(content);
|
||||||
|
return;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (activeTunnels.size >= CONFIG.MAX_TUNNELS) {
|
if (activeTunnels.size >= CONFIG.MAX_TUNNELS) {
|
||||||
@@ -128,11 +173,51 @@ if (cluster.isMaster) {
|
|||||||
socket.destroy();
|
socket.destroy();
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
const publicKey = Buffer.from(b32.decode.asBytes(split[0].toUpperCase()));
|
let subdomain = split[0].toLowerCase();
|
||||||
if (publicKey.length < 32) {
|
let publicKey;
|
||||||
console.log('Invalid public key');
|
|
||||||
socket.destroy();
|
// Try decoding subdomain as base32 hash
|
||||||
return;
|
try {
|
||||||
|
publicKey = Buffer.from(b32.decode.asBytes(subdomain.toUpperCase()));
|
||||||
|
if (publicKey.length !== 32) throw new Error('Invalid public key length');
|
||||||
|
if (CONFIG.DEBUG) console.log(`Subdomain ${subdomain} is a valid hash, using directly`);
|
||||||
|
} catch (e) {
|
||||||
|
// Not a valid hash, perform API lookup
|
||||||
|
if (CONFIG.DEBUG) console.log(`Subdomain ${subdomain} is not a valid hash, performing API lookup`);
|
||||||
|
const isMapRequest = subdomain.endsWith('-map');
|
||||||
|
const baseSubdomain = isMapRequest ? subdomain.replace(/-map$/, '') : subdomain;
|
||||||
|
const lookupUrl = `${CONFIG.LOOKUP_API}/${baseSubdomain}`;
|
||||||
|
|
||||||
|
try {
|
||||||
|
if (CONFIG.DEBUG) console.log(`Fetching from ${lookupUrl} for ${isMapRequest ? 'map' : 'website'} request`);
|
||||||
|
const response = await fetch(lookupUrl);
|
||||||
|
const data = await response.json();
|
||||||
|
|
||||||
|
if (!data.success || !data.data) {
|
||||||
|
console.log(`No record found for subdomain ${baseSubdomain}`);
|
||||||
|
socket.destroy();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
const hash = isMapRequest ? data.data.connectionHashMap : data.data.connectionHash;
|
||||||
|
if (CONFIG.DEBUG) console.log(`Using hash: ${hash} for ${isMapRequest ? 'connectionHashMap' : 'connectionHash'}`);
|
||||||
|
if (!hash) {
|
||||||
|
console.log(`No ${isMapRequest ? 'map' : 'website'} hash found for ${baseSubdomain}`);
|
||||||
|
socket.destroy();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
publicKey = Buffer.from(b32.decode.asBytes(hash.toUpperCase()));
|
||||||
|
if (publicKey.length !== 32) {
|
||||||
|
console.log(`Invalid public key from API for ${baseSubdomain}: ${hash}`);
|
||||||
|
socket.destroy();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
} catch (apiErr) {
|
||||||
|
console.error(`API lookup error for ${baseSubdomain}:`, apiErr.message);
|
||||||
|
socket.destroy();
|
||||||
|
return;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (activeTunnels.size >= CONFIG.MAX_TUNNELS) {
|
if (activeTunnels.size >= CONFIG.MAX_TUNNELS) {
|
||||||
|
Reference in New Issue
Block a user