fix(core): harden UDP session handling, QUIC control message validation, and bridge process cleanup
This commit is contained in:
@@ -3,6 +3,6 @@
|
||||
*/
|
||||
export const commitinfo = {
|
||||
name: '@serve.zone/remoteingress',
|
||||
version: '4.15.2',
|
||||
version: '4.15.3',
|
||||
description: 'Edge ingress tunnel for DcRouter - tunnels TCP and UDP traffic from the network edge to SmartProxy over TLS or QUIC, preserving client IP via PROXY protocol.'
|
||||
}
|
||||
|
||||
@@ -222,14 +222,21 @@ export class RemoteIngressEdge extends EventEmitter {
|
||||
this.bridge.removeListener('exit', this.handleCrashRecovery);
|
||||
this.bridge.on('exit', this.handleCrashRecovery);
|
||||
|
||||
await this.bridge.sendCommand('startEdge', {
|
||||
hubHost: edgeConfig.hubHost,
|
||||
hubPort: edgeConfig.hubPort ?? 8443,
|
||||
edgeId: edgeConfig.edgeId,
|
||||
secret: edgeConfig.secret,
|
||||
...(edgeConfig.bindAddress ? { bindAddress: edgeConfig.bindAddress } : {}),
|
||||
...(edgeConfig.transportMode ? { transportMode: edgeConfig.transportMode } : {}),
|
||||
});
|
||||
try {
|
||||
await this.bridge.sendCommand('startEdge', {
|
||||
hubHost: edgeConfig.hubHost,
|
||||
hubPort: edgeConfig.hubPort ?? 8443,
|
||||
edgeId: edgeConfig.edgeId,
|
||||
secret: edgeConfig.secret,
|
||||
...(edgeConfig.bindAddress ? { bindAddress: edgeConfig.bindAddress } : {}),
|
||||
...(edgeConfig.transportMode ? { transportMode: edgeConfig.transportMode } : {}),
|
||||
});
|
||||
} catch (err) {
|
||||
// Clean up the spawned process to avoid orphaning it
|
||||
this.bridge.removeListener('exit', this.handleCrashRecovery);
|
||||
this.bridge.kill();
|
||||
throw err;
|
||||
}
|
||||
|
||||
this.started = true;
|
||||
this.restartAttempts = 0;
|
||||
@@ -282,6 +289,9 @@ export class RemoteIngressEdge extends EventEmitter {
|
||||
this.started = false;
|
||||
}
|
||||
this.savedConfig = null;
|
||||
// Remove all listeners to prevent memory buildup
|
||||
this.bridge.removeAllListeners();
|
||||
this.removeAllListeners();
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -326,6 +336,10 @@ export class RemoteIngressEdge extends EventEmitter {
|
||||
}
|
||||
|
||||
await new Promise(resolve => setTimeout(resolve, this.restartBackoffMs));
|
||||
// Re-check after backoff — stop() may have been called during the wait
|
||||
if (this.stopping || !this.savedConfig) {
|
||||
return;
|
||||
}
|
||||
this.restartBackoffMs = Math.min(this.restartBackoffMs * 2, MAX_RESTART_BACKOFF_MS);
|
||||
this.restartAttempts++;
|
||||
|
||||
|
||||
@@ -156,13 +156,20 @@ export class RemoteIngressHub extends EventEmitter {
|
||||
this.bridge.removeListener('exit', this.handleCrashRecovery);
|
||||
this.bridge.on('exit', this.handleCrashRecovery);
|
||||
|
||||
await this.bridge.sendCommand('startHub', {
|
||||
tunnelPort: config.tunnelPort ?? 8443,
|
||||
targetHost: config.targetHost ?? '127.0.0.1',
|
||||
...(config.tls?.certPem && config.tls?.keyPem
|
||||
? { tlsCertPem: config.tls.certPem, tlsKeyPem: config.tls.keyPem }
|
||||
: {}),
|
||||
});
|
||||
try {
|
||||
await this.bridge.sendCommand('startHub', {
|
||||
tunnelPort: config.tunnelPort ?? 8443,
|
||||
targetHost: config.targetHost ?? '127.0.0.1',
|
||||
...(config.tls?.certPem && config.tls?.keyPem
|
||||
? { tlsCertPem: config.tls.certPem, tlsKeyPem: config.tls.keyPem }
|
||||
: {}),
|
||||
});
|
||||
} catch (err) {
|
||||
// Clean up the spawned process to avoid orphaning it
|
||||
this.bridge.removeListener('exit', this.handleCrashRecovery);
|
||||
this.bridge.kill();
|
||||
throw err;
|
||||
}
|
||||
|
||||
this.started = true;
|
||||
this.restartAttempts = 0;
|
||||
@@ -186,6 +193,9 @@ export class RemoteIngressHub extends EventEmitter {
|
||||
}
|
||||
this.savedConfig = null;
|
||||
this.savedEdges = [];
|
||||
// Remove all listeners to prevent memory buildup
|
||||
this.bridge.removeAllListeners();
|
||||
this.removeAllListeners();
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -232,6 +242,10 @@ export class RemoteIngressHub extends EventEmitter {
|
||||
}
|
||||
|
||||
await new Promise(resolve => setTimeout(resolve, this.restartBackoffMs));
|
||||
// Re-check after backoff — stop() may have been called during the wait
|
||||
if (this.stopping || !this.savedConfig) {
|
||||
return;
|
||||
}
|
||||
this.restartBackoffMs = Math.min(this.restartBackoffMs * 2, MAX_RESTART_BACKOFF_MS);
|
||||
this.restartAttempts++;
|
||||
|
||||
|
||||
Reference in New Issue
Block a user