7
7
//! * server then sends [`FrameType::RelayToClientDatagrams`] to recipient
8
8
//! * server sends [`FrameType::NodeGone`] when the other client disconnects
9
9
10
- use bytes:: { BufMut , Bytes , BytesMut } ;
10
+ use bytes:: { Buf , BufMut , Bytes , BytesMut } ;
11
11
use iroh_base:: { NodeId , SignatureError } ;
12
12
use n0_future:: time:: { self , Duration } ;
13
13
use nested_enum_utils:: common_fields;
@@ -165,39 +165,46 @@ impl<T: AsRef<[u8]>> From<T> for Datagrams {
165
165
impl Datagrams {
166
166
fn write_to < O : BufMut > ( & self , mut dst : O ) -> O {
167
167
let ecn = self . ecn . map_or ( 0 , |ecn| ecn as u8 ) ;
168
- let segment_size = self . segment_size . unwrap_or_default ( ) ;
169
168
dst. put_u8 ( ecn) ;
170
- dst. put_u16 ( segment_size) ;
169
+ if let Some ( segment_size) = self . segment_size {
170
+ dst. put_u16 ( segment_size) ;
171
+ }
171
172
dst. put ( self . contents . as_ref ( ) ) ;
172
173
dst
173
174
}
174
175
175
176
fn encoded_len ( & self ) -> usize {
176
177
1 // ECN byte
177
- + 2 // segment size
178
+ + self . segment_size . map_or ( 0 , |_| 2 ) // segment size, when None, then a packed representation is assumed
178
179
+ self . contents . len ( )
179
180
}
180
181
181
- fn from_bytes ( bytes : Bytes ) -> Result < Self , Error > {
182
- // 1 bytes ECN, 2 bytes segment size
183
- snafu:: ensure!( bytes. len( ) > 3 , InvalidFrameSnafu ) ;
182
+ fn from_bytes ( mut bytes : Bytes , is_batch : bool ) -> Result < Self , Error > {
183
+ if is_batch {
184
+ // 1 bytes ECN, 2 bytes segment size
185
+ snafu:: ensure!( bytes. len( ) >= 3 , InvalidFrameSnafu ) ;
186
+ } else {
187
+ snafu:: ensure!( bytes. len( ) >= 1 , InvalidFrameSnafu ) ;
188
+ }
184
189
185
- let ecn_byte = bytes[ 0 ] ;
190
+ let ecn_byte = bytes. get_u8 ( ) ;
186
191
let ecn = quinn_proto:: EcnCodepoint :: from_bits ( ecn_byte) ;
187
192
188
- let segment_size = u16:: from_be_bytes ( bytes[ 1 ..3 ] . try_into ( ) . expect ( "length checked" ) ) ;
189
- let segment_size = if segment_size == 0 {
190
- None
193
+ let segment_size = if is_batch {
194
+ let segment_size = bytes. get_u16 ( ) ; // length checked above
195
+ if segment_size == 0 {
196
+ None
197
+ } else {
198
+ Some ( segment_size)
199
+ }
191
200
} else {
192
- Some ( segment_size )
201
+ None
193
202
} ;
194
203
195
- let contents = bytes. slice ( 3 ..) ;
196
-
197
204
Ok ( Self {
198
205
ecn,
199
206
segment_size,
200
- contents,
207
+ contents : bytes ,
201
208
} )
202
209
}
203
210
}
@@ -206,7 +213,13 @@ impl RelayToClientMsg {
206
213
/// Returns this frame's corresponding frame type.
207
214
pub fn typ ( & self ) -> FrameType {
208
215
match self {
209
- Self :: Datagrams { .. } => FrameType :: RelayToClientDatagrams ,
216
+ Self :: Datagrams { datagrams, .. } => {
217
+ if datagrams. segment_size . is_some ( ) {
218
+ FrameType :: RelayToClientDatagrams
219
+ } else {
220
+ FrameType :: RelayToClientDatagram
221
+ }
222
+ }
210
223
Self :: NodeGone { .. } => FrameType :: NodeGone ,
211
224
Self :: Ping { .. } => FrameType :: Ping ,
212
225
Self :: Pong { .. } => FrameType :: Pong ,
@@ -289,13 +302,16 @@ impl RelayToClientMsg {
289
302
) ;
290
303
291
304
let res = match frame_type {
292
- FrameType :: RelayToClientDatagrams => {
305
+ FrameType :: RelayToClientDatagram | FrameType :: RelayToClientDatagrams => {
293
306
snafu:: ensure!( content. len( ) >= NodeId :: LENGTH , InvalidFrameSnafu ) ;
294
307
295
308
let remote_node_id = cache
296
309
. key_from_slice ( & content[ ..NodeId :: LENGTH ] )
297
310
. context ( InvalidPublicKeySnafu ) ?;
298
- let datagrams = Datagrams :: from_bytes ( content. slice ( NodeId :: LENGTH ..) ) ?;
311
+ let datagrams = Datagrams :: from_bytes (
312
+ content. slice ( NodeId :: LENGTH ..) ,
313
+ frame_type == FrameType :: RelayToClientDatagrams ,
314
+ ) ?;
299
315
Self :: Datagrams {
300
316
remote_node_id,
301
317
datagrams,
@@ -356,7 +372,13 @@ impl RelayToClientMsg {
356
372
impl ClientToRelayMsg {
357
373
pub ( crate ) fn typ ( & self ) -> FrameType {
358
374
match self {
359
- Self :: Datagrams { .. } => FrameType :: ClientToRelayDatagrams ,
375
+ Self :: Datagrams { datagrams, .. } => {
376
+ if datagrams. segment_size . is_some ( ) {
377
+ FrameType :: ClientToRelayDatagrams
378
+ } else {
379
+ FrameType :: ClientToRelayDatagram
380
+ }
381
+ }
360
382
Self :: Ping { .. } => FrameType :: Ping ,
361
383
Self :: Pong { .. } => FrameType :: Pong ,
362
384
}
@@ -415,11 +437,14 @@ impl ClientToRelayMsg {
415
437
) ;
416
438
417
439
let res = match frame_type {
418
- FrameType :: ClientToRelayDatagrams => {
440
+ FrameType :: ClientToRelayDatagram | FrameType :: ClientToRelayDatagrams => {
419
441
let dst_node_id = cache
420
442
. key_from_slice ( & content[ ..NodeId :: LENGTH ] )
421
443
. context ( InvalidPublicKeySnafu ) ?;
422
- let datagrams = Datagrams :: from_bytes ( content. slice ( NodeId :: LENGTH ..) ) ?;
444
+ let datagrams = Datagrams :: from_bytes (
445
+ content. slice ( NodeId :: LENGTH ..) ,
446
+ frame_type == FrameType :: ClientToRelayDatagrams ,
447
+ ) ?;
423
448
Self :: Datagrams {
424
449
dst_node_id,
425
450
datagrams,
@@ -508,9 +533,39 @@ mod tests {
508
533
} ,
509
534
}
510
535
. write_to( Vec :: new( ) ) ,
511
- "06 19 7f 6b 23 e1 6c 85 32 c6 ab c8 38 fa cd 5e
512
- a7 89 be 0c 76 b2 92 03 34 03 9b fa 8b 3d 36 8d
513
- 61 48 65 6c 6c 6f 20 57 6f 72 6c 64 21" ,
536
+ // frame type
537
+ // public key first 16 bytes
538
+ // public key second 16 bytes
539
+ // ECN byte
540
+ // segment size
541
+ // hello world contents bytes
542
+ "07
543
+ 19 7f 6b 23 e1 6c 85 32 c6 ab c8 38 fa cd 5e a7
544
+ 89 be 0c 76 b2 92 03 34 03 9b fa 8b 3d 36 8d 61
545
+ 03
546
+ 00 06
547
+ 48 65 6c 6c 6f 20 57 6f 72 6c 64 21" ,
548
+ ) ,
549
+ (
550
+ RelayToClientMsg :: Datagrams {
551
+ remote_node_id: client_key. public( ) ,
552
+ datagrams: Datagrams {
553
+ ecn: Some ( quinn:: EcnCodepoint :: Ce ) ,
554
+ segment_size: None ,
555
+ contents: "Hello World!" . into( ) ,
556
+ } ,
557
+ }
558
+ . write_to( Vec :: new( ) ) ,
559
+ // frame type
560
+ // public key first 16 bytes
561
+ // public key second 16 bytes
562
+ // ECN byte
563
+ // hello world contents bytes
564
+ "06
565
+ 19 7f 6b 23 e1 6c 85 32 c6 ab c8 38 fa cd 5e a7
566
+ 89 be 0c 76 b2 92 03 34 03 9b fa 8b 3d 36 8d 61
567
+ 03
568
+ 48 65 6c 6c 6f 20 57 6f 72 6c 64 21" ,
514
569
) ,
515
570
(
516
571
RelayToClientMsg :: Restarting {
@@ -552,6 +607,27 @@ mod tests {
552
607
a7 89 be 0c 76 b2 92 03 34 03 9b fa 8b 3d 36 8d
553
608
61 47 6f 6f 64 62 79 65 21" ,
554
609
) ,
610
+ (
611
+ ClientToRelayMsg :: Datagrams {
612
+ dst_node_id: client_key. public( ) ,
613
+ datagrams: Datagrams {
614
+ ecn: Some ( quinn:: EcnCodepoint :: Ce ) ,
615
+ segment_size: None ,
616
+ contents: "Hello World!" . into( ) ,
617
+ } ,
618
+ }
619
+ . write_to( Vec :: new( ) ) ,
620
+ // frame type
621
+ // public key first 16 bytes
622
+ // public key second 16 bytes
623
+ // ECN byte
624
+ // hello world contents
625
+ "04
626
+ 19 7f 6b 23 e1 6c 85 32 c6 ab c8 38 fa cd 5e a7
627
+ 89 be 0c 76 b2 92 03 34 03 9b fa 8b 3d 36 8d 61
628
+ 03
629
+ 48 65 6c 6c 6f 20 57 6f 72 6c 64 21" ,
630
+ ) ,
555
631
] ) ;
556
632
557
633
Ok ( ( ) )
0 commit comments