Skip to main content

mctx_core/
error.rs

1use std::{io, net::IpAddr};
2use thiserror::Error;
3
4/// Errors returned by the multicast sender core.
5#[derive(Debug, Error)]
6pub enum MctxError {
7    /// The configured destination port is invalid.
8    #[error("MCTX: invalid destination port")]
9    InvalidDestinationPort,
10
11    /// The configured group address is not a valid multicast IP address.
12    #[error("MCTX: group must be a multicast IPv4 or IPv6 address")]
13    InvalidMulticastGroup,
14
15    /// The configured source port is invalid.
16    #[error("MCTX: invalid source port")]
17    InvalidSourcePort,
18
19    /// The configured source IP address is invalid.
20    #[error("MCTX: invalid source address")]
21    InvalidSourceAddress,
22
23    /// The configured multicast interface selector is invalid.
24    #[error("MCTX: invalid interface address")]
25    InvalidInterfaceAddress,
26
27    /// The configured IPv6 interface index is invalid.
28    #[error("MCTX: invalid IPv6 interface index")]
29    InvalidIpv6InterfaceIndex,
30
31    /// The configured source address does not match the group address family.
32    #[error("MCTX: source address family must match multicast group family")]
33    SourceAddressFamilyMismatch,
34
35    /// The configured outgoing interface does not match the group address family.
36    #[error("MCTX: outgoing interface family must match multicast group family")]
37    OutgoingInterfaceFamilyMismatch,
38
39    /// The configured IPv6 source address and outgoing interface disagree about
40    /// which interface should be used.
41    #[error(
42        "MCTX: IPv6 source address {source_addr} resolves to interface index {source_interface_index}, expected {outgoing_interface_index}"
43    )]
44    Ipv6SourceInterfaceMismatch {
45        source_addr: IpAddr,
46        source_interface_index: u32,
47        outgoing_interface_index: u32,
48    },
49
50    /// A scoped IPv6 multicast destination needs a concrete interface index.
51    #[error(
52        "MCTX: IPv6 interface-local and link-local multicast destinations require an outgoing interface or source address"
53    )]
54    Ipv6ScopedMulticastRequiresInterface,
55
56    /// Resolving a local IPv6 address to its interface index failed.
57    #[error("MCTX: failed to resolve IPv6 interface: {0}")]
58    InterfaceDiscoveryFailed(String),
59
60    /// A publication with the same configuration already exists.
61    #[error("MCTX: publication already exists")]
62    DuplicatePublication,
63
64    /// No publication with the requested ID exists.
65    #[error("MCTX: publication not found")]
66    PublicationNotFound,
67
68    /// Creating the UDP socket failed.
69    #[error("MCTX: failed to create UDP socket: {0}")]
70    SocketCreateFailed(io::Error),
71
72    /// Setting a socket option failed.
73    #[error("MCTX: failed to set socket option: {0}")]
74    SocketOptionFailed(io::Error),
75
76    /// Binding the UDP socket failed.
77    #[error("MCTX: failed to bind UDP socket: {0}")]
78    SocketBindFailed(io::Error),
79
80    /// Connecting the UDP socket failed.
81    #[error("MCTX: failed to connect UDP socket: {0}")]
82    SocketConnectFailed(io::Error),
83
84    /// Reading the local address from a socket failed.
85    #[error("MCTX: failed to read local address from socket: {0}")]
86    SocketLocalAddrFailed(io::Error),
87
88    /// The provided existing socket does not match the configured IP family.
89    #[error("MCTX: existing socket address family does not match the publication")]
90    ExistingSocketAddressFamilyMismatch,
91
92    /// The provided existing socket is bound to a different UDP port than requested.
93    #[error("MCTX: existing socket is bound to UDP port {actual}, expected {expected}")]
94    ExistingSocketPortMismatch { expected: u16, actual: u16 },
95
96    /// The provided existing socket is bound to a different local IP address than requested.
97    #[error("MCTX: existing socket is bound to local IP address {actual}, expected {expected}")]
98    ExistingSocketAddressMismatch { expected: IpAddr, actual: IpAddr },
99
100    /// Sending a packet failed.
101    #[error("MCTX: send failed: {0}")]
102    SendFailed(io::Error),
103}
104
105impl MctxError {
106    #[cfg(feature = "tokio")]
107    pub(crate) fn is_would_block(&self) -> bool {
108        matches!(self, Self::SendFailed(error) if error.kind() == io::ErrorKind::WouldBlock)
109    }
110}