Mercurial > crates > systemd-socket
annotate src/error.rs @ 24:1941e9d9819c
Fix unsound manipulation of env vars
Modifying env vars in multi-threaded process is unsound but this crate
was neither checking the number of threads nor mark its functions as
`unsafe`. This change fixes it by both adding a check and adding an
`unsafe` function that can bypass that check if needed.
author | Martin Habovstiak <martin.habovstiak@gmail.com> |
---|---|
date | Fri, 28 Feb 2025 13:52:31 +0100 |
parents | f6334887e3c8 |
children | cfef4593e207 |
rev | line source |
---|---|
0 | 1 //! Error types that can occur when dealing with `SocketAddr` |
2 //! | |
3 //! This module separates the error types from root module to avoid clutter. | |
4 | |
5 | |
6 use thiserror::Error; | |
24
1941e9d9819c
Fix unsound manipulation of env vars
Martin Habovstiak <martin.habovstiak@gmail.com>
parents:
21
diff
changeset
|
7 use std::fmt; |
0 | 8 use std::io; |
9 | |
24
1941e9d9819c
Fix unsound manipulation of env vars
Martin Habovstiak <martin.habovstiak@gmail.com>
parents:
21
diff
changeset
|
10 /// Error returned when the library initialization fails. |
1941e9d9819c
Fix unsound manipulation of env vars
Martin Habovstiak <martin.habovstiak@gmail.com>
parents:
21
diff
changeset
|
11 #[derive(Debug)] |
1941e9d9819c
Fix unsound manipulation of env vars
Martin Habovstiak <martin.habovstiak@gmail.com>
parents:
21
diff
changeset
|
12 pub struct InitError(pub(crate) InitErrorInner); |
1941e9d9819c
Fix unsound manipulation of env vars
Martin Habovstiak <martin.habovstiak@gmail.com>
parents:
21
diff
changeset
|
13 |
1941e9d9819c
Fix unsound manipulation of env vars
Martin Habovstiak <martin.habovstiak@gmail.com>
parents:
21
diff
changeset
|
14 #[cfg(all(target_os = "linux", feature = "enable_systemd"))] |
1941e9d9819c
Fix unsound manipulation of env vars
Martin Habovstiak <martin.habovstiak@gmail.com>
parents:
21
diff
changeset
|
15 type InitErrorInner = super::systemd_sockets::InitError; |
1941e9d9819c
Fix unsound manipulation of env vars
Martin Habovstiak <martin.habovstiak@gmail.com>
parents:
21
diff
changeset
|
16 |
1941e9d9819c
Fix unsound manipulation of env vars
Martin Habovstiak <martin.habovstiak@gmail.com>
parents:
21
diff
changeset
|
17 #[cfg(not(all(target_os = "linux", feature = "enable_systemd")))] |
1941e9d9819c
Fix unsound manipulation of env vars
Martin Habovstiak <martin.habovstiak@gmail.com>
parents:
21
diff
changeset
|
18 type InitErrorInner = std::convert::Infallible; |
1941e9d9819c
Fix unsound manipulation of env vars
Martin Habovstiak <martin.habovstiak@gmail.com>
parents:
21
diff
changeset
|
19 |
1941e9d9819c
Fix unsound manipulation of env vars
Martin Habovstiak <martin.habovstiak@gmail.com>
parents:
21
diff
changeset
|
20 impl fmt::Display for InitError { |
1941e9d9819c
Fix unsound manipulation of env vars
Martin Habovstiak <martin.habovstiak@gmail.com>
parents:
21
diff
changeset
|
21 #[inline] |
1941e9d9819c
Fix unsound manipulation of env vars
Martin Habovstiak <martin.habovstiak@gmail.com>
parents:
21
diff
changeset
|
22 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { |
1941e9d9819c
Fix unsound manipulation of env vars
Martin Habovstiak <martin.habovstiak@gmail.com>
parents:
21
diff
changeset
|
23 fmt::Display::fmt(&self.0, f) |
1941e9d9819c
Fix unsound manipulation of env vars
Martin Habovstiak <martin.habovstiak@gmail.com>
parents:
21
diff
changeset
|
24 } |
1941e9d9819c
Fix unsound manipulation of env vars
Martin Habovstiak <martin.habovstiak@gmail.com>
parents:
21
diff
changeset
|
25 } |
1941e9d9819c
Fix unsound manipulation of env vars
Martin Habovstiak <martin.habovstiak@gmail.com>
parents:
21
diff
changeset
|
26 |
1941e9d9819c
Fix unsound manipulation of env vars
Martin Habovstiak <martin.habovstiak@gmail.com>
parents:
21
diff
changeset
|
27 impl std::error::Error for InitError { |
1941e9d9819c
Fix unsound manipulation of env vars
Martin Habovstiak <martin.habovstiak@gmail.com>
parents:
21
diff
changeset
|
28 #[inline] |
1941e9d9819c
Fix unsound manipulation of env vars
Martin Habovstiak <martin.habovstiak@gmail.com>
parents:
21
diff
changeset
|
29 fn source(&self) -> Option<&(dyn std::error::Error + 'static)> { |
1941e9d9819c
Fix unsound manipulation of env vars
Martin Habovstiak <martin.habovstiak@gmail.com>
parents:
21
diff
changeset
|
30 self.0.source() |
1941e9d9819c
Fix unsound manipulation of env vars
Martin Habovstiak <martin.habovstiak@gmail.com>
parents:
21
diff
changeset
|
31 } |
1941e9d9819c
Fix unsound manipulation of env vars
Martin Habovstiak <martin.habovstiak@gmail.com>
parents:
21
diff
changeset
|
32 } |
1941e9d9819c
Fix unsound manipulation of env vars
Martin Habovstiak <martin.habovstiak@gmail.com>
parents:
21
diff
changeset
|
33 |
0 | 34 /// Error that can occur during parsing of `SocketAddr` from a string |
35 /// | |
36 /// This encapsulates possible errors that can occur when parsing the input. | |
37 /// It is currently opaque because the representation is not certain yet. | |
38 /// It can be displayed using the standard `Error` trait. | |
39 #[derive(Debug, Error)] | |
40 #[error(transparent)] | |
41 pub struct ParseError(#[from] pub(crate) ParseErrorInner); | |
42 | |
43 #[derive(Debug, Error)] | |
44 pub(crate) enum ParseErrorInner { | |
45 #[error("failed to parse socket address")] | |
4
66c0e10c89fc
Support resolving hostnames
Martin Habovstiak <martin.habovstiak@gmail.com>
parents:
2
diff
changeset
|
46 ResolvAddr(#[from] crate::resolv_addr::ResolvAddrError), |
16
bc76507dd878
Fixed conditional compilation based on OS
Martin Habovstiak <martin.habovstiak@gmail.com>
parents:
13
diff
changeset
|
47 #[cfg(all(target_os = "linux", feature = "enable_systemd"))] |
0 | 48 #[error("invalid character '{c}' in systemd socket name {string} at position {pos}")] |
2
cabc4aafdd85
Added length check and a few tests
Martin Habovstiak <martin.habovstiak@gmail.com>
parents:
0
diff
changeset
|
49 InvalidCharacter { string: String, c: char, pos: usize, }, |
16
bc76507dd878
Fixed conditional compilation based on OS
Martin Habovstiak <martin.habovstiak@gmail.com>
parents:
13
diff
changeset
|
50 #[cfg(all(target_os = "linux", feature = "enable_systemd"))] |
2
cabc4aafdd85
Added length check and a few tests
Martin Habovstiak <martin.habovstiak@gmail.com>
parents:
0
diff
changeset
|
51 #[error("systemd socket name {string} is {len} characters long which is more than the limit 255")] |
cabc4aafdd85
Added length check and a few tests
Martin Habovstiak <martin.habovstiak@gmail.com>
parents:
0
diff
changeset
|
52 LongSocketName { string: String, len: usize, }, |
16
bc76507dd878
Fixed conditional compilation based on OS
Martin Habovstiak <martin.habovstiak@gmail.com>
parents:
13
diff
changeset
|
53 #[cfg(not(all(target_os = "linux", feature = "enable_systemd")))] |
bc76507dd878
Fixed conditional compilation based on OS
Martin Habovstiak <martin.habovstiak@gmail.com>
parents:
13
diff
changeset
|
54 #[cfg_attr(not(target_os = "linux"), error("can't parse {0} because systemd is not supported on this operating system"))] |
bc76507dd878
Fixed conditional compilation based on OS
Martin Habovstiak <martin.habovstiak@gmail.com>
parents:
13
diff
changeset
|
55 #[cfg_attr(target_os = "linux", error("can't parse {0} because systemd support was disabled during build"))] |
6
a7893294e9b2
Make the crate compilable on non-linux systems
Martin Habovstiak <martin.habovstiak@gmail.com>
parents:
4
diff
changeset
|
56 SystemdUnsupported(String), |
0 | 57 } |
58 | |
59 /// Error that can occur during parsing of `SocketAddr` from a `OsStr`/`OsString` | |
60 /// | |
61 /// As opposed to parsing from `&str` or `String`, parsing from `OsStr` can fail due to one more | |
62 /// reason: invalid UTF-8. This error type expresses this possibility and is returned whenever such | |
63 /// conversion is attempted. It is not opaque because the possible variants are pretty much | |
64 /// certain, but it may contain `ParseError` which is opaque. | |
65 /// | |
66 /// This error can be displayed using standard `Error` trait. | |
67 /// See `ParseError` for more information. | |
68 #[derive(Debug, Error)] | |
69 pub enum ParseOsStrError { | |
70 /// The input was not a valid UTF-8 string | |
71 #[error("the address is not a valid UTF-8 string")] | |
72 InvalidUtf8, | |
73 /// The input was a valid UTF-8 string but the address was invalid | |
74 #[error(transparent)] | |
75 InvalidAddress(#[from] ParseError), | |
76 } | |
77 | |
78 /// Error that can occur during binding of a socket | |
79 /// | |
80 /// This encapsulates possible errors that can occur when binding a socket or receiving a socket | |
81 /// from systemd. | |
82 /// It is currently opaque because the representation is not certain yet. | |
83 /// It can be displayed using the standard `Error` trait. | |
84 #[derive(Debug, Error)] | |
85 #[error(transparent)] | |
86 pub struct BindError(#[from] pub(crate) BindErrorInner); | |
87 | |
88 #[derive(Debug, Error)] | |
89 pub(crate) enum BindErrorInner { | |
90 #[error("failed to bind {addr}")] | |
91 BindFailed { addr: std::net::SocketAddr, #[source] error: io::Error, }, | |
4
66c0e10c89fc
Support resolving hostnames
Martin Habovstiak <martin.habovstiak@gmail.com>
parents:
2
diff
changeset
|
92 #[error("failed to bind {addr}")] |
66c0e10c89fc
Support resolving hostnames
Martin Habovstiak <martin.habovstiak@gmail.com>
parents:
2
diff
changeset
|
93 BindOrResolvFailed { addr: crate::resolv_addr::ResolvAddr, #[source] error: io::Error, }, |
16
bc76507dd878
Fixed conditional compilation based on OS
Martin Habovstiak <martin.habovstiak@gmail.com>
parents:
13
diff
changeset
|
94 #[cfg(all(target_os = "linux", feature = "enable_systemd"))] |
0 | 95 #[error("failed to receive descriptors with names")] |
96 ReceiveDescriptors(#[source] crate::systemd_sockets::Error), | |
97 #[error("missing systemd socket {0} - a typo or an attempt to bind twice")] | |
16
bc76507dd878
Fixed conditional compilation based on OS
Martin Habovstiak <martin.habovstiak@gmail.com>
parents:
13
diff
changeset
|
98 #[cfg(all(target_os = "linux", feature = "enable_systemd"))] |
0 | 99 MissingDescriptor(String), |
100 #[error("the systemd socket {0} is not an internet socket")] | |
16
bc76507dd878
Fixed conditional compilation based on OS
Martin Habovstiak <martin.habovstiak@gmail.com>
parents:
13
diff
changeset
|
101 #[cfg(all(target_os = "linux", feature = "enable_systemd"))] |
0 | 102 NotInetSocket(String), |
103 } | |
104 | |
105 /// Error that can happen when binding Tokio socket. | |
106 /// | |
107 /// As opposed to `std` and `async_std` sockets, tokio sockets can fail to convert. | |
108 /// This error type expresses this possibility. | |
21
f6334887e3c8
Support `tokio` 1.0
Martin Habovstiak <martin.habovstiak@gmail.com>
parents:
16
diff
changeset
|
109 #[cfg(any(feature = "tokio", feature = "tokio_0_2", feature = "tokio_0_3"))] |
0 | 110 #[derive(Debug, Error)] |
111 #[error(transparent)] | |
112 pub enum TokioBindError { | |
113 /// Either binding of socket or receiving systemd socket failed | |
114 Bind(#[from] BindError), | |
115 /// Conversion from std `std::net::TcpListener` to `tokio::net::TcpListener` failed | |
116 Convert(#[from] TokioConversionError), | |
117 } | |
118 | |
119 /// Error that can happen when converting Tokio socket. | |
120 /// | |
121 /// As opposed to `std` and `async_std` sockets, tokio sockets can fail to convert. | |
122 /// This error type encapsulates conversion error together with additional information so that it | |
123 /// can be displayed nicely. The encapsulation also allows for future-proofing. | |
21
f6334887e3c8
Support `tokio` 1.0
Martin Habovstiak <martin.habovstiak@gmail.com>
parents:
16
diff
changeset
|
124 #[cfg(any(feature = "tokio", feature = "tokio_0_2", feature = "tokio_0_3"))] |
0 | 125 #[derive(Debug, Error)] |
126 #[error("failed to convert std socket {addr} into tokio socket")] | |
127 pub struct TokioConversionError { | |
128 pub(crate) addr: crate::SocketAddrInner, | |
129 #[source] | |
130 pub(crate) error: io::Error, | |
131 } | |
132 |