@push.rocks/smartproxy 5.0.0 → 6.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist_ts/00_commitinfo_data.js +1 -1
- package/dist_ts/classes.pp.interfaces.d.ts +23 -0
- package/dist_ts/classes.pp.networkproxybridge.d.ts +15 -1
- package/dist_ts/classes.pp.networkproxybridge.js +116 -21
- package/dist_ts/classes.pp.portproxy.d.ts +20 -4
- package/dist_ts/classes.pp.portproxy.js +321 -22
- package/dist_ts/index.d.ts +6 -6
- package/dist_ts/index.js +7 -7
- package/dist_ts/networkproxy/classes.np.certificatemanager.d.ts +77 -0
- package/dist_ts/networkproxy/classes.np.certificatemanager.js +354 -0
- package/dist_ts/networkproxy/classes.np.connectionpool.d.ts +47 -0
- package/dist_ts/networkproxy/classes.np.connectionpool.js +210 -0
- package/dist_ts/networkproxy/classes.np.networkproxy.d.ts +117 -0
- package/dist_ts/networkproxy/classes.np.networkproxy.js +375 -0
- package/dist_ts/networkproxy/classes.np.requesthandler.d.ts +51 -0
- package/dist_ts/networkproxy/classes.np.requesthandler.js +210 -0
- package/dist_ts/networkproxy/classes.np.types.d.ts +82 -0
- package/dist_ts/networkproxy/classes.np.types.js +35 -0
- package/dist_ts/networkproxy/classes.np.websockethandler.d.ts +38 -0
- package/dist_ts/networkproxy/classes.np.websockethandler.js +188 -0
- package/dist_ts/networkproxy/index.d.ts +6 -0
- package/dist_ts/networkproxy/index.js +8 -0
- package/dist_ts/nfttablesproxy/classes.nftablesproxy.d.ts +219 -0
- package/dist_ts/nfttablesproxy/classes.nftablesproxy.js +1542 -0
- package/dist_ts/port80handler/classes.port80handler.d.ts +260 -0
- package/dist_ts/port80handler/classes.port80handler.js +928 -0
- package/dist_ts/smartproxy/classes.pp.connectionhandler.d.ts +39 -0
- package/dist_ts/smartproxy/classes.pp.connectionhandler.js +754 -0
- package/dist_ts/smartproxy/classes.pp.connectionmanager.d.ts +78 -0
- package/dist_ts/smartproxy/classes.pp.connectionmanager.js +378 -0
- package/dist_ts/smartproxy/classes.pp.domainconfigmanager.d.ts +55 -0
- package/dist_ts/smartproxy/classes.pp.domainconfigmanager.js +103 -0
- package/dist_ts/smartproxy/classes.pp.interfaces.d.ts +133 -0
- package/dist_ts/smartproxy/classes.pp.interfaces.js +2 -0
- package/dist_ts/smartproxy/classes.pp.networkproxybridge.d.ts +57 -0
- package/dist_ts/smartproxy/classes.pp.networkproxybridge.js +306 -0
- package/dist_ts/smartproxy/classes.pp.portrangemanager.d.ts +56 -0
- package/dist_ts/smartproxy/classes.pp.portrangemanager.js +179 -0
- package/dist_ts/smartproxy/classes.pp.securitymanager.d.ts +47 -0
- package/dist_ts/smartproxy/classes.pp.securitymanager.js +126 -0
- package/dist_ts/smartproxy/classes.pp.snihandler.d.ts +153 -0
- package/dist_ts/smartproxy/classes.pp.snihandler.js +1053 -0
- package/dist_ts/smartproxy/classes.pp.timeoutmanager.d.ts +47 -0
- package/dist_ts/smartproxy/classes.pp.timeoutmanager.js +154 -0
- package/dist_ts/smartproxy/classes.pp.tlsalert.d.ts +149 -0
- package/dist_ts/smartproxy/classes.pp.tlsalert.js +225 -0
- package/dist_ts/smartproxy/classes.pp.tlsmanager.d.ts +57 -0
- package/dist_ts/smartproxy/classes.pp.tlsmanager.js +132 -0
- package/dist_ts/smartproxy/classes.smartproxy.d.ts +64 -0
- package/dist_ts/smartproxy/classes.smartproxy.js +567 -0
- package/package.json +1 -1
- package/readme.md +77 -27
- package/ts/00_commitinfo_data.ts +1 -1
- package/ts/index.ts +6 -6
- package/ts/networkproxy/classes.np.certificatemanager.ts +398 -0
- package/ts/networkproxy/classes.np.connectionpool.ts +241 -0
- package/ts/networkproxy/classes.np.networkproxy.ts +469 -0
- package/ts/networkproxy/classes.np.requesthandler.ts +278 -0
- package/ts/networkproxy/classes.np.types.ts +123 -0
- package/ts/networkproxy/classes.np.websockethandler.ts +226 -0
- package/ts/networkproxy/index.ts +7 -0
- package/ts/{classes.port80handler.ts → port80handler/classes.port80handler.ts} +249 -1
- package/ts/{classes.pp.connectionhandler.ts → smartproxy/classes.pp.connectionhandler.ts} +1 -1
- package/ts/{classes.pp.connectionmanager.ts → smartproxy/classes.pp.connectionmanager.ts} +1 -1
- package/ts/{classes.pp.domainconfigmanager.ts → smartproxy/classes.pp.domainconfigmanager.ts} +1 -1
- package/ts/{classes.pp.interfaces.ts → smartproxy/classes.pp.interfaces.ts} +31 -5
- package/ts/{classes.pp.networkproxybridge.ts → smartproxy/classes.pp.networkproxybridge.ts} +129 -28
- package/ts/{classes.pp.securitymanager.ts → smartproxy/classes.pp.securitymanager.ts} +1 -1
- package/ts/{classes.pp.tlsmanager.ts → smartproxy/classes.pp.tlsmanager.ts} +1 -1
- package/ts/smartproxy/classes.smartproxy.ts +679 -0
- package/ts/classes.networkproxy.ts +0 -1730
- package/ts/classes.pp.acmemanager.ts +0 -149
- package/ts/classes.pp.portproxy.ts +0 -344
- /package/ts/{classes.nftablesproxy.ts → nfttablesproxy/classes.nftablesproxy.ts} +0 -0
- /package/ts/{classes.pp.portrangemanager.ts → smartproxy/classes.pp.portrangemanager.ts} +0 -0
- /package/ts/{classes.pp.snihandler.ts → smartproxy/classes.pp.snihandler.ts} +0 -0
- /package/ts/{classes.pp.timeoutmanager.ts → smartproxy/classes.pp.timeoutmanager.ts} +0 -0
- /package/ts/{classes.pp.tlsalert.ts → smartproxy/classes.pp.tlsalert.ts} +0 -0
|
@@ -1,149 +0,0 @@
|
|
|
1
|
-
import type { IPortProxySettings } from './classes.pp.interfaces.js';
|
|
2
|
-
import { NetworkProxyBridge } from './classes.pp.networkproxybridge.js';
|
|
3
|
-
|
|
4
|
-
/**
|
|
5
|
-
* Manages ACME certificate operations
|
|
6
|
-
*/
|
|
7
|
-
export class AcmeManager {
|
|
8
|
-
constructor(
|
|
9
|
-
private settings: IPortProxySettings,
|
|
10
|
-
private networkProxyBridge: NetworkProxyBridge
|
|
11
|
-
) {}
|
|
12
|
-
|
|
13
|
-
/**
|
|
14
|
-
* Get current ACME settings
|
|
15
|
-
*/
|
|
16
|
-
public getAcmeSettings(): IPortProxySettings['acme'] {
|
|
17
|
-
return this.settings.acme;
|
|
18
|
-
}
|
|
19
|
-
|
|
20
|
-
/**
|
|
21
|
-
* Check if ACME is enabled
|
|
22
|
-
*/
|
|
23
|
-
public isAcmeEnabled(): boolean {
|
|
24
|
-
return !!this.settings.acme?.enabled;
|
|
25
|
-
}
|
|
26
|
-
|
|
27
|
-
/**
|
|
28
|
-
* Update ACME certificate settings
|
|
29
|
-
*/
|
|
30
|
-
public async updateAcmeSettings(acmeSettings: IPortProxySettings['acme']): Promise<void> {
|
|
31
|
-
console.log('Updating ACME certificate settings');
|
|
32
|
-
|
|
33
|
-
// Check if enabled state is changing
|
|
34
|
-
const enabledChanging = this.settings.acme?.enabled !== acmeSettings.enabled;
|
|
35
|
-
|
|
36
|
-
// Update settings
|
|
37
|
-
this.settings.acme = {
|
|
38
|
-
...this.settings.acme,
|
|
39
|
-
...acmeSettings,
|
|
40
|
-
};
|
|
41
|
-
|
|
42
|
-
// Get NetworkProxy instance
|
|
43
|
-
const networkProxy = this.networkProxyBridge.getNetworkProxy();
|
|
44
|
-
|
|
45
|
-
if (!networkProxy) {
|
|
46
|
-
console.log('Cannot update ACME settings - NetworkProxy not initialized');
|
|
47
|
-
return;
|
|
48
|
-
}
|
|
49
|
-
|
|
50
|
-
try {
|
|
51
|
-
// If enabled state changed, we need to restart NetworkProxy
|
|
52
|
-
if (enabledChanging) {
|
|
53
|
-
console.log(`ACME enabled state changed to: ${acmeSettings.enabled}`);
|
|
54
|
-
|
|
55
|
-
// Stop the current NetworkProxy
|
|
56
|
-
await this.networkProxyBridge.stop();
|
|
57
|
-
|
|
58
|
-
// Reinitialize with new settings
|
|
59
|
-
await this.networkProxyBridge.initialize();
|
|
60
|
-
|
|
61
|
-
// Start NetworkProxy with new settings
|
|
62
|
-
await this.networkProxyBridge.start();
|
|
63
|
-
} else {
|
|
64
|
-
// Just update the settings in the existing NetworkProxy
|
|
65
|
-
console.log('Updating ACME settings in NetworkProxy without restart');
|
|
66
|
-
|
|
67
|
-
// Update settings in NetworkProxy
|
|
68
|
-
if (networkProxy.options && networkProxy.options.acme) {
|
|
69
|
-
networkProxy.options.acme = { ...this.settings.acme };
|
|
70
|
-
|
|
71
|
-
// For certificate renewals, we might want to trigger checks with the new settings
|
|
72
|
-
if (acmeSettings.renewThresholdDays !== undefined) {
|
|
73
|
-
console.log(`Setting new renewal threshold to ${acmeSettings.renewThresholdDays} days`);
|
|
74
|
-
networkProxy.options.acme.renewThresholdDays = acmeSettings.renewThresholdDays;
|
|
75
|
-
}
|
|
76
|
-
|
|
77
|
-
// Update other settings that might affect certificate operations
|
|
78
|
-
if (acmeSettings.useProduction !== undefined) {
|
|
79
|
-
console.log(`Setting ACME to ${acmeSettings.useProduction ? 'production' : 'staging'} mode`);
|
|
80
|
-
}
|
|
81
|
-
|
|
82
|
-
if (acmeSettings.autoRenew !== undefined) {
|
|
83
|
-
console.log(`Setting auto-renewal to ${acmeSettings.autoRenew ? 'enabled' : 'disabled'}`);
|
|
84
|
-
}
|
|
85
|
-
}
|
|
86
|
-
}
|
|
87
|
-
} catch (err) {
|
|
88
|
-
console.log(`Error updating ACME settings: ${err}`);
|
|
89
|
-
}
|
|
90
|
-
}
|
|
91
|
-
|
|
92
|
-
/**
|
|
93
|
-
* Request a certificate for a specific domain
|
|
94
|
-
*/
|
|
95
|
-
public async requestCertificate(domain: string): Promise<boolean> {
|
|
96
|
-
// Validate domain format
|
|
97
|
-
if (!this.isValidDomain(domain)) {
|
|
98
|
-
console.log(`Invalid domain format: ${domain}`);
|
|
99
|
-
return false;
|
|
100
|
-
}
|
|
101
|
-
|
|
102
|
-
// Delegate to NetworkProxyManager
|
|
103
|
-
return this.networkProxyBridge.requestCertificate(domain);
|
|
104
|
-
}
|
|
105
|
-
|
|
106
|
-
/**
|
|
107
|
-
* Basic domain validation
|
|
108
|
-
*/
|
|
109
|
-
private isValidDomain(domain: string): boolean {
|
|
110
|
-
// Very basic domain validation
|
|
111
|
-
if (!domain || domain.length === 0) {
|
|
112
|
-
return false;
|
|
113
|
-
}
|
|
114
|
-
|
|
115
|
-
// Check for wildcard domains (they can't get ACME certs)
|
|
116
|
-
if (domain.includes('*')) {
|
|
117
|
-
console.log(`Wildcard domains like "${domain}" are not supported for ACME certificates`);
|
|
118
|
-
return false;
|
|
119
|
-
}
|
|
120
|
-
|
|
121
|
-
// Check if domain has at least one dot and no invalid characters
|
|
122
|
-
const validDomainRegex = /^[a-zA-Z0-9]([a-zA-Z0-9-]{0,61}[a-zA-Z0-9])?(\.[a-zA-Z0-9]([a-zA-Z0-9-]{0,61}[a-zA-Z0-9])?)*$/;
|
|
123
|
-
if (!validDomainRegex.test(domain)) {
|
|
124
|
-
console.log(`Domain "${domain}" has invalid format`);
|
|
125
|
-
return false;
|
|
126
|
-
}
|
|
127
|
-
|
|
128
|
-
return true;
|
|
129
|
-
}
|
|
130
|
-
|
|
131
|
-
/**
|
|
132
|
-
* Get eligible domains for ACME certificates
|
|
133
|
-
*/
|
|
134
|
-
public getEligibleDomains(): string[] {
|
|
135
|
-
// Collect all eligible domains from domain configs
|
|
136
|
-
const domains: string[] = [];
|
|
137
|
-
|
|
138
|
-
for (const config of this.settings.domainConfigs) {
|
|
139
|
-
// Skip domains that can't be used with ACME
|
|
140
|
-
const eligibleDomains = config.domains.filter(domain =>
|
|
141
|
-
!domain.includes('*') && this.isValidDomain(domain)
|
|
142
|
-
);
|
|
143
|
-
|
|
144
|
-
domains.push(...eligibleDomains);
|
|
145
|
-
}
|
|
146
|
-
|
|
147
|
-
return domains;
|
|
148
|
-
}
|
|
149
|
-
}
|
|
@@ -1,344 +0,0 @@
|
|
|
1
|
-
import * as plugins from './plugins.js';
|
|
2
|
-
import type { IPortProxySettings, IDomainConfig } from './classes.pp.interfaces.js';
|
|
3
|
-
import { ConnectionManager } from './classes.pp.connectionmanager.js';
|
|
4
|
-
import { SecurityManager } from './classes.pp.securitymanager.js';
|
|
5
|
-
import { DomainConfigManager } from './classes.pp.domainconfigmanager.js';
|
|
6
|
-
import { TlsManager } from './classes.pp.tlsmanager.js';
|
|
7
|
-
import { NetworkProxyBridge } from './classes.pp.networkproxybridge.js';
|
|
8
|
-
import { TimeoutManager } from './classes.pp.timeoutmanager.js';
|
|
9
|
-
import { AcmeManager } from './classes.pp.acmemanager.js';
|
|
10
|
-
import { PortRangeManager } from './classes.pp.portrangemanager.js';
|
|
11
|
-
import { ConnectionHandler } from './classes.pp.connectionhandler.js';
|
|
12
|
-
|
|
13
|
-
/**
|
|
14
|
-
* PortProxy - Main class that coordinates all components
|
|
15
|
-
*/
|
|
16
|
-
export class PortProxy {
|
|
17
|
-
private netServers: plugins.net.Server[] = [];
|
|
18
|
-
private connectionLogger: NodeJS.Timeout | null = null;
|
|
19
|
-
private isShuttingDown: boolean = false;
|
|
20
|
-
|
|
21
|
-
// Component managers
|
|
22
|
-
private connectionManager: ConnectionManager;
|
|
23
|
-
private securityManager: SecurityManager;
|
|
24
|
-
public domainConfigManager: DomainConfigManager;
|
|
25
|
-
private tlsManager: TlsManager;
|
|
26
|
-
private networkProxyBridge: NetworkProxyBridge;
|
|
27
|
-
private timeoutManager: TimeoutManager;
|
|
28
|
-
private acmeManager: AcmeManager;
|
|
29
|
-
private portRangeManager: PortRangeManager;
|
|
30
|
-
private connectionHandler: ConnectionHandler;
|
|
31
|
-
|
|
32
|
-
constructor(settingsArg: IPortProxySettings) {
|
|
33
|
-
// Set reasonable defaults for all settings
|
|
34
|
-
this.settings = {
|
|
35
|
-
...settingsArg,
|
|
36
|
-
targetIP: settingsArg.targetIP || 'localhost',
|
|
37
|
-
initialDataTimeout: settingsArg.initialDataTimeout || 120000,
|
|
38
|
-
socketTimeout: settingsArg.socketTimeout || 3600000,
|
|
39
|
-
inactivityCheckInterval: settingsArg.inactivityCheckInterval || 60000,
|
|
40
|
-
maxConnectionLifetime: settingsArg.maxConnectionLifetime || 86400000,
|
|
41
|
-
inactivityTimeout: settingsArg.inactivityTimeout || 14400000,
|
|
42
|
-
gracefulShutdownTimeout: settingsArg.gracefulShutdownTimeout || 30000,
|
|
43
|
-
noDelay: settingsArg.noDelay !== undefined ? settingsArg.noDelay : true,
|
|
44
|
-
keepAlive: settingsArg.keepAlive !== undefined ? settingsArg.keepAlive : true,
|
|
45
|
-
keepAliveInitialDelay: settingsArg.keepAliveInitialDelay || 10000,
|
|
46
|
-
maxPendingDataSize: settingsArg.maxPendingDataSize || 10 * 1024 * 1024,
|
|
47
|
-
disableInactivityCheck: settingsArg.disableInactivityCheck || false,
|
|
48
|
-
enableKeepAliveProbes:
|
|
49
|
-
settingsArg.enableKeepAliveProbes !== undefined ? settingsArg.enableKeepAliveProbes : true,
|
|
50
|
-
enableDetailedLogging: settingsArg.enableDetailedLogging || false,
|
|
51
|
-
enableTlsDebugLogging: settingsArg.enableTlsDebugLogging || false,
|
|
52
|
-
enableRandomizedTimeouts: settingsArg.enableRandomizedTimeouts || false,
|
|
53
|
-
allowSessionTicket:
|
|
54
|
-
settingsArg.allowSessionTicket !== undefined ? settingsArg.allowSessionTicket : true,
|
|
55
|
-
maxConnectionsPerIP: settingsArg.maxConnectionsPerIP || 100,
|
|
56
|
-
connectionRateLimitPerMinute: settingsArg.connectionRateLimitPerMinute || 300,
|
|
57
|
-
keepAliveTreatment: settingsArg.keepAliveTreatment || 'extended',
|
|
58
|
-
keepAliveInactivityMultiplier: settingsArg.keepAliveInactivityMultiplier || 6,
|
|
59
|
-
extendedKeepAliveLifetime: settingsArg.extendedKeepAliveLifetime || 7 * 24 * 60 * 60 * 1000,
|
|
60
|
-
networkProxyPort: settingsArg.networkProxyPort || 8443,
|
|
61
|
-
acme: settingsArg.acme || {
|
|
62
|
-
enabled: false,
|
|
63
|
-
port: 80,
|
|
64
|
-
contactEmail: 'admin@example.com',
|
|
65
|
-
useProduction: false,
|
|
66
|
-
renewThresholdDays: 30,
|
|
67
|
-
autoRenew: true,
|
|
68
|
-
certificateStore: './certs',
|
|
69
|
-
skipConfiguredCerts: false,
|
|
70
|
-
},
|
|
71
|
-
};
|
|
72
|
-
|
|
73
|
-
// Initialize component managers
|
|
74
|
-
this.timeoutManager = new TimeoutManager(this.settings);
|
|
75
|
-
this.securityManager = new SecurityManager(this.settings);
|
|
76
|
-
this.connectionManager = new ConnectionManager(
|
|
77
|
-
this.settings,
|
|
78
|
-
this.securityManager,
|
|
79
|
-
this.timeoutManager
|
|
80
|
-
);
|
|
81
|
-
this.domainConfigManager = new DomainConfigManager(this.settings);
|
|
82
|
-
this.tlsManager = new TlsManager(this.settings);
|
|
83
|
-
this.networkProxyBridge = new NetworkProxyBridge(this.settings);
|
|
84
|
-
this.portRangeManager = new PortRangeManager(this.settings);
|
|
85
|
-
this.acmeManager = new AcmeManager(this.settings, this.networkProxyBridge);
|
|
86
|
-
|
|
87
|
-
// Initialize connection handler
|
|
88
|
-
this.connectionHandler = new ConnectionHandler(
|
|
89
|
-
this.settings,
|
|
90
|
-
this.connectionManager,
|
|
91
|
-
this.securityManager,
|
|
92
|
-
this.domainConfigManager,
|
|
93
|
-
this.tlsManager,
|
|
94
|
-
this.networkProxyBridge,
|
|
95
|
-
this.timeoutManager,
|
|
96
|
-
this.portRangeManager
|
|
97
|
-
);
|
|
98
|
-
}
|
|
99
|
-
|
|
100
|
-
/**
|
|
101
|
-
* The settings for the port proxy
|
|
102
|
-
*/
|
|
103
|
-
public settings: IPortProxySettings;
|
|
104
|
-
|
|
105
|
-
/**
|
|
106
|
-
* Start the proxy server
|
|
107
|
-
*/
|
|
108
|
-
public async start() {
|
|
109
|
-
// Don't start if already shutting down
|
|
110
|
-
if (this.isShuttingDown) {
|
|
111
|
-
console.log("Cannot start PortProxy while it's shutting down");
|
|
112
|
-
return;
|
|
113
|
-
}
|
|
114
|
-
|
|
115
|
-
// Initialize and start NetworkProxy if needed
|
|
116
|
-
if (
|
|
117
|
-
this.settings.useNetworkProxy &&
|
|
118
|
-
this.settings.useNetworkProxy.length > 0
|
|
119
|
-
) {
|
|
120
|
-
await this.networkProxyBridge.initialize();
|
|
121
|
-
await this.networkProxyBridge.start();
|
|
122
|
-
}
|
|
123
|
-
|
|
124
|
-
// Validate port configuration
|
|
125
|
-
const configWarnings = this.portRangeManager.validateConfiguration();
|
|
126
|
-
if (configWarnings.length > 0) {
|
|
127
|
-
console.log("Port configuration warnings:");
|
|
128
|
-
for (const warning of configWarnings) {
|
|
129
|
-
console.log(` - ${warning}`);
|
|
130
|
-
}
|
|
131
|
-
}
|
|
132
|
-
|
|
133
|
-
// Get listening ports from PortRangeManager
|
|
134
|
-
const listeningPorts = this.portRangeManager.getListeningPorts();
|
|
135
|
-
|
|
136
|
-
// Create servers for each port
|
|
137
|
-
for (const port of listeningPorts) {
|
|
138
|
-
const server = plugins.net.createServer((socket) => {
|
|
139
|
-
// Check if shutting down
|
|
140
|
-
if (this.isShuttingDown) {
|
|
141
|
-
socket.end();
|
|
142
|
-
socket.destroy();
|
|
143
|
-
return;
|
|
144
|
-
}
|
|
145
|
-
|
|
146
|
-
// Delegate to connection handler
|
|
147
|
-
this.connectionHandler.handleConnection(socket);
|
|
148
|
-
}).on('error', (err: Error) => {
|
|
149
|
-
console.log(`Server Error on port ${port}: ${err.message}`);
|
|
150
|
-
});
|
|
151
|
-
|
|
152
|
-
server.listen(port, () => {
|
|
153
|
-
const isNetworkProxyPort = this.settings.useNetworkProxy?.includes(port);
|
|
154
|
-
console.log(
|
|
155
|
-
`PortProxy -> OK: Now listening on port ${port}${
|
|
156
|
-
this.settings.sniEnabled && !isNetworkProxyPort ? ' (SNI passthrough enabled)' : ''
|
|
157
|
-
}${isNetworkProxyPort ? ' (NetworkProxy forwarding enabled)' : ''}`
|
|
158
|
-
);
|
|
159
|
-
});
|
|
160
|
-
|
|
161
|
-
this.netServers.push(server);
|
|
162
|
-
}
|
|
163
|
-
|
|
164
|
-
// Set up periodic connection logging and inactivity checks
|
|
165
|
-
this.connectionLogger = setInterval(() => {
|
|
166
|
-
// Immediately return if shutting down
|
|
167
|
-
if (this.isShuttingDown) return;
|
|
168
|
-
|
|
169
|
-
// Perform inactivity check
|
|
170
|
-
this.connectionManager.performInactivityCheck();
|
|
171
|
-
|
|
172
|
-
// Log connection statistics
|
|
173
|
-
const now = Date.now();
|
|
174
|
-
let maxIncoming = 0;
|
|
175
|
-
let maxOutgoing = 0;
|
|
176
|
-
let tlsConnections = 0;
|
|
177
|
-
let nonTlsConnections = 0;
|
|
178
|
-
let completedTlsHandshakes = 0;
|
|
179
|
-
let pendingTlsHandshakes = 0;
|
|
180
|
-
let keepAliveConnections = 0;
|
|
181
|
-
let networkProxyConnections = 0;
|
|
182
|
-
|
|
183
|
-
// Get connection records for analysis
|
|
184
|
-
const connectionRecords = this.connectionManager.getConnections();
|
|
185
|
-
|
|
186
|
-
// Analyze active connections
|
|
187
|
-
for (const record of connectionRecords.values()) {
|
|
188
|
-
// Track connection stats
|
|
189
|
-
if (record.isTLS) {
|
|
190
|
-
tlsConnections++;
|
|
191
|
-
if (record.tlsHandshakeComplete) {
|
|
192
|
-
completedTlsHandshakes++;
|
|
193
|
-
} else {
|
|
194
|
-
pendingTlsHandshakes++;
|
|
195
|
-
}
|
|
196
|
-
} else {
|
|
197
|
-
nonTlsConnections++;
|
|
198
|
-
}
|
|
199
|
-
|
|
200
|
-
if (record.hasKeepAlive) {
|
|
201
|
-
keepAliveConnections++;
|
|
202
|
-
}
|
|
203
|
-
|
|
204
|
-
if (record.usingNetworkProxy) {
|
|
205
|
-
networkProxyConnections++;
|
|
206
|
-
}
|
|
207
|
-
|
|
208
|
-
maxIncoming = Math.max(maxIncoming, now - record.incomingStartTime);
|
|
209
|
-
if (record.outgoingStartTime) {
|
|
210
|
-
maxOutgoing = Math.max(maxOutgoing, now - record.outgoingStartTime);
|
|
211
|
-
}
|
|
212
|
-
}
|
|
213
|
-
|
|
214
|
-
// Get termination stats
|
|
215
|
-
const terminationStats = this.connectionManager.getTerminationStats();
|
|
216
|
-
|
|
217
|
-
// Log detailed stats
|
|
218
|
-
console.log(
|
|
219
|
-
`Active connections: ${connectionRecords.size}. ` +
|
|
220
|
-
`Types: TLS=${tlsConnections} (Completed=${completedTlsHandshakes}, Pending=${pendingTlsHandshakes}), ` +
|
|
221
|
-
`Non-TLS=${nonTlsConnections}, KeepAlive=${keepAliveConnections}, NetworkProxy=${networkProxyConnections}. ` +
|
|
222
|
-
`Longest running: IN=${plugins.prettyMs(maxIncoming)}, OUT=${plugins.prettyMs(maxOutgoing)}. ` +
|
|
223
|
-
`Termination stats: ${JSON.stringify({
|
|
224
|
-
IN: terminationStats.incoming,
|
|
225
|
-
OUT: terminationStats.outgoing,
|
|
226
|
-
})}`
|
|
227
|
-
);
|
|
228
|
-
}, this.settings.inactivityCheckInterval || 60000);
|
|
229
|
-
|
|
230
|
-
// Make sure the interval doesn't keep the process alive
|
|
231
|
-
if (this.connectionLogger.unref) {
|
|
232
|
-
this.connectionLogger.unref();
|
|
233
|
-
}
|
|
234
|
-
}
|
|
235
|
-
|
|
236
|
-
/**
|
|
237
|
-
* Stop the proxy server
|
|
238
|
-
*/
|
|
239
|
-
public async stop() {
|
|
240
|
-
console.log('PortProxy shutting down...');
|
|
241
|
-
this.isShuttingDown = true;
|
|
242
|
-
|
|
243
|
-
// Stop accepting new connections
|
|
244
|
-
const closeServerPromises: Promise<void>[] = this.netServers.map(
|
|
245
|
-
(server) =>
|
|
246
|
-
new Promise<void>((resolve) => {
|
|
247
|
-
if (!server.listening) {
|
|
248
|
-
resolve();
|
|
249
|
-
return;
|
|
250
|
-
}
|
|
251
|
-
server.close((err) => {
|
|
252
|
-
if (err) {
|
|
253
|
-
console.log(`Error closing server: ${err.message}`);
|
|
254
|
-
}
|
|
255
|
-
resolve();
|
|
256
|
-
});
|
|
257
|
-
})
|
|
258
|
-
);
|
|
259
|
-
|
|
260
|
-
// Stop the connection logger
|
|
261
|
-
if (this.connectionLogger) {
|
|
262
|
-
clearInterval(this.connectionLogger);
|
|
263
|
-
this.connectionLogger = null;
|
|
264
|
-
}
|
|
265
|
-
|
|
266
|
-
// Wait for servers to close
|
|
267
|
-
await Promise.all(closeServerPromises);
|
|
268
|
-
console.log('All servers closed. Cleaning up active connections...');
|
|
269
|
-
|
|
270
|
-
// Clean up all active connections
|
|
271
|
-
this.connectionManager.clearConnections();
|
|
272
|
-
|
|
273
|
-
// Stop NetworkProxy
|
|
274
|
-
await this.networkProxyBridge.stop();
|
|
275
|
-
|
|
276
|
-
// Clear all servers
|
|
277
|
-
this.netServers = [];
|
|
278
|
-
|
|
279
|
-
console.log('PortProxy shutdown complete.');
|
|
280
|
-
}
|
|
281
|
-
|
|
282
|
-
/**
|
|
283
|
-
* Updates the domain configurations for the proxy
|
|
284
|
-
*/
|
|
285
|
-
public async updateDomainConfigs(newDomainConfigs: IDomainConfig[]): Promise<void> {
|
|
286
|
-
console.log(`Updating domain configurations (${newDomainConfigs.length} configs)`);
|
|
287
|
-
|
|
288
|
-
// Update domain configs in DomainConfigManager
|
|
289
|
-
this.domainConfigManager.updateDomainConfigs(newDomainConfigs);
|
|
290
|
-
|
|
291
|
-
// If NetworkProxy is initialized, resync the configurations
|
|
292
|
-
if (this.networkProxyBridge.getNetworkProxy()) {
|
|
293
|
-
await this.networkProxyBridge.syncDomainConfigsToNetworkProxy();
|
|
294
|
-
}
|
|
295
|
-
}
|
|
296
|
-
|
|
297
|
-
/**
|
|
298
|
-
* Updates the ACME certificate settings
|
|
299
|
-
*/
|
|
300
|
-
public async updateAcmeSettings(acmeSettings: IPortProxySettings['acme']): Promise<void> {
|
|
301
|
-
console.log('Updating ACME certificate settings');
|
|
302
|
-
|
|
303
|
-
// Delegate to AcmeManager
|
|
304
|
-
await this.acmeManager.updateAcmeSettings(acmeSettings);
|
|
305
|
-
}
|
|
306
|
-
|
|
307
|
-
/**
|
|
308
|
-
* Requests a certificate for a specific domain
|
|
309
|
-
*/
|
|
310
|
-
public async requestCertificate(domain: string): Promise<boolean> {
|
|
311
|
-
// Delegate to AcmeManager
|
|
312
|
-
return this.acmeManager.requestCertificate(domain);
|
|
313
|
-
}
|
|
314
|
-
|
|
315
|
-
/**
|
|
316
|
-
* Get statistics about current connections
|
|
317
|
-
*/
|
|
318
|
-
public getStatistics(): any {
|
|
319
|
-
const connectionRecords = this.connectionManager.getConnections();
|
|
320
|
-
const terminationStats = this.connectionManager.getTerminationStats();
|
|
321
|
-
|
|
322
|
-
let tlsConnections = 0;
|
|
323
|
-
let nonTlsConnections = 0;
|
|
324
|
-
let keepAliveConnections = 0;
|
|
325
|
-
let networkProxyConnections = 0;
|
|
326
|
-
|
|
327
|
-
// Analyze active connections
|
|
328
|
-
for (const record of connectionRecords.values()) {
|
|
329
|
-
if (record.isTLS) tlsConnections++;
|
|
330
|
-
else nonTlsConnections++;
|
|
331
|
-
if (record.hasKeepAlive) keepAliveConnections++;
|
|
332
|
-
if (record.usingNetworkProxy) networkProxyConnections++;
|
|
333
|
-
}
|
|
334
|
-
|
|
335
|
-
return {
|
|
336
|
-
activeConnections: connectionRecords.size,
|
|
337
|
-
tlsConnections,
|
|
338
|
-
nonTlsConnections,
|
|
339
|
-
keepAliveConnections,
|
|
340
|
-
networkProxyConnections,
|
|
341
|
-
terminationStats
|
|
342
|
-
};
|
|
343
|
-
}
|
|
344
|
-
}
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|