-
Notifications
You must be signed in to change notification settings - Fork 1.5k
/
app.js
31 lines (28 loc) · 1.47 KB
/
app.js
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
const net=require('net');
const {WebSocket,createWebSocketStream}=require('ws');
const logcb= (...args)=>console.log.bind(this,...args);
const errcb= (...args)=>console.error.bind(this,...args);
const uuid= (process.env.UUID||'d342d11e-d424-4583-b36e-524ab1f0afa4').replace(/-/g, "");
const port= process.env.PORT||3000;
const wss=new WebSocket.Server({port},logcb('listen:', port));
wss.on('connection', ws=>{
console.log("on connection")
ws.once('message', msg=>{
const [VERSION]=msg;
const id=msg.slice(1, 17);
if(!id.every((v,i)=>v==parseInt(uuid.substr(i*2,2),16))) return;
let i = msg.slice(17, 18).readUInt8()+19;
const port = msg.slice(i, i+=2).readUInt16BE(0);
const ATYP = msg.slice(i, i+=1).readUInt8();
const host= ATYP==1? msg.slice(i,i+=4).join('.')://IPV4
(ATYP==2? new TextDecoder().decode(msg.slice(i+1, i+=1+msg.slice(i,i+1).readUInt8()))://domain
(ATYP==3? msg.slice(i,i+=16).reduce((s,b,i,a)=>(i%2?s.concat(a.slice(i-1,i+1)):s), []).map(b=>b.readUInt16BE(0).toString(16)).join(':'):''));//ipv6
logcb('conn:', host,port);
ws.send(new Uint8Array([VERSION, 0]));
const duplex=createWebSocketStream(ws);
net.connect({host,port}, function(){
this.write(msg.slice(i));
duplex.on('error',errcb('E1:')).pipe(this).on('error',errcb('E2:')).pipe(duplex);
}).on('error',errcb('Conn-Err:',{host,port}));
}).on('error',errcb('EE:'));
});