-
Notifications
You must be signed in to change notification settings - Fork 6
Expand file tree
/
Copy pathsocket-relays.js
More file actions
135 lines (118 loc) · 4.03 KB
/
Copy pathsocket-relays.js
File metadata and controls
135 lines (118 loc) · 4.03 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
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
import createDebug from 'debug';
import { sockets } from './socket-map.js';
const debug = createDebug('hsync:relay');
const debugError = createDebug('hsync:error');
debugError.color = 1;
let net;
export function setNet(netImpl) {
net = netImpl;
}
export function initRelays(hsyncClient) {
const cachedRelays = {};
function getSocketRelays() {
const hKeys = Object.keys(cachedRelays);
debug('getSocketListeners', hKeys);
const retVal = hKeys.map((hk) => {
const l = cachedRelays[hk];
return {
port: l.port,
targetHost: l.targetHost,
targetPort: l.targetPort,
whitelist: l.whitelist || '',
blacklist: l.blacklist || '',
hostName: l.targetHost,
hasPassword: !!l.password,
};
});
return retVal;
}
function connectSocket(peer, { port, socketId, hostName, password }) {
debug('connectSocket', port, socketId, hostName);
peer.notifications.oncloseRelaySocket((peer, { socketId }) => {
debug('closeRelaySocket', socketId);
if (sockets[socketId]) {
sockets[socketId].end();
delete sockets[socketId];
return 'closeRelaySocket ok';
}
return `closeRelaySocket no matching socket for ${socketId}`;
});
const relay = cachedRelays['p' + port];
debug('connect relay', port, socketId, peer.hostName);
if (!relay) {
throw new Error('no relay found for port: ' + port);
}
// Check password if relay requires one
if (relay.password) {
if (!password) {
throw new Error('password required for relay on port: ' + port);
}
if (relay.password !== password) {
throw new Error('invalid password for relay on port: ' + port);
}
debug('password verified for relay', port);
}
// TODO: check white and black lists on peer
// const relayDataTopic = `msg/${hostName}/${hsyncClient.myHostName}/relayData/${socketId}`;
return new Promise((resolve, reject) => {
const socket = new net.Socket();
socket.socketId = socketId;
sockets[socketId] = socket;
socket.connect(relay.targetPort, relay.targetHost, () => {
debug(`CONNECTED TO LOCAL SERVER`, socket.socketId, socket.hostName, port);
resolve({ socketId, targetHost: relay.targetHost, targetPort: relay.targetPort });
});
socket.on('data', async (data) => {
debug(`data in ${socket.socketId}`, relay.targetPort, relay.targetHost, data.length);
// TODO: queue data if peer is not ready
if (peer.packAndSend) {
debug('sending relay data via rtc', socket.socketId, data.length);
peer.packAndSend(`socketData/${socket.socketId}`, Buffer.from(data));
return;
}
});
socket.on('close', async () => {
debug(`LOCAL CONNECTION CLOSED`, socket.socketId);
if (sockets[socket.socketId]) {
try {
await peer.notifiers.closeListenerSocket({ socketId });
} catch (e) {
debug('error closing socket', e);
}
delete sockets[socket.socketId];
}
});
socket.on('error', (e) => {
debugError(`LOCAL CONNECTION ERROR`, socket.socketId, e);
delete sockets[socket.socketId];
reject(e);
});
});
}
function addSocketRelay({ whitelist, blacklist, port, targetPort, targetHost, password }) {
targetPort = targetPort || port;
targetHost = targetHost || 'localhost';
debug('creating relay', whitelist, blacklist, port, targetPort, targetHost, password ? '(password protected)' : '');
const newRelay = {
whitelist,
blacklist,
port,
targetPort,
targetHost,
hostName: targetHost,
password,
};
cachedRelays['p' + port] = newRelay;
return newRelay;
}
hsyncClient.cachedRelays = cachedRelays;
hsyncClient.addSocketRelay = addSocketRelay;
hsyncClient.getSocketRelays = getSocketRelays;
hsyncClient.connectSocket = connectSocket;
return {
// receiveListenerData,
getSocketRelays,
connectSocket,
addSocketRelay,
};
}