Skip to content

Commit d1e59f8

Browse files
committed
refactor(port-forwarding): split handleDownstreamConnection into smaller parts
1 parent 552e290 commit d1e59f8

1 file changed

Lines changed: 25 additions & 5 deletions

File tree

src/lib/port-forwarding/device-port-forwarder.ts

Lines changed: 25 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -83,6 +83,21 @@ export class DevicePortForwarder extends EventEmitter {
8383
this.activeSockets.add(localSocket);
8484
this.emit('clientConnected', localSocket);
8585

86+
const upstreamSocket = await this.openUpstreamForClient(localSocket);
87+
if (!upstreamSocket) {
88+
return;
89+
}
90+
91+
this.activeSockets.add(upstreamSocket);
92+
this.emit('upstreamConnected', upstreamSocket);
93+
this.bridgeSockets(localSocket, upstreamSocket);
94+
}
95+
96+
/**
97+
* Opens the upstream socket while watching for the client going away.
98+
* Returns undefined after cleanup if the connect fails or the client disconnected meanwhile.
99+
*/
100+
private async openUpstreamForClient(localSocket: Socket): Promise<Socket | undefined> {
86101
let clientError: Error | undefined;
87102
let clientClosed = false;
88103
const onEarlyError = (err: Error): void => {
@@ -94,15 +109,15 @@ export class DevicePortForwarder extends EventEmitter {
94109
localSocket.once('error', onEarlyError);
95110
localSocket.once('close', onEarlyClose);
96111

97-
let upstreamSocket: Socket | undefined;
112+
let upstreamSocket: Socket;
98113
try {
99114
upstreamSocket = await this.openUpstreamSocket();
100115
} catch (err) {
101116
this.activeSockets.delete(localSocket);
102117
this.emit('upstreamConnectError', err);
103118
this.emit('clientDisconnected', localSocket, err);
104119
localSocket.destroy();
105-
return;
120+
return undefined;
106121
} finally {
107122
localSocket.off('error', onEarlyError);
108123
localSocket.off('close', onEarlyClose);
@@ -113,12 +128,16 @@ export class DevicePortForwarder extends EventEmitter {
113128
this.emit('clientDisconnected', localSocket, clientError);
114129
localSocket.destroy();
115130
upstreamSocket.destroy();
116-
return;
131+
return undefined;
117132
}
118133

119-
this.activeSockets.add(upstreamSocket);
120-
this.emit('upstreamConnected', upstreamSocket);
134+
return upstreamSocket;
135+
}
121136

137+
/**
138+
* Pipes the two sockets together and tears both down when either side closes or errors.
139+
*/
140+
private bridgeSockets(localSocket: Socket, upstreamSocket: Socket): void {
122141
let cleanedUp = false;
123142
const teardown = (): void => {
124143
this.activeSockets.delete(localSocket);
@@ -135,6 +154,7 @@ export class DevicePortForwarder extends EventEmitter {
135154
upstreamSocket.destroy();
136155
};
137156

157+
let clientError: Error | undefined;
138158
localSocket.once('error', (err) => {
139159
clientError = err;
140160
teardown();

0 commit comments

Comments
 (0)