1

Updated error handling to log common errors

This commit is contained in:
Evan Pratten 2023-07-20 14:50:54 -04:00
parent 81eaf22be0
commit c50c241729
9 changed files with 60 additions and 23 deletions

View File

@ -9,7 +9,7 @@ use crate::{
use self::{
error::Nat64Error,
table::Nat64Table,
utils::{embed_address, extract_address},
utils::{embed_address, extract_address, unwrap_log},
};
use ipnet::{Ipv4Net, Ipv6Net};
use protomask_tun::TunDevice;
@ -99,11 +99,14 @@ impl Nat64 {
// Spawn a task to process the packet
tokio::spawn(async move {
let output =
translate_ipv4_to_ipv6(packet, new_source, new_destination)
.unwrap();
tx.send(output.into()).await.unwrap();
PACKET_COUNTER.with_label_values(&["ipv6", "sent"]).inc();
if let Some(output) = unwrap_log(translate_ipv4_to_ipv6(
packet,
new_source,
new_destination,
)) {
tx.send(output.into()).await.unwrap();
PACKET_COUNTER.with_label_values(&["ipv6", "sent"]).inc();
}
});
}
6 => {
@ -145,11 +148,14 @@ impl Nat64 {
// Spawn a task to process the packet
tokio::spawn(async move {
let output =
translate_ipv6_to_ipv4(packet, new_source, new_destination)
.unwrap();
tx.send(output.into()).await.unwrap();
PACKET_COUNTER.with_label_values(&["ipv4", "sent"]).inc();
if let Some(output) = unwrap_log(translate_ipv6_to_ipv4(
packet,
new_source,
new_destination,
)) {
tx.send(output.into()).await.unwrap();
PACKET_COUNTER.with_label_values(&["ipv4", "sent"]).inc();
}
});
}
n => {

View File

@ -2,6 +2,8 @@ use std::net::{Ipv4Addr, Ipv6Addr};
use ipnet::Ipv6Net;
use crate::packet::error::PacketError;
/// Embed an IPv4 address in an IPv6 prefix
pub fn embed_address(ipv4_address: Ipv4Addr, ipv6_prefix: Ipv6Net) -> Ipv6Addr {
let v4_octets = ipv4_address.octets();
@ -23,3 +25,33 @@ pub fn extract_address(ipv6_address: Ipv6Addr) -> Ipv4Addr {
let octets = ipv6_address.octets();
Ipv4Addr::new(octets[12], octets[13], octets[14], octets[15])
}
/// Logs errors instead of crashing out of them
pub fn unwrap_log<T>(result: Result<T, PacketError>) -> Option<T> {
match result {
Ok(value) => Some(value),
Err(err) => match err {
PacketError::MismatchedAddressFamily(addr_a, addr_b) => {
log::error!(
"Mismatched address family between {} and {}",
addr_a,
addr_b
);
None
}
PacketError::TooShort(len, data) => {
log::warn!("Received packet that's too short to parse. Length {}", len);
log::debug!("Short packet: {:?}", data);
None
}
PacketError::UnsupportedIcmpType(icmp_type) => {
log::warn!("Unsupported ICMP type {}", icmp_type);
None
}
PacketError::UnsupportedIcmpv6Type(icmp_type) => {
log::warn!("Unsupported ICMPv6 type {}", icmp_type);
None
}
},
}
}

View File

@ -5,7 +5,7 @@ pub enum PacketError {
#[error("Mismatched source and destination address family: source={0:?}, destination={1:?}")]
MismatchedAddressFamily(IpAddr, IpAddr),
#[error("Packet too short: {0}")]
TooShort(usize),
TooShort(usize, Vec<u8>),
#[error("Unsupported ICMP type: {0}")]
UnsupportedIcmpType(u8),
#[error("Unsupported ICMPv6 type: {0}")]

View File

@ -31,8 +31,8 @@ where
fn try_from(bytes: Vec<u8>) -> Result<Self, Self::Error> {
// Parse the packet
let packet =
pnet_packet::icmp::IcmpPacket::new(&bytes).ok_or(PacketError::TooShort(bytes.len()))?;
let packet = pnet_packet::icmp::IcmpPacket::new(&bytes)
.ok_or(PacketError::TooShort(bytes.len(), bytes.to_vec()))?;
// Return the packet
Ok(Self {
@ -43,7 +43,6 @@ where
}
}
impl<T> Into<Vec<u8>> for IcmpPacket<T>
where
T: Into<Vec<u8>>,

View File

@ -50,7 +50,7 @@ where
) -> Result<Self, PacketError> {
// Parse the packet
let packet = pnet_packet::icmpv6::Icmpv6Packet::new(bytes)
.ok_or(PacketError::TooShort(bytes.len()))?;
.ok_or(PacketError::TooShort(bytes.len(), bytes.to_vec()))?;
// Return the packet
Ok(Self {
@ -72,7 +72,7 @@ impl Icmpv6Packet<RawBytes> {
) -> Result<Self, PacketError> {
// Parse the packet
let packet = pnet_packet::icmpv6::Icmpv6Packet::new(bytes)
.ok_or(PacketError::TooShort(bytes.len()))?;
.ok_or(PacketError::TooShort(bytes.len(), bytes.to_vec()))?;
// Return the packet
Ok(Self {

View File

@ -71,7 +71,7 @@ where
fn try_from(bytes: Vec<u8>) -> Result<Self, Self::Error> {
// Parse the packet
let packet =
pnet_packet::ipv4::Ipv4Packet::new(&bytes).ok_or(PacketError::TooShort(bytes.len()))?;
pnet_packet::ipv4::Ipv4Packet::new(&bytes).ok_or(PacketError::TooShort(bytes.len(), bytes.to_vec()))?;
// Return the packet
Ok(Self {

View File

@ -47,7 +47,7 @@ where
fn try_from(bytes: Vec<u8>) -> Result<Self, Self::Error> {
// Parse the packet
let packet =
pnet_packet::ipv6::Ipv6Packet::new(&bytes).ok_or(PacketError::TooShort(bytes.len()))?;
pnet_packet::ipv6::Ipv6Packet::new(&bytes).ok_or(PacketError::TooShort(bytes.len(), bytes.to_vec()))?;
// Return the packet
Ok(Self {

View File

@ -131,7 +131,7 @@ where
// Parse the packet
let parsed = pnet_packet::tcp::TcpPacket::new(bytes)
.ok_or_else(|| PacketError::TooShort(bytes.len()))?;
.ok_or_else(|| PacketError::TooShort(bytes.len(), bytes.to_vec()))?;
// Build the struct
Ok(Self {
@ -165,7 +165,7 @@ impl TcpPacket<RawBytes> {
// Parse the packet
let parsed = pnet_packet::tcp::TcpPacket::new(bytes)
.ok_or_else(|| PacketError::TooShort(bytes.len()))?;
.ok_or_else(|| PacketError::TooShort(bytes.len(), bytes.to_vec()))?;
// Build the struct
Ok(Self {

View File

@ -102,7 +102,7 @@ where
// Parse the packet
let parsed = pnet_packet::udp::UdpPacket::new(bytes)
.ok_or_else(|| PacketError::TooShort(bytes.len()))?;
.ok_or_else(|| PacketError::TooShort(bytes.len(), bytes.to_vec()))?;
// Build the struct
Ok(Self {
@ -130,7 +130,7 @@ impl UdpPacket<RawBytes> {
// Parse the packet
let parsed = pnet_packet::udp::UdpPacket::new(bytes)
.ok_or_else(|| PacketError::TooShort(bytes.len()))?;
.ok_or_else(|| PacketError::TooShort(bytes.len(), bytes.to_vec()))?;
// Build the struct
Ok(Self {