1// Copyright 2018 The Fuchsia Authors. All rights reserved.
2// Use of this source code is governed by a BSD-style license that can be
3// found in the LICENSE file.
45//! Common error types for the netstack.
67use net_types::ip::{GenericOverIp, Ip};
8use packet::Nested;
9use thiserror::Error;
1011/// Error when something is not supported.
12#[derive(Debug, PartialEq, Eq, Error, GenericOverIp)]
13#[generic_over_ip()]
14#[error("not supported")]
15pub struct NotSupportedError;
1617/// Error when something exists unexpectedly.
18#[derive(Debug, Error, PartialEq, Eq)]
19#[error("already exists")]
20pub struct ExistsError;
2122impl From<ExistsError> for SocketError {
23fn from(_: ExistsError) -> SocketError {
24 SocketError::Local(LocalAddressError::AddressInUse)
25 }
26}
2728/// Error when something unexpectedly doesn't exist, such as trying to
29/// remove an element when the element is not present.
30#[derive(Debug, Error, PartialEq, Eq)]
31#[error("not found")]
32pub struct NotFoundError;
3334/// Error type for errors common to local addresses.
35#[derive(Error, Debug, PartialEq, GenericOverIp)]
36#[generic_over_ip()]
37pub enum LocalAddressError {
38/// Cannot bind to address.
39#[error("can't bind to address")]
40CannotBindToAddress,
4142/// Failed to allocate local port.
43#[error("failed to allocate local port")]
44FailedToAllocateLocalPort,
4546/// Specified local address does not match any expected address.
47#[error("specified local address does not match any expected address")]
48AddressMismatch,
4950/// The requested address/socket pair is in use.
51#[error("address in use")]
52AddressInUse,
5354/// The address cannot be used because of its zone.
55 ///
56 /// TODO(https://fxbug.dev/42054471): Make this an IP socket error once UDP
57 /// sockets contain IP sockets.
58#[error(transparent)]
59Zone(#[from] ZonedAddressError),
6061/// The requested address is mapped (i.e. an IPv4-mapped-IPv6 address), but
62 /// the socket is not dual-stack enabled.
63#[error("address is mapped")]
64AddressUnexpectedlyMapped,
65}
6667/// Indicates a problem related to an address with a zone.
68#[derive(Copy, Clone, Debug, Error, Eq, PartialEq, GenericOverIp)]
69#[generic_over_ip()]
70pub enum ZonedAddressError {
71/// The address scope requires a zone but didn't have one.
72#[error("the address requires a zone but didn't have one")]
73RequiredZoneNotProvided,
74/// The address has a zone that doesn't match an existing device constraint.
75#[error("the socket's device does not match the zone")]
76DeviceZoneMismatch,
77}
7879/// An error encountered when attempting to create a UDP, TCP, or ICMP connection.
80#[derive(Error, Debug, PartialEq)]
81pub enum RemoteAddressError {
82/// No route to host.
83#[error("no route to host")]
84NoRoute,
85}
8687/// Error type for connection errors.
88#[derive(Error, Debug, PartialEq)]
89pub enum SocketError {
90/// Errors related to the local address.
91#[error(transparent)]
92Local(#[from] LocalAddressError),
9394/// Errors related to the remote address.
95#[error(transparent)]
96Remote(RemoteAddressError),
97}
9899/// Error when link address resolution failed for a neighbor.
100#[derive(Error, Debug, PartialEq)]
101#[error("address resolution failed")]
102pub struct AddressResolutionFailed;
103104/// An error and a serializer.
105///
106/// This error type encodes the common pattern of returning an error and the
107/// original serializer that caused the error. For brevity, users are encouraged
108/// to alias this to local types.
109///
110/// It provides a `From` implementation from `(E, S)` for convenience and
111/// impedance matching with the [`packet`] crate.
112#[derive(Debug, PartialEq, Eq)]
113pub struct ErrorAndSerializer<E, S> {
114/// The error observed.
115pub error: E,
116/// The serializer accompanying the error.
117pub serializer: S,
118}
119120impl<E, S> ErrorAndSerializer<E, S> {
121/// Changes the serializer type.
122pub fn map_serializer<N, F: FnOnce(S) -> N>(self, f: F) -> ErrorAndSerializer<E, N> {
123let Self { error, serializer } = self;
124 ErrorAndSerializer { error, serializer: f(serializer) }
125 }
126127/// Changes the error type.
128pub fn map_err<N, F: FnOnce(E) -> N>(self, f: F) -> ErrorAndSerializer<N, S> {
129let Self { error, serializer } = self;
130 ErrorAndSerializer { error: f(error), serializer }
131 }
132133/// Changes the error type using [`Into::into`].
134pub fn err_into<N: From<E>>(self) -> ErrorAndSerializer<N, S> {
135self.map_err(Into::into)
136 }
137138/// Consumes this pair and returns only the error, dropping the serializer.
139pub fn into_err(self) -> E {
140self.error
141 }
142}
143144impl<E, I, O> ErrorAndSerializer<E, Nested<I, O>> {
145/// A convenience function for dealing with [`Nested`] serializers.
146 ///
147 /// Equivalent to using [`ErrorAndSerializer::map_serializer`].
148pub fn into_inner(self) -> ErrorAndSerializer<E, I> {
149self.map_serializer(|s| s.into_inner())
150 }
151}