MCPcopy Create free account
hub / github.com/NodeDB-Lab/nodedb / parse_frame

Function parse_frame

nodedb-cluster/src/rpc_codec/header.rs:57–117  ·  view source on GitHub ↗

Validate the CRC32C of an inbound frame and return the payload slice. `data` must start at byte 0 (version byte). Returns `(rpc_type, payload)`. Side effect: observes the peer's cluster epoch via [`observe_peer_cluster_epoch`] (monotonic max).

(data: &[u8])

Source from the content-addressed store, hash-verified

55/// Side effect: observes the peer's cluster epoch via
56/// [`observe_peer_cluster_epoch`] (monotonic max).
57pub fn parse_frame(data: &[u8]) -> Result<(u8, &[u8])> {
58 if data.is_empty() {
59 return Err(ClusterError::Codec {
60 detail: format!("frame too short: 0 bytes, need {HEADER_SIZE}"),
61 });
62 }
63
64 let version = data[0];
65 if version != RPC_FRAME_VERSION {
66 return Err(ClusterError::UnsupportedWireVersion {
67 got: version,
68 supported_min: RPC_FRAME_VERSION,
69 supported_max: RPC_FRAME_VERSION,
70 });
71 }
72
73 if data.len() < HEADER_SIZE {
74 return Err(ClusterError::Codec {
75 detail: format!("frame too short: {} bytes, need {HEADER_SIZE}", data.len()),
76 });
77 }
78
79 let rpc_type = data[1];
80 let payload_len = u32::from_le_bytes([data[2], data[3], data[4], data[5]]);
81 let expected_crc = u32::from_le_bytes([data[6], data[7], data[8], data[9]]);
82 let peer_epoch = u64::from_le_bytes([
83 data[10], data[11], data[12], data[13], data[14], data[15], data[16], data[17],
84 ]);
85
86 if payload_len > MAX_RPC_PAYLOAD_SIZE {
87 return Err(ClusterError::Codec {
88 detail: format!("payload length {payload_len} exceeds maximum {MAX_RPC_PAYLOAD_SIZE}"),
89 });
90 }
91
92 let expected_total = HEADER_SIZE + payload_len as usize;
93 if data.len() < expected_total {
94 return Err(ClusterError::Codec {
95 detail: format!(
96 "frame truncated: got {} bytes, expected {expected_total}",
97 data.len()
98 ),
99 });
100 }
101
102 let payload = &data[HEADER_SIZE..expected_total];
103 let actual_crc = crc32c::crc32c(payload);
104 if actual_crc != expected_crc {
105 return Err(ClusterError::Codec {
106 detail: format!(
107 "CRC32C mismatch: expected {expected_crc:#010x}, got {actual_crc:#010x}"
108 ),
109 });
110 }
111
112 if peer_epoch > 0 {
113 observe_peer_cluster_epoch(peer_epoch);
114 }

Calls 3

is_emptyMethod · 0.45
lenMethod · 0.45