feat(core): Gnutella joining after Java, measured against Java
GnutellaRun lets Java's PeerToPeerAnwendung join peers on terminal-net. The core's gnutella.ts does the same: a ping in Java's text format to port 6346, a pong back, the ping sent on to the other peers and their pongs back the way it came, at most the program's number of peers. Departure from Java: a ping that comes a second time gets no pong and its connection stays (Java's worker throws on the missing pong). Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
@@ -123,6 +123,7 @@ import { firewallLogPage, forwardingTablePage, ripTablePage, routerIndexPage } f
|
||||
import { applyFirewallSettings, firewallSettingsPage } from './apps/firewallSettings.js';
|
||||
import { parentPath, VirtualFileSystem } from '../model/virtualFileSystem.js';
|
||||
import { EMAIL_SERVER_ACCOUNTS_FILE, serverAccountsFileText } from './emailAccountsFile.js';
|
||||
import { GNUTELLA_FOLDER, GnutellaPeer } from './apps/gnutella.js';
|
||||
import {
|
||||
PRODUCTION_TRACE_RETENTION,
|
||||
type HeaderField,
|
||||
@@ -882,6 +883,8 @@ export class NetworkRuntimeEngine {
|
||||
private dnsIdRandom: JavaCompatibleRandom;
|
||||
/** Draws the command line's first ICMP identifier (Terminal.setIdentifier: new Random()). */
|
||||
private icmpIdentifierRandom: JavaCompatibleRandom;
|
||||
/** Draws Gnutella packet ids (PeerToPeerPaket.guidErstellen: new Random()). */
|
||||
private gnutellaGuidRandom: JavaCompatibleRandom;
|
||||
/** Nodes whose ARP table lost its broadcast row (arp -d 255.255.255.255), until the table is reset. */
|
||||
private readonly arpBroadcastRowRemoved = new Set<Id>();
|
||||
private runtimeSpeed: RuntimeSpeed;
|
||||
@@ -930,6 +933,7 @@ export class NetworkRuntimeEngine {
|
||||
private readonly emailServersByNodeId = new Map<Id, EmailServer>();
|
||||
private readonly emailClientsByNodeId = new Map<Id, EmailClient>();
|
||||
private readonly terminalsByNodeId = new Map<Id, Terminal>();
|
||||
private readonly gnutellaPeersByNodeId = new Map<Id, GnutellaPeer>();
|
||||
/** The time of day a program writes into a mail (Java's new Date()). */
|
||||
private readonly wallClock: () => number;
|
||||
/** Each node's firewall log; it outlives a stop and a new start, as Java's log page does. */
|
||||
@@ -981,6 +985,7 @@ export class NetworkRuntimeEngine {
|
||||
this.linkLocalRandom = new JavaCompatibleRandom(normalizedSeed ^ 0x4c4c_4144n);
|
||||
this.dnsIdRandom = new JavaCompatibleRandom(normalizedSeed ^ 0x444e_5349n);
|
||||
this.icmpIdentifierRandom = new JavaCompatibleRandom(normalizedSeed ^ 0x4943_4d50n);
|
||||
this.gnutellaGuidRandom = new JavaCompatibleRandom(normalizedSeed ^ 0x474e_5554n);
|
||||
this.runtimeSpeed = new RuntimeSpeed();
|
||||
this.packetTraceRetentionPolicy = packetTraceRetentionPolicy;
|
||||
this.stateValue.simulationSpeedPercent = this.runtimeSpeed.percent;
|
||||
@@ -1035,6 +1040,7 @@ export class NetworkRuntimeEngine {
|
||||
this.linkLocalRandom = new JavaCompatibleRandom(seed ^ 0x4c4c_4144n);
|
||||
this.dnsIdRandom = new JavaCompatibleRandom(seed ^ 0x444e_5349n);
|
||||
this.icmpIdentifierRandom = new JavaCompatibleRandom(seed ^ 0x4943_4d50n);
|
||||
this.gnutellaGuidRandom = new JavaCompatibleRandom(seed ^ 0x474e_5554n);
|
||||
this.arpBroadcastRowRemoved.clear();
|
||||
this.isProcessingScheduledEvents = false;
|
||||
this.applicationThreads.clear();
|
||||
@@ -1065,6 +1071,7 @@ export class NetworkRuntimeEngine {
|
||||
this.emailServersByNodeId.clear();
|
||||
this.emailClientsByNodeId.clear();
|
||||
this.terminalsByNodeId.clear();
|
||||
this.gnutellaPeersByNodeId.clear();
|
||||
this.arpLookups = [];
|
||||
this.protocolThreads.clear();
|
||||
this.dnsQueriesBySocketId.clear();
|
||||
@@ -1161,6 +1168,19 @@ export class NetworkRuntimeEngine {
|
||||
return this.terminalsByNodeId.get(nodeId);
|
||||
}
|
||||
|
||||
/** The node's Gnutella program while the simulation runs, if it has one installed. */
|
||||
gnutella(nodeId: Id): GnutellaPeer | undefined {
|
||||
return this.gnutellaPeersByNodeId.get(nodeId);
|
||||
}
|
||||
|
||||
/** A Gnutella packet's id (PeerToPeerPaket.guidErstellen: Random.nextInt until it is not negative). */
|
||||
drawGnutellaGuid(): number {
|
||||
for (;;) {
|
||||
const value = this.gnutellaGuidRandom.next(32) | 0;
|
||||
if (value >= 0) return value;
|
||||
}
|
||||
}
|
||||
|
||||
/** The node's e-mail program while the simulation runs, if it has one installed. */
|
||||
emailClient(nodeId: Id): EmailClient | undefined {
|
||||
return this.emailClientsByNodeId.get(nodeId);
|
||||
@@ -1224,6 +1244,7 @@ export class NetworkRuntimeEngine {
|
||||
this.emailServersByNodeId.clear();
|
||||
this.emailClientsByNodeId.clear();
|
||||
this.terminalsByNodeId.clear();
|
||||
this.gnutellaPeersByNodeId.clear();
|
||||
for (const node of snapshot.nodes) {
|
||||
const echoServer = snapshot.echoServersByNodeId.get(node.id);
|
||||
if (echoServer !== undefined) this.echoServersByNodeId.set(node.id, new EchoServer(this, node.id, echoServer));
|
||||
@@ -1251,6 +1272,13 @@ export class NetworkRuntimeEngine {
|
||||
this.writeEmailServerAccountsFile(nodeId, emailServer.domain, emailServer.accounts);
|
||||
}
|
||||
if (snapshot.terminalNodeIds.has(node.id)) this.terminalsByNodeId.set(node.id, new Terminal(this, node.id, this.nodeFiles(node.id)));
|
||||
const gnutella = snapshot.gnutellaByNodeId.get(node.id);
|
||||
if (gnutella !== undefined) {
|
||||
// PeerToPeerAnwendung.setSystemSoftware: the folder of the files to share.
|
||||
const files = this.nodeFiles(node.id);
|
||||
if (!files.contains(GNUTELLA_FOLDER)) files.createDirectory(GNUTELLA_FOLDER);
|
||||
this.gnutellaPeersByNodeId.set(node.id, new GnutellaPeer(this, node.id, gnutella));
|
||||
}
|
||||
const emailClient = snapshot.emailClientsByNodeId.get(node.id);
|
||||
if (emailClient !== undefined) {
|
||||
const nodeId = node.id;
|
||||
|
||||
Reference in New Issue
Block a user