update to working

This commit is contained in:
Raven Scott 2024-11-09 09:15:23 -05:00
parent f47c46c88e
commit 9d93a11327

180
p2ns.js
View File

@ -1,4 +1,3 @@
require('dotenv').config(); // Load environment variables
const { exec } = require('child_process'); const { exec } = require('child_process');
const dgram = require('dgram'); const dgram = require('dgram');
const dnsPacket = require('dns-packet'); const dnsPacket = require('dns-packet');
@ -9,16 +8,11 @@ const http = require('http');
const b4a = require('b4a'); const b4a = require('b4a');
const { createHash } = require('crypto'); const { createHash } = require('crypto');
const net = require('net'); const net = require('net');
const os = require('os');
// Corestore and Hyperswarm setup for P2P sync // Corestore and Hyperswarm setup for P2P sync
const store = new Corestore('./my-storage'); const store = new Corestore('./my-storage');
const swarm = new Hyperswarm(); const swarm = new Hyperswarm();
// Option for setting a customizable masterNetwork_discoveryKey for TLD syncing
const masterNetworkDiscoveryKey = process.env.masterNetworkDiscoveryKey
? Buffer.from(process.env.masterNetworkDiscoveryKey, 'hex')
: null;
const dnsCore = store.get({ name: 'dns-core' }); const dnsCore = store.get({ name: 'dns-core' });
let holesailClient = null; let holesailClient = null;
@ -26,8 +20,6 @@ const dnsServer = dgram.createSocket('udp4');
const domainToIPMap = {}; const domainToIPMap = {};
let currentIP = 2; // Start assigning IP addresses from 192.168.100.2 let currentIP = 2; // Start assigning IP addresses from 192.168.100.2
console.log(`Loaded masterNetworkDiscoveryKey: ${masterNetworkDiscoveryKey ? masterNetworkDiscoveryKey.toString('hex') : 'None'}`);
// Helper function to remove existing virtual interface if it already exists (for macOS) // Helper function to remove existing virtual interface if it already exists (for macOS)
function removeExistingInterface(subnetName) { function removeExistingInterface(subnetName) {
return new Promise((resolve) => { return new Promise((resolve) => {
@ -110,7 +102,7 @@ function checkPublicDNS(domain) {
questions: [{ type: 'A', name: domain }] questions: [{ type: 'A', name: domain }]
}); });
resolver.send(query, 53, '1.1.1.1', (err) => { resolver.send(query, 53, '192.168.0.16', (err) => {
if (err) { if (err) {
logDebug(`Error forwarding DNS query to 1.1.1.1: ${err}`); logDebug(`Error forwarding DNS query to 1.1.1.1: ${err}`);
return resolve(null); return resolve(null);
@ -130,45 +122,44 @@ function checkPublicDNS(domain) {
}); });
} }
const activeConnections = {}; // Store active connections by domain
// Function to start Holesail client for tunneling and use port 80 with SO_REUSEADDR // Function to start Holesail client for tunneling and use port 80 with SO_REUSEADDR
function startHolesailClient(domain, hash, ip, port) { function startHolesailClient(domain, hash, ip, port) {
logDebug(`Attempting to start/reuse Holesail client for domain: ${domain}`); logDebug(`Starting Holesail client for domain: ${domain}, hash: ${hash}, IP: ${ip}, Port: ${port}`);
if (activeConnections[domain]) {
logDebug(`Reusing existing Holesail client for domain: ${domain} on ${ip}:${port}`);
return activeConnections[domain]; // Reuse the existing connection
}
logDebug(`Starting new Holesail client for domain: ${domain}, hash: ${hash}, IP: ${ip}, Port: ${port}`);
const connector = setupConnector(hash); const connector = setupConnector(hash);
const holesailClient = new HolesailClient(connector); holesailClient = new HolesailClient(connector);
holesailClient.connect({ port: port, address: ip, reuseAddr: true }, () => { holesailClient.connect({ port: port, address: ip, reuseAddr: true }, () => {
logDebug(`Holesail client for ${domain} connected on ${ip}:${port}`); logDebug(`Holesail client for ${domain} connected on ${ip}:${port}`);
}); });
// Store the client in activeConnections
activeConnections[domain] = holesailClient;
// Set a timeout to destroy and remove from activeConnections after 5 minutes (300,000 ms)
setTimeout(() => { setTimeout(() => {
logDebug(`Destroying Holesail client for domain ${domain}`); logDebug(`Destroying Holesail client for ${domain}`);
holesailClient.destroy(); holesailClient.destroy();
delete activeConnections[domain]; // Remove the client from activeConnections
}, 300000); }, 300000);
}
return holesailClient; // Function to restart Holesail client if the port is unresponsive
async function restartHolesailClient(domain, hash, ip, port) {
const isResponsive = await checkPortResponsive(ip, port);
if (!isResponsive) {
logDebug(`Port ${port} on ${ip} is unresponsive, destroying and recreating the Holesail client`);
if (holesailClient) {
holesailClient.destroy();
}
await createInterfaceForDomain(domain);
startHolesailClient(domain, hash, ip, port);
} else {
logDebug(`Port ${port} on ${ip} is responsive, using the existing connection.`);
}
} }
// Ensure the DNS Core is ready before joining the swarm // Ensure the DNS Core is ready before joining the swarm
(async () => { (async () => {
await dnsCore.ready(); await dnsCore.ready();
const topic = dnsCore.discoveryKey;
// Use masterNetworkDiscoveryKey if provided; otherwise, use dnsCore.discoveryKey
const topic = masterNetworkDiscoveryKey || dnsCore.discoveryKey;
logDebug(`DNS Core ready, joining Hyperswarm with topic: ${topic.toString('hex')}`); logDebug(`DNS Core ready, joining Hyperswarm with topic: ${topic.toString('hex')}`);
@ -190,5 +181,130 @@ async function addDomain(domain, hash) {
logDebug(`Domain ${domain} added to DNS core`); logDebug(`Domain ${domain} added to DNS core`);
} }
// Function to handle long connectors (128-byte) or standard connectors (64-byte)
function setupConnector(keyInput) {
if (keyInput.length === 64) {
logDebug(`Using 64-byte connector: ${keyInput}`);
return keyInput;
} else {
logDebug(`Hashing 128-byte connector: ${keyInput}`);
const connector = createHash('sha256').update(keyInput.toString()).digest('hex');
const seed = Buffer.from(connector, 'hex');
return b4a.toString(seed, 'hex');
}
}
// DNS Server Setup for listening on port 53
dnsServer.on('message', async (msg, rinfo) => {
const query = dnsPacket.decode(msg);
const domain = query.questions[0].name;
const type = query.questions[0].type;
logDebug(`DNS query received: Domain = ${domain}, Type = ${type}`);
await dnsCore.ready();
let p2pRecord = null;
for await (const data of dnsCore.createReadStream()) {
const record = JSON.parse(data.toString());
if (record.domain === domain) {
p2pRecord = record;
break;
}
}
const publicDNSRecords = await checkPublicDNS(domain);
if (p2pRecord) {
const localIP = domainToIPMap[domain] || await createInterfaceForDomain(domain);
startHolesailClient(domain, p2pRecord.hash, localIP, 80);
const response = dnsPacket.encode({
type: 'response',
id: query.id,
questions: query.questions,
answers: [{
type: 'A',
name: domain,
ttl: 300,
data: localIP
}]
});
dnsServer.send(response, rinfo.port, rinfo.address);
} else if (publicDNSRecords) {
const response = dnsPacket.encode({
type: 'response',
id: query.id,
questions: query.questions,
answers: publicDNSRecords
});
dnsServer.send(response, rinfo.port, rinfo.address);
} else {
logDebug(`No P2P or public DNS records found for ${domain}`);
const response = dnsPacket.encode({
type: 'response',
id: query.id,
questions: query.questions,
answers: []
});
dnsServer.send(response, rinfo.port, rinfo.address);
}
});
// Ensure DNS server binds to port 53 with elevated permissions (may require sudo)
dnsServer.bind(53, '0.0.0.0', (err) => {
if (err) {
console.error(`Failed to bind DNS server to port 53: ${err.message}`);
process.exit(1);
} else {
logDebug('DNS Server running on port 53, bound to 0.0.0.0');
}
});
// HTTP Server with DNS query before proxying
http.createServer(async (req, res) => {
const domain = req.url.replace("/", "");
logDebug(`HTTP request for domain: ${domain}`);
try {
const localIP = domainToIPMap[domain] || await createInterfaceForDomain(domain);
if (!localIP) {
logDebug(`No DNS records for ${domain}`);
res.writeHead(404);
return res.end('Domain not found');
}
await restartHolesailClient(domain, '78b94094b5ee1e352fec1f37e9cf3780561bcaa6ef9e0678100c9283888f', localIP, 80);
const options = {
hostname: localIP,
port: 80,
path: req.url,
method: req.method,
headers: req.headers,
};
const proxyRequest = http.request(options, (proxyRes) => {
res.writeHead(proxyRes.statusCode, proxyRes.headers);
proxyRes.pipe(res, { end: true });
});
proxyRequest.on('error', (err) => {
logDebug(`Error proxying request for ${domain}: ${err.message}`);
res.writeHead(500);
res.end('Internal Server Error');
});
req.pipe(proxyRequest, { end: true });
} catch (err) {
logDebug(`Failed to handle request for ${domain}: ${err.message}`);
res.writeHead(500);
res.end('Internal Server Error');
}
}).listen(80, '127.0.0.1', () => {
logDebug('HTTP server running on port 80');
});
// Example: Add a domain to the P2P DNS system // Example: Add a domain to the P2P DNS system
addDomain('hello.geek', '07b8b52fbbad7a89ce26ad2d8375e6a82b2e3c02f18596bddff18e9c31164b04'); addDomain('hello.geek', '78b94094b5ee1e352fec1f37e9cf3780561bcaa6ef9e0678100c9283888f');