@push.rocks/smartproxy 19.6.2 → 19.6.7
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/proxies/smart-proxy/connection-manager.d.ts +4 -7
- package/dist_ts/proxies/smart-proxy/connection-manager.js +22 -22
- package/dist_ts/proxies/smart-proxy/http-proxy-bridge.d.ts +4 -3
- package/dist_ts/proxies/smart-proxy/http-proxy-bridge.js +9 -9
- package/dist_ts/proxies/smart-proxy/metrics-collector.d.ts +68 -56
- package/dist_ts/proxies/smart-proxy/metrics-collector.js +226 -176
- package/dist_ts/proxies/smart-proxy/models/interfaces.d.ts +5 -0
- package/dist_ts/proxies/smart-proxy/models/metrics-types.d.ts +94 -48
- package/dist_ts/proxies/smart-proxy/nftables-manager.d.ts +4 -4
- package/dist_ts/proxies/smart-proxy/nftables-manager.js +6 -6
- package/dist_ts/proxies/smart-proxy/port-manager.d.ts +4 -7
- package/dist_ts/proxies/smart-proxy/port-manager.js +6 -9
- package/dist_ts/proxies/smart-proxy/route-connection-handler.d.ts +4 -15
- package/dist_ts/proxies/smart-proxy/route-connection-handler.js +128 -128
- package/dist_ts/proxies/smart-proxy/security-manager.d.ts +3 -3
- package/dist_ts/proxies/smart-proxy/security-manager.js +9 -9
- package/dist_ts/proxies/smart-proxy/smart-proxy.d.ts +20 -13
- package/dist_ts/proxies/smart-proxy/smart-proxy.js +16 -13
- package/dist_ts/proxies/smart-proxy/throughput-tracker.d.ts +36 -0
- package/dist_ts/proxies/smart-proxy/throughput-tracker.js +117 -0
- package/dist_ts/proxies/smart-proxy/timeout-manager.d.ts +4 -3
- package/dist_ts/proxies/smart-proxy/timeout-manager.js +16 -16
- package/dist_ts/proxies/smart-proxy/tls-manager.d.ts +3 -3
- package/dist_ts/proxies/smart-proxy/tls-manager.js +12 -12
- package/package.json +8 -17
- package/readme.hints.md +0 -897
- package/readme.md +960 -54
- package/readme.plan.md +301 -562
- package/ts/proxies/smart-proxy/connection-manager.ts +23 -21
- package/ts/proxies/smart-proxy/http-proxy-bridge.ts +9 -8
- package/ts/proxies/smart-proxy/metrics-collector.ts +277 -189
- package/ts/proxies/smart-proxy/models/interfaces.ts +7 -0
- package/ts/proxies/smart-proxy/models/metrics-types.ts +93 -41
- package/ts/proxies/smart-proxy/nftables-manager.ts +5 -5
- package/ts/proxies/smart-proxy/port-manager.ts +6 -14
- package/ts/proxies/smart-proxy/route-connection-handler.ts +136 -136
- package/ts/proxies/smart-proxy/security-manager.ts +8 -8
- package/ts/proxies/smart-proxy/smart-proxy.ts +26 -35
- package/ts/proxies/smart-proxy/throughput-tracker.ts +144 -0
- package/ts/proxies/smart-proxy/timeout-manager.ts +16 -15
- package/ts/proxies/smart-proxy/tls-manager.ts +11 -11
- package/readme.connections.md +0 -724
- package/readme.delete.md +0 -187
- package/readme.memory-leaks-fixed.md +0 -45
- package/readme.metrics.md +0 -591
- package/readme.monitoring.md +0 -202
- package/readme.proxy-chain-summary.md +0 -112
- package/readme.proxy-protocol-example.md +0 -462
- package/readme.proxy-protocol.md +0 -415
- package/readme.routing.md +0 -341
- package/readme.websocket-keepalive-config.md +0 -140
- package/readme.websocket-keepalive-fix.md +0 -63
package/readme.monitoring.md
DELETED
|
@@ -1,202 +0,0 @@
|
|
|
1
|
-
# Production Connection Monitoring
|
|
2
|
-
|
|
3
|
-
This document explains how to use the ProductionConnectionMonitor to diagnose connection accumulation issues in real-time.
|
|
4
|
-
|
|
5
|
-
## Quick Start
|
|
6
|
-
|
|
7
|
-
```typescript
|
|
8
|
-
import ProductionConnectionMonitor from './.nogit/debug/production-connection-monitor.js';
|
|
9
|
-
|
|
10
|
-
// After starting your proxy
|
|
11
|
-
const monitor = new ProductionConnectionMonitor(proxy);
|
|
12
|
-
monitor.start(5000); // Check every 5 seconds
|
|
13
|
-
|
|
14
|
-
// The monitor will automatically capture diagnostics when:
|
|
15
|
-
// - Connections exceed 50 (default threshold)
|
|
16
|
-
// - Sudden spike of 20+ connections occurs
|
|
17
|
-
// - You manually call monitor.forceCaptureNow()
|
|
18
|
-
```
|
|
19
|
-
|
|
20
|
-
## What Gets Captured
|
|
21
|
-
|
|
22
|
-
When accumulation is detected, the monitor saves a JSON file with:
|
|
23
|
-
|
|
24
|
-
### Connection Details
|
|
25
|
-
- Socket states (destroyed, readable, writable, readyState)
|
|
26
|
-
- Connection age and activity timestamps
|
|
27
|
-
- Data transfer statistics (bytes sent/received)
|
|
28
|
-
- Target host and port information
|
|
29
|
-
- Keep-alive status
|
|
30
|
-
- Event listener counts
|
|
31
|
-
|
|
32
|
-
### System State
|
|
33
|
-
- Memory usage
|
|
34
|
-
- Event loop lag
|
|
35
|
-
- Connection count trends
|
|
36
|
-
- Termination statistics
|
|
37
|
-
|
|
38
|
-
## Reading Diagnostic Files
|
|
39
|
-
|
|
40
|
-
Files are saved to `.nogit/connection-diagnostics/` with names like:
|
|
41
|
-
```
|
|
42
|
-
accumulation_2025-06-07T20-20-43-733Z_force_capture.json
|
|
43
|
-
```
|
|
44
|
-
|
|
45
|
-
### Key Fields to Check
|
|
46
|
-
|
|
47
|
-
1. **Socket States**
|
|
48
|
-
```json
|
|
49
|
-
"incomingState": {
|
|
50
|
-
"destroyed": false,
|
|
51
|
-
"readable": true,
|
|
52
|
-
"writable": true,
|
|
53
|
-
"readyState": "open"
|
|
54
|
-
}
|
|
55
|
-
```
|
|
56
|
-
- Both destroyed = zombie connection
|
|
57
|
-
- One destroyed = half-zombie
|
|
58
|
-
- Both alive but old = potential stuck connection
|
|
59
|
-
|
|
60
|
-
2. **Data Transfer**
|
|
61
|
-
```json
|
|
62
|
-
"bytesReceived": 36,
|
|
63
|
-
"bytesSent": 0,
|
|
64
|
-
"timeSinceLastActivity": 60000
|
|
65
|
-
```
|
|
66
|
-
- No bytes sent back = stuck connection
|
|
67
|
-
- High bytes but old = slow backend
|
|
68
|
-
- No activity = idle connection
|
|
69
|
-
|
|
70
|
-
3. **Connection Flags**
|
|
71
|
-
```json
|
|
72
|
-
"hasReceivedInitialData": false,
|
|
73
|
-
"hasKeepAlive": true,
|
|
74
|
-
"connectionClosed": false
|
|
75
|
-
```
|
|
76
|
-
- hasReceivedInitialData=false on non-TLS = immediate routing
|
|
77
|
-
- hasKeepAlive=true = extended timeout applies
|
|
78
|
-
- connectionClosed=false = still tracked
|
|
79
|
-
|
|
80
|
-
## Common Patterns
|
|
81
|
-
|
|
82
|
-
### 1. Hanging Backend Pattern
|
|
83
|
-
```json
|
|
84
|
-
{
|
|
85
|
-
"bytesReceived": 36,
|
|
86
|
-
"bytesSent": 0,
|
|
87
|
-
"age": 120000,
|
|
88
|
-
"targetHost": "backend.example.com",
|
|
89
|
-
"incomingState": { "destroyed": false },
|
|
90
|
-
"outgoingState": { "destroyed": false }
|
|
91
|
-
}
|
|
92
|
-
```
|
|
93
|
-
**Fix**: The stuck connection detection (60s timeout) should clean these up.
|
|
94
|
-
|
|
95
|
-
### 2. Zombie Connection Pattern
|
|
96
|
-
```json
|
|
97
|
-
{
|
|
98
|
-
"incomingState": { "destroyed": true },
|
|
99
|
-
"outgoingState": { "destroyed": true },
|
|
100
|
-
"connectionClosed": false
|
|
101
|
-
}
|
|
102
|
-
```
|
|
103
|
-
**Fix**: The zombie detection should clean these up within 30s.
|
|
104
|
-
|
|
105
|
-
### 3. Event Listener Leak Pattern
|
|
106
|
-
```json
|
|
107
|
-
{
|
|
108
|
-
"incomingListeners": {
|
|
109
|
-
"data": 15,
|
|
110
|
-
"error": 20,
|
|
111
|
-
"close": 18
|
|
112
|
-
}
|
|
113
|
-
}
|
|
114
|
-
```
|
|
115
|
-
**Issue**: Event listeners accumulating, potential memory leak.
|
|
116
|
-
|
|
117
|
-
### 4. No Outgoing Socket Pattern
|
|
118
|
-
```json
|
|
119
|
-
{
|
|
120
|
-
"outgoingState": { "exists": false },
|
|
121
|
-
"connectionClosed": false,
|
|
122
|
-
"age": 5000
|
|
123
|
-
}
|
|
124
|
-
```
|
|
125
|
-
**Issue**: Connection setup failed but cleanup didn't trigger.
|
|
126
|
-
|
|
127
|
-
## Forcing Diagnostic Capture
|
|
128
|
-
|
|
129
|
-
To capture current state immediately:
|
|
130
|
-
```typescript
|
|
131
|
-
monitor.forceCaptureNow();
|
|
132
|
-
```
|
|
133
|
-
|
|
134
|
-
This is useful when you notice accumulation starting.
|
|
135
|
-
|
|
136
|
-
## Automated Analysis
|
|
137
|
-
|
|
138
|
-
The monitor automatically analyzes patterns and logs:
|
|
139
|
-
- Zombie/half-zombie counts
|
|
140
|
-
- Stuck connection counts
|
|
141
|
-
- Old connection counts
|
|
142
|
-
- Memory usage
|
|
143
|
-
- Recommendations
|
|
144
|
-
|
|
145
|
-
## Integration Example
|
|
146
|
-
|
|
147
|
-
```typescript
|
|
148
|
-
// In your proxy startup script
|
|
149
|
-
import { SmartProxy } from '@push.rocks/smartproxy';
|
|
150
|
-
import ProductionConnectionMonitor from './production-connection-monitor.js';
|
|
151
|
-
|
|
152
|
-
async function startProxyWithMonitoring() {
|
|
153
|
-
const proxy = new SmartProxy({
|
|
154
|
-
// your config
|
|
155
|
-
});
|
|
156
|
-
|
|
157
|
-
await proxy.start();
|
|
158
|
-
|
|
159
|
-
// Start monitoring
|
|
160
|
-
const monitor = new ProductionConnectionMonitor(proxy);
|
|
161
|
-
monitor.start(5000);
|
|
162
|
-
|
|
163
|
-
// Optional: Capture on specific events
|
|
164
|
-
process.on('SIGUSR1', () => {
|
|
165
|
-
console.log('Manual diagnostic capture triggered');
|
|
166
|
-
monitor.forceCaptureNow();
|
|
167
|
-
});
|
|
168
|
-
|
|
169
|
-
// Graceful shutdown
|
|
170
|
-
process.on('SIGTERM', async () => {
|
|
171
|
-
monitor.stop();
|
|
172
|
-
await proxy.stop();
|
|
173
|
-
process.exit(0);
|
|
174
|
-
});
|
|
175
|
-
}
|
|
176
|
-
```
|
|
177
|
-
|
|
178
|
-
## Troubleshooting
|
|
179
|
-
|
|
180
|
-
### Monitor Not Detecting Accumulation
|
|
181
|
-
- Check threshold settings (default: 50 connections)
|
|
182
|
-
- Reduce check interval for faster detection
|
|
183
|
-
- Use forceCaptureNow() to capture current state
|
|
184
|
-
|
|
185
|
-
### Too Many False Positives
|
|
186
|
-
- Increase accumulation threshold
|
|
187
|
-
- Increase spike threshold
|
|
188
|
-
- Adjust check interval
|
|
189
|
-
|
|
190
|
-
### Missing Diagnostic Data
|
|
191
|
-
- Ensure output directory exists and is writable
|
|
192
|
-
- Check disk space
|
|
193
|
-
- Verify process has write permissions
|
|
194
|
-
|
|
195
|
-
## Next Steps
|
|
196
|
-
|
|
197
|
-
1. Deploy the monitor to production
|
|
198
|
-
2. Wait for accumulation to occur
|
|
199
|
-
3. Share diagnostic files for analysis
|
|
200
|
-
4. Apply targeted fixes based on patterns found
|
|
201
|
-
|
|
202
|
-
The diagnostic data will reveal the exact state of connections when accumulation occurs, enabling precise fixes for your specific scenario.
|
|
@@ -1,112 +0,0 @@
|
|
|
1
|
-
# SmartProxy: Proxy Protocol and Proxy Chaining Summary
|
|
2
|
-
|
|
3
|
-
## Quick Summary
|
|
4
|
-
|
|
5
|
-
SmartProxy supports proxy chaining through the **WrappedSocket** infrastructure, which is designed to handle PROXY protocol for preserving real client IP addresses across multiple proxy layers. While the infrastructure is in place (v19.5.19+), the actual PROXY protocol parsing is not yet implemented.
|
|
6
|
-
|
|
7
|
-
## Current State
|
|
8
|
-
|
|
9
|
-
### ✅ What's Implemented
|
|
10
|
-
- **WrappedSocket class** - Foundation for proxy protocol support
|
|
11
|
-
- **Proxy IP configuration** - `proxyIPs` setting to define trusted proxies
|
|
12
|
-
- **Socket wrapping** - All incoming connections wrapped automatically
|
|
13
|
-
- **Connection tracking** - Real client IP tracking in connection records
|
|
14
|
-
- **Test infrastructure** - Tests for proxy chaining scenarios
|
|
15
|
-
|
|
16
|
-
### ❌ What's Missing
|
|
17
|
-
- **PROXY protocol v1 parsing** - Header parsing not implemented
|
|
18
|
-
- **PROXY protocol v2 support** - Binary format not supported
|
|
19
|
-
- **Automatic header generation** - Must be manually implemented
|
|
20
|
-
- **Production testing** - No HAProxy/AWS ELB compatibility tests
|
|
21
|
-
|
|
22
|
-
## Key Files
|
|
23
|
-
|
|
24
|
-
### Core Implementation
|
|
25
|
-
- `ts/core/models/wrapped-socket.ts` - WrappedSocket class
|
|
26
|
-
- `ts/core/models/socket-types.ts` - Helper functions
|
|
27
|
-
- `ts/proxies/smart-proxy/route-connection-handler.ts` - Connection handling
|
|
28
|
-
- `ts/proxies/smart-proxy/models/interfaces.ts` - Configuration interfaces
|
|
29
|
-
|
|
30
|
-
### Tests
|
|
31
|
-
- `test/test.wrapped-socket.ts` - WrappedSocket unit tests
|
|
32
|
-
- `test/test.proxy-chain-simple.node.ts` - Basic proxy chain test
|
|
33
|
-
- `test/test.proxy-chaining-accumulation.node.ts` - Connection leak tests
|
|
34
|
-
|
|
35
|
-
### Documentation
|
|
36
|
-
- `readme.proxy-protocol.md` - Detailed implementation guide
|
|
37
|
-
- `readme.proxy-protocol-example.md` - Code examples and future implementation
|
|
38
|
-
- `readme.hints.md` - Project overview with WrappedSocket notes
|
|
39
|
-
|
|
40
|
-
## Quick Configuration Example
|
|
41
|
-
|
|
42
|
-
```typescript
|
|
43
|
-
// Outer proxy (internet-facing)
|
|
44
|
-
const outerProxy = new SmartProxy({
|
|
45
|
-
sendProxyProtocol: true, // Will send PROXY protocol (when implemented)
|
|
46
|
-
routes: [{
|
|
47
|
-
name: 'forward-to-inner',
|
|
48
|
-
match: { ports: 443 },
|
|
49
|
-
action: {
|
|
50
|
-
type: 'forward',
|
|
51
|
-
target: { host: 'inner-proxy.local', port: 443 },
|
|
52
|
-
tls: { mode: 'passthrough' }
|
|
53
|
-
}
|
|
54
|
-
}]
|
|
55
|
-
});
|
|
56
|
-
|
|
57
|
-
// Inner proxy (backend-facing)
|
|
58
|
-
const innerProxy = new SmartProxy({
|
|
59
|
-
proxyIPs: ['outer-proxy.local'], // Trust the outer proxy
|
|
60
|
-
acceptProxyProtocol: true, // Will parse PROXY protocol (when implemented)
|
|
61
|
-
routes: [{
|
|
62
|
-
name: 'forward-to-backend',
|
|
63
|
-
match: { ports: 443, domains: 'api.example.com' },
|
|
64
|
-
action: {
|
|
65
|
-
type: 'forward',
|
|
66
|
-
target: { host: 'backend.local', port: 8080 },
|
|
67
|
-
tls: { mode: 'terminate' }
|
|
68
|
-
}
|
|
69
|
-
}]
|
|
70
|
-
});
|
|
71
|
-
```
|
|
72
|
-
|
|
73
|
-
## How It Works (Conceptually)
|
|
74
|
-
|
|
75
|
-
1. **Client** connects to **Outer Proxy**
|
|
76
|
-
2. **Outer Proxy** wraps socket in WrappedSocket
|
|
77
|
-
3. **Outer Proxy** forwards to **Inner Proxy**
|
|
78
|
-
- Would prepend: `PROXY TCP4 <client-ip> <proxy-ip> <client-port> <proxy-port>\r\n`
|
|
79
|
-
4. **Inner Proxy** receives connection from trusted proxy
|
|
80
|
-
5. **Inner Proxy** would parse PROXY protocol header
|
|
81
|
-
6. **Inner Proxy** updates WrappedSocket with real client IP
|
|
82
|
-
7. **Backend** receives connection with preserved client information
|
|
83
|
-
|
|
84
|
-
## Important Notes
|
|
85
|
-
|
|
86
|
-
### Connection Cleanup
|
|
87
|
-
The fix for proxy chain connection accumulation (v19.5.14+) changed the default socket behavior:
|
|
88
|
-
- **Before**: Half-open connections supported by default (caused accumulation)
|
|
89
|
-
- **After**: Both sockets close when one closes (prevents accumulation)
|
|
90
|
-
- **Override**: Set `enableHalfOpen: true` if half-open needed
|
|
91
|
-
|
|
92
|
-
### Security
|
|
93
|
-
- Only parse PROXY protocol from IPs listed in `proxyIPs`
|
|
94
|
-
- Never use `0.0.0.0/0` as a trusted proxy range
|
|
95
|
-
- Each proxy in chain must explicitly trust the previous proxy
|
|
96
|
-
|
|
97
|
-
### Testing
|
|
98
|
-
Use the test files as reference implementations:
|
|
99
|
-
- Simple chains: `test.proxy-chain-simple.node.ts`
|
|
100
|
-
- Connection leaks: `test.proxy-chaining-accumulation.node.ts`
|
|
101
|
-
- Rapid reconnects: `test.rapid-retry-cleanup.node.ts`
|
|
102
|
-
|
|
103
|
-
## Next Steps
|
|
104
|
-
|
|
105
|
-
To fully implement PROXY protocol support:
|
|
106
|
-
1. Implement the parser in `ProxyProtocolParser` class
|
|
107
|
-
2. Integrate parser into `handleConnection` method
|
|
108
|
-
3. Add header generation to `setupDirectConnection`
|
|
109
|
-
4. Test with real proxies (HAProxy, nginx, AWS ELB)
|
|
110
|
-
5. Add PROXY protocol v2 support for better performance
|
|
111
|
-
|
|
112
|
-
See `readme.proxy-protocol-example.md` for detailed implementation examples.
|