blob: c7577e33de9f5d53831eaf67e6aa55ee270819b4 [file] [log] [blame]
// Copyright 2018 The Fuchsia Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
//! Custom error types for the netstack.
use net_types::ip::{GenericOverIp, Ip};
use packet_formats::error::*;
use thiserror::Error;
/// Results returned from many functions in the netstack.
pub type Result<T> = core::result::Result<T, NetstackError>;
/// Top-level error type the netstack.
#[derive(Error, Debug, PartialEq)]
pub enum NetstackError {
#[error("{}", _0)]
/// Errors related to packet parsing.
Parse(ParseError),
/// Error when item already exists.
#[error("Item already exists")]
Exists,
/// Error when item is not found.
#[error("Item not found")]
NotFound,
/// Errors related to sending UDP frames/packets.
#[error("{}", _0)]
SendUdp(crate::transport::udp::SendToError),
/// Errors related to connections.
#[error("{}", _0)]
Connect(SocketError),
/// Error when there is no route to an address.
#[error("No route to address")]
NoRoute,
/// Error when a maximum transmission unit (MTU) is exceeded.
#[error("MTU exceeded")]
Mtu,
// Add error types here as we add more to the stack.
}
/// Error when something is not supported.
#[derive(Debug, PartialEq, Eq, Error, GenericOverIp)]
#[generic_over_ip()]
#[error("Not supported")]
pub struct NotSupportedError;
/// Error when something exists unexpectedly.
#[derive(Debug, Error, PartialEq, Eq)]
#[error("Already exists")]
pub struct ExistsError;
impl From<ExistsError> for NetstackError {
fn from(_: ExistsError) -> NetstackError {
NetstackError::Exists
}
}
impl From<ExistsError> for SocketError {
fn from(_: ExistsError) -> SocketError {
SocketError::Local(LocalAddressError::AddressInUse)
}
}
/// Error when something unexpectedly doesn't exist, such as trying to
/// remove an element when the element is not present.
#[derive(Debug, Error, PartialEq, Eq)]
#[error("Not found")]
pub struct NotFoundError;
impl From<NotFoundError> for NetstackError {
fn from(_: NotFoundError) -> NetstackError {
NetstackError::NotFound
}
}
/// Error type for errors common to local addresses.
#[derive(Error, Debug, PartialEq, GenericOverIp)]
#[generic_over_ip()]
pub enum LocalAddressError {
/// Cannot bind to address.
#[error("can't bind to address")]
CannotBindToAddress,
/// Failed to allocate local port.
#[error("failed to allocate local port")]
FailedToAllocateLocalPort,
/// Specified local address does not match any expected address.
#[error("specified local address does not match any expected address")]
AddressMismatch,
/// The requested address/socket pair is in use.
#[error("Address in use")]
AddressInUse,
/// The address cannot be used because of its zone.
///
/// TODO(https://fxbug.dev/42054471): Make this an IP socket error once UDP
/// sockets contain IP sockets.
#[error("{}", _0)]
Zone(#[from] ZonedAddressError),
/// The requested address is mapped (i.e. an IPv4-mapped-IPv6 address), but
/// the socket is not dual-stack enabled.
#[error("Address is mapped")]
AddressUnexpectedlyMapped,
}
/// Indicates a problem related to an address with a zone.
#[derive(Copy, Clone, Debug, Error, Eq, PartialEq, GenericOverIp)]
#[generic_over_ip()]
pub enum ZonedAddressError {
/// The address scope requires a zone but didn't have one.
#[error("the address requires a zone but didn't have one")]
RequiredZoneNotProvided,
/// The address has a zone that doesn't match an existing device constraint.
#[error("the socket's device does not match the zone")]
DeviceZoneMismatch,
}
// TODO(joshlf): Once we support a more general model of sockets in which UDP
// and ICMP connections are special cases of UDP and ICMP sockets, we can
// introduce a more specialized ListenerError which does not contain the NoRoute
// variant.
/// An error encountered when attempting to create a UDP, TCP, or ICMP connection.
#[derive(Error, Debug, PartialEq)]
pub enum RemoteAddressError {
/// No route to host.
#[error("no route to host")]
NoRoute,
}
/// Error type for connection errors.
#[derive(Error, Debug, PartialEq)]
pub enum SocketError {
#[error("{}", _0)]
/// Errors related to the local address.
Local(#[from] LocalAddressError),
#[error("{}", _0)]
/// Errors related to the remote address.
Remote(RemoteAddressError),
}
/// Error when no route exists to a remote address.
#[derive(Debug, PartialEq, Eq)]
pub struct NoRouteError;
impl From<NoRouteError> for NetstackError {
fn from(_: NoRouteError) -> NetstackError {
NetstackError::NoRoute
}
}
impl From<NoRouteError> for SocketError {
fn from(_: NoRouteError) -> SocketError {
SocketError::Remote(RemoteAddressError::NoRoute)
}
}
/// Error when link address resolution failed for a neighbor.
#[derive(Debug, PartialEq)]
pub struct AddressResolutionFailed;