Skip to main content

mcrx_core/
error.rs

1use std::io;
2use thiserror::Error;
3
4/// Errors returned by the multicast receiver core.
5#[derive(Debug, Error)]
6pub enum McrxError {
7    /// The configured destination port is invalid.
8    #[error("MCRX: invalid destination port")]
9    InvalidDestinationPort,
10
11    /// The configured group address is not a valid multicast IP address.
12    #[error("MCRX: group must be a multicast IP address")]
13    InvalidMulticastGroup,
14
15    /// An SSM-reserved multicast group was configured without a source filter.
16    #[error("MCRX: SSM-range multicast groups require a source address")]
17    SsmGroupRequiresSource,
18
19    /// The configured SSM source address is invalid.
20    #[error("MCRX: invalid source address")]
21    InvalidSourceAddress,
22
23    /// The configured IPv6 SSM group is not in the IPv6 SSM range.
24    #[error("MCRX: IPv6 SSM groups must use the ff3x:: prefix")]
25    InvalidIpv6SsmGroup,
26
27    /// The configured IPv4 SSM group is not in the IPv4 SSM range.
28    #[error("MCRX: IPv4 SSM groups must use the 232.0.0.0/8 range")]
29    InvalidIpv4SsmGroup,
30
31    /// The configured SSM source address family does not match the group family.
32    #[error("MCRX: source address family must match group address family")]
33    SourceAddressFamilyMismatch,
34
35    /// The configured interface address family does not match the group family.
36    #[error("MCRX: interface address family must match group address family")]
37    InterfaceAddressFamilyMismatch,
38
39    /// The configured interface index is invalid.
40    #[error("MCRX: interface index must be greater than 0")]
41    InvalidInterfaceIndex,
42
43    /// The configured interface index is only valid for IPv6 subscriptions.
44    #[error("MCRX: interface index is only supported for IPv6 subscriptions")]
45    InterfaceIndexRequiresIpv6,
46
47    /// A normal UDP or per-subscription raw context already contains this config.
48    ///
49    /// The opt-in shared raw context deliberately permits duplicate logical
50    /// configs and therefore does not return this variant for duplicates.
51    #[error("MCRX: subscription already exists")]
52    DuplicateSubscription,
53
54    /// No subscription with the requested ID exists.
55    #[error("MCRX: subscription not found")]
56    SubscriptionNotFound,
57
58    /// The subscription is not currently joined to its multicast group.
59    #[error("MCRX: subscription not joined")]
60    SubscriptionNotJoined,
61
62    /// The subscription is already joined to its multicast group.
63    #[error("MCRX: subscription already joined")]
64    SubscriptionAlreadyJoined,
65
66    /// Creating the UDP socket failed.
67    #[error("MCRX: failed to create UDP socket: {0}")]
68    SocketCreateFailed(io::Error),
69
70    /// Setting a socket option failed.
71    #[error("MCRX: failed to set socket option: {0}")]
72    SocketOptionFailed(io::Error),
73
74    /// Binding the UDP socket failed.
75    #[error("MCRX: failed to bind UDP socket: {0}")]
76    SocketBindFailed(io::Error),
77
78    /// Creating the raw receive socket failed.
79    #[error("MCRX: failed to create raw receive socket: {0}")]
80    RawSocketCreateFailed(io::Error),
81
82    /// Binding the raw receive socket failed.
83    #[error("MCRX: failed to bind raw receive socket: {0}")]
84    RawSocketBindFailed(io::Error),
85
86    /// Raw multicast receive is not supported on this platform in this build.
87    #[error("MCRX: raw multicast receive is not supported on this platform: {0}")]
88    RawPacketReceiveUnsupported(String),
89
90    /// The configured shared raw capture limits are invalid.
91    #[cfg(feature = "raw-shared-capture")]
92    #[error("MCRX: shared raw capture limits must be greater than zero")]
93    InvalidSharedRawCaptureLimits,
94
95    /// The shared raw capture context reached its logical membership limit.
96    #[cfg(feature = "raw-shared-capture")]
97    #[error("MCRX: shared raw capture subscription limit of {limit} reached")]
98    SharedRawCaptureSubscriptionLimitExceeded { limit: usize },
99
100    /// Legacy placeholder retained for source compatibility.
101    ///
102    /// IPv6 receive is implemented and this variant is no longer returned.
103    #[deprecated(note = "IPv6 receive is implemented; this variant is never returned")]
104    #[error("MCRX: requested IPv6 functionality is not implemented yet")]
105    Ipv6NotYetImplemented,
106
107    /// A low-level subscription contains internally inconsistent address families.
108    #[error("MCRX: invalid subscription address-family combination")]
109    InvalidSubscriptionAddressFamily,
110
111    /// A low-level adopted receive socket could not be prepared safely.
112    #[error("MCRX: receive socket setup failed: {0}")]
113    ReceiveSocketSetupFailed(String),
114
115    /// A received datagram did not include the destination metadata needed to
116    /// verify that it belongs to the subscription.
117    #[error("MCRX: receive packet did not include destination address metadata")]
118    ReceiveMetadataUnavailable,
119
120    /// Reading the local address of an existing socket failed.
121    #[error("MCRX: failed to read local address from existing socket: {0}")]
122    SocketLocalAddrFailed(io::Error),
123
124    /// Looking up a socket extension function failed.
125    #[error("MCRX: failed to look up socket extension function: {0}")]
126    SocketIoctlFailed(io::Error),
127
128    /// The provided existing socket family does not match the subscription configuration.
129    #[error("MCRX: existing socket address family does not match the subscription configuration")]
130    ExistingSocketAddressFamilyMismatch,
131
132    /// The provided existing socket is bound to a different UDP port than the subscription.
133    #[error("MCRX: existing socket is bound to UDP port {actual}, expected {expected}")]
134    ExistingSocketPortMismatch { expected: u16, actual: u16 },
135
136    /// Joining a multicast group failed.
137    #[error("MCRX: failed to join multicast group: {0}")]
138    MulticastJoinFailed(io::Error),
139
140    /// Leaving a multicast group failed.
141    #[error("MCRX: failed to leave multicast group: {0}")]
142    MulticastLeaveFailed(io::Error),
143
144    /// Source-specific multicast is not supported on this platform.
145    #[error("MCRX: source-specific multicast is not supported on this platform")]
146    SourceSpecificMulticastUnsupported,
147
148    /// IPv6 source-specific multicast requires explicit interface selection.
149    #[error(
150        "MCRX: IPv6 source-specific multicast requires an explicit interface address or interface index"
151    )]
152    Ipv6SourceSpecificMulticastRequiresInterface,
153
154    /// Legacy placeholder retained for source compatibility.
155    ///
156    /// IPv6 SSM receive is implemented and this variant is no longer returned.
157    #[deprecated(note = "IPv6 SSM receive is implemented; this variant is never returned")]
158    #[error("MCRX: IPv6 source-specific multicast is not implemented yet")]
159    Ipv6SourceSpecificMulticastNotYetImplemented,
160
161    /// Binding the interface probe socket failed.
162    #[error("MCRX: failed to bind interface probe socket: {0}")]
163    InterfaceProbeBindFailed(io::Error),
164
165    /// Connecting the interface probe socket failed.
166    #[error("MCRX: failed to connect interface probe socket: {0}")]
167    InterfaceProbeConnectFailed(io::Error),
168
169    /// Reading the local address from the interface probe socket failed.
170    #[error("MCRX: failed to read local address from interface probe socket: {0}")]
171    InterfaceProbeLocalAddrFailed(io::Error),
172
173    /// Discovering the local network interface failed.
174    #[error("MCRX: failed to discover local interface: {0}")]
175    InterfaceDiscoveryFailed(String),
176
177    /// The received packet came from a non-IP socket address.
178    #[error("MCRX: received packet from non-IP socket address")]
179    NonIpSocketAddress,
180
181    /// Receiving a packet failed.
182    #[error("MCRX: receive failed: {0}")]
183    ReceiveFailed(io::Error),
184}