@@ -38,6 +38,9 @@ impl MioError {
3838 }
3939}
4040
41+ // maximal ammount of queued data to send per peer is 64 MiB
42+ const MAX_QUEUED_BYTES : usize = 0x4000000 ;
43+
4144#[ derive( Debug ) ]
4245#[ allow( clippy:: large_enum_variant) ]
4346pub enum MioService {
@@ -181,6 +184,7 @@ struct Listener {
181184struct Connection {
182185 stream : TcpStream ,
183186 transmits : VecDeque < ( Box < [ u8 ] > , usize ) > ,
187+ queued_bytes : usize ,
184188 connected : bool ,
185189 incoming_ready : bool ,
186190}
@@ -272,8 +276,10 @@ where
272276 }
273277 } else {
274278 while let Some ( ( buf, mut offset) ) = connection. transmits . pop_front ( ) {
279+ connection. queued_bytes -= buf. len ( ) - offset;
275280 match connection. stream . write ( & buf[ offset..] ) {
276281 Err ( err) if err. kind ( ) == io:: ErrorKind :: WouldBlock => {
282+ connection. queued_bytes += buf. len ( ) - offset;
277283 connection. transmits . push_front ( ( buf, offset) ) ;
278284 rereg = true ;
279285 break ;
@@ -292,6 +298,7 @@ where
292298 if offset == buf. len ( ) {
293299 self . send ( MioEvent :: OutgoingDataDidSend ( addr, Ok ( ( ) ) ) ) ;
294300 } else {
301+ connection. queued_bytes += buf. len ( ) - offset;
295302 connection. transmits . push_front ( ( buf, offset) ) ;
296303 }
297304 }
@@ -383,6 +390,7 @@ where
383390 let connection = Connection {
384391 stream,
385392 transmits : VecDeque :: default ( ) ,
393+ queued_bytes : 0 ,
386394 connected : true ,
387395 incoming_ready : false ,
388396 } ;
@@ -449,6 +457,7 @@ where
449457 Connection {
450458 stream,
451459 transmits : VecDeque :: default ( ) ,
460+ queued_bytes : 0 ,
452461 connected : false ,
453462 incoming_ready : false ,
454463 } ,
@@ -516,7 +525,17 @@ where
516525 }
517526 Send ( addr, buf) => {
518527 if let Some ( connection) = self . connections . get_mut ( & addr) {
528+ connection. queued_bytes += buf. len ( ) ;
519529 connection. transmits . push_back ( ( buf, 0 ) ) ;
530+ if connection. transmits . len ( ) > 1 && connection. queued_bytes > MAX_QUEUED_BYTES
531+ {
532+ self . connections . remove ( & addr) ;
533+ // the peer is too slow, it requires us to send more and more,
534+ // but cannot accept the data
535+ let msg = "probably malicious" . to_string ( ) ;
536+ self . send ( MioEvent :: ConnectionDidClose ( addr, Err ( msg) ) ) ;
537+ return ;
538+ }
520539 let interests =
521540 match ( connection. incoming_ready , connection. transmits . is_empty ( ) ) {
522541 ( false , false ) => {
@@ -541,12 +560,8 @@ where
541560 }
542561 }
543562 Disconnect ( addr) => {
544- if let Some ( connection) = self . connections . remove ( & addr) {
545- connection
546- . stream
547- . shutdown ( Shutdown :: Both )
548- . unwrap_or_default ( ) ;
549- }
563+ // drop the connection and destructor will close it
564+ self . connections . remove ( & addr) ;
550565 }
551566 }
552567 }
0 commit comments