netstack3_base/error.rs
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151
// 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.
//! Common error types for the netstack.
use net_types::ip::{GenericOverIp, Ip};
use packet::Nested;
use thiserror::Error;
/// 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 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;
/// 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(transparent)]
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,
}
/// 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 {
/// Errors related to the local address.
#[error(transparent)]
Local(#[from] LocalAddressError),
/// Errors related to the remote address.
#[error(transparent)]
Remote(RemoteAddressError),
}
/// Error when link address resolution failed for a neighbor.
#[derive(Error, Debug, PartialEq)]
#[error("address resolution failed")]
pub struct AddressResolutionFailed;
/// An error and a serializer.
///
/// This error type encodes the common pattern of returning an error and the
/// original serializer that caused the error. For brevity, users are encouraged
/// to alias this to local types.
///
/// It provides a `From` implementation from `(E, S)` for convenience and
/// impedance matching with the [`packet`] crate.
#[derive(Debug, PartialEq, Eq)]
pub struct ErrorAndSerializer<E, S> {
/// The error observed.
pub error: E,
/// The serializer accompanying the error.
pub serializer: S,
}
impl<E, S> ErrorAndSerializer<E, S> {
/// Changes the serializer type.
pub fn map_serializer<N, F: FnOnce(S) -> N>(self, f: F) -> ErrorAndSerializer<E, N> {
let Self { error, serializer } = self;
ErrorAndSerializer { error, serializer: f(serializer) }
}
/// Changes the error type.
pub fn map_err<N, F: FnOnce(E) -> N>(self, f: F) -> ErrorAndSerializer<N, S> {
let Self { error, serializer } = self;
ErrorAndSerializer { error: f(error), serializer }
}
/// Changes the error type using [`Into::into`].
pub fn err_into<N: From<E>>(self) -> ErrorAndSerializer<N, S> {
self.map_err(Into::into)
}
/// Consumes this pair and returns only the error, dropping the serializer.
pub fn into_err(self) -> E {
self.error
}
}
impl<E, I, O> ErrorAndSerializer<E, Nested<I, O>> {
/// A convenience function for dealing with [`Nested`] serializers.
///
/// Equivalent to using [`ErrorAndSerializer::map_serializer`].
pub fn into_inner(self) -> ErrorAndSerializer<E, I> {
self.map_serializer(|s| s.into_inner())
}
}