@@ -90,9 +90,7 @@ var server = net.createServer(function (connection) {
90
90
} ) ;
91
91
const encryptor = new Encryptor ( KEY , METHOD ) ;
92
92
let stage = 0 ;
93
- let headerLength = 0 ;
94
93
let cachedPieces = [ ] ;
95
- let addrLen = 0 ;
96
94
let ws = null ;
97
95
let remoteAddr = null ;
98
96
let remotePort = null ;
@@ -115,126 +113,136 @@ var server = net.createServer(function (connection) {
115
113
return ;
116
114
}
117
115
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
+ // +----+-----+-------+------+----------+----------+
124
121
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 ( ) ;
132
149
return ;
133
150
}
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 ) {
138
158
connection . end ( ) ;
139
159
return ;
140
160
}
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 ;
160
170
}
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"
168
182
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);
174
188
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 ) ;
177
191
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 ;
183
197
184
- const agent = new HttpsProxyAgent ( opts ) ;
198
+ const agent = new HttpsProxyAgent ( opts ) ;
185
199
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,
206
203
} ) ;
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' ,
211
207
} ) ;
208
+ }
212
209
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 ,
216
217
} ) ;
218
+ cachedPieces = null ; // save memory
219
+ stage = 5 ;
220
+ } ) ;
217
221
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
+ } ) ;
225
226
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' ) ;
236
229
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 ) ;
237
244
}
245
+ stage = 4 ;
238
246
} else if ( stage === 4 ) {
239
247
// remote server not connected
240
248
// cache received buffers
0 commit comments