Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
17 changes: 15 additions & 2 deletions crates/sof-observer/fuzz/fuzz_targets/shred_fec_recover.rs
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ use sof::{
},
shred::{
fec::FecRecoverer,
wire::{ParsedShred, parse_shred},
wire::{ParsedDataShredHeader, ParsedShred, ParsedShredHeader, parse_shred},
},
};

Expand Down Expand Up @@ -217,7 +217,20 @@ fuzz_target!(|bytes: &[u8]| {
}
};

let recovered = recoverer.ingest_packet(&packet);
let Ok(parsed) = parse_shred(&packet) else {
assert!(recoverer.tracked_sets() <= max_tracked_sets);
continue;
};
let parsed_header = match parsed {
ParsedShred::Data(data) => ParsedShredHeader::Data(ParsedDataShredHeader {
common: data.common,
data_header: data.data_header,
payload_offset: SIZE_OF_DATA_SHRED_HEADERS,
payload_len: data.payload.len(),
}),
ParsedShred::Code(code) => ParsedShredHeader::Code(code),
};
let recovered = recoverer.ingest_packet(&packet, &parsed_header);
assert!(recoverer.tracked_sets() <= max_tracked_sets);

for recovered_packet in recovered {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -510,7 +510,8 @@ where
parsed_header_slot(&packet.parsed_header),
&mut observed_slot_leaders,
);
let recovered_packets = fec_recoverer.ingest_packet(packet.packet_bytes.as_ref());
let recovered_packets = fec_recoverer
.ingest_packet(packet.packet_bytes.as_ref(), &packet.parsed_header);
push_primary_shred(packet, &mut accepted_shreds);

for recovered in recovered_packets {
Expand Down
28 changes: 12 additions & 16 deletions crates/sof-observer/src/shred/fec/core.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ use std::collections::{HashMap, hash_map::Entry};

use reed_solomon_erasure::galois_8::ReedSolomon;

use crate::shred::wire::{ParsedShred, ShredVariant, parse_shred};
use crate::shred::wire::{ParsedShredHeader, ShredVariant};

#[path = "recover.rs"]
mod recover;
Expand Down Expand Up @@ -69,23 +69,19 @@ impl FecRecoverer {
}
}

pub fn ingest_packet(&mut self, packet: &[u8]) -> Vec<Vec<u8>> {
let parsed = match parse_shred(packet) {
Ok(parsed) => parsed,
Err(_) => return Vec::new(),
};
pub fn ingest_packet(&mut self, packet: &[u8], parsed: &ParsedShredHeader) -> Vec<Vec<u8>> {
let signature = match parse_packet_signature(packet) {
Some(signature) => signature,
None => return Vec::new(),
};

let (slot, fec_set_index, variant) = match &parsed {
ParsedShred::Data(data) => (
let (slot, fec_set_index, variant) = match parsed {
ParsedShredHeader::Data(data) => (
data.common.slot,
data.common.fec_set_index,
SetVariant::from(data.common.shred_variant),
),
ParsedShred::Code(code) => (
ParsedShredHeader::Code(code) => (
code.common.slot,
code.common.fec_set_index,
SetVariant::from(code.common.shred_variant),
Expand All @@ -102,13 +98,13 @@ impl FecRecoverer {
if !set.accepts_variant(variant) {
return Vec::new();
}
set.ingest_packet(&parsed, packet);
set.ingest_packet(parsed, packet);
recovered = recover_missing_data(set, fec_set_index, &mut self.reed_solomon_cache)
.unwrap_or_default();
should_remove = set.is_data_complete_for_config(fec_set_index);
} else {
let mut new_set = ErasureSet::new(signature);
new_set.ingest_packet(&parsed, packet);
new_set.ingest_packet(parsed, packet);
let _ = self.sets.insert(set_id, new_set);
}

Expand Down Expand Up @@ -154,10 +150,10 @@ impl ErasureSet {
self.variant.is_none_or(|existing| existing == incoming)
}

fn ingest_packet(&mut self, parsed: &ParsedShred, packet: &[u8]) {
fn ingest_packet(&mut self, parsed: &ParsedShredHeader, packet: &[u8]) {
let common_variant = match parsed {
ParsedShred::Data(data) => data.common.shred_variant,
ParsedShred::Code(code) => code.common.shred_variant,
ParsedShredHeader::Data(data) => data.common.shred_variant,
ParsedShredHeader::Code(code) => code.common.shred_variant,
};
if self.variant.is_none() {
self.variant = Some(SetVariant::from(common_variant));
Expand All @@ -167,7 +163,7 @@ impl ErasureSet {
};

match parsed {
ParsedShred::Data(data) => {
ParsedShredHeader::Data(data) => {
let Some(shard) = extract_data_erasure_shard(packet, shard_len) else {
return;
};
Expand All @@ -179,7 +175,7 @@ impl ErasureSet {
}
}
}
ParsedShred::Code(code) => {
ParsedShredHeader::Code(code) => {
let Some(shard) = extract_coding_erasure_shard(packet, shard_len) else {
return;
};
Expand Down
Loading