@@ -7,7 +7,7 @@ use core::{cell::RefCell, mem, net::SocketAddrV4};
77use futures:: future:: { select, Either } ;
88use log:: info;
99use lz4_flex:: decompress;
10- use pixie_shared:: { Image , TcpRequest , UdpRequest , BODY_LEN , CHUNKS_PORT , HEADER_LEN } ;
10+ use pixie_shared:: { ChunkHash , Image , TcpRequest , UdpRequest , BODY_LEN , CHUNKS_PORT , HEADER_LEN } ;
1111use uefi:: proto:: console:: text:: Color ;
1212
1313struct PartialChunk {
@@ -57,21 +57,24 @@ struct Stats {
5757 requested : usize ,
5858}
5959
60- async fn handle_packet (
60+ fn handle_packet (
6161 buf : & [ u8 ] ,
62- chunks_info : & mut BTreeMap < [ u8 ; 32 ] , ( usize , usize , Vec < usize > ) > ,
63- received : & mut BTreeMap < [ u8 ; 32 ] , PartialChunk > ,
62+ chunks_info : & mut BTreeMap < ChunkHash , ( usize , usize , Vec < usize > ) > ,
63+ received : & mut BTreeMap < ChunkHash , PartialChunk > ,
64+ last_seen : & mut Vec < ChunkHash > ,
6465) -> Result < Option < ( Vec < usize > , Vec < u8 > ) > > {
65- let hash: & [ u8 ; 32 ] = buf[ ..32 ] . try_into ( ) . unwrap ( ) ;
66+ let hash: ChunkHash = buf[ ..32 ] . try_into ( ) . unwrap ( ) ;
6667 let index = u16:: from_le_bytes ( buf[ 32 ..34 ] . try_into ( ) . unwrap ( ) ) as usize ;
67- let csize = match chunks_info. get ( hash) {
68+ let csize = match chunks_info. get ( & hash) {
6869 Some ( & ( _, csize, _) ) => csize,
6970 _ => return Ok ( None ) ,
7071 } ;
7172
7273 let pchunk = received
73- . entry ( * hash)
74+ . entry ( hash)
7475 . or_insert_with ( || PartialChunk :: new ( csize) ) ;
76+ last_seen. retain ( |x| x != & hash) ;
77+ last_seen. push ( hash) ;
7578
7679 let rot_index = ( index as u16 ) . wrapping_add ( 32 ) as usize ;
7780 match & mut pchunk. missing_first [ rot_index] {
@@ -101,8 +104,9 @@ async fn handle_packet(
101104 }
102105 }
103106
104- let ( size, _, pos) = chunks_info. remove ( hash) . unwrap ( ) ;
105- let mut pchunk = received. remove ( hash) . unwrap ( ) ;
107+ let ( size, _, pos) = chunks_info. remove ( & hash) . unwrap ( ) ;
108+ let mut pchunk = received. remove ( & hash) . unwrap ( ) ;
109+ last_seen. retain ( |x| x != & hash) ;
106110
107111 let mut xor = [ [ 0 ; BODY_LEN ] ; 32 ] ;
108112 for packet in 0 ..pchunk. missing_first . len ( ) {
@@ -126,6 +130,7 @@ async fn handle_packet(
126130
127131 let data = decompress ( & pchunk. data [ 32 * BODY_LEN ..] , size)
128132 . map_err ( |e| Error :: Generic ( e. to_string ( ) ) ) ?;
133+ assert_eq ! ( data. len( ) , size) ;
129134
130135 Ok ( Some ( ( pos, data) ) )
131136}
@@ -226,6 +231,7 @@ pub async fn flash(os: UefiOS, server_addr: SocketAddrV4) -> Result<()> {
226231
227232 let task1 = async {
228233 let mut tx = tx;
234+ let mut last_seen = Vec :: new ( ) ;
229235 while !chunks_info. is_empty ( ) {
230236 let recv = Box :: pin ( socket. recv ( & mut buf) ) ;
231237 let sleep = Box :: pin ( os. sleep_us ( 100_000 ) ) ;
@@ -234,13 +240,18 @@ pub async fn flash(os: UefiOS, server_addr: SocketAddrV4) -> Result<()> {
234240 stats. borrow_mut ( ) . pack_recv += 1 ;
235241 assert ! ( buf. len( ) >= 34 ) ;
236242
237- let chunk = handle_packet ( buf, & mut chunks_info, & mut received) . await ?;
243+ let chunk =
244+ handle_packet ( buf, & mut chunks_info, & mut received, & mut last_seen) ?;
238245 if let Some ( ( pos, data) ) = chunk {
239246 tx. send ( ( pos, data) ) . await ;
240247 }
241248
242- if received. len ( ) > 128 {
243- received. pop_last ( ) ;
249+ assert_eq ! ( last_seen. len( ) , received. len( ) ) ;
250+ if last_seen. len ( ) > 128 {
251+ let hash = last_seen. remove ( 0 ) ;
252+ received
253+ . remove ( & hash)
254+ . expect ( "last_seen should contain only received chunks" ) ;
244255 }
245256 }
246257 Either :: Right ( ( ( ) , _sleep) ) => {
0 commit comments