libhyperproxy/dist/proxies/multiSocket.js

250 lines
8.2 KiB
JavaScript
Raw Normal View History

2023-04-15 22:40:09 +00:00
"use strict";
var __importDefault = (this && this.__importDefault) || function (mod) {
return (mod && mod.__esModule) ? mod : { "default": mod };
};
Object.defineProperty(exports, "__esModule", { value: true });
const proxy_js_1 = __importDefault(require("../proxy.js"));
const tcpSocket_js_1 = __importDefault(require("./multiSocket/tcpSocket.js"));
const compact_encoding_1 = require("compact-encoding");
const serialize_error_1 = require("serialize-error");
const b4a_1 = __importDefault(require("b4a"));
const util_js_1 = require("../util.js");
const dummySocket_js_1 = __importDefault(require("./multiSocket/dummySocket.js"));
2023-04-16 02:38:07 +00:00
const peer_js_1 = __importDefault(require("./multiSocket/peer.js"));
2023-04-15 22:40:09 +00:00
const socketEncoding = {
preencode(state, m) {
compact_encoding_1.uint.preencode(state, m.id);
compact_encoding_1.uint.preencode(state, m.remoteId);
},
encode(state, m) {
compact_encoding_1.uint.encode(state, m.id);
compact_encoding_1.uint.encode(state, m.remoteId);
},
decode(state, m) {
return {
remoteId: compact_encoding_1.uint.decode(state, m),
id: compact_encoding_1.uint.decode(state, m),
};
},
};
const writeSocketEncoding = {
preencode(state, m) {
socketEncoding.preencode(state, m);
compact_encoding_1.raw.preencode(state, m.data);
},
encode(state, m) {
socketEncoding.encode(state, m);
compact_encoding_1.raw.encode(state, m.data);
},
decode(state, m) {
const socket = socketEncoding.decode(state, m);
return {
...socket,
data: compact_encoding_1.raw.decode(state, m),
};
},
};
const errorSocketEncoding = {
2023-04-16 18:29:26 +00:00
preencode(state, m) {
socketEncoding.preencode(state, m);
compact_encoding_1.json.preencode(state, (0, serialize_error_1.serializeError)(m.err));
},
encode(state, m) {
socketEncoding.encode(state, m);
compact_encoding_1.json.encode(state, (0, serialize_error_1.serializeError)(m.err));
},
2023-04-15 22:40:09 +00:00
decode(state, m) {
const socket = socketEncoding.decode(state, m);
return {
...socket,
err: (0, serialize_error_1.deserializeError)(compact_encoding_1.json.decode(state, m)),
};
},
};
const nextSocketId = (0, util_js_1.idFactory)(1);
class MultiSocketProxy extends proxy_js_1.default {
2023-04-16 07:42:14 +00:00
async handlePeer({ peer, muxer, ...options }) {
const conn = new peer_js_1.default({
2023-04-16 02:38:07 +00:00
...this.socketOptions,
proxy: this,
peer,
muxer,
...options,
2023-04-16 07:42:14 +00:00
});
await conn.init();
this.emit("peer", conn);
2023-04-16 02:38:07 +00:00
}
2023-04-15 22:40:09 +00:00
socketClass;
_peers = new Map();
2023-04-16 09:48:53 +00:00
_nextPeer;
2023-04-15 22:40:09 +00:00
_server = false;
_allowedPorts = [];
constructor(options) {
2023-04-16 02:17:57 +00:00
super(options);
2023-04-15 22:40:09 +00:00
if (options.socketClass) {
this.socketClass = options.socketClass;
}
else {
if (options.server) {
this.socketClass = tcpSocket_js_1.default;
}
else {
this.socketClass = dummySocket_js_1.default;
}
}
if (options.server) {
this._server = true;
}
2023-04-16 09:48:53 +00:00
this._nextPeer = (0, util_js_1.roundRobinFactory)(this._peers);
2023-04-15 22:40:09 +00:00
}
_socketMap = new Map();
get socketMap() {
return this._socketMap;
}
_sockets = new Map();
get sockets() {
return this._sockets;
}
2023-04-16 09:24:00 +00:00
async handleNewPeerChannel(peer) {
this.update(await this._getPublicKey(peer), {
peer,
});
await this._registerOpenSocketMessage(peer);
await this._registerWriteSocketMessage(peer);
await this._registerCloseSocketMessage(peer);
await this._registerTimeoutSocketMessage(peer);
await this._registerErrorSocketMessage(peer);
2023-04-15 22:40:09 +00:00
}
async handleClosePeer(peer) {
for (const item of this._sockets) {
if (item[1].peer.peer === peer) {
item[1].end();
}
}
2023-04-16 09:24:00 +00:00
const pubkey = this._toString(await this._getPublicKey(peer));
2023-04-15 22:40:09 +00:00
if (this._peers.has(pubkey)) {
this._peers.delete(pubkey);
}
}
get(pubkey) {
if (this._peers.has(this._toString(pubkey))) {
return this._peers.get(this._toString(pubkey));
}
return undefined;
}
update(pubkey, data) {
const peer = this.get(pubkey) ?? {};
this._peers.set(this._toString(pubkey), {
...peer,
...data,
...{
messages: {
...peer?.messages,
...data?.messages,
},
},
});
}
2023-04-16 09:38:59 +00:00
createSocket(options) {
2023-04-15 22:40:09 +00:00
if (!this._peers.size) {
throw new Error("no peers found");
}
const peer = this._nextPeer();
const socketId = nextSocketId();
const socket = new this.socketClass(socketId, this, peer, options);
this._sockets.set(socketId, socket);
return socket;
}
2023-04-16 09:24:00 +00:00
async _registerOpenSocketMessage(peer) {
2023-04-15 22:40:09 +00:00
const self = this;
2023-04-16 11:11:59 +00:00
const message = await peer.channel.addMessage({
2023-04-15 22:40:09 +00:00
encoding: {
preencode: compact_encoding_1.json.preencode,
encode: compact_encoding_1.json.encode,
2023-04-16 18:15:51 +00:00
decode: this._server ? compact_encoding_1.json.decode : socketEncoding.decode,
2023-04-15 22:40:09 +00:00
},
async onmessage(m) {
if (self._allowedPorts.length &&
!self._allowedPorts.includes(m.port)) {
2023-04-16 18:20:12 +00:00
self.get(await self._getPublicKey(peer)).messages.errorSocket.send({
2023-04-15 22:40:09 +00:00
id: m.id,
err: new Error(`port ${m.port} not allowed`),
});
return;
}
m = m;
if (self._server) {
2023-04-16 18:20:12 +00:00
new self.socketClass(nextSocketId(), m, self, self.get(await self._getPublicKey(peer)), m).connect();
2023-04-15 22:40:09 +00:00
return;
}
const socket = self._sockets.get(m.id);
if (socket) {
socket.remoteId = m.remoteId;
// @ts-ignore
socket.emit("connect");
}
},
});
2023-04-16 09:24:00 +00:00
this.update(await this._getPublicKey(peer), {
2023-04-15 22:40:09 +00:00
messages: { openSocket: message },
});
}
2023-04-16 09:24:00 +00:00
async _registerWriteSocketMessage(peer) {
2023-04-15 22:40:09 +00:00
const self = this;
2023-04-16 11:11:59 +00:00
const message = await peer.channel.addMessage({
2023-04-15 22:40:09 +00:00
encoding: writeSocketEncoding,
onmessage(m) {
self._sockets.get(m.id)?.push(m.data);
},
});
2023-04-16 09:24:00 +00:00
this.update(await this._getPublicKey(peer), {
2023-04-15 22:40:09 +00:00
messages: { writeSocket: message },
});
}
2023-04-16 09:24:00 +00:00
async _registerCloseSocketMessage(peer) {
2023-04-15 22:40:09 +00:00
const self = this;
2023-04-16 11:11:59 +00:00
const message = await peer.channel.addMessage({
2023-04-15 22:40:09 +00:00
encoding: socketEncoding,
onmessage(m) {
self._sockets.get(m.id)?.end();
},
});
2023-04-16 09:24:00 +00:00
this.update(await this._getPublicKey(peer), {
2023-04-15 22:40:09 +00:00
messages: { closeSocket: message },
});
}
2023-04-16 09:24:00 +00:00
async _registerTimeoutSocketMessage(peer) {
2023-04-15 22:40:09 +00:00
const self = this;
2023-04-16 11:11:59 +00:00
const message = await peer.channel.addMessage({
2023-04-15 22:40:09 +00:00
encoding: socketEncoding,
onmessage(m) {
// @ts-ignore
self._sockets.get(m.id)?.emit("timeout");
},
});
2023-04-16 09:24:00 +00:00
this.update(await this._getPublicKey(peer), {
2023-04-15 22:40:09 +00:00
messages: { timeoutSocket: message },
});
}
2023-04-16 09:24:00 +00:00
async _registerErrorSocketMessage(peer) {
2023-04-15 22:40:09 +00:00
const self = this;
2023-04-16 11:11:59 +00:00
const message = await peer.channel.addMessage({
2023-04-15 22:40:09 +00:00
encoding: errorSocketEncoding,
onmessage(m) {
// @ts-ignore
self._sockets.get(m.id)?.emit("error", m.err);
},
});
2023-04-16 09:24:00 +00:00
this.update(await this._getPublicKey(peer), {
2023-04-15 22:40:09 +00:00
messages: { errorSocket: message },
});
}
_toString(pubkey) {
return b4a_1.default.from(pubkey).toString("hex");
}
2023-04-16 09:24:00 +00:00
async _getPublicKey(peer) {
return (0, util_js_1.maybeGetAsyncProperty)(peer.stream.remotePublicKey);
}
2023-04-15 22:40:09 +00:00
}
exports.default = MultiSocketProxy;