-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathRouter.js
More file actions
102 lines (72 loc) · 2.53 KB
/
Router.js
File metadata and controls
102 lines (72 loc) · 2.53 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
import tls from 'tls';
import net from 'net';
import EventEmitter from 'events';
import debug from 'debug';
const log = debug('fwdizer:Router');
export default class Router extends EventEmitter {
constructor({
externalPort,
internalPort = 0,
tlsConfig
}) {
super();
log(`Creating for external port ${externalPort} (internal port - ${
internalPort
})`);
const externalSocketQueue = [];
const externalServer = net.createServer();
externalServer.listen(externalPort);
externalServer.on('error', (error) => {
log(`External Server Error: ${error.toString()}`);
this.selfDestruct();
});
externalServer.on('close', () => {
log('External Server Closed');
this.selfDestruct();
});
externalServer.on('connection', (socket) => {
log('New Client on External Server - emit newConnection');
externalSocketQueue.push(socket);
this.emit('newConnection');
});
const internalServer = tls.createServer({
...tlsConfig,
requestCert: true,
rejectUnauthorized: true
});
internalServer.listen(internalPort, () => {
this.internalPort = internalServer.address().port;
log(`Duplex ready - external ${externalPort} internal ${
this.internalPort
} - emitting ready.`);
this.emit('ready', {
internalPort: this.internalPort
});
});
internalServer.on('error', (error) => {
log(`Internal Server Error: ${error.toString()}`);
this.selfDestruct();
});
internalServer.on('close', () => {
log('Internal Server Closed');
this.selfDestruct();
});
internalServer.on('secureConnection', (socket) => {
log('Received secure connection on internal server...');
if (externalSocketQueue.length === 0) {
log('...but no sockets are in the queue.');
return socket.end();
}
log('...Forwarding a pending socket.');
const queuedExternalSocket = externalSocketQueue.shift();
queuedExternalSocket.pipe(socket);
socket.pipe(queuedExternalSocket);
});
}
selfDestruct() {
log('Self-Destructing');
this.externalServer.close();
this.internalServer.close();
this.emit('dead');
}
}