@@ -2,10 +2,12 @@ use std::cmp::{min, max};
2
2
use std:: collections:: VecDeque ;
3
3
use std:: net:: { ToSocketAddrs , SocketAddr , UdpSocket } ;
4
4
use std:: io:: { Result , Error , ErrorKind } ;
5
+ use std:: error:: Error as ErrorTrait ;
5
6
use util:: { now_microseconds, ewma} ;
6
7
use packet:: { Packet , PacketType , Encodable , Decodable , ExtensionType , HEADER_SIZE } ;
7
8
use rand:: { self , Rng } ;
8
9
use with_read_timeout:: WithReadTimeout ;
10
+ use std:: fmt;
9
11
10
12
// For simplicity's sake, let us assume no packet will ever exceed the
11
13
// Ethernet maximum transfer unit of 1500 bytes.
@@ -34,23 +36,45 @@ pub enum SocketError {
34
36
ConnectionClosed ,
35
37
ConnectionReset ,
36
38
ConnectionTimedOut ,
39
+ UserTimedOut ,
37
40
InvalidAddress ,
38
41
InvalidPacket ,
39
42
InvalidReply ,
40
43
}
41
44
45
+ impl fmt:: Display for SocketError {
46
+ fn fmt ( & self , f : & mut fmt:: Formatter ) -> fmt:: Result {
47
+ write ! ( f, "{:?}" , * self )
48
+ }
49
+ }
50
+
51
+ impl ErrorTrait for SocketError {
52
+ fn description ( & self ) -> & str {
53
+ use self :: SocketError :: * ;
54
+ match * self {
55
+ ConnectionClosed => "The socket is closed" ,
56
+ ConnectionReset => "Connection reset by remote peer" ,
57
+ ConnectionTimedOut => "Connection timed out" ,
58
+ UserTimedOut => "User timeout reached" ,
59
+ InvalidAddress => "Invalid address" ,
60
+ InvalidPacket => "Error parsing packet" ,
61
+ InvalidReply => "The remote peer sent an invalid reply" ,
62
+ }
63
+ }
64
+ }
65
+
42
66
impl From < SocketError > for Error {
43
67
fn from ( error : SocketError ) -> Error {
44
68
use self :: SocketError :: * ;
45
- let ( kind, message ) = match error {
46
- ConnectionClosed => ( ErrorKind :: NotConnected , "The socket is closed" ) ,
47
- ConnectionReset => ( ErrorKind :: ConnectionReset , "Connection reset by remote peer" ) ,
48
- ConnectionTimedOut => ( ErrorKind :: TimedOut , "Connection timed out" ) ,
49
- InvalidAddress => ( ErrorKind :: InvalidInput , "Invalid address" ) ,
50
- InvalidPacket => ( ErrorKind :: Other , "Error parsing packet" ) ,
51
- InvalidReply => ( ErrorKind :: ConnectionRefused , "The remote peer sent an invalid reply" ) ,
69
+ let kind = match error {
70
+ ConnectionClosed => ErrorKind :: NotConnected ,
71
+ ConnectionReset => ErrorKind :: ConnectionReset ,
72
+ ConnectionTimedOut | UserTimedOut => ErrorKind :: TimedOut ,
73
+ InvalidAddress => ErrorKind :: InvalidInput ,
74
+ InvalidPacket => ErrorKind :: Other ,
75
+ InvalidReply => ErrorKind :: ConnectionRefused ,
52
76
} ;
53
- Error :: new ( kind, message )
77
+ Error :: new ( kind, error )
54
78
}
55
79
}
56
80
@@ -185,6 +209,9 @@ pub struct UtpSocket {
185
209
186
210
/// Maximum retransmission retries
187
211
pub max_retransmission_retries : u32 ,
212
+
213
+ /// Used by `set_read_timeout`.
214
+ user_read_timeout : i64 ,
188
215
}
189
216
190
217
impl UtpSocket {
@@ -231,6 +258,7 @@ impl UtpSocket {
231
258
congestion_timeout : INITIAL_CONGESTION_TIMEOUT ,
232
259
cwnd : INIT_CWND * MSS ,
233
260
max_retransmission_retries : MAX_RETRANSMISSION_RETRIES ,
261
+ user_read_timeout : 0 ,
234
262
}
235
263
}
236
264
@@ -335,7 +363,7 @@ impl UtpSocket {
335
363
// Receive JAKE
336
364
let mut buf = [ 0 ; BUF_SIZE ] ;
337
365
while self . state != SocketState :: Closed {
338
- try!( self . recv ( & mut buf) ) ;
366
+ try!( self . recv ( & mut buf, false ) ) ;
339
367
}
340
368
341
369
Ok ( ( ) )
@@ -364,7 +392,8 @@ impl UtpSocket {
364
392
return Ok ( ( 0 , self . connected_to ) ) ;
365
393
}
366
394
367
- match self . recv ( buf) {
395
+ let user_read_timeout = self . user_read_timeout ;
396
+ match self . recv ( buf, user_read_timeout != 0 ) {
368
397
Ok ( ( 0 , _src) ) => continue ,
369
398
Ok ( x) => return Ok ( x) ,
370
399
Err ( e) => return Err ( e)
@@ -373,11 +402,32 @@ impl UtpSocket {
373
402
}
374
403
}
375
404
376
- fn recv ( & mut self , buf : & mut [ u8 ] ) -> Result < ( usize , SocketAddr ) > {
405
+ /// Changes read operations to block for at most the specified number of
406
+ /// milliseconds.
407
+ pub fn set_read_timeout ( & mut self , user_timeout : Option < i64 > ) {
408
+ self . user_read_timeout = match user_timeout {
409
+ Some ( t) => {
410
+ if t > 0 {
411
+ t
412
+ } else {
413
+ 0
414
+ }
415
+ } ,
416
+ None => 0
417
+ }
418
+ }
419
+
420
+ fn recv ( & mut self , buf : & mut [ u8 ] , use_user_timeout : bool )
421
+ -> Result < ( usize , SocketAddr ) > {
377
422
let mut b = [ 0 ; BUF_SIZE + HEADER_SIZE ] ;
378
423
let now = now_microseconds ( ) ;
379
424
let ( read, src) ;
380
425
let mut retries = 0 ;
426
+ let user_timeout = if use_user_timeout {
427
+ self . user_read_timeout
428
+ } else {
429
+ 0
430
+ } ;
381
431
382
432
// Try to receive a packet and handle timeouts
383
433
loop {
@@ -387,17 +437,32 @@ impl UtpSocket {
387
437
return Err ( Error :: from ( SocketError :: ConnectionTimedOut ) ) ;
388
438
}
389
439
390
- let timeout = if self . state != SocketState :: New {
440
+ let congestion_timeout = if self . state != SocketState :: New {
391
441
debug ! ( "setting read timeout of {} ms" , self . congestion_timeout) ;
392
442
self . congestion_timeout as i64
393
443
} else { 0 } ;
444
+ let timeout = if user_timeout != 0 {
445
+ if congestion_timeout != 0 {
446
+ use std:: cmp:: min;
447
+ min ( congestion_timeout, user_timeout)
448
+ } else {
449
+ user_timeout
450
+ }
451
+ } else {
452
+ congestion_timeout
453
+ } ;
454
+
455
+ if user_timeout != 0
456
+ && ( ( now_microseconds ( ) - now) / 1000 ) as i64 >= user_timeout {
457
+ return Err ( Error :: from ( SocketError :: UserTimedOut ) ) ;
458
+ }
394
459
395
460
match self . socket . recv_timeout ( & mut b, timeout) {
396
461
Ok ( ( r, s) ) => { read = r; src = s; break } ,
397
462
Err ( ref e) if ( e. kind ( ) == ErrorKind :: WouldBlock ||
398
463
e. kind ( ) == ErrorKind :: TimedOut ) => {
399
464
debug ! ( "recv_from timed out" ) ;
400
- try!( self . handle_receive_timeout ( ) ) ;
465
+ try!( self . handle_receive_timeout ( user_timeout != 0 ) ) ;
401
466
} ,
402
467
Err ( e) => return Err ( e) ,
403
468
} ;
@@ -438,8 +503,11 @@ impl UtpSocket {
438
503
Ok ( ( read, src) )
439
504
}
440
505
441
- fn handle_receive_timeout ( & mut self ) -> Result < ( ) > {
442
- self . congestion_timeout = self . congestion_timeout * 2 ;
506
+ fn handle_receive_timeout ( & mut self , keep_current_timeout : bool )
507
+ -> Result < ( ) > {
508
+ if !keep_current_timeout {
509
+ self . congestion_timeout *= 2
510
+ }
443
511
self . cwnd = MSS ;
444
512
445
513
// There are three possible cases here:
@@ -605,7 +673,7 @@ impl UtpSocket {
605
673
let mut buf = [ 0u8 ; BUF_SIZE ] ;
606
674
while !self . send_window . is_empty ( ) {
607
675
debug ! ( "packets in send window: {}" , self . send_window. len( ) ) ;
608
- try!( self . recv ( & mut buf) ) ;
676
+ try!( self . recv ( & mut buf, false ) ) ;
609
677
}
610
678
611
679
Ok ( ( ) )
@@ -637,7 +705,7 @@ impl UtpSocket {
637
705
debug ! ( "self.duplicate_ack_count: {}" , self . duplicate_ack_count) ;
638
706
debug ! ( "now_microseconds() - now = {}" , now_microseconds( ) - now) ;
639
707
let mut buf = [ 0 ; BUF_SIZE ] ;
640
- try!( self . recv ( & mut buf) ) ;
708
+ try!( self . recv ( & mut buf, false ) ) ;
641
709
}
642
710
debug ! ( "out: now_microseconds() - now = {}" , now_microseconds( ) - now) ;
643
711
@@ -1355,7 +1423,7 @@ mod test {
1355
1423
thread:: spawn ( move || {
1356
1424
// Make the server listen for incoming connections
1357
1425
let mut buf = [ 0u8 ; BUF_SIZE ] ;
1358
- let _resp = server. recv ( & mut buf) ;
1426
+ let _resp = server. recv ( & mut buf, false ) ;
1359
1427
tx. send ( server. seq_nr ) . unwrap ( ) ;
1360
1428
1361
1429
// Close the connection
@@ -1719,7 +1787,7 @@ mod test {
1719
1787
1720
1788
let mut buf = [ 0 ; BUF_SIZE ] ;
1721
1789
// Expect SYN
1722
- iotry ! ( server. recv( & mut buf) ) ;
1790
+ iotry ! ( server. recv( & mut buf, false ) ) ;
1723
1791
1724
1792
// Receive data
1725
1793
let data_packet = match server. socket . recv_from ( & mut buf) {
@@ -1792,7 +1860,7 @@ mod test {
1792
1860
} ) ;
1793
1861
1794
1862
let mut buf = [ 0u8 ; BUF_SIZE ] ;
1795
- server. recv ( & mut buf) . unwrap ( ) ;
1863
+ server. recv ( & mut buf, false ) . unwrap ( ) ;
1796
1864
// After establishing a new connection, the server's ids are a mirror of the client's.
1797
1865
assert_eq ! ( server. receiver_connection_id, server. sender_connection_id + 1 ) ;
1798
1866
@@ -1899,7 +1967,7 @@ mod test {
1899
1967
} ) ;
1900
1968
1901
1969
let mut buf = [ 0u8 ; BUF_SIZE ] ;
1902
- iotry ! ( server. recv( & mut buf) ) ;
1970
+ iotry ! ( server. recv( & mut buf, false ) ) ;
1903
1971
// After establishing a new connection, the server's ids are a mirror of the client's.
1904
1972
assert_eq ! ( server. receiver_connection_id, server. sender_connection_id + 1 ) ;
1905
1973
@@ -2233,7 +2301,7 @@ mod test {
2233
2301
let mut buf = [ 0 ; BUF_SIZE ] ;
2234
2302
2235
2303
// Accept connection
2236
- iotry ! ( server. recv( & mut buf) ) ;
2304
+ iotry ! ( server. recv( & mut buf, false ) ) ;
2237
2305
2238
2306
// Send FIN without acknowledging packets received
2239
2307
let mut packet = Packet :: new ( ) ;
@@ -2348,7 +2416,7 @@ mod test {
2348
2416
2349
2417
// Try to receive ACKs, time out too many times on flush, and fail with `TimedOut`
2350
2418
let mut buf = [ 0 ; BUF_SIZE ] ;
2351
- match server. recv ( & mut buf) {
2419
+ match server. recv ( & mut buf, false ) {
2352
2420
Err ( ref e) if e. kind ( ) == ErrorKind :: TimedOut => ( ) ,
2353
2421
x => panic ! ( "Expected Err(TimedOut), got {:?}" , x) ,
2354
2422
}
0 commit comments