Parse an inbound datagram: verify MAC, bind envelope's advertised origin to the observed remote address, reject replays, then decode the inner [`SwimMessage`].
(auth: &SwimAuth, from: SocketAddr, bytes: &[u8])
| 115 | /// origin to the observed remote address, reject replays, then decode |
| 116 | /// the inner [`SwimMessage`]. |
| 117 | pub fn unwrap(auth: &SwimAuth, from: SocketAddr, bytes: &[u8]) -> Result<SwimMessage, SwimError> { |
| 118 | let (fields, inner_frame) = |
| 119 | auth_envelope::parse_envelope(bytes, &auth.mac_key).map_err(|e| SwimError::Decode { |
| 120 | detail: format!("swim envelope: {e}"), |
| 121 | })?; |
| 122 | |
| 123 | let expected = addr_hash(from); |
| 124 | if fields.from_node_id != expected { |
| 125 | return Err(SwimError::Decode { |
| 126 | detail: format!( |
| 127 | "swim envelope from {from} claimed addr_hash {}, observed hash {}", |
| 128 | fields.from_node_id, expected |
| 129 | ), |
| 130 | }); |
| 131 | } |
| 132 | |
| 133 | auth.seq_in |
| 134 | .accept(fields.from_node_id, fields.seq) |
| 135 | .map_err(|e| SwimError::Decode { |
| 136 | detail: format!("swim replay: {e}"), |
| 137 | })?; |
| 138 | |
| 139 | codec::decode(inner_frame) |
| 140 | } |
| 141 | |
| 142 | #[cfg(test)] |
| 143 | mod tests { |