@@ -97,6 +97,11 @@ func startUDPEchoServer(t testing.TB) (*net.UDPConn, *sync.WaitGroup) {
97
97
return conn , & running
98
98
}
99
99
100
+ func makeLimiter (cipherList service.CipherList ) service.TrafficLimiter {
101
+ c := service .MakeTestTrafficLimiterConfig (cipherList )
102
+ return service .NewTrafficLimiter (& c )
103
+ }
104
+
100
105
func TestTCPEcho (t * testing.T ) {
101
106
echoListener , echoRunning := startTCPEchoServer (t )
102
107
@@ -111,7 +116,7 @@ func TestTCPEcho(t *testing.T) {
111
116
}
112
117
replayCache := service .NewReplayCache (5 )
113
118
const testTimeout = 200 * time .Millisecond
114
- proxy := service .NewTCPService (cipherList , & replayCache , & metrics.NoOpMetrics {}, testTimeout )
119
+ proxy := service .NewTCPService (cipherList , & replayCache , & metrics.NoOpMetrics {}, testTimeout , makeLimiter ( cipherList ) )
115
120
proxy .SetTargetIPValidator (allowAll )
116
121
go proxy .Serve (proxyListener )
117
122
@@ -164,6 +169,192 @@ func TestTCPEcho(t *testing.T) {
164
169
echoRunning .Wait ()
165
170
}
166
171
172
+ func TestTrafficLimiterTCP (t * testing.T ) {
173
+ echoListener , echoRunning := startTCPEchoServer (t )
174
+
175
+ proxyListener , err := net .ListenTCP ("tcp" , & net.TCPAddr {IP : net .ParseIP ("127.0.0.1" ), Port : 0 })
176
+ if err != nil {
177
+ t .Fatalf ("ListenTCP failed: %v" , err )
178
+ }
179
+ secrets := ss .MakeTestSecrets (1 )
180
+ cipherList , err := service .MakeTestCiphers (secrets )
181
+ if err != nil {
182
+ t .Fatal (err )
183
+ }
184
+ replayCache := service .NewReplayCache (5 )
185
+ const testTimeout = 5 * time .Second
186
+
187
+ key := cipherList .SnapshotForClientIP (net.IP {})[0 ].Value .(* service.CipherEntry ).ID
188
+ trafficLimiter := service .NewTrafficLimiter (& service.TrafficLimiterConfig {
189
+ KeyToRateLimit : map [string ]int {
190
+ key : 1000 ,
191
+ },
192
+ })
193
+
194
+ proxy := service .NewTCPService (cipherList , & replayCache , & metrics.NoOpMetrics {}, testTimeout , trafficLimiter )
195
+ proxy .SetTargetIPValidator (allowAll )
196
+ go proxy .Serve (proxyListener )
197
+
198
+ proxyHost , proxyPort , err := net .SplitHostPort (proxyListener .Addr ().String ())
199
+ if err != nil {
200
+ t .Fatal (err )
201
+ }
202
+ portNum , err := strconv .Atoi (proxyPort )
203
+ if err != nil {
204
+ t .Fatal (err )
205
+ }
206
+ client , err := client .NewClient (proxyHost , portNum , secrets [0 ], ss .TestCipher )
207
+ if err != nil {
208
+ t .Fatalf ("Failed to create ShadowsocksClient: %v" , err )
209
+ }
210
+
211
+ doWriteRead := func (N int , repeats int ) time.Duration {
212
+ up := ss .MakeTestPayload (N )
213
+ conn , err := client .DialTCP (nil , echoListener .Addr ().String ())
214
+ defer conn .Close ()
215
+ if err != nil {
216
+ t .Fatalf ("ShadowsocksClient.DialTCP failed: %v" , err )
217
+ }
218
+ start := time .Now ()
219
+ down := make ([]byte , N )
220
+
221
+ for i := 0 ; i < repeats ; i ++ {
222
+ n , err := conn .Write (up )
223
+ if err != nil {
224
+ t .Fatal (err )
225
+ }
226
+ if n != N {
227
+ t .Fatalf ("Tried to upload %d bytes, but only sent %d" , N , n )
228
+ }
229
+
230
+ n , err = io .ReadFull (conn , down )
231
+ if err != nil && err != io .EOF {
232
+ t .Fatal (err )
233
+ }
234
+ if n != N {
235
+ t .Fatalf ("Expected to download %d bytes, but only received %d" , N , n )
236
+ }
237
+
238
+ if ! bytes .Equal (up , down ) {
239
+ t .Fatal ("Echo mismatch" )
240
+ }
241
+ }
242
+
243
+ return time .Now ().Sub (start )
244
+ }
245
+
246
+ period1 := doWriteRead (200 , 4 )
247
+ if period1 < 500 * time .Millisecond {
248
+ t .Fatalf ("Write-read loop is too fast" )
249
+ }
250
+
251
+ time .Sleep (1 * time .Second )
252
+
253
+ period2 := doWriteRead (200 , 2 )
254
+ if period2 > 100 * time .Millisecond {
255
+ t .Fatalf ("Write-read loop is too slow" )
256
+ }
257
+
258
+ period3 := doWriteRead (500 , 2 )
259
+ if period3 < 500 * time .Millisecond {
260
+ t .Fatalf ("Write-read loop is too fast" )
261
+ }
262
+
263
+ proxy .Stop ()
264
+ echoListener .Close ()
265
+ echoRunning .Wait ()
266
+ }
267
+
268
+ func TestTrafficLimiterUDP (t * testing.T ) {
269
+ echoConn , echoRunning := startUDPEchoServer (t )
270
+
271
+ proxyConn , err := net .ListenUDP ("udp" , & net.UDPAddr {IP : net .ParseIP ("127.0.0.1" ), Port : 0 })
272
+ if err != nil {
273
+ t .Fatalf ("ListenTCP failed: %v" , err )
274
+ }
275
+ secrets := ss .MakeTestSecrets (1 )
276
+ cipherList , err := service .MakeTestCiphers (secrets )
277
+ if err != nil {
278
+ t .Fatal (err )
279
+ }
280
+ testMetrics := & fakeUDPMetrics {fakeLocation : "QQ" }
281
+
282
+ key := cipherList .SnapshotForClientIP (net.IP {})[0 ].Value .(* service.CipherEntry ).ID
283
+ trafficLimiter := service .NewTrafficLimiter (& service.TrafficLimiterConfig {
284
+ KeyToRateLimit : map [string ]int {
285
+ key : 1000 ,
286
+ },
287
+ })
288
+
289
+ proxy := service .NewUDPService (time .Hour , cipherList , testMetrics , trafficLimiter )
290
+ proxy .SetTargetIPValidator (allowAll )
291
+ go proxy .Serve (proxyConn )
292
+
293
+ proxyHost , proxyPort , err := net .SplitHostPort (proxyConn .LocalAddr ().String ())
294
+ if err != nil {
295
+ t .Fatal (err )
296
+ }
297
+ portNum , err := strconv .Atoi (proxyPort )
298
+ if err != nil {
299
+ t .Fatal (err )
300
+ }
301
+ client , err := client .NewClient (proxyHost , portNum , secrets [0 ], ss .TestCipher )
302
+ if err != nil {
303
+ t .Fatalf ("Failed to create ShadowsocksClient: %v" , err )
304
+ }
305
+ conn , err := client .ListenUDP (nil )
306
+ if err != nil {
307
+ t .Fatalf ("ShadowsocksClient.ListenUDP failed: %v" , err )
308
+ }
309
+
310
+ run := func (N int , expectReadError bool ) {
311
+ up := ss .MakeTestPayload (N )
312
+ n , err := conn .WriteTo (up , echoConn .LocalAddr ())
313
+ if err != nil {
314
+ t .Fatal (err )
315
+ }
316
+ if n != N {
317
+ t .Fatalf ("Tried to upload %d bytes, but only sent %d" , N , n )
318
+ }
319
+
320
+ conn .SetReadDeadline (time .Now ().Add (50 * time .Millisecond ))
321
+
322
+ down := make ([]byte , N )
323
+ n , addr , err := conn .ReadFrom (down )
324
+ if err != nil {
325
+ if ! expectReadError {
326
+ t .Fatalf ("Unexpected read error: %v" , err )
327
+ }
328
+ return
329
+ } else {
330
+ if expectReadError {
331
+ t .Fatalf ("Expected read error" )
332
+ }
333
+ }
334
+ if n != N {
335
+ t .Fatalf ("Tried to download %d bytes, but only sent %d" , N , n )
336
+ }
337
+ if addr .String () != echoConn .LocalAddr ().String () {
338
+ t .Errorf ("Reported address mismatch: %s != %s" , addr .String (), echoConn .LocalAddr ().String ())
339
+ }
340
+
341
+ if ! bytes .Equal (up , down ) {
342
+ t .Fatal ("Echo mismatch" )
343
+ }
344
+ }
345
+
346
+ for i := 0 ; i < 3 ; i ++ {
347
+ run (300 , false )
348
+ run (300 , true )
349
+ time .Sleep (time .Second )
350
+ }
351
+
352
+ conn .Close ()
353
+ echoConn .Close ()
354
+ echoRunning .Wait ()
355
+ proxy .GracefulStop ()
356
+ }
357
+
167
358
type statusMetrics struct {
168
359
metrics.NoOpMetrics
169
360
sync.Mutex
@@ -184,7 +375,7 @@ func TestRestrictedAddresses(t *testing.T) {
184
375
require .NoError (t , err )
185
376
const testTimeout = 200 * time .Millisecond
186
377
testMetrics := & statusMetrics {}
187
- proxy := service .NewTCPService (cipherList , nil , testMetrics , testTimeout )
378
+ proxy := service .NewTCPService (cipherList , nil , testMetrics , testTimeout , makeLimiter ( cipherList ) )
188
379
go proxy .Serve (proxyListener )
189
380
190
381
proxyHost , proxyPort , err := net .SplitHostPort (proxyListener .Addr ().String ())
@@ -266,7 +457,7 @@ func TestUDPEcho(t *testing.T) {
266
457
t .Fatal (err )
267
458
}
268
459
testMetrics := & fakeUDPMetrics {fakeLocation : "QQ" }
269
- proxy := service .NewUDPService (time .Hour , cipherList , testMetrics )
460
+ proxy := service .NewUDPService (time .Hour , cipherList , testMetrics , makeLimiter ( cipherList ) )
270
461
proxy .SetTargetIPValidator (allowAll )
271
462
go proxy .Serve (proxyConn )
272
463
@@ -363,7 +554,7 @@ func BenchmarkTCPThroughput(b *testing.B) {
363
554
b .Fatal (err )
364
555
}
365
556
const testTimeout = 200 * time .Millisecond
366
- proxy := service .NewTCPService (cipherList , nil , & metrics.NoOpMetrics {}, testTimeout )
557
+ proxy := service .NewTCPService (cipherList , nil , & metrics.NoOpMetrics {}, testTimeout , makeLimiter ( cipherList ) )
367
558
proxy .SetTargetIPValidator (allowAll )
368
559
go proxy .Serve (proxyListener )
369
560
@@ -430,7 +621,7 @@ func BenchmarkTCPMultiplexing(b *testing.B) {
430
621
}
431
622
replayCache := service .NewReplayCache (service .MaxCapacity )
432
623
const testTimeout = 200 * time .Millisecond
433
- proxy := service .NewTCPService (cipherList , & replayCache , & metrics.NoOpMetrics {}, testTimeout )
624
+ proxy := service .NewTCPService (cipherList , & replayCache , & metrics.NoOpMetrics {}, testTimeout , makeLimiter ( cipherList ) )
434
625
proxy .SetTargetIPValidator (allowAll )
435
626
go proxy .Serve (proxyListener )
436
627
@@ -505,7 +696,7 @@ func BenchmarkUDPEcho(b *testing.B) {
505
696
if err != nil {
506
697
b .Fatal (err )
507
698
}
508
- proxy := service .NewUDPService (time .Hour , cipherList , & metrics.NoOpMetrics {})
699
+ proxy := service .NewUDPService (time .Hour , cipherList , & metrics.NoOpMetrics {}, makeLimiter ( cipherList ) )
509
700
proxy .SetTargetIPValidator (allowAll )
510
701
go proxy .Serve (proxyConn )
511
702
@@ -554,7 +745,7 @@ func BenchmarkUDPManyKeys(b *testing.B) {
554
745
if err != nil {
555
746
b .Fatal (err )
556
747
}
557
- proxy := service .NewUDPService (time .Hour , cipherList , & metrics.NoOpMetrics {})
748
+ proxy := service .NewUDPService (time .Hour , cipherList , & metrics.NoOpMetrics {}, makeLimiter ( cipherList ) )
558
749
proxy .SetTargetIPValidator (allowAll )
559
750
go proxy .Serve (proxyConn )
560
751
0 commit comments