1212// See the License for the specific language governing permissions and
1313// limitations under the License.
1414
15+ use std:: cell:: RefCell ;
1516use std:: io:: ErrorKind ;
1617use std:: net:: SocketAddr ;
1718
@@ -29,6 +30,9 @@ use slab::Slab;
2930use tquic:: PacketInfo ;
3031use tquic:: PacketSendHandler ;
3132
33+ pub mod packet_loss;
34+ pub use packet_loss:: { LossPacketType , PacketLossConfig , PacketLossSimulator } ;
35+
3236pub type Result < T > = std:: result:: Result < T , Box < dyn std:: error:: Error > > ;
3337
3438/// Supported application protocols.
@@ -98,10 +102,25 @@ pub struct QuicSocket {
98102
99103 /// Local address of the initial socket.
100104 local_addr : SocketAddr ,
105+
106+ /// Packet loss simulator for testing
107+ packet_loss : RefCell < Option < PacketLossSimulator > > ,
108+
109+ /// Connection ID length for packet parsing
110+ dcid_len : usize ,
101111}
102112
103113impl QuicSocket {
104114 pub fn new ( local : & SocketAddr , registry : & Registry ) -> Result < Self > {
115+ Self :: with_packet_loss ( local, registry, None , 8 )
116+ }
117+
118+ pub fn with_packet_loss (
119+ local : & SocketAddr ,
120+ registry : & Registry ,
121+ packet_loss_config : Option < PacketLossConfig > ,
122+ dcid_len : usize ,
123+ ) -> Result < Self > {
105124 let mut socks = Slab :: new ( ) ;
106125 let mut addrs = FxHashMap :: default ( ) ;
107126
@@ -113,10 +132,14 @@ impl QuicSocket {
113132 let socket = socks. get_mut ( sid) . unwrap ( ) ;
114133 registry. register ( socket, Token ( sid) , Interest :: READABLE ) ?;
115134
135+ let packet_loss = RefCell :: new ( packet_loss_config. map ( PacketLossSimulator :: new) ) ;
136+
116137 Ok ( Self {
117138 socks,
118139 addrs,
119140 local_addr,
141+ packet_loss,
142+ dcid_len,
120143 } )
121144 }
122145
@@ -166,14 +189,38 @@ impl QuicSocket {
166189 } ;
167190
168191 match socket. recv_from ( buf) {
169- Ok ( ( len, remote) ) => Ok ( ( len, socket. local_addr ( ) ?, remote) ) ,
192+ Ok ( ( len, remote) ) => {
193+ // Check if packet should be dropped due to loss simulation
194+ if let Ok ( mut packet_loss) = self . packet_loss . try_borrow_mut ( ) {
195+ if let Some ( ref mut simulator) = * packet_loss {
196+ if simulator. should_drop_incoming ( & buf[ ..len] , self . dcid_len ) {
197+ debug ! ( "Simulating incoming packet loss - dropping packet" ) ;
198+ return Err ( std:: io:: Error :: new (
199+ ErrorKind :: WouldBlock ,
200+ "simulated packet loss" ,
201+ ) ) ;
202+ }
203+ }
204+ }
205+ Ok ( ( len, socket. local_addr ( ) ?, remote) )
206+ }
170207 Err ( e) => Err ( e) ,
171208 }
172209 }
173210
174211 /// Send data on the socket to the given address.
175212 /// Note: packets with unknown src address are dropped.
176213 pub fn send_to ( & self , buf : & [ u8 ] , src : SocketAddr , dst : SocketAddr ) -> std:: io:: Result < usize > {
214+ // Check if packet should be dropped due to loss simulation
215+ if let Ok ( mut packet_loss) = self . packet_loss . try_borrow_mut ( ) {
216+ if let Some ( ref mut simulator) = * packet_loss {
217+ if simulator. should_drop_outgoing ( buf, self . dcid_len ) {
218+ debug ! ( "Simulating outgoing packet loss - dropping packet" ) ;
219+ return Ok ( buf. len ( ) ) ; // Pretend we sent it
220+ }
221+ }
222+ }
223+
177224 let sid = match self . addrs . get ( & src) {
178225 Some ( sid) => sid,
179226 None => {
0 commit comments