@@ -90,9 +90,7 @@ var server = net.createServer(function (connection) {
9090 } ) ;
9191 const encryptor = new Encryptor ( KEY , METHOD ) ;
9292 let stage = 0 ;
93- let headerLength = 0 ;
9493 let cachedPieces = [ ] ;
95- let addrLen = 0 ;
9694 let ws = null ;
9795 let remoteAddr = null ;
9896 let remotePort = null ;
@@ -115,126 +113,136 @@ var server = net.createServer(function (connection) {
115113 return ;
116114 }
117115 if ( stage === 1 ) {
118- try {
119- // +----+-----+-------+------+----------+----------+
120- // |VER | CMD | RSV | ATYP | DST.ADDR | DST.PORT |
121- // +----+-----+-------+------+----------+----------+
122- // | 1 | 1 | X'00' | 1 | Variable | 2 |
123- // +----+-----+-------+------+----------+----------+
116+ // +----+-----+-------+------+----------+----------+
117+ // |VER | CMD | RSV | ATYP | DST.ADDR | DST.PORT |
118+ // +----+-----+-------+------+----------+----------+
119+ // | 1 | 1 | X'00' | 1 | Variable | 2 |
120+ // +----+-----+-------+------+----------+----------+
124121
125- //cmd and addrtype
126- const cmd = data [ 1 ] ;
127- const addrtype = data [ 3 ] ;
128- if ( cmd !== 1 ) {
129- console . log ( 'unsupported cmd:' , cmd ) ;
130- const reply = Buffer . from ( '\u0005\u0007\u0000\u0001' , 'binary' ) ;
131- connection . end ( reply ) ;
122+ let headerLength = 5 ;
123+
124+ if ( data . length < headerLength ) {
125+ connection . end ( ) ;
126+ return ;
127+ }
128+ const cmd = data [ 1 ] ;
129+ const addrtype = data [ 3 ] ;
130+ if ( cmd !== 1 ) {
131+ console . log ( 'unsupported cmd:' , cmd ) ;
132+ const reply = Buffer . from ( '\u0005\u0007\u0000\u0001' , 'binary' ) ;
133+ connection . end ( reply ) ;
134+ return ;
135+ }
136+ if ( ! [ 1 , 3 , 4 ] . includes ( addrtype ) ) {
137+ console . log ( 'unsupported addrtype:' , addrtype ) ;
138+ connection . end ( ) ;
139+ return ;
140+ }
141+ addrToSend = data . slice ( 3 , 4 ) . toString ( 'binary' ) ;
142+
143+ // read address and port
144+ if ( addrtype === 1 ) {
145+ // ipv4
146+ headerLength = 4 + 4 + 2 ;
147+ if ( data . length < headerLength ) {
148+ connection . end ( ) ;
132149 return ;
133150 }
134- if ( addrtype === 3 ) {
135- addrLen = data [ 4 ] ;
136- } else if ( addrtype !== 1 && addrtype !== 4 ) {
137- console . log ( 'unsupported addrtype:' , addrtype ) ;
151+ remoteAddr = inetNtoa ( 4 , data . slice ( 4 , 8 ) ) ;
152+ addrToSend += data . slice ( 4 , 10 ) . toString ( 'binary' ) ;
153+ remotePort = data . readUInt16BE ( 8 ) ;
154+ } else if ( addrtype === 4 ) {
155+ // ipv6
156+ headerLength = 4 + 16 + 2 ;
157+ if ( data . length < headerLength ) {
138158 connection . end ( ) ;
139159 return ;
140160 }
141- addrToSend = data . slice ( 3 , 4 ) . toString ( 'binary' ) ;
142- // read address and port
143- if ( addrtype === 1 ) {
144- // ipv4
145- remoteAddr = inetNtoa ( 4 , data . slice ( 4 , 8 ) ) ;
146- addrToSend += data . slice ( 4 , 10 ) . toString ( 'binary' ) ;
147- remotePort = data . readUInt16BE ( 8 ) ;
148- headerLength = 10 ;
149- } else if ( addrtype === 4 ) {
150- // ipv6
151- remoteAddr = inetNtoa ( 6 , data . slice ( 4 , 20 ) ) ;
152- addrToSend += data . slice ( 4 , 22 ) . toString ( 'binary' ) ;
153- remotePort = data . readUInt16BE ( 20 ) ;
154- headerLength = 22 ;
155- } else {
156- remoteAddr = data . slice ( 5 , 5 + addrLen ) . toString ( 'binary' ) ;
157- addrToSend += data . slice ( 4 , 5 + addrLen + 2 ) . toString ( 'binary' ) ;
158- remotePort = data . readUInt16BE ( 5 + addrLen ) ;
159- headerLength = 5 + addrLen + 2 ;
161+ remoteAddr = inetNtoa ( 6 , data . slice ( 4 , 20 ) ) ;
162+ addrToSend += data . slice ( 4 , 22 ) . toString ( 'binary' ) ;
163+ remotePort = data . readUInt16BE ( 20 ) ;
164+ } else {
165+ const addrLen = data [ 4 ] ;
166+ headerLength = 5 + addrLen + 2 ;
167+ if ( data . length < headerLength ) {
168+ connection . end ( ) ;
169+ return ;
160170 }
161- let buf = Buffer . alloc ( 10 ) ;
162- buf . write ( '\u0005\u0000\u0000\u0001' , 0 , 4 , 'binary' ) ;
163- buf . write ( '\u0000\u0000\u0000\u0000' , 4 , 4 , 'binary' ) ;
164- buf . writeUInt16BE ( remotePort , 8 ) ;
165- connection . write ( buf ) ;
166- // connect to remote server
167- // ws = new WebSocket aServer, protocol: "binary"
171+ remoteAddr = data . slice ( 5 , 5 + addrLen ) . toString ( 'binary' ) ;
172+ addrToSend += data . slice ( 4 , 5 + addrLen + 2 ) . toString ( 'binary' ) ;
173+ remotePort = data . readUInt16BE ( 5 + addrLen ) ;
174+ }
175+ let buf = Buffer . alloc ( 10 ) ;
176+ buf . write ( '\u0005\u0000\u0000\u0001' , 0 , 4 , 'binary' ) ;
177+ buf . write ( '\u0000\u0000\u0000\u0000' , 4 , 4 , 'binary' ) ;
178+ buf . writeUInt16BE ( remotePort , 8 ) ;
179+ connection . write ( buf ) ;
180+ // connect to remote server
181+ // ws = new WebSocket aServer, protocol: "binary"
168182
169- if ( HTTPPROXY ) {
170- // WebSocket endpoint for the proxy to connect to
171- const endpoint = aServer ;
172- const parsed = url . parse ( endpoint ) ;
173- //console.log('attempting to connect to WebSocket %j', endpoint);
183+ if ( HTTPPROXY ) {
184+ // WebSocket endpoint for the proxy to connect to
185+ const endpoint = aServer ;
186+ const parsed = url . parse ( endpoint ) ;
187+ //console.log('attempting to connect to WebSocket %j', endpoint);
174188
175- // create an instance of the `HttpsProxyAgent` class with the proxy server information
176- const opts = url . parse ( HTTPPROXY ) ;
189+ // create an instance of the `HttpsProxyAgent` class with the proxy server information
190+ const opts = url . parse ( HTTPPROXY ) ;
177191
178- // IMPORTANT! Set the `secureEndpoint` option to `false` when connecting
179- // over "ws://", but `true` when connecting over "wss://"
180- opts . secureEndpoint = parsed . protocol
181- ? parsed . protocol == 'wss:'
182- : false ;
192+ // IMPORTANT! Set the `secureEndpoint` option to `false` when connecting
193+ // over "ws://", but `true` when connecting over "wss://"
194+ opts . secureEndpoint = parsed . protocol
195+ ? parsed . protocol == 'wss:'
196+ : false ;
183197
184- const agent = new HttpsProxyAgent ( opts ) ;
198+ const agent = new HttpsProxyAgent ( opts ) ;
185199
186- ws = new WebSocket ( aServer , {
187- protocol : 'binary' ,
188- agent,
189- } ) ;
190- } else {
191- ws = new WebSocket ( aServer , {
192- protocol : 'binary' ,
193- } ) ;
194- }
195-
196- ws . on ( 'open' , function ( ) {
197- console . log ( `connecting ${ remoteAddr } via ${ aServer } ` ) ;
198- let addrToSendBuf = Buffer . from ( addrToSend , 'binary' ) ;
199- addrToSendBuf = encryptor . encrypt ( addrToSendBuf ) ;
200- ws . send ( addrToSendBuf , { binary : true } ) ;
201- ws . send ( encryptor . encrypt ( Buffer . concat ( cachedPieces ) ) , {
202- binary : true ,
203- } ) ;
204- cachedPieces = null ; // save memory
205- stage = 5 ;
200+ ws = new WebSocket ( aServer , {
201+ protocol : 'binary' ,
202+ agent,
206203 } ) ;
207-
208- ws . on ( 'message' , function ( data , flags ) {
209- data = encryptor . decrypt ( data ) ;
210- connection . write ( data ) ;
204+ } else {
205+ ws = new WebSocket ( aServer , {
206+ protocol : 'binary' ,
211207 } ) ;
208+ }
212209
213- ws . on ( 'close' , function ( ) {
214- console . log ( 'remote disconnected' ) ;
215- connection . destroy ( ) ;
210+ ws . on ( 'open' , function ( ) {
211+ console . log ( `connecting ${ remoteAddr } via ${ aServer } ` ) ;
212+ let addrToSendBuf = Buffer . from ( addrToSend , 'binary' ) ;
213+ addrToSendBuf = encryptor . encrypt ( addrToSendBuf ) ;
214+ ws . send ( addrToSendBuf , { binary : true } ) ;
215+ ws . send ( encryptor . encrypt ( Buffer . concat ( cachedPieces ) ) , {
216+ binary : true ,
216217 } ) ;
218+ cachedPieces = null ; // save memory
219+ stage = 5 ;
220+ } ) ;
217221
218- ws . on ( 'error' , function ( e ) {
219- console . log ( `remote ${ remoteAddr } :${ remotePort } error: ${ e } ` ) ;
220- connection . destroy ( ) ;
221- server . getConnections ( function ( err , count ) {
222- console . log ( 'concurrent connections:' , count ) ;
223- } ) ;
224- } ) ;
222+ ws . on ( 'message' , function ( data , flags ) {
223+ data = encryptor . decrypt ( data ) ;
224+ connection . write ( data ) ;
225+ } ) ;
225226
226- if ( data . length > headerLength ) {
227- let buf = Buffer . alloc ( data . length - headerLength ) ;
228- data . copy ( buf , 0 , headerLength ) ;
229- cachedPieces . push ( buf ) ;
230- }
231- stage = 4 ;
232- } catch ( error ) {
233- // may encounter index out of range
234- const e = error ;
235- console . log ( e ) ;
227+ ws . on ( 'close' , function ( ) {
228+ console . log ( 'remote disconnected' ) ;
236229 connection . destroy ( ) ;
230+ } ) ;
231+
232+ ws . on ( 'error' , function ( e ) {
233+ console . log ( `remote ${ remoteAddr } :${ remotePort } error: ${ e } ` ) ;
234+ connection . destroy ( ) ;
235+ server . getConnections ( function ( err , count ) {
236+ console . log ( 'concurrent connections:' , count ) ;
237+ } ) ;
238+ } ) ;
239+
240+ if ( data . length > headerLength ) {
241+ let buf = Buffer . alloc ( data . length - headerLength ) ;
242+ data . copy ( buf , 0 , headerLength ) ;
243+ cachedPieces . push ( buf ) ;
237244 }
245+ stage = 4 ;
238246 } else if ( stage === 4 ) {
239247 // remote server not connected
240248 // cache received buffers
0 commit comments