annotate src/lib.rs @ 26:0feab4f4c2ce

Relax version requirements and update MSRV The MSRV was accidentally increased without documentation. Increase itself is fine since it satisfies "latest stable Debian" condition but given there are soundness issues this relaxes the version requirements to work on 1.48 and also documents it.
author Martin Habovstiak <martin.habovstiak@gmail.com>
date Fri, 28 Feb 2025 23:10:11 +0100
parents 8e20daee41ed
children cfef4593e207 e15210d1e534
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
rev   line source
0
a65053246c29 Initial commit
Martin Habovstiak <martin.habovstiak@gmail.com>
parents:
diff changeset
1 //! A convenience crate for optionally supporting systemd socket activation.
a65053246c29 Initial commit
Martin Habovstiak <martin.habovstiak@gmail.com>
parents:
diff changeset
2 //!
a65053246c29 Initial commit
Martin Habovstiak <martin.habovstiak@gmail.com>
parents:
diff changeset
3 //! ## About
24
1941e9d9819c Fix unsound manipulation of env vars
Martin Habovstiak <martin.habovstiak@gmail.com>
parents: 22
diff changeset
4 //!
1941e9d9819c Fix unsound manipulation of env vars
Martin Habovstiak <martin.habovstiak@gmail.com>
parents: 22
diff changeset
5 //! **Important:** because of various reasons it is recommended to call the [`init`] function at
1941e9d9819c Fix unsound manipulation of env vars
Martin Habovstiak <martin.habovstiak@gmail.com>
parents: 22
diff changeset
6 //! the start of your program!
0
a65053246c29 Initial commit
Martin Habovstiak <martin.habovstiak@gmail.com>
parents:
diff changeset
7 //!
a65053246c29 Initial commit
Martin Habovstiak <martin.habovstiak@gmail.com>
parents:
diff changeset
8 //! The goal of this crate is to make socket activation with systemd in your project trivial.
a65053246c29 Initial commit
Martin Habovstiak <martin.habovstiak@gmail.com>
parents:
diff changeset
9 //! It provides a replacement for `std::net::SocketAddr` that allows parsing the bind address from string just like the one from `std`
a65053246c29 Initial commit
Martin Habovstiak <martin.habovstiak@gmail.com>
parents:
diff changeset
10 //! but on top of that also allows `systemd://socket_name` format that tells it to use systemd activation with given socket name.
a65053246c29 Initial commit
Martin Habovstiak <martin.habovstiak@gmail.com>
parents:
diff changeset
11 //! Then it provides a method to bind the address which will return the socket from systemd if available.
24
1941e9d9819c Fix unsound manipulation of env vars
Martin Habovstiak <martin.habovstiak@gmail.com>
parents: 22
diff changeset
12 //!
0
a65053246c29 Initial commit
Martin Habovstiak <martin.habovstiak@gmail.com>
parents:
diff changeset
13 //! The provided type supports conversions from various types of strings and also `serde` and `parse_arg` via feature flag.
a65053246c29 Initial commit
Martin Habovstiak <martin.habovstiak@gmail.com>
parents:
diff changeset
14 //! Thanks to this the change to your code should be minimal - parsing will continue to work, it'll just allow a new format.
a65053246c29 Initial commit
Martin Habovstiak <martin.habovstiak@gmail.com>
parents:
diff changeset
15 //! You only need to change the code to use `SocketAddr::bind()` instead of `TcpListener::bind()` for binding.
a65053246c29 Initial commit
Martin Habovstiak <martin.habovstiak@gmail.com>
parents:
diff changeset
16 //!
6
a7893294e9b2 Make the crate compilable on non-linux systems
Martin Habovstiak <martin.habovstiak@gmail.com>
parents: 4
diff changeset
17 //! You also don't need to worry about conditional compilation to ensure OS compatibility.
a7893294e9b2 Make the crate compilable on non-linux systems
Martin Habovstiak <martin.habovstiak@gmail.com>
parents: 4
diff changeset
18 //! This crate handles that for you by disabling systemd on non-linux systems.
a7893294e9b2 Make the crate compilable on non-linux systems
Martin Habovstiak <martin.habovstiak@gmail.com>
parents: 4
diff changeset
19 //!
21
f6334887e3c8 Support `tokio` 1.0
Martin Habovstiak <martin.habovstiak@gmail.com>
parents: 20
diff changeset
20 //! Further, the crate also provides methods for binding `tokio` 1.0, 0.2, 0.3, and `async_std` sockets if the appropriate features are
4
66c0e10c89fc Support resolving hostnames
Martin Habovstiak <martin.habovstiak@gmail.com>
parents: 3
diff changeset
21 //! activated.
0
a65053246c29 Initial commit
Martin Habovstiak <martin.habovstiak@gmail.com>
parents:
diff changeset
22 //!
a65053246c29 Initial commit
Martin Habovstiak <martin.habovstiak@gmail.com>
parents:
diff changeset
23 //! ## Example
a65053246c29 Initial commit
Martin Habovstiak <martin.habovstiak@gmail.com>
parents:
diff changeset
24 //!
a65053246c29 Initial commit
Martin Habovstiak <martin.habovstiak@gmail.com>
parents:
diff changeset
25 //! ```no_run
a65053246c29 Initial commit
Martin Habovstiak <martin.habovstiak@gmail.com>
parents:
diff changeset
26 //! use systemd_socket::SocketAddr;
a65053246c29 Initial commit
Martin Habovstiak <martin.habovstiak@gmail.com>
parents:
diff changeset
27 //! use std::convert::TryFrom;
a65053246c29 Initial commit
Martin Habovstiak <martin.habovstiak@gmail.com>
parents:
diff changeset
28 //! use std::io::Write;
a65053246c29 Initial commit
Martin Habovstiak <martin.habovstiak@gmail.com>
parents:
diff changeset
29 //!
24
1941e9d9819c Fix unsound manipulation of env vars
Martin Habovstiak <martin.habovstiak@gmail.com>
parents: 22
diff changeset
30 //! systemd_socket::init().expect("Failed to initialize systemd sockets");
0
a65053246c29 Initial commit
Martin Habovstiak <martin.habovstiak@gmail.com>
parents:
diff changeset
31 //! let mut args = std::env::args_os();
a65053246c29 Initial commit
Martin Habovstiak <martin.habovstiak@gmail.com>
parents:
diff changeset
32 //! let program_name = args.next().expect("unknown program name");
a65053246c29 Initial commit
Martin Habovstiak <martin.habovstiak@gmail.com>
parents:
diff changeset
33 //! let socket_addr = args.next().expect("missing socket address");
a65053246c29 Initial commit
Martin Habovstiak <martin.habovstiak@gmail.com>
parents:
diff changeset
34 //! let socket_addr = SocketAddr::try_from(socket_addr).expect("failed to parse socket address");
a65053246c29 Initial commit
Martin Habovstiak <martin.habovstiak@gmail.com>
parents:
diff changeset
35 //! let socket = socket_addr.bind().expect("failed to bind socket");
a65053246c29 Initial commit
Martin Habovstiak <martin.habovstiak@gmail.com>
parents:
diff changeset
36 //!
a65053246c29 Initial commit
Martin Habovstiak <martin.habovstiak@gmail.com>
parents:
diff changeset
37 //! loop {
a65053246c29 Initial commit
Martin Habovstiak <martin.habovstiak@gmail.com>
parents:
diff changeset
38 //! let _ = socket
a65053246c29 Initial commit
Martin Habovstiak <martin.habovstiak@gmail.com>
parents:
diff changeset
39 //! .accept()
a65053246c29 Initial commit
Martin Habovstiak <martin.habovstiak@gmail.com>
parents:
diff changeset
40 //! .expect("failed to accept connection")
a65053246c29 Initial commit
Martin Habovstiak <martin.habovstiak@gmail.com>
parents:
diff changeset
41 //! .0
a65053246c29 Initial commit
Martin Habovstiak <martin.habovstiak@gmail.com>
parents:
diff changeset
42 //! .write_all(b"Hello world!")
a65053246c29 Initial commit
Martin Habovstiak <martin.habovstiak@gmail.com>
parents:
diff changeset
43 //! .map_err(|err| eprintln!("Failed to send {}", err));
a65053246c29 Initial commit
Martin Habovstiak <martin.habovstiak@gmail.com>
parents:
diff changeset
44 //! }
a65053246c29 Initial commit
Martin Habovstiak <martin.habovstiak@gmail.com>
parents:
diff changeset
45 //! ```
a65053246c29 Initial commit
Martin Habovstiak <martin.habovstiak@gmail.com>
parents:
diff changeset
46 //!
a65053246c29 Initial commit
Martin Habovstiak <martin.habovstiak@gmail.com>
parents:
diff changeset
47 //! ## Features
a65053246c29 Initial commit
Martin Habovstiak <martin.habovstiak@gmail.com>
parents:
diff changeset
48 //!
13
f740dadd2948 Added enable_systemd feature
Martin Habovstiak <martin.habovstiak@gmail.com>
parents: 11
diff changeset
49 //! * `enable_systemd` - on by default, the existence of this feature can allow your users to turn
f740dadd2948 Added enable_systemd feature
Martin Habovstiak <martin.habovstiak@gmail.com>
parents: 11
diff changeset
50 //! off systemd support if they don't need it. Note that it's already disabled on non-linux
f740dadd2948 Added enable_systemd feature
Martin Habovstiak <martin.habovstiak@gmail.com>
parents: 11
diff changeset
51 //! systems, so you don't need to care about that.
0
a65053246c29 Initial commit
Martin Habovstiak <martin.habovstiak@gmail.com>
parents:
diff changeset
52 //! * `serde` - implements `serde::Deserialize` for `SocketAddr`
a65053246c29 Initial commit
Martin Habovstiak <martin.habovstiak@gmail.com>
parents:
diff changeset
53 //! * `parse_arg` - implements `parse_arg::ParseArg` for `SocketAddr`
21
f6334887e3c8 Support `tokio` 1.0
Martin Habovstiak <martin.habovstiak@gmail.com>
parents: 20
diff changeset
54 //! * `tokio` - adds `bind_tokio` method to `SocketAddr` (tokio 1.0)
4
66c0e10c89fc Support resolving hostnames
Martin Habovstiak <martin.habovstiak@gmail.com>
parents: 3
diff changeset
55 //! * `tokio_0_2` - adds `bind_tokio_0_2` method to `SocketAddr`
66c0e10c89fc Support resolving hostnames
Martin Habovstiak <martin.habovstiak@gmail.com>
parents: 3
diff changeset
56 //! * `tokio_0_3` - adds `bind_tokio_0_3` method to `SocketAddr`
66c0e10c89fc Support resolving hostnames
Martin Habovstiak <martin.habovstiak@gmail.com>
parents: 3
diff changeset
57 //! * `async_std` - adds `bind_async_std` method to `SocketAddr`
3
0edcde404b02 Added information about MSRV
Martin Habovstiak <martin.habovstiak@gmail.com>
parents: 2
diff changeset
58 //!
24
1941e9d9819c Fix unsound manipulation of env vars
Martin Habovstiak <martin.habovstiak@gmail.com>
parents: 22
diff changeset
59 //! ## Soundness
1941e9d9819c Fix unsound manipulation of env vars
Martin Habovstiak <martin.habovstiak@gmail.com>
parents: 22
diff changeset
60 //!
1941e9d9819c Fix unsound manipulation of env vars
Martin Habovstiak <martin.habovstiak@gmail.com>
parents: 22
diff changeset
61 //! The systemd file descriptors are transferred using environment variables and since they are
1941e9d9819c Fix unsound manipulation of env vars
Martin Habovstiak <martin.habovstiak@gmail.com>
parents: 22
diff changeset
62 //! file descriptors, they should have move semantics. However environment variables in Rust do not
1941e9d9819c Fix unsound manipulation of env vars
Martin Habovstiak <martin.habovstiak@gmail.com>
parents: 22
diff changeset
63 //! have move semantics and even modifying them is very dangerous.
1941e9d9819c Fix unsound manipulation of env vars
Martin Habovstiak <martin.habovstiak@gmail.com>
parents: 22
diff changeset
64 //!
1941e9d9819c Fix unsound manipulation of env vars
Martin Habovstiak <martin.habovstiak@gmail.com>
parents: 22
diff changeset
65 //! Because of this, the crate only allows initialization when there's only one thread running.
1941e9d9819c Fix unsound manipulation of env vars
Martin Habovstiak <martin.habovstiak@gmail.com>
parents: 22
diff changeset
66 //! However that still doesn't prevent all possible problems: if some other code closes file
1941e9d9819c Fix unsound manipulation of env vars
Martin Habovstiak <martin.habovstiak@gmail.com>
parents: 22
diff changeset
67 //! descriptors stored in those environment variables you can get an invalid socket.
1941e9d9819c Fix unsound manipulation of env vars
Martin Habovstiak <martin.habovstiak@gmail.com>
parents: 22
diff changeset
68 //!
1941e9d9819c Fix unsound manipulation of env vars
Martin Habovstiak <martin.habovstiak@gmail.com>
parents: 22
diff changeset
69 //! This situation is obviously ridiculous because there shouldn't be a reason to use another
1941e9d9819c Fix unsound manipulation of env vars
Martin Habovstiak <martin.habovstiak@gmail.com>
parents: 22
diff changeset
70 //! library to do the same thing. It could also be argued that whichever code doesn't clear the
1941e9d9819c Fix unsound manipulation of env vars
Martin Habovstiak <martin.habovstiak@gmail.com>
parents: 22
diff changeset
71 //! evironment variable is broken (even though understandably) and it's not a fault of this library.
1941e9d9819c Fix unsound manipulation of env vars
Martin Habovstiak <martin.habovstiak@gmail.com>
parents: 22
diff changeset
72 //!
3
0edcde404b02 Added information about MSRV
Martin Habovstiak <martin.habovstiak@gmail.com>
parents: 2
diff changeset
73 //! ## MSRV
0edcde404b02 Added information about MSRV
Martin Habovstiak <martin.habovstiak@gmail.com>
parents: 2
diff changeset
74 //!
0edcde404b02 Added information about MSRV
Martin Habovstiak <martin.habovstiak@gmail.com>
parents: 2
diff changeset
75 //! This crate must always compile with the latest Rust available in the latest Debian stable.
26
0feab4f4c2ce Relax version requirements and update MSRV
Martin Habovstiak <martin.habovstiak@gmail.com>
parents: 25
diff changeset
76 //! That is currently Rust 1.48.0. (Debian 11 - Bullseye)
3
0edcde404b02 Added information about MSRV
Martin Habovstiak <martin.habovstiak@gmail.com>
parents: 2
diff changeset
77
22
f33e2c048104 Enable `doc_auto_cfg` in docs.rs builds
Martin Habovstiak <martin.habovstiak@gmail.com>
parents: 21
diff changeset
78 #![cfg_attr(docsrs, feature(doc_auto_cfg))]
0
a65053246c29 Initial commit
Martin Habovstiak <martin.habovstiak@gmail.com>
parents:
diff changeset
79
a65053246c29 Initial commit
Martin Habovstiak <martin.habovstiak@gmail.com>
parents:
diff changeset
80 #![deny(missing_docs)]
a65053246c29 Initial commit
Martin Habovstiak <martin.habovstiak@gmail.com>
parents:
diff changeset
81
a65053246c29 Initial commit
Martin Habovstiak <martin.habovstiak@gmail.com>
parents:
diff changeset
82 pub mod error;
4
66c0e10c89fc Support resolving hostnames
Martin Habovstiak <martin.habovstiak@gmail.com>
parents: 3
diff changeset
83 mod resolv_addr;
0
a65053246c29 Initial commit
Martin Habovstiak <martin.habovstiak@gmail.com>
parents:
diff changeset
84
a65053246c29 Initial commit
Martin Habovstiak <martin.habovstiak@gmail.com>
parents:
diff changeset
85 use std::convert::{TryFrom, TryInto};
a65053246c29 Initial commit
Martin Habovstiak <martin.habovstiak@gmail.com>
parents:
diff changeset
86 use std::fmt;
a65053246c29 Initial commit
Martin Habovstiak <martin.habovstiak@gmail.com>
parents:
diff changeset
87 use std::ffi::{OsStr, OsString};
a65053246c29 Initial commit
Martin Habovstiak <martin.habovstiak@gmail.com>
parents:
diff changeset
88 use crate::error::*;
4
66c0e10c89fc Support resolving hostnames
Martin Habovstiak <martin.habovstiak@gmail.com>
parents: 3
diff changeset
89 use crate::resolv_addr::ResolvAddr;
0
a65053246c29 Initial commit
Martin Habovstiak <martin.habovstiak@gmail.com>
parents:
diff changeset
90
16
bc76507dd878 Fixed conditional compilation based on OS
Martin Habovstiak <martin.habovstiak@gmail.com>
parents: 13
diff changeset
91 #[cfg(not(all(target_os = "linux", feature = "enable_systemd")))]
6
a7893294e9b2 Make the crate compilable on non-linux systems
Martin Habovstiak <martin.habovstiak@gmail.com>
parents: 4
diff changeset
92 use std::convert::Infallible as Never;
a7893294e9b2 Make the crate compilable on non-linux systems
Martin Habovstiak <martin.habovstiak@gmail.com>
parents: 4
diff changeset
93
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
a65053246c29 Initial commit
Martin Habovstiak <martin.habovstiak@gmail.com>
parents:
diff changeset
95 pub(crate) mod systemd_sockets {
a65053246c29 Initial commit
Martin Habovstiak <martin.habovstiak@gmail.com>
parents:
diff changeset
96 use std::fmt;
a65053246c29 Initial commit
Martin Habovstiak <martin.habovstiak@gmail.com>
parents:
diff changeset
97 use std::sync::Mutex;
a65053246c29 Initial commit
Martin Habovstiak <martin.habovstiak@gmail.com>
parents:
diff changeset
98 use libsystemd::activation::FileDescriptor;
20
2b78a483f84b Update `libsystemd`
Martin Habovstiak <martin.habovstiak@gmail.com>
parents: 18
diff changeset
99 use libsystemd::errors::SdError as LibSystemdError;
0
a65053246c29 Initial commit
Martin Habovstiak <martin.habovstiak@gmail.com>
parents:
diff changeset
100
a65053246c29 Initial commit
Martin Habovstiak <martin.habovstiak@gmail.com>
parents:
diff changeset
101 #[derive(Debug)]
24
1941e9d9819c Fix unsound manipulation of env vars
Martin Habovstiak <martin.habovstiak@gmail.com>
parents: 22
diff changeset
102 pub(crate) struct Error(&'static Mutex<InitError>);
0
a65053246c29 Initial commit
Martin Habovstiak <martin.habovstiak@gmail.com>
parents:
diff changeset
103
a65053246c29 Initial commit
Martin Habovstiak <martin.habovstiak@gmail.com>
parents:
diff changeset
104 impl fmt::Display for Error {
a65053246c29 Initial commit
Martin Habovstiak <martin.habovstiak@gmail.com>
parents:
diff changeset
105 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
24
1941e9d9819c Fix unsound manipulation of env vars
Martin Habovstiak <martin.habovstiak@gmail.com>
parents: 22
diff changeset
106 use std::error::Error as _;
1941e9d9819c Fix unsound manipulation of env vars
Martin Habovstiak <martin.habovstiak@gmail.com>
parents: 22
diff changeset
107
1941e9d9819c Fix unsound manipulation of env vars
Martin Habovstiak <martin.habovstiak@gmail.com>
parents: 22
diff changeset
108 let guard = self.0.lock().expect("mutex poisoned");
1941e9d9819c Fix unsound manipulation of env vars
Martin Habovstiak <martin.habovstiak@gmail.com>
parents: 22
diff changeset
109 fmt::Display::fmt(&*guard, f)?;
1941e9d9819c Fix unsound manipulation of env vars
Martin Habovstiak <martin.habovstiak@gmail.com>
parents: 22
diff changeset
110 let mut source_opt = guard.source();
1941e9d9819c Fix unsound manipulation of env vars
Martin Habovstiak <martin.habovstiak@gmail.com>
parents: 22
diff changeset
111 while let Some(source) = source_opt {
1941e9d9819c Fix unsound manipulation of env vars
Martin Habovstiak <martin.habovstiak@gmail.com>
parents: 22
diff changeset
112 write!(f, ": {}", source)?;
1941e9d9819c Fix unsound manipulation of env vars
Martin Habovstiak <martin.habovstiak@gmail.com>
parents: 22
diff changeset
113 source_opt = source.source();
1941e9d9819c Fix unsound manipulation of env vars
Martin Habovstiak <martin.habovstiak@gmail.com>
parents: 22
diff changeset
114 }
1941e9d9819c Fix unsound manipulation of env vars
Martin Habovstiak <martin.habovstiak@gmail.com>
parents: 22
diff changeset
115 Ok(())
0
a65053246c29 Initial commit
Martin Habovstiak <martin.habovstiak@gmail.com>
parents:
diff changeset
116 }
a65053246c29 Initial commit
Martin Habovstiak <martin.habovstiak@gmail.com>
parents:
diff changeset
117 }
a65053246c29 Initial commit
Martin Habovstiak <martin.habovstiak@gmail.com>
parents:
diff changeset
118
25
8e20daee41ed Set CLOEXEC flag on the descriptors
Martin Habovstiak <martin.habovstiak@gmail.com>
parents: 24
diff changeset
119 type StoredSocket = Result<Socket, ()>;
8e20daee41ed Set CLOEXEC flag on the descriptors
Martin Habovstiak <martin.habovstiak@gmail.com>
parents: 24
diff changeset
120
0
a65053246c29 Initial commit
Martin Habovstiak <martin.habovstiak@gmail.com>
parents:
diff changeset
121 // No source we can't keep the mutex locked
a65053246c29 Initial commit
Martin Habovstiak <martin.habovstiak@gmail.com>
parents:
diff changeset
122 impl std::error::Error for Error {}
a65053246c29 Initial commit
Martin Habovstiak <martin.habovstiak@gmail.com>
parents:
diff changeset
123
24
1941e9d9819c Fix unsound manipulation of env vars
Martin Habovstiak <martin.habovstiak@gmail.com>
parents: 22
diff changeset
124 pub(crate) unsafe fn init(protected: bool) -> Result<(), InitError> {
1941e9d9819c Fix unsound manipulation of env vars
Martin Habovstiak <martin.habovstiak@gmail.com>
parents: 22
diff changeset
125 SYSTEMD_SOCKETS.get_or_try_init(|| SystemdSockets::new(protected, true).map(Ok)).map(drop)
1941e9d9819c Fix unsound manipulation of env vars
Martin Habovstiak <martin.habovstiak@gmail.com>
parents: 22
diff changeset
126 }
1941e9d9819c Fix unsound manipulation of env vars
Martin Habovstiak <martin.habovstiak@gmail.com>
parents: 22
diff changeset
127
25
8e20daee41ed Set CLOEXEC flag on the descriptors
Martin Habovstiak <martin.habovstiak@gmail.com>
parents: 24
diff changeset
128 pub(crate) fn take(name: &str) -> Result<Option<StoredSocket>, Error> {
24
1941e9d9819c Fix unsound manipulation of env vars
Martin Habovstiak <martin.habovstiak@gmail.com>
parents: 22
diff changeset
129 let sockets = SYSTEMD_SOCKETS.get_or_init(|| SystemdSockets::new_protected(false).map_err(Mutex::new));
1941e9d9819c Fix unsound manipulation of env vars
Martin Habovstiak <martin.habovstiak@gmail.com>
parents: 22
diff changeset
130 match sockets {
0
a65053246c29 Initial commit
Martin Habovstiak <martin.habovstiak@gmail.com>
parents:
diff changeset
131 Ok(sockets) => Ok(sockets.take(name)),
a65053246c29 Initial commit
Martin Habovstiak <martin.habovstiak@gmail.com>
parents:
diff changeset
132 Err(error) => Err(Error(error))
a65053246c29 Initial commit
Martin Habovstiak <martin.habovstiak@gmail.com>
parents:
diff changeset
133 }
a65053246c29 Initial commit
Martin Habovstiak <martin.habovstiak@gmail.com>
parents:
diff changeset
134 }
a65053246c29 Initial commit
Martin Habovstiak <martin.habovstiak@gmail.com>
parents:
diff changeset
135
24
1941e9d9819c Fix unsound manipulation of env vars
Martin Habovstiak <martin.habovstiak@gmail.com>
parents: 22
diff changeset
136 #[derive(Debug)]
1941e9d9819c Fix unsound manipulation of env vars
Martin Habovstiak <martin.habovstiak@gmail.com>
parents: 22
diff changeset
137 pub(crate) enum InitError {
1941e9d9819c Fix unsound manipulation of env vars
Martin Habovstiak <martin.habovstiak@gmail.com>
parents: 22
diff changeset
138 OpenStatus(std::io::Error),
1941e9d9819c Fix unsound manipulation of env vars
Martin Habovstiak <martin.habovstiak@gmail.com>
parents: 22
diff changeset
139 ReadStatus(std::io::Error),
1941e9d9819c Fix unsound manipulation of env vars
Martin Habovstiak <martin.habovstiak@gmail.com>
parents: 22
diff changeset
140 ThreadCountNotFound,
1941e9d9819c Fix unsound manipulation of env vars
Martin Habovstiak <martin.habovstiak@gmail.com>
parents: 22
diff changeset
141 MultipleThreads,
1941e9d9819c Fix unsound manipulation of env vars
Martin Habovstiak <martin.habovstiak@gmail.com>
parents: 22
diff changeset
142 LibSystemd(LibSystemdError),
1941e9d9819c Fix unsound manipulation of env vars
Martin Habovstiak <martin.habovstiak@gmail.com>
parents: 22
diff changeset
143 }
1941e9d9819c Fix unsound manipulation of env vars
Martin Habovstiak <martin.habovstiak@gmail.com>
parents: 22
diff changeset
144
1941e9d9819c Fix unsound manipulation of env vars
Martin Habovstiak <martin.habovstiak@gmail.com>
parents: 22
diff changeset
145 impl From<LibSystemdError> for InitError {
1941e9d9819c Fix unsound manipulation of env vars
Martin Habovstiak <martin.habovstiak@gmail.com>
parents: 22
diff changeset
146 fn from(value: LibSystemdError) -> Self {
1941e9d9819c Fix unsound manipulation of env vars
Martin Habovstiak <martin.habovstiak@gmail.com>
parents: 22
diff changeset
147 Self::LibSystemd(value)
1941e9d9819c Fix unsound manipulation of env vars
Martin Habovstiak <martin.habovstiak@gmail.com>
parents: 22
diff changeset
148 }
1941e9d9819c Fix unsound manipulation of env vars
Martin Habovstiak <martin.habovstiak@gmail.com>
parents: 22
diff changeset
149 }
1941e9d9819c Fix unsound manipulation of env vars
Martin Habovstiak <martin.habovstiak@gmail.com>
parents: 22
diff changeset
150
1941e9d9819c Fix unsound manipulation of env vars
Martin Habovstiak <martin.habovstiak@gmail.com>
parents: 22
diff changeset
151 impl fmt::Display for InitError {
1941e9d9819c Fix unsound manipulation of env vars
Martin Habovstiak <martin.habovstiak@gmail.com>
parents: 22
diff changeset
152 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
1941e9d9819c Fix unsound manipulation of env vars
Martin Habovstiak <martin.habovstiak@gmail.com>
parents: 22
diff changeset
153 match self {
1941e9d9819c Fix unsound manipulation of env vars
Martin Habovstiak <martin.habovstiak@gmail.com>
parents: 22
diff changeset
154 Self::OpenStatus(_) => write!(f, "failed to open /proc/self/status"),
1941e9d9819c Fix unsound manipulation of env vars
Martin Habovstiak <martin.habovstiak@gmail.com>
parents: 22
diff changeset
155 Self::ReadStatus(_) => write!(f, "failed to read /proc/self/status"),
1941e9d9819c Fix unsound manipulation of env vars
Martin Habovstiak <martin.habovstiak@gmail.com>
parents: 22
diff changeset
156 Self::ThreadCountNotFound => write!(f, "/proc/self/status doesn't contain Threads entry"),
1941e9d9819c Fix unsound manipulation of env vars
Martin Habovstiak <martin.habovstiak@gmail.com>
parents: 22
diff changeset
157 Self::MultipleThreads => write!(f, "there is more than one thread running"),
1941e9d9819c Fix unsound manipulation of env vars
Martin Habovstiak <martin.habovstiak@gmail.com>
parents: 22
diff changeset
158 // We have nothing to say about the error, let's flatten it
1941e9d9819c Fix unsound manipulation of env vars
Martin Habovstiak <martin.habovstiak@gmail.com>
parents: 22
diff changeset
159 Self::LibSystemd(error) => fmt::Display::fmt(error, f),
1941e9d9819c Fix unsound manipulation of env vars
Martin Habovstiak <martin.habovstiak@gmail.com>
parents: 22
diff changeset
160 }
1941e9d9819c Fix unsound manipulation of env vars
Martin Habovstiak <martin.habovstiak@gmail.com>
parents: 22
diff changeset
161 }
1941e9d9819c Fix unsound manipulation of env vars
Martin Habovstiak <martin.habovstiak@gmail.com>
parents: 22
diff changeset
162 }
1941e9d9819c Fix unsound manipulation of env vars
Martin Habovstiak <martin.habovstiak@gmail.com>
parents: 22
diff changeset
163
1941e9d9819c Fix unsound manipulation of env vars
Martin Habovstiak <martin.habovstiak@gmail.com>
parents: 22
diff changeset
164 impl std::error::Error for InitError {
1941e9d9819c Fix unsound manipulation of env vars
Martin Habovstiak <martin.habovstiak@gmail.com>
parents: 22
diff changeset
165 fn source(&self) -> Option<&(dyn std::error::Error + 'static)> {
1941e9d9819c Fix unsound manipulation of env vars
Martin Habovstiak <martin.habovstiak@gmail.com>
parents: 22
diff changeset
166 match self {
1941e9d9819c Fix unsound manipulation of env vars
Martin Habovstiak <martin.habovstiak@gmail.com>
parents: 22
diff changeset
167 Self::OpenStatus(error) => Some(error),
1941e9d9819c Fix unsound manipulation of env vars
Martin Habovstiak <martin.habovstiak@gmail.com>
parents: 22
diff changeset
168 Self::ReadStatus(error) => Some(error),
1941e9d9819c Fix unsound manipulation of env vars
Martin Habovstiak <martin.habovstiak@gmail.com>
parents: 22
diff changeset
169 Self::ThreadCountNotFound => None,
1941e9d9819c Fix unsound manipulation of env vars
Martin Habovstiak <martin.habovstiak@gmail.com>
parents: 22
diff changeset
170 Self::MultipleThreads => None,
1941e9d9819c Fix unsound manipulation of env vars
Martin Habovstiak <martin.habovstiak@gmail.com>
parents: 22
diff changeset
171 // We have nothing to say about the error, let's flatten it
1941e9d9819c Fix unsound manipulation of env vars
Martin Habovstiak <martin.habovstiak@gmail.com>
parents: 22
diff changeset
172 Self::LibSystemd(error) => error.source(),
1941e9d9819c Fix unsound manipulation of env vars
Martin Habovstiak <martin.habovstiak@gmail.com>
parents: 22
diff changeset
173 }
1941e9d9819c Fix unsound manipulation of env vars
Martin Habovstiak <martin.habovstiak@gmail.com>
parents: 22
diff changeset
174 }
1941e9d9819c Fix unsound manipulation of env vars
Martin Habovstiak <martin.habovstiak@gmail.com>
parents: 22
diff changeset
175 }
1941e9d9819c Fix unsound manipulation of env vars
Martin Habovstiak <martin.habovstiak@gmail.com>
parents: 22
diff changeset
176
25
8e20daee41ed Set CLOEXEC flag on the descriptors
Martin Habovstiak <martin.habovstiak@gmail.com>
parents: 24
diff changeset
177 pub(crate) enum Socket {
8e20daee41ed Set CLOEXEC flag on the descriptors
Martin Habovstiak <martin.habovstiak@gmail.com>
parents: 24
diff changeset
178 TcpListener(std::net::TcpListener),
8e20daee41ed Set CLOEXEC flag on the descriptors
Martin Habovstiak <martin.habovstiak@gmail.com>
parents: 24
diff changeset
179 }
8e20daee41ed Set CLOEXEC flag on the descriptors
Martin Habovstiak <martin.habovstiak@gmail.com>
parents: 24
diff changeset
180
8e20daee41ed Set CLOEXEC flag on the descriptors
Martin Habovstiak <martin.habovstiak@gmail.com>
parents: 24
diff changeset
181 impl std::convert::TryFrom<FileDescriptor> for Socket {
8e20daee41ed Set CLOEXEC flag on the descriptors
Martin Habovstiak <martin.habovstiak@gmail.com>
parents: 24
diff changeset
182 type Error = ();
8e20daee41ed Set CLOEXEC flag on the descriptors
Martin Habovstiak <martin.habovstiak@gmail.com>
parents: 24
diff changeset
183
8e20daee41ed Set CLOEXEC flag on the descriptors
Martin Habovstiak <martin.habovstiak@gmail.com>
parents: 24
diff changeset
184 fn try_from(value: FileDescriptor) -> Result<Self, Self::Error> {
8e20daee41ed Set CLOEXEC flag on the descriptors
Martin Habovstiak <martin.habovstiak@gmail.com>
parents: 24
diff changeset
185 use libsystemd::activation::IsType;
8e20daee41ed Set CLOEXEC flag on the descriptors
Martin Habovstiak <martin.habovstiak@gmail.com>
parents: 24
diff changeset
186 use std::os::unix::io::{FromRawFd, IntoRawFd, AsRawFd};
8e20daee41ed Set CLOEXEC flag on the descriptors
Martin Habovstiak <martin.habovstiak@gmail.com>
parents: 24
diff changeset
187
8e20daee41ed Set CLOEXEC flag on the descriptors
Martin Habovstiak <martin.habovstiak@gmail.com>
parents: 24
diff changeset
188 fn set_cloexec(fd: std::os::unix::io::RawFd) {
8e20daee41ed Set CLOEXEC flag on the descriptors
Martin Habovstiak <martin.habovstiak@gmail.com>
parents: 24
diff changeset
189 // SAFETY: The function is a harmless syscall
8e20daee41ed Set CLOEXEC flag on the descriptors
Martin Habovstiak <martin.habovstiak@gmail.com>
parents: 24
diff changeset
190 let flags = unsafe { libc::fcntl(fd, libc::F_GETFD) };
8e20daee41ed Set CLOEXEC flag on the descriptors
Martin Habovstiak <martin.habovstiak@gmail.com>
parents: 24
diff changeset
191 if flags != -1 && flags & libc::FD_CLOEXEC == 0 {
8e20daee41ed Set CLOEXEC flag on the descriptors
Martin Habovstiak <martin.habovstiak@gmail.com>
parents: 24
diff changeset
192 // We ignore errors, since the FD is still usable
8e20daee41ed Set CLOEXEC flag on the descriptors
Martin Habovstiak <martin.habovstiak@gmail.com>
parents: 24
diff changeset
193 // SAFETY: socket is definitely a valid file descriptor and setting CLOEXEC is
8e20daee41ed Set CLOEXEC flag on the descriptors
Martin Habovstiak <martin.habovstiak@gmail.com>
parents: 24
diff changeset
194 // a sound operation.
8e20daee41ed Set CLOEXEC flag on the descriptors
Martin Habovstiak <martin.habovstiak@gmail.com>
parents: 24
diff changeset
195 unsafe {
8e20daee41ed Set CLOEXEC flag on the descriptors
Martin Habovstiak <martin.habovstiak@gmail.com>
parents: 24
diff changeset
196 libc::fcntl(fd, libc::F_SETFD, flags | libc::FD_CLOEXEC);
8e20daee41ed Set CLOEXEC flag on the descriptors
Martin Habovstiak <martin.habovstiak@gmail.com>
parents: 24
diff changeset
197 }
8e20daee41ed Set CLOEXEC flag on the descriptors
Martin Habovstiak <martin.habovstiak@gmail.com>
parents: 24
diff changeset
198 }
8e20daee41ed Set CLOEXEC flag on the descriptors
Martin Habovstiak <martin.habovstiak@gmail.com>
parents: 24
diff changeset
199 }
8e20daee41ed Set CLOEXEC flag on the descriptors
Martin Habovstiak <martin.habovstiak@gmail.com>
parents: 24
diff changeset
200
8e20daee41ed Set CLOEXEC flag on the descriptors
Martin Habovstiak <martin.habovstiak@gmail.com>
parents: 24
diff changeset
201 if value.is_inet() {
8e20daee41ed Set CLOEXEC flag on the descriptors
Martin Habovstiak <martin.habovstiak@gmail.com>
parents: 24
diff changeset
202 // SAFETY: FileDescriptor is obtained from systemd, so it should be valid.
8e20daee41ed Set CLOEXEC flag on the descriptors
Martin Habovstiak <martin.habovstiak@gmail.com>
parents: 24
diff changeset
203 let socket = unsafe { std::net::TcpListener::from_raw_fd(value.into_raw_fd()) };
8e20daee41ed Set CLOEXEC flag on the descriptors
Martin Habovstiak <martin.habovstiak@gmail.com>
parents: 24
diff changeset
204 set_cloexec(socket.as_raw_fd());
8e20daee41ed Set CLOEXEC flag on the descriptors
Martin Habovstiak <martin.habovstiak@gmail.com>
parents: 24
diff changeset
205 Ok(Socket::TcpListener(socket))
8e20daee41ed Set CLOEXEC flag on the descriptors
Martin Habovstiak <martin.habovstiak@gmail.com>
parents: 24
diff changeset
206 } else {
8e20daee41ed Set CLOEXEC flag on the descriptors
Martin Habovstiak <martin.habovstiak@gmail.com>
parents: 24
diff changeset
207 // We still need to make the filedescriptor harmless.
8e20daee41ed Set CLOEXEC flag on the descriptors
Martin Habovstiak <martin.habovstiak@gmail.com>
parents: 24
diff changeset
208 set_cloexec(value.into_raw_fd());
8e20daee41ed Set CLOEXEC flag on the descriptors
Martin Habovstiak <martin.habovstiak@gmail.com>
parents: 24
diff changeset
209 Err(())
8e20daee41ed Set CLOEXEC flag on the descriptors
Martin Habovstiak <martin.habovstiak@gmail.com>
parents: 24
diff changeset
210 }
8e20daee41ed Set CLOEXEC flag on the descriptors
Martin Habovstiak <martin.habovstiak@gmail.com>
parents: 24
diff changeset
211 }
8e20daee41ed Set CLOEXEC flag on the descriptors
Martin Habovstiak <martin.habovstiak@gmail.com>
parents: 24
diff changeset
212 }
8e20daee41ed Set CLOEXEC flag on the descriptors
Martin Habovstiak <martin.habovstiak@gmail.com>
parents: 24
diff changeset
213
8e20daee41ed Set CLOEXEC flag on the descriptors
Martin Habovstiak <martin.habovstiak@gmail.com>
parents: 24
diff changeset
214 struct SystemdSockets(std::sync::Mutex<std::collections::HashMap<String, StoredSocket>>);
0
a65053246c29 Initial commit
Martin Habovstiak <martin.habovstiak@gmail.com>
parents:
diff changeset
215
a65053246c29 Initial commit
Martin Habovstiak <martin.habovstiak@gmail.com>
parents:
diff changeset
216 impl SystemdSockets {
24
1941e9d9819c Fix unsound manipulation of env vars
Martin Habovstiak <martin.habovstiak@gmail.com>
parents: 22
diff changeset
217 fn new_protected(explicit: bool) -> Result<Self, InitError> {
1941e9d9819c Fix unsound manipulation of env vars
Martin Habovstiak <martin.habovstiak@gmail.com>
parents: 22
diff changeset
218 unsafe { Self::new(true, explicit) }
1941e9d9819c Fix unsound manipulation of env vars
Martin Habovstiak <martin.habovstiak@gmail.com>
parents: 22
diff changeset
219 }
1941e9d9819c Fix unsound manipulation of env vars
Martin Habovstiak <martin.habovstiak@gmail.com>
parents: 22
diff changeset
220
1941e9d9819c Fix unsound manipulation of env vars
Martin Habovstiak <martin.habovstiak@gmail.com>
parents: 22
diff changeset
221 unsafe fn new(protected: bool, explicit: bool) -> Result<Self, InitError> {
25
8e20daee41ed Set CLOEXEC flag on the descriptors
Martin Habovstiak <martin.habovstiak@gmail.com>
parents: 24
diff changeset
222 use std::convert::TryFrom;
8e20daee41ed Set CLOEXEC flag on the descriptors
Martin Habovstiak <martin.habovstiak@gmail.com>
parents: 24
diff changeset
223
24
1941e9d9819c Fix unsound manipulation of env vars
Martin Habovstiak <martin.habovstiak@gmail.com>
parents: 22
diff changeset
224 if explicit {
1941e9d9819c Fix unsound manipulation of env vars
Martin Habovstiak <martin.habovstiak@gmail.com>
parents: 22
diff changeset
225 if std::env::var_os("LISTEN_PID").is_none() && std::env::var_os("LISTEN_FDS").is_none() && std::env::var_os("LISTEN_FDNAMES").is_none() {
1941e9d9819c Fix unsound manipulation of env vars
Martin Habovstiak <martin.habovstiak@gmail.com>
parents: 22
diff changeset
226 // Systemd is not used - make the map empty
1941e9d9819c Fix unsound manipulation of env vars
Martin Habovstiak <martin.habovstiak@gmail.com>
parents: 22
diff changeset
227 return Ok(SystemdSockets(Mutex::new(Default::default())));
1941e9d9819c Fix unsound manipulation of env vars
Martin Habovstiak <martin.habovstiak@gmail.com>
parents: 22
diff changeset
228 }
1941e9d9819c Fix unsound manipulation of env vars
Martin Habovstiak <martin.habovstiak@gmail.com>
parents: 22
diff changeset
229 }
1941e9d9819c Fix unsound manipulation of env vars
Martin Habovstiak <martin.habovstiak@gmail.com>
parents: 22
diff changeset
230
1941e9d9819c Fix unsound manipulation of env vars
Martin Habovstiak <martin.habovstiak@gmail.com>
parents: 22
diff changeset
231 if protected { Self::check_single_thread()? }
0
a65053246c29 Initial commit
Martin Habovstiak <martin.habovstiak@gmail.com>
parents:
diff changeset
232 // MUST BE true FOR SAFETY!!!
25
8e20daee41ed Set CLOEXEC flag on the descriptors
Martin Habovstiak <martin.habovstiak@gmail.com>
parents: 24
diff changeset
233 let map = libsystemd::activation::receive_descriptors_with_names(/*unset env = */ protected)?.into_iter().map(|(fd, name)| {
8e20daee41ed Set CLOEXEC flag on the descriptors
Martin Habovstiak <martin.habovstiak@gmail.com>
parents: 24
diff changeset
234 (name, Socket::try_from(fd))
8e20daee41ed Set CLOEXEC flag on the descriptors
Martin Habovstiak <martin.habovstiak@gmail.com>
parents: 24
diff changeset
235 }).collect();
0
a65053246c29 Initial commit
Martin Habovstiak <martin.habovstiak@gmail.com>
parents:
diff changeset
236 Ok(SystemdSockets(Mutex::new(map)))
a65053246c29 Initial commit
Martin Habovstiak <martin.habovstiak@gmail.com>
parents:
diff changeset
237 }
a65053246c29 Initial commit
Martin Habovstiak <martin.habovstiak@gmail.com>
parents:
diff changeset
238
24
1941e9d9819c Fix unsound manipulation of env vars
Martin Habovstiak <martin.habovstiak@gmail.com>
parents: 22
diff changeset
239 fn check_single_thread() -> Result<(), InitError> {
1941e9d9819c Fix unsound manipulation of env vars
Martin Habovstiak <martin.habovstiak@gmail.com>
parents: 22
diff changeset
240 use std::io::BufRead;
1941e9d9819c Fix unsound manipulation of env vars
Martin Habovstiak <martin.habovstiak@gmail.com>
parents: 22
diff changeset
241
1941e9d9819c Fix unsound manipulation of env vars
Martin Habovstiak <martin.habovstiak@gmail.com>
parents: 22
diff changeset
242 let status = std::fs::File::open("/proc/self/status").map_err(InitError::OpenStatus)?;
1941e9d9819c Fix unsound manipulation of env vars
Martin Habovstiak <martin.habovstiak@gmail.com>
parents: 22
diff changeset
243 let mut status = std::io::BufReader::new(status);
1941e9d9819c Fix unsound manipulation of env vars
Martin Habovstiak <martin.habovstiak@gmail.com>
parents: 22
diff changeset
244 let mut line = String::new();
1941e9d9819c Fix unsound manipulation of env vars
Martin Habovstiak <martin.habovstiak@gmail.com>
parents: 22
diff changeset
245 loop {
1941e9d9819c Fix unsound manipulation of env vars
Martin Habovstiak <martin.habovstiak@gmail.com>
parents: 22
diff changeset
246 if status.read_line(&mut line).map_err(InitError::ReadStatus)? == 0 {
1941e9d9819c Fix unsound manipulation of env vars
Martin Habovstiak <martin.habovstiak@gmail.com>
parents: 22
diff changeset
247 return Err(InitError::ThreadCountNotFound);
1941e9d9819c Fix unsound manipulation of env vars
Martin Habovstiak <martin.habovstiak@gmail.com>
parents: 22
diff changeset
248 }
1941e9d9819c Fix unsound manipulation of env vars
Martin Habovstiak <martin.habovstiak@gmail.com>
parents: 22
diff changeset
249 if let Some(threads) = line.strip_prefix("Threads:") {
1941e9d9819c Fix unsound manipulation of env vars
Martin Habovstiak <martin.habovstiak@gmail.com>
parents: 22
diff changeset
250 if threads.trim() == "1" {
1941e9d9819c Fix unsound manipulation of env vars
Martin Habovstiak <martin.habovstiak@gmail.com>
parents: 22
diff changeset
251 break;
1941e9d9819c Fix unsound manipulation of env vars
Martin Habovstiak <martin.habovstiak@gmail.com>
parents: 22
diff changeset
252 } else {
1941e9d9819c Fix unsound manipulation of env vars
Martin Habovstiak <martin.habovstiak@gmail.com>
parents: 22
diff changeset
253 return Err(InitError::MultipleThreads);
1941e9d9819c Fix unsound manipulation of env vars
Martin Habovstiak <martin.habovstiak@gmail.com>
parents: 22
diff changeset
254 }
1941e9d9819c Fix unsound manipulation of env vars
Martin Habovstiak <martin.habovstiak@gmail.com>
parents: 22
diff changeset
255 }
1941e9d9819c Fix unsound manipulation of env vars
Martin Habovstiak <martin.habovstiak@gmail.com>
parents: 22
diff changeset
256 line.clear();
1941e9d9819c Fix unsound manipulation of env vars
Martin Habovstiak <martin.habovstiak@gmail.com>
parents: 22
diff changeset
257 }
1941e9d9819c Fix unsound manipulation of env vars
Martin Habovstiak <martin.habovstiak@gmail.com>
parents: 22
diff changeset
258 Ok(())
1941e9d9819c Fix unsound manipulation of env vars
Martin Habovstiak <martin.habovstiak@gmail.com>
parents: 22
diff changeset
259 }
1941e9d9819c Fix unsound manipulation of env vars
Martin Habovstiak <martin.habovstiak@gmail.com>
parents: 22
diff changeset
260
25
8e20daee41ed Set CLOEXEC flag on the descriptors
Martin Habovstiak <martin.habovstiak@gmail.com>
parents: 24
diff changeset
261 fn take(&self, name: &str) -> Option<StoredSocket> {
0
a65053246c29 Initial commit
Martin Habovstiak <martin.habovstiak@gmail.com>
parents:
diff changeset
262 // MUST remove THE SOCKET FOR SAFETY!!!
a65053246c29 Initial commit
Martin Habovstiak <martin.habovstiak@gmail.com>
parents:
diff changeset
263 self.0.lock().expect("poisoned mutex").remove(name)
a65053246c29 Initial commit
Martin Habovstiak <martin.habovstiak@gmail.com>
parents:
diff changeset
264 }
a65053246c29 Initial commit
Martin Habovstiak <martin.habovstiak@gmail.com>
parents:
diff changeset
265 }
a65053246c29 Initial commit
Martin Habovstiak <martin.habovstiak@gmail.com>
parents:
diff changeset
266
24
1941e9d9819c Fix unsound manipulation of env vars
Martin Habovstiak <martin.habovstiak@gmail.com>
parents: 22
diff changeset
267 static SYSTEMD_SOCKETS: once_cell::sync::OnceCell<Result<SystemdSockets, Mutex<InitError>>> = once_cell::sync::OnceCell::new();
0
a65053246c29 Initial commit
Martin Habovstiak <martin.habovstiak@gmail.com>
parents:
diff changeset
268 }
a65053246c29 Initial commit
Martin Habovstiak <martin.habovstiak@gmail.com>
parents:
diff changeset
269
a65053246c29 Initial commit
Martin Habovstiak <martin.habovstiak@gmail.com>
parents:
diff changeset
270 /// Socket address that can be an ordinary address or a systemd socket
a65053246c29 Initial commit
Martin Habovstiak <martin.habovstiak@gmail.com>
parents:
diff changeset
271 ///
a65053246c29 Initial commit
Martin Habovstiak <martin.habovstiak@gmail.com>
parents:
diff changeset
272 /// This is the core type of this crate that abstracts possible addresses.
a65053246c29 Initial commit
Martin Habovstiak <martin.habovstiak@gmail.com>
parents:
diff changeset
273 /// It can be (fallibly) converted from various types of strings or deserialized with `serde`.
a65053246c29 Initial commit
Martin Habovstiak <martin.habovstiak@gmail.com>
parents:
diff changeset
274 /// After it's created, it can be bound as `TcpListener` from `std` or even `tokio` or `async_std`
a65053246c29 Initial commit
Martin Habovstiak <martin.habovstiak@gmail.com>
parents:
diff changeset
275 /// if the appropriate feature is enabled.
a65053246c29 Initial commit
Martin Habovstiak <martin.habovstiak@gmail.com>
parents:
diff changeset
276 ///
a65053246c29 Initial commit
Martin Habovstiak <martin.habovstiak@gmail.com>
parents:
diff changeset
277 /// Optional dependencies on `parse_arg` and `serde` make it trivial to use with
a65053246c29 Initial commit
Martin Habovstiak <martin.habovstiak@gmail.com>
parents:
diff changeset
278 /// [`configure_me`](https://crates.io/crates/configure_me).
a65053246c29 Initial commit
Martin Habovstiak <martin.habovstiak@gmail.com>
parents:
diff changeset
279 #[derive(Debug)]
a65053246c29 Initial commit
Martin Habovstiak <martin.habovstiak@gmail.com>
parents:
diff changeset
280 #[cfg_attr(feature = "serde", derive(serde_crate::Deserialize), serde(crate = "serde_crate", try_from = "serde_str_helpers::DeserBorrowStr"))]
a65053246c29 Initial commit
Martin Habovstiak <martin.habovstiak@gmail.com>
parents:
diff changeset
281 pub struct SocketAddr(SocketAddrInner);
a65053246c29 Initial commit
Martin Habovstiak <martin.habovstiak@gmail.com>
parents:
diff changeset
282
a65053246c29 Initial commit
Martin Habovstiak <martin.habovstiak@gmail.com>
parents:
diff changeset
283 impl SocketAddr {
17
dfb727367934 Allow specifying systemd name directly
Martin Habovstiak <martin.habovstiak@gmail.com>
parents: 16
diff changeset
284 /// Creates SocketAddr from systemd name directly, without requiring `systemd://` prefix.
dfb727367934 Allow specifying systemd name directly
Martin Habovstiak <martin.habovstiak@gmail.com>
parents: 16
diff changeset
285 ///
dfb727367934 Allow specifying systemd name directly
Martin Habovstiak <martin.habovstiak@gmail.com>
parents: 16
diff changeset
286 /// Always fails with systemd unsupported error if systemd is not supported.
dfb727367934 Allow specifying systemd name directly
Martin Habovstiak <martin.habovstiak@gmail.com>
parents: 16
diff changeset
287 pub fn from_systemd_name<T: Into<String>>(name: T) -> Result<Self, ParseError> {
dfb727367934 Allow specifying systemd name directly
Martin Habovstiak <martin.habovstiak@gmail.com>
parents: 16
diff changeset
288 Self::inner_from_systemd_name(name.into(), false)
dfb727367934 Allow specifying systemd name directly
Martin Habovstiak <martin.habovstiak@gmail.com>
parents: 16
diff changeset
289 }
dfb727367934 Allow specifying systemd name directly
Martin Habovstiak <martin.habovstiak@gmail.com>
parents: 16
diff changeset
290
dfb727367934 Allow specifying systemd name directly
Martin Habovstiak <martin.habovstiak@gmail.com>
parents: 16
diff changeset
291 #[cfg(all(target_os = "linux", feature = "enable_systemd"))]
dfb727367934 Allow specifying systemd name directly
Martin Habovstiak <martin.habovstiak@gmail.com>
parents: 16
diff changeset
292 fn inner_from_systemd_name(name: String, prefixed: bool) -> Result<Self, ParseError> {
dfb727367934 Allow specifying systemd name directly
Martin Habovstiak <martin.habovstiak@gmail.com>
parents: 16
diff changeset
293 let real_systemd_name = if prefixed {
dfb727367934 Allow specifying systemd name directly
Martin Habovstiak <martin.habovstiak@gmail.com>
parents: 16
diff changeset
294 &name[SYSTEMD_PREFIX.len()..]
dfb727367934 Allow specifying systemd name directly
Martin Habovstiak <martin.habovstiak@gmail.com>
parents: 16
diff changeset
295 } else {
dfb727367934 Allow specifying systemd name directly
Martin Habovstiak <martin.habovstiak@gmail.com>
parents: 16
diff changeset
296 &name
dfb727367934 Allow specifying systemd name directly
Martin Habovstiak <martin.habovstiak@gmail.com>
parents: 16
diff changeset
297 };
dfb727367934 Allow specifying systemd name directly
Martin Habovstiak <martin.habovstiak@gmail.com>
parents: 16
diff changeset
298
dfb727367934 Allow specifying systemd name directly
Martin Habovstiak <martin.habovstiak@gmail.com>
parents: 16
diff changeset
299 let name_len = real_systemd_name.len();
dfb727367934 Allow specifying systemd name directly
Martin Habovstiak <martin.habovstiak@gmail.com>
parents: 16
diff changeset
300 match real_systemd_name.chars().enumerate().find(|(_, c)| !c.is_ascii() || *c < ' ' || *c == ':') {
dfb727367934 Allow specifying systemd name directly
Martin Habovstiak <martin.habovstiak@gmail.com>
parents: 16
diff changeset
301 None if name_len <= 255 && prefixed => Ok(SocketAddr(SocketAddrInner::Systemd(name))),
dfb727367934 Allow specifying systemd name directly
Martin Habovstiak <martin.habovstiak@gmail.com>
parents: 16
diff changeset
302 None if name_len <= 255 && !prefixed => Ok(SocketAddr(SocketAddrInner::SystemdNoPrefix(name))),
dfb727367934 Allow specifying systemd name directly
Martin Habovstiak <martin.habovstiak@gmail.com>
parents: 16
diff changeset
303 None => Err(ParseErrorInner::LongSocketName { string: name, len: name_len }.into()),
dfb727367934 Allow specifying systemd name directly
Martin Habovstiak <martin.habovstiak@gmail.com>
parents: 16
diff changeset
304 Some((pos, c)) => Err(ParseErrorInner::InvalidCharacter { string: name, c, pos, }.into()),
dfb727367934 Allow specifying systemd name directly
Martin Habovstiak <martin.habovstiak@gmail.com>
parents: 16
diff changeset
305 }
dfb727367934 Allow specifying systemd name directly
Martin Habovstiak <martin.habovstiak@gmail.com>
parents: 16
diff changeset
306 }
dfb727367934 Allow specifying systemd name directly
Martin Habovstiak <martin.habovstiak@gmail.com>
parents: 16
diff changeset
307
dfb727367934 Allow specifying systemd name directly
Martin Habovstiak <martin.habovstiak@gmail.com>
parents: 16
diff changeset
308
dfb727367934 Allow specifying systemd name directly
Martin Habovstiak <martin.habovstiak@gmail.com>
parents: 16
diff changeset
309 #[cfg(not(all(target_os = "linux", feature = "enable_systemd")))]
dfb727367934 Allow specifying systemd name directly
Martin Habovstiak <martin.habovstiak@gmail.com>
parents: 16
diff changeset
310 fn inner_from_systemd_name(name: String, _prefixed: bool) -> Result<Self, ParseError> {
dfb727367934 Allow specifying systemd name directly
Martin Habovstiak <martin.habovstiak@gmail.com>
parents: 16
diff changeset
311 Err(ParseError(ParseErrorInner::SystemdUnsupported(name)))
dfb727367934 Allow specifying systemd name directly
Martin Habovstiak <martin.habovstiak@gmail.com>
parents: 16
diff changeset
312 }
dfb727367934 Allow specifying systemd name directly
Martin Habovstiak <martin.habovstiak@gmail.com>
parents: 16
diff changeset
313
0
a65053246c29 Initial commit
Martin Habovstiak <martin.habovstiak@gmail.com>
parents:
diff changeset
314 /// Creates `std::net::TcpListener`
a65053246c29 Initial commit
Martin Habovstiak <martin.habovstiak@gmail.com>
parents:
diff changeset
315 ///
a65053246c29 Initial commit
Martin Habovstiak <martin.habovstiak@gmail.com>
parents:
diff changeset
316 /// This method either `binds` the socket, if the address was provided or uses systemd socket
a65053246c29 Initial commit
Martin Habovstiak <martin.habovstiak@gmail.com>
parents:
diff changeset
317 /// if the socket name was provided.
a65053246c29 Initial commit
Martin Habovstiak <martin.habovstiak@gmail.com>
parents:
diff changeset
318 pub fn bind(self) -> Result<std::net::TcpListener, BindError> {
4
66c0e10c89fc Support resolving hostnames
Martin Habovstiak <martin.habovstiak@gmail.com>
parents: 3
diff changeset
319 match self.0 {
66c0e10c89fc Support resolving hostnames
Martin Habovstiak <martin.habovstiak@gmail.com>
parents: 3
diff changeset
320 SocketAddrInner::Ordinary(addr) => match std::net::TcpListener::bind(addr) {
66c0e10c89fc Support resolving hostnames
Martin Habovstiak <martin.habovstiak@gmail.com>
parents: 3
diff changeset
321 Ok(socket) => Ok(socket),
66c0e10c89fc Support resolving hostnames
Martin Habovstiak <martin.habovstiak@gmail.com>
parents: 3
diff changeset
322 Err(error) => Err(BindErrorInner::BindFailed { addr, error, }.into()),
66c0e10c89fc Support resolving hostnames
Martin Habovstiak <martin.habovstiak@gmail.com>
parents: 3
diff changeset
323 },
66c0e10c89fc Support resolving hostnames
Martin Habovstiak <martin.habovstiak@gmail.com>
parents: 3
diff changeset
324 SocketAddrInner::WithHostname(addr) => match std::net::TcpListener::bind(addr.as_str()) {
66c0e10c89fc Support resolving hostnames
Martin Habovstiak <martin.habovstiak@gmail.com>
parents: 3
diff changeset
325 Ok(socket) => Ok(socket),
66c0e10c89fc Support resolving hostnames
Martin Habovstiak <martin.habovstiak@gmail.com>
parents: 3
diff changeset
326 Err(error) => Err(BindErrorInner::BindOrResolvFailed { addr, error, }.into()),
66c0e10c89fc Support resolving hostnames
Martin Habovstiak <martin.habovstiak@gmail.com>
parents: 3
diff changeset
327 },
17
dfb727367934 Allow specifying systemd name directly
Martin Habovstiak <martin.habovstiak@gmail.com>
parents: 16
diff changeset
328 SocketAddrInner::Systemd(socket_name) => Self::get_systemd(socket_name, true).map(|(socket, _)| socket),
dfb727367934 Allow specifying systemd name directly
Martin Habovstiak <martin.habovstiak@gmail.com>
parents: 16
diff changeset
329 SocketAddrInner::SystemdNoPrefix(socket_name) => Self::get_systemd(socket_name, false).map(|(socket, _)| socket),
4
66c0e10c89fc Support resolving hostnames
Martin Habovstiak <martin.habovstiak@gmail.com>
parents: 3
diff changeset
330 }
0
a65053246c29 Initial commit
Martin Habovstiak <martin.habovstiak@gmail.com>
parents:
diff changeset
331 }
a65053246c29 Initial commit
Martin Habovstiak <martin.habovstiak@gmail.com>
parents:
diff changeset
332
a65053246c29 Initial commit
Martin Habovstiak <martin.habovstiak@gmail.com>
parents:
diff changeset
333 /// Creates `tokio::net::TcpListener`
a65053246c29 Initial commit
Martin Habovstiak <martin.habovstiak@gmail.com>
parents:
diff changeset
334 ///
21
f6334887e3c8 Support `tokio` 1.0
Martin Habovstiak <martin.habovstiak@gmail.com>
parents: 20
diff changeset
335 /// To be specific, it binds the socket or converts systemd socket to `tokio` 1.0 socket.
f6334887e3c8 Support `tokio` 1.0
Martin Habovstiak <martin.habovstiak@gmail.com>
parents: 20
diff changeset
336 ///
f6334887e3c8 Support `tokio` 1.0
Martin Habovstiak <martin.habovstiak@gmail.com>
parents: 20
diff changeset
337 /// This method either `binds` the socket, if the address was provided or uses systemd socket
f6334887e3c8 Support `tokio` 1.0
Martin Habovstiak <martin.habovstiak@gmail.com>
parents: 20
diff changeset
338 /// if the socket name was provided.
f6334887e3c8 Support `tokio` 1.0
Martin Habovstiak <martin.habovstiak@gmail.com>
parents: 20
diff changeset
339 #[cfg(feature = "tokio")]
f6334887e3c8 Support `tokio` 1.0
Martin Habovstiak <martin.habovstiak@gmail.com>
parents: 20
diff changeset
340 pub async fn bind_tokio(self) -> Result<tokio::net::TcpListener, TokioBindError> {
f6334887e3c8 Support `tokio` 1.0
Martin Habovstiak <martin.habovstiak@gmail.com>
parents: 20
diff changeset
341 match self.0 {
f6334887e3c8 Support `tokio` 1.0
Martin Habovstiak <martin.habovstiak@gmail.com>
parents: 20
diff changeset
342 SocketAddrInner::Ordinary(addr) => match tokio::net::TcpListener::bind(addr).await {
f6334887e3c8 Support `tokio` 1.0
Martin Habovstiak <martin.habovstiak@gmail.com>
parents: 20
diff changeset
343 Ok(socket) => Ok(socket),
f6334887e3c8 Support `tokio` 1.0
Martin Habovstiak <martin.habovstiak@gmail.com>
parents: 20
diff changeset
344 Err(error) => Err(TokioBindError::Bind(BindErrorInner::BindFailed { addr, error, }.into())),
f6334887e3c8 Support `tokio` 1.0
Martin Habovstiak <martin.habovstiak@gmail.com>
parents: 20
diff changeset
345 },
f6334887e3c8 Support `tokio` 1.0
Martin Habovstiak <martin.habovstiak@gmail.com>
parents: 20
diff changeset
346 SocketAddrInner::WithHostname(addr) => match tokio::net::TcpListener::bind(addr.as_str()).await {
f6334887e3c8 Support `tokio` 1.0
Martin Habovstiak <martin.habovstiak@gmail.com>
parents: 20
diff changeset
347 Ok(socket) => Ok(socket),
f6334887e3c8 Support `tokio` 1.0
Martin Habovstiak <martin.habovstiak@gmail.com>
parents: 20
diff changeset
348 Err(error) => Err(TokioBindError::Bind(BindErrorInner::BindOrResolvFailed { addr, error, }.into())),
f6334887e3c8 Support `tokio` 1.0
Martin Habovstiak <martin.habovstiak@gmail.com>
parents: 20
diff changeset
349 },
f6334887e3c8 Support `tokio` 1.0
Martin Habovstiak <martin.habovstiak@gmail.com>
parents: 20
diff changeset
350 SocketAddrInner::Systemd(socket_name) => {
f6334887e3c8 Support `tokio` 1.0
Martin Habovstiak <martin.habovstiak@gmail.com>
parents: 20
diff changeset
351 let (socket, addr) = Self::get_systemd(socket_name, true)?;
f6334887e3c8 Support `tokio` 1.0
Martin Habovstiak <martin.habovstiak@gmail.com>
parents: 20
diff changeset
352 socket.try_into().map_err(|error| TokioConversionError { addr, error, }.into())
f6334887e3c8 Support `tokio` 1.0
Martin Habovstiak <martin.habovstiak@gmail.com>
parents: 20
diff changeset
353 },
f6334887e3c8 Support `tokio` 1.0
Martin Habovstiak <martin.habovstiak@gmail.com>
parents: 20
diff changeset
354 SocketAddrInner::SystemdNoPrefix(socket_name) => {
f6334887e3c8 Support `tokio` 1.0
Martin Habovstiak <martin.habovstiak@gmail.com>
parents: 20
diff changeset
355 let (socket, addr) = Self::get_systemd(socket_name, false)?;
f6334887e3c8 Support `tokio` 1.0
Martin Habovstiak <martin.habovstiak@gmail.com>
parents: 20
diff changeset
356 socket.try_into().map_err(|error| TokioConversionError { addr, error, }.into())
f6334887e3c8 Support `tokio` 1.0
Martin Habovstiak <martin.habovstiak@gmail.com>
parents: 20
diff changeset
357 },
f6334887e3c8 Support `tokio` 1.0
Martin Habovstiak <martin.habovstiak@gmail.com>
parents: 20
diff changeset
358 }
f6334887e3c8 Support `tokio` 1.0
Martin Habovstiak <martin.habovstiak@gmail.com>
parents: 20
diff changeset
359 }
f6334887e3c8 Support `tokio` 1.0
Martin Habovstiak <martin.habovstiak@gmail.com>
parents: 20
diff changeset
360
f6334887e3c8 Support `tokio` 1.0
Martin Habovstiak <martin.habovstiak@gmail.com>
parents: 20
diff changeset
361 /// Creates `tokio::net::TcpListener`
f6334887e3c8 Support `tokio` 1.0
Martin Habovstiak <martin.habovstiak@gmail.com>
parents: 20
diff changeset
362 ///
4
66c0e10c89fc Support resolving hostnames
Martin Habovstiak <martin.habovstiak@gmail.com>
parents: 3
diff changeset
363 /// To be specific, it binds the socket or converts systemd socket to `tokio` 0.2 socket.
0
a65053246c29 Initial commit
Martin Habovstiak <martin.habovstiak@gmail.com>
parents:
diff changeset
364 ///
a65053246c29 Initial commit
Martin Habovstiak <martin.habovstiak@gmail.com>
parents:
diff changeset
365 /// This method either `binds` the socket, if the address was provided or uses systemd socket
a65053246c29 Initial commit
Martin Habovstiak <martin.habovstiak@gmail.com>
parents:
diff changeset
366 /// if the socket name was provided.
a65053246c29 Initial commit
Martin Habovstiak <martin.habovstiak@gmail.com>
parents:
diff changeset
367 #[cfg(feature = "tokio_0_2")]
4
66c0e10c89fc Support resolving hostnames
Martin Habovstiak <martin.habovstiak@gmail.com>
parents: 3
diff changeset
368 pub async fn bind_tokio_0_2(self) -> Result<tokio_0_2::net::TcpListener, TokioBindError> {
66c0e10c89fc Support resolving hostnames
Martin Habovstiak <martin.habovstiak@gmail.com>
parents: 3
diff changeset
369 match self.0 {
66c0e10c89fc Support resolving hostnames
Martin Habovstiak <martin.habovstiak@gmail.com>
parents: 3
diff changeset
370 SocketAddrInner::Ordinary(addr) => match tokio_0_2::net::TcpListener::bind(addr).await {
66c0e10c89fc Support resolving hostnames
Martin Habovstiak <martin.habovstiak@gmail.com>
parents: 3
diff changeset
371 Ok(socket) => Ok(socket),
66c0e10c89fc Support resolving hostnames
Martin Habovstiak <martin.habovstiak@gmail.com>
parents: 3
diff changeset
372 Err(error) => Err(TokioBindError::Bind(BindErrorInner::BindFailed { addr, error, }.into())),
66c0e10c89fc Support resolving hostnames
Martin Habovstiak <martin.habovstiak@gmail.com>
parents: 3
diff changeset
373 },
66c0e10c89fc Support resolving hostnames
Martin Habovstiak <martin.habovstiak@gmail.com>
parents: 3
diff changeset
374 SocketAddrInner::WithHostname(addr) => match tokio_0_2::net::TcpListener::bind(addr.as_str()).await {
66c0e10c89fc Support resolving hostnames
Martin Habovstiak <martin.habovstiak@gmail.com>
parents: 3
diff changeset
375 Ok(socket) => Ok(socket),
66c0e10c89fc Support resolving hostnames
Martin Habovstiak <martin.habovstiak@gmail.com>
parents: 3
diff changeset
376 Err(error) => Err(TokioBindError::Bind(BindErrorInner::BindOrResolvFailed { addr, error, }.into())),
66c0e10c89fc Support resolving hostnames
Martin Habovstiak <martin.habovstiak@gmail.com>
parents: 3
diff changeset
377 },
66c0e10c89fc Support resolving hostnames
Martin Habovstiak <martin.habovstiak@gmail.com>
parents: 3
diff changeset
378 SocketAddrInner::Systemd(socket_name) => {
17
dfb727367934 Allow specifying systemd name directly
Martin Habovstiak <martin.habovstiak@gmail.com>
parents: 16
diff changeset
379 let (socket, addr) = Self::get_systemd(socket_name, true)?;
dfb727367934 Allow specifying systemd name directly
Martin Habovstiak <martin.habovstiak@gmail.com>
parents: 16
diff changeset
380 socket.try_into().map_err(|error| TokioConversionError { addr, error, }.into())
dfb727367934 Allow specifying systemd name directly
Martin Habovstiak <martin.habovstiak@gmail.com>
parents: 16
diff changeset
381 },
dfb727367934 Allow specifying systemd name directly
Martin Habovstiak <martin.habovstiak@gmail.com>
parents: 16
diff changeset
382 SocketAddrInner::SystemdNoPrefix(socket_name) => {
dfb727367934 Allow specifying systemd name directly
Martin Habovstiak <martin.habovstiak@gmail.com>
parents: 16
diff changeset
383 let (socket, addr) = Self::get_systemd(socket_name, false)?;
4
66c0e10c89fc Support resolving hostnames
Martin Habovstiak <martin.habovstiak@gmail.com>
parents: 3
diff changeset
384 socket.try_into().map_err(|error| TokioConversionError { addr, error, }.into())
66c0e10c89fc Support resolving hostnames
Martin Habovstiak <martin.habovstiak@gmail.com>
parents: 3
diff changeset
385 },
66c0e10c89fc Support resolving hostnames
Martin Habovstiak <martin.habovstiak@gmail.com>
parents: 3
diff changeset
386 }
0
a65053246c29 Initial commit
Martin Habovstiak <martin.habovstiak@gmail.com>
parents:
diff changeset
387 }
a65053246c29 Initial commit
Martin Habovstiak <martin.habovstiak@gmail.com>
parents:
diff changeset
388
a65053246c29 Initial commit
Martin Habovstiak <martin.habovstiak@gmail.com>
parents:
diff changeset
389 /// Creates `tokio::net::TcpListener`
a65053246c29 Initial commit
Martin Habovstiak <martin.habovstiak@gmail.com>
parents:
diff changeset
390 ///
4
66c0e10c89fc Support resolving hostnames
Martin Habovstiak <martin.habovstiak@gmail.com>
parents: 3
diff changeset
391 /// To be specific, it binds the socket or converts systemd socket to `tokio` 0.3 socket.
0
a65053246c29 Initial commit
Martin Habovstiak <martin.habovstiak@gmail.com>
parents:
diff changeset
392 ///
a65053246c29 Initial commit
Martin Habovstiak <martin.habovstiak@gmail.com>
parents:
diff changeset
393 /// This method either `binds` the socket, if the address was provided or uses systemd socket
a65053246c29 Initial commit
Martin Habovstiak <martin.habovstiak@gmail.com>
parents:
diff changeset
394 /// if the socket name was provided.
a65053246c29 Initial commit
Martin Habovstiak <martin.habovstiak@gmail.com>
parents:
diff changeset
395 #[cfg(feature = "tokio_0_3")]
4
66c0e10c89fc Support resolving hostnames
Martin Habovstiak <martin.habovstiak@gmail.com>
parents: 3
diff changeset
396 pub async fn bind_tokio_0_3(self) -> Result<tokio_0_3::net::TcpListener, TokioBindError> {
66c0e10c89fc Support resolving hostnames
Martin Habovstiak <martin.habovstiak@gmail.com>
parents: 3
diff changeset
397 match self.0 {
66c0e10c89fc Support resolving hostnames
Martin Habovstiak <martin.habovstiak@gmail.com>
parents: 3
diff changeset
398 SocketAddrInner::Ordinary(addr) => match tokio_0_3::net::TcpListener::bind(addr).await {
66c0e10c89fc Support resolving hostnames
Martin Habovstiak <martin.habovstiak@gmail.com>
parents: 3
diff changeset
399 Ok(socket) => Ok(socket),
66c0e10c89fc Support resolving hostnames
Martin Habovstiak <martin.habovstiak@gmail.com>
parents: 3
diff changeset
400 Err(error) => Err(TokioBindError::Bind(BindErrorInner::BindFailed { addr, error, }.into())),
66c0e10c89fc Support resolving hostnames
Martin Habovstiak <martin.habovstiak@gmail.com>
parents: 3
diff changeset
401 },
66c0e10c89fc Support resolving hostnames
Martin Habovstiak <martin.habovstiak@gmail.com>
parents: 3
diff changeset
402 SocketAddrInner::WithHostname(addr) => match tokio_0_3::net::TcpListener::bind(addr.as_str()).await {
66c0e10c89fc Support resolving hostnames
Martin Habovstiak <martin.habovstiak@gmail.com>
parents: 3
diff changeset
403 Ok(socket) => Ok(socket),
66c0e10c89fc Support resolving hostnames
Martin Habovstiak <martin.habovstiak@gmail.com>
parents: 3
diff changeset
404 Err(error) => Err(TokioBindError::Bind(BindErrorInner::BindOrResolvFailed { addr, error, }.into())),
66c0e10c89fc Support resolving hostnames
Martin Habovstiak <martin.habovstiak@gmail.com>
parents: 3
diff changeset
405 },
66c0e10c89fc Support resolving hostnames
Martin Habovstiak <martin.habovstiak@gmail.com>
parents: 3
diff changeset
406 SocketAddrInner::Systemd(socket_name) => {
17
dfb727367934 Allow specifying systemd name directly
Martin Habovstiak <martin.habovstiak@gmail.com>
parents: 16
diff changeset
407 let (socket, addr) = Self::get_systemd(socket_name, true)?;
dfb727367934 Allow specifying systemd name directly
Martin Habovstiak <martin.habovstiak@gmail.com>
parents: 16
diff changeset
408 socket.try_into().map_err(|error| TokioConversionError { addr, error, }.into())
dfb727367934 Allow specifying systemd name directly
Martin Habovstiak <martin.habovstiak@gmail.com>
parents: 16
diff changeset
409 },
dfb727367934 Allow specifying systemd name directly
Martin Habovstiak <martin.habovstiak@gmail.com>
parents: 16
diff changeset
410 SocketAddrInner::SystemdNoPrefix(socket_name) => {
dfb727367934 Allow specifying systemd name directly
Martin Habovstiak <martin.habovstiak@gmail.com>
parents: 16
diff changeset
411 let (socket, addr) = Self::get_systemd(socket_name, false)?;
4
66c0e10c89fc Support resolving hostnames
Martin Habovstiak <martin.habovstiak@gmail.com>
parents: 3
diff changeset
412 socket.try_into().map_err(|error| TokioConversionError { addr, error, }.into())
66c0e10c89fc Support resolving hostnames
Martin Habovstiak <martin.habovstiak@gmail.com>
parents: 3
diff changeset
413 },
66c0e10c89fc Support resolving hostnames
Martin Habovstiak <martin.habovstiak@gmail.com>
parents: 3
diff changeset
414 }
0
a65053246c29 Initial commit
Martin Habovstiak <martin.habovstiak@gmail.com>
parents:
diff changeset
415 }
a65053246c29 Initial commit
Martin Habovstiak <martin.habovstiak@gmail.com>
parents:
diff changeset
416
a65053246c29 Initial commit
Martin Habovstiak <martin.habovstiak@gmail.com>
parents:
diff changeset
417 /// Creates `async_std::net::TcpListener`
a65053246c29 Initial commit
Martin Habovstiak <martin.habovstiak@gmail.com>
parents:
diff changeset
418 ///
4
66c0e10c89fc Support resolving hostnames
Martin Habovstiak <martin.habovstiak@gmail.com>
parents: 3
diff changeset
419 /// To be specific, it binds the socket or converts systemd socket to `async_std` socket.
0
a65053246c29 Initial commit
Martin Habovstiak <martin.habovstiak@gmail.com>
parents:
diff changeset
420 ///
a65053246c29 Initial commit
Martin Habovstiak <martin.habovstiak@gmail.com>
parents:
diff changeset
421 /// This method either `binds` the socket, if the address was provided or uses systemd socket
a65053246c29 Initial commit
Martin Habovstiak <martin.habovstiak@gmail.com>
parents:
diff changeset
422 /// if the socket name was provided.
a65053246c29 Initial commit
Martin Habovstiak <martin.habovstiak@gmail.com>
parents:
diff changeset
423 #[cfg(feature = "async-std")]
4
66c0e10c89fc Support resolving hostnames
Martin Habovstiak <martin.habovstiak@gmail.com>
parents: 3
diff changeset
424 pub async fn bind_async_std(self) -> Result<async_std::net::TcpListener, BindError> {
66c0e10c89fc Support resolving hostnames
Martin Habovstiak <martin.habovstiak@gmail.com>
parents: 3
diff changeset
425 match self.0 {
66c0e10c89fc Support resolving hostnames
Martin Habovstiak <martin.habovstiak@gmail.com>
parents: 3
diff changeset
426 SocketAddrInner::Ordinary(addr) => match async_std::net::TcpListener::bind(addr).await {
66c0e10c89fc Support resolving hostnames
Martin Habovstiak <martin.habovstiak@gmail.com>
parents: 3
diff changeset
427 Ok(socket) => Ok(socket),
66c0e10c89fc Support resolving hostnames
Martin Habovstiak <martin.habovstiak@gmail.com>
parents: 3
diff changeset
428 Err(error) => Err(BindErrorInner::BindFailed { addr, error, }.into()),
66c0e10c89fc Support resolving hostnames
Martin Habovstiak <martin.habovstiak@gmail.com>
parents: 3
diff changeset
429 },
66c0e10c89fc Support resolving hostnames
Martin Habovstiak <martin.habovstiak@gmail.com>
parents: 3
diff changeset
430 SocketAddrInner::WithHostname(addr) => match async_std::net::TcpListener::bind(addr.as_str()).await {
66c0e10c89fc Support resolving hostnames
Martin Habovstiak <martin.habovstiak@gmail.com>
parents: 3
diff changeset
431 Ok(socket) => Ok(socket),
66c0e10c89fc Support resolving hostnames
Martin Habovstiak <martin.habovstiak@gmail.com>
parents: 3
diff changeset
432 Err(error) => Err(BindErrorInner::BindOrResolvFailed { addr, error, }.into()),
66c0e10c89fc Support resolving hostnames
Martin Habovstiak <martin.habovstiak@gmail.com>
parents: 3
diff changeset
433 },
66c0e10c89fc Support resolving hostnames
Martin Habovstiak <martin.habovstiak@gmail.com>
parents: 3
diff changeset
434 SocketAddrInner::Systemd(socket_name) => {
17
dfb727367934 Allow specifying systemd name directly
Martin Habovstiak <martin.habovstiak@gmail.com>
parents: 16
diff changeset
435 let (socket, _) = Self::get_systemd(socket_name, true)?;
dfb727367934 Allow specifying systemd name directly
Martin Habovstiak <martin.habovstiak@gmail.com>
parents: 16
diff changeset
436 Ok(socket.into())
dfb727367934 Allow specifying systemd name directly
Martin Habovstiak <martin.habovstiak@gmail.com>
parents: 16
diff changeset
437 },
dfb727367934 Allow specifying systemd name directly
Martin Habovstiak <martin.habovstiak@gmail.com>
parents: 16
diff changeset
438 SocketAddrInner::SystemdNoPrefix(socket_name) => {
dfb727367934 Allow specifying systemd name directly
Martin Habovstiak <martin.habovstiak@gmail.com>
parents: 16
diff changeset
439 let (socket, _) = Self::get_systemd(socket_name, false)?;
4
66c0e10c89fc Support resolving hostnames
Martin Habovstiak <martin.habovstiak@gmail.com>
parents: 3
diff changeset
440 Ok(socket.into())
66c0e10c89fc Support resolving hostnames
Martin Habovstiak <martin.habovstiak@gmail.com>
parents: 3
diff changeset
441 },
66c0e10c89fc Support resolving hostnames
Martin Habovstiak <martin.habovstiak@gmail.com>
parents: 3
diff changeset
442 }
0
a65053246c29 Initial commit
Martin Habovstiak <martin.habovstiak@gmail.com>
parents:
diff changeset
443 }
a65053246c29 Initial commit
Martin Habovstiak <martin.habovstiak@gmail.com>
parents:
diff changeset
444
a65053246c29 Initial commit
Martin Habovstiak <martin.habovstiak@gmail.com>
parents:
diff changeset
445 // We can't impl<T: Deref<Target=str> + Into<String>> TryFrom<T> for SocketAddr because of orphan
a65053246c29 Initial commit
Martin Habovstiak <martin.habovstiak@gmail.com>
parents:
diff changeset
446 // rules.
a65053246c29 Initial commit
Martin Habovstiak <martin.habovstiak@gmail.com>
parents:
diff changeset
447 fn try_from_generic<'a, T>(string: T) -> Result<Self, ParseError> where T: 'a + std::ops::Deref<Target=str> + Into<String> {
a65053246c29 Initial commit
Martin Habovstiak <martin.habovstiak@gmail.com>
parents:
diff changeset
448 if string.starts_with(SYSTEMD_PREFIX) {
17
dfb727367934 Allow specifying systemd name directly
Martin Habovstiak <martin.habovstiak@gmail.com>
parents: 16
diff changeset
449 Self::inner_from_systemd_name(string.into(), true)
0
a65053246c29 Initial commit
Martin Habovstiak <martin.habovstiak@gmail.com>
parents:
diff changeset
450 } else {
4
66c0e10c89fc Support resolving hostnames
Martin Habovstiak <martin.habovstiak@gmail.com>
parents: 3
diff changeset
451 match string.parse() {
66c0e10c89fc Support resolving hostnames
Martin Habovstiak <martin.habovstiak@gmail.com>
parents: 3
diff changeset
452 Ok(addr) => Ok(SocketAddr(SocketAddrInner::Ordinary(addr))),
66c0e10c89fc Support resolving hostnames
Martin Habovstiak <martin.habovstiak@gmail.com>
parents: 3
diff changeset
453 Err(_) => Ok(SocketAddr(SocketAddrInner::WithHostname(ResolvAddr::try_from_generic(string).map_err(ParseErrorInner::ResolvAddr)?))),
66c0e10c89fc Support resolving hostnames
Martin Habovstiak <martin.habovstiak@gmail.com>
parents: 3
diff changeset
454 }
0
a65053246c29 Initial commit
Martin Habovstiak <martin.habovstiak@gmail.com>
parents:
diff changeset
455 }
a65053246c29 Initial commit
Martin Habovstiak <martin.habovstiak@gmail.com>
parents:
diff changeset
456 }
a65053246c29 Initial commit
Martin Habovstiak <martin.habovstiak@gmail.com>
parents:
diff changeset
457
16
bc76507dd878 Fixed conditional compilation based on OS
Martin Habovstiak <martin.habovstiak@gmail.com>
parents: 13
diff changeset
458 #[cfg(all(target_os = "linux", feature = "enable_systemd"))]
17
dfb727367934 Allow specifying systemd name directly
Martin Habovstiak <martin.habovstiak@gmail.com>
parents: 16
diff changeset
459 fn get_systemd(socket_name: String, prefixed: bool) -> Result<(std::net::TcpListener, SocketAddrInner), BindError> {
25
8e20daee41ed Set CLOEXEC flag on the descriptors
Martin Habovstiak <martin.habovstiak@gmail.com>
parents: 24
diff changeset
460 use systemd_sockets::Socket;
0
a65053246c29 Initial commit
Martin Habovstiak <martin.habovstiak@gmail.com>
parents:
diff changeset
461
17
dfb727367934 Allow specifying systemd name directly
Martin Habovstiak <martin.habovstiak@gmail.com>
parents: 16
diff changeset
462 let real_systemd_name = if prefixed {
dfb727367934 Allow specifying systemd name directly
Martin Habovstiak <martin.habovstiak@gmail.com>
parents: 16
diff changeset
463 &socket_name[SYSTEMD_PREFIX.len()..]
dfb727367934 Allow specifying systemd name directly
Martin Habovstiak <martin.habovstiak@gmail.com>
parents: 16
diff changeset
464 } else {
dfb727367934 Allow specifying systemd name directly
Martin Habovstiak <martin.habovstiak@gmail.com>
parents: 16
diff changeset
465 &socket_name
dfb727367934 Allow specifying systemd name directly
Martin Habovstiak <martin.habovstiak@gmail.com>
parents: 16
diff changeset
466 };
dfb727367934 Allow specifying systemd name directly
Martin Habovstiak <martin.habovstiak@gmail.com>
parents: 16
diff changeset
467
dfb727367934 Allow specifying systemd name directly
Martin Habovstiak <martin.habovstiak@gmail.com>
parents: 16
diff changeset
468 let socket = systemd_sockets::take(real_systemd_name).map_err(BindErrorInner::ReceiveDescriptors)?;
25
8e20daee41ed Set CLOEXEC flag on the descriptors
Martin Habovstiak <martin.habovstiak@gmail.com>
parents: 24
diff changeset
469 // match instead of combinators to avoid cloning socket_name
8e20daee41ed Set CLOEXEC flag on the descriptors
Martin Habovstiak <martin.habovstiak@gmail.com>
parents: 24
diff changeset
470 match socket {
8e20daee41ed Set CLOEXEC flag on the descriptors
Martin Habovstiak <martin.habovstiak@gmail.com>
parents: 24
diff changeset
471 Some(Ok(Socket::TcpListener(socket))) => Ok((socket, SocketAddrInner::Systemd(socket_name))),
8e20daee41ed Set CLOEXEC flag on the descriptors
Martin Habovstiak <martin.habovstiak@gmail.com>
parents: 24
diff changeset
472 Some(_) => Err(BindErrorInner::NotInetSocket(socket_name).into()),
8e20daee41ed Set CLOEXEC flag on the descriptors
Martin Habovstiak <martin.habovstiak@gmail.com>
parents: 24
diff changeset
473 None => Err(BindErrorInner::MissingDescriptor(socket_name).into())
0
a65053246c29 Initial commit
Martin Habovstiak <martin.habovstiak@gmail.com>
parents:
diff changeset
474 }
a65053246c29 Initial commit
Martin Habovstiak <martin.habovstiak@gmail.com>
parents:
diff changeset
475 }
6
a7893294e9b2 Make the crate compilable on non-linux systems
Martin Habovstiak <martin.habovstiak@gmail.com>
parents: 4
diff changeset
476
a7893294e9b2 Make the crate compilable on non-linux systems
Martin Habovstiak <martin.habovstiak@gmail.com>
parents: 4
diff changeset
477 // This approach makes the rest of the code much simpler as it doesn't require sprinkling it
16
bc76507dd878 Fixed conditional compilation based on OS
Martin Habovstiak <martin.habovstiak@gmail.com>
parents: 13
diff changeset
478 // with #[cfg(all(target_os = "linux", feature = "enable_systemd"))] yet still statically guarantees it won't execute.
bc76507dd878 Fixed conditional compilation based on OS
Martin Habovstiak <martin.habovstiak@gmail.com>
parents: 13
diff changeset
479 #[cfg(not(all(target_os = "linux", feature = "enable_systemd")))]
17
dfb727367934 Allow specifying systemd name directly
Martin Habovstiak <martin.habovstiak@gmail.com>
parents: 16
diff changeset
480 fn get_systemd(socket_name: Never, _prefixed: bool) -> Result<(std::net::TcpListener, SocketAddrInner), BindError> {
6
a7893294e9b2 Make the crate compilable on non-linux systems
Martin Habovstiak <martin.habovstiak@gmail.com>
parents: 4
diff changeset
481 match socket_name {}
a7893294e9b2 Make the crate compilable on non-linux systems
Martin Habovstiak <martin.habovstiak@gmail.com>
parents: 4
diff changeset
482 }
0
a65053246c29 Initial commit
Martin Habovstiak <martin.habovstiak@gmail.com>
parents:
diff changeset
483 }
a65053246c29 Initial commit
Martin Habovstiak <martin.habovstiak@gmail.com>
parents:
diff changeset
484
24
1941e9d9819c Fix unsound manipulation of env vars
Martin Habovstiak <martin.habovstiak@gmail.com>
parents: 22
diff changeset
485 /// Initializes the library while there's only a single thread.
1941e9d9819c Fix unsound manipulation of env vars
Martin Habovstiak <martin.habovstiak@gmail.com>
parents: 22
diff changeset
486 ///
1941e9d9819c Fix unsound manipulation of env vars
Martin Habovstiak <martin.habovstiak@gmail.com>
parents: 22
diff changeset
487 /// Unfortunately, this library has to be initialized and, for soundness, this initialization must
1941e9d9819c Fix unsound manipulation of env vars
Martin Habovstiak <martin.habovstiak@gmail.com>
parents: 22
diff changeset
488 /// happen when no other threads are running. This is attempted automatically when trying to bind a
1941e9d9819c Fix unsound manipulation of env vars
Martin Habovstiak <martin.habovstiak@gmail.com>
parents: 22
diff changeset
489 /// systemd socket but at that time there may be other threads running and error reporting also
1941e9d9819c Fix unsound manipulation of env vars
Martin Habovstiak <martin.habovstiak@gmail.com>
parents: 22
diff changeset
490 /// faces some restrictions. This function provides better control over the initialization point
1941e9d9819c Fix unsound manipulation of env vars
Martin Habovstiak <martin.habovstiak@gmail.com>
parents: 22
diff changeset
491 /// and returns a more idiomatic error type.
1941e9d9819c Fix unsound manipulation of env vars
Martin Habovstiak <martin.habovstiak@gmail.com>
parents: 22
diff changeset
492 ///
1941e9d9819c Fix unsound manipulation of env vars
Martin Habovstiak <martin.habovstiak@gmail.com>
parents: 22
diff changeset
493 /// You should generally call this at around the top of `main`, where no threads were created yet.
25
8e20daee41ed Set CLOEXEC flag on the descriptors
Martin Habovstiak <martin.habovstiak@gmail.com>
parents: 24
diff changeset
494 /// While technically, you may spawn a thread and call this function after that thread terminated,
8e20daee41ed Set CLOEXEC flag on the descriptors
Martin Habovstiak <martin.habovstiak@gmail.com>
parents: 24
diff changeset
495 /// this has the additional problem that the descriptors are still around, so if that thread (or the
8e20daee41ed Set CLOEXEC flag on the descriptors
Martin Habovstiak <martin.habovstiak@gmail.com>
parents: 24
diff changeset
496 /// current one!) forks and execs the descriptors will leak into the child.
24
1941e9d9819c Fix unsound manipulation of env vars
Martin Habovstiak <martin.habovstiak@gmail.com>
parents: 22
diff changeset
497 #[inline]
1941e9d9819c Fix unsound manipulation of env vars
Martin Habovstiak <martin.habovstiak@gmail.com>
parents: 22
diff changeset
498 pub fn init() -> Result<(), error::InitError> {
1941e9d9819c Fix unsound manipulation of env vars
Martin Habovstiak <martin.habovstiak@gmail.com>
parents: 22
diff changeset
499 #[cfg(all(target_os = "linux", feature = "enable_systemd"))]
1941e9d9819c Fix unsound manipulation of env vars
Martin Habovstiak <martin.habovstiak@gmail.com>
parents: 22
diff changeset
500 {
1941e9d9819c Fix unsound manipulation of env vars
Martin Habovstiak <martin.habovstiak@gmail.com>
parents: 22
diff changeset
501 // Calling with true is always sound
1941e9d9819c Fix unsound manipulation of env vars
Martin Habovstiak <martin.habovstiak@gmail.com>
parents: 22
diff changeset
502 unsafe { systemd_sockets::init(true) }.map_err(error::InitError)
1941e9d9819c Fix unsound manipulation of env vars
Martin Habovstiak <martin.habovstiak@gmail.com>
parents: 22
diff changeset
503 }
1941e9d9819c Fix unsound manipulation of env vars
Martin Habovstiak <martin.habovstiak@gmail.com>
parents: 22
diff changeset
504 #[cfg(not(all(target_os = "linux", feature = "enable_systemd")))]
1941e9d9819c Fix unsound manipulation of env vars
Martin Habovstiak <martin.habovstiak@gmail.com>
parents: 22
diff changeset
505 {
1941e9d9819c Fix unsound manipulation of env vars
Martin Habovstiak <martin.habovstiak@gmail.com>
parents: 22
diff changeset
506 Ok(())
1941e9d9819c Fix unsound manipulation of env vars
Martin Habovstiak <martin.habovstiak@gmail.com>
parents: 22
diff changeset
507 }
1941e9d9819c Fix unsound manipulation of env vars
Martin Habovstiak <martin.habovstiak@gmail.com>
parents: 22
diff changeset
508 }
1941e9d9819c Fix unsound manipulation of env vars
Martin Habovstiak <martin.habovstiak@gmail.com>
parents: 22
diff changeset
509
1941e9d9819c Fix unsound manipulation of env vars
Martin Habovstiak <martin.habovstiak@gmail.com>
parents: 22
diff changeset
510 /// Initializes the library without protection against double close.
1941e9d9819c Fix unsound manipulation of env vars
Martin Habovstiak <martin.habovstiak@gmail.com>
parents: 22
diff changeset
511 ///
1941e9d9819c Fix unsound manipulation of env vars
Martin Habovstiak <martin.habovstiak@gmail.com>
parents: 22
diff changeset
512 /// Unfortunately, this library has to be initialized and, because double closing file descriptors
1941e9d9819c Fix unsound manipulation of env vars
Martin Habovstiak <martin.habovstiak@gmail.com>
parents: 22
diff changeset
513 /// is unsound, the library has some protections against double close. However these protections
1941e9d9819c Fix unsound manipulation of env vars
Martin Habovstiak <martin.habovstiak@gmail.com>
parents: 22
diff changeset
514 /// come with the limitation that the library must be initailized with a single thread.
1941e9d9819c Fix unsound manipulation of env vars
Martin Habovstiak <martin.habovstiak@gmail.com>
parents: 22
diff changeset
515 ///
1941e9d9819c Fix unsound manipulation of env vars
Martin Habovstiak <martin.habovstiak@gmail.com>
parents: 22
diff changeset
516 /// If for any reason you're unable to call `init` in a single thread at around the top of `main`
1941e9d9819c Fix unsound manipulation of env vars
Martin Habovstiak <martin.habovstiak@gmail.com>
parents: 22
diff changeset
517 /// (and this should be almost never) you may call this method if you've ensured that no other part
1941e9d9819c Fix unsound manipulation of env vars
Martin Habovstiak <martin.habovstiak@gmail.com>
parents: 22
diff changeset
518 /// of your codebase is operating on systemd-provided file descriptors stored in the environment
1941e9d9819c Fix unsound manipulation of env vars
Martin Habovstiak <martin.habovstiak@gmail.com>
parents: 22
diff changeset
519 /// variables.
25
8e20daee41ed Set CLOEXEC flag on the descriptors
Martin Habovstiak <martin.habovstiak@gmail.com>
parents: 24
diff changeset
520 ///
8e20daee41ed Set CLOEXEC flag on the descriptors
Martin Habovstiak <martin.habovstiak@gmail.com>
parents: 24
diff changeset
521 /// Note however that doing so uncovers another problem: if another thread forks and execs the
8e20daee41ed Set CLOEXEC flag on the descriptors
Martin Habovstiak <martin.habovstiak@gmail.com>
parents: 24
diff changeset
522 /// systemd file descriptors will get passed into that program! In such case you somehow need to
8e20daee41ed Set CLOEXEC flag on the descriptors
Martin Habovstiak <martin.habovstiak@gmail.com>
parents: 24
diff changeset
523 /// clean up the file descriptors yourself.
24
1941e9d9819c Fix unsound manipulation of env vars
Martin Habovstiak <martin.habovstiak@gmail.com>
parents: 22
diff changeset
524 pub unsafe fn init_unprotected() -> Result<(), error::InitError> {
1941e9d9819c Fix unsound manipulation of env vars
Martin Habovstiak <martin.habovstiak@gmail.com>
parents: 22
diff changeset
525 #[cfg(all(target_os = "linux", feature = "enable_systemd"))]
1941e9d9819c Fix unsound manipulation of env vars
Martin Habovstiak <martin.habovstiak@gmail.com>
parents: 22
diff changeset
526 {
1941e9d9819c Fix unsound manipulation of env vars
Martin Habovstiak <martin.habovstiak@gmail.com>
parents: 22
diff changeset
527 systemd_sockets::init(false).map_err(error::InitError)
1941e9d9819c Fix unsound manipulation of env vars
Martin Habovstiak <martin.habovstiak@gmail.com>
parents: 22
diff changeset
528 }
1941e9d9819c Fix unsound manipulation of env vars
Martin Habovstiak <martin.habovstiak@gmail.com>
parents: 22
diff changeset
529 #[cfg(not(all(target_os = "linux", feature = "enable_systemd")))]
1941e9d9819c Fix unsound manipulation of env vars
Martin Habovstiak <martin.habovstiak@gmail.com>
parents: 22
diff changeset
530 {
1941e9d9819c Fix unsound manipulation of env vars
Martin Habovstiak <martin.habovstiak@gmail.com>
parents: 22
diff changeset
531 Ok(())
1941e9d9819c Fix unsound manipulation of env vars
Martin Habovstiak <martin.habovstiak@gmail.com>
parents: 22
diff changeset
532 }
1941e9d9819c Fix unsound manipulation of env vars
Martin Habovstiak <martin.habovstiak@gmail.com>
parents: 22
diff changeset
533 }
1941e9d9819c Fix unsound manipulation of env vars
Martin Habovstiak <martin.habovstiak@gmail.com>
parents: 22
diff changeset
534
0
a65053246c29 Initial commit
Martin Habovstiak <martin.habovstiak@gmail.com>
parents:
diff changeset
535 /// Displays the address in format that can be parsed again.
a65053246c29 Initial commit
Martin Habovstiak <martin.habovstiak@gmail.com>
parents:
diff changeset
536 ///
a65053246c29 Initial commit
Martin Habovstiak <martin.habovstiak@gmail.com>
parents:
diff changeset
537 /// **Important: While I don't expect this impl to change, don't rely on it!**
a65053246c29 Initial commit
Martin Habovstiak <martin.habovstiak@gmail.com>
parents:
diff changeset
538 /// It should be used mostly for debugging/logging.
a65053246c29 Initial commit
Martin Habovstiak <martin.habovstiak@gmail.com>
parents:
diff changeset
539 impl fmt::Display for SocketAddr {
a65053246c29 Initial commit
Martin Habovstiak <martin.habovstiak@gmail.com>
parents:
diff changeset
540 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
a65053246c29 Initial commit
Martin Habovstiak <martin.habovstiak@gmail.com>
parents:
diff changeset
541 fmt::Display::fmt(&self.0, f)
a65053246c29 Initial commit
Martin Habovstiak <martin.habovstiak@gmail.com>
parents:
diff changeset
542 }
a65053246c29 Initial commit
Martin Habovstiak <martin.habovstiak@gmail.com>
parents:
diff changeset
543 }
a65053246c29 Initial commit
Martin Habovstiak <martin.habovstiak@gmail.com>
parents:
diff changeset
544
a65053246c29 Initial commit
Martin Habovstiak <martin.habovstiak@gmail.com>
parents:
diff changeset
545 impl fmt::Display for SocketAddrInner {
a65053246c29 Initial commit
Martin Habovstiak <martin.habovstiak@gmail.com>
parents:
diff changeset
546 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
a65053246c29 Initial commit
Martin Habovstiak <martin.habovstiak@gmail.com>
parents:
diff changeset
547 match self {
a65053246c29 Initial commit
Martin Habovstiak <martin.habovstiak@gmail.com>
parents:
diff changeset
548 SocketAddrInner::Ordinary(addr) => fmt::Display::fmt(addr, f),
a65053246c29 Initial commit
Martin Habovstiak <martin.habovstiak@gmail.com>
parents:
diff changeset
549 SocketAddrInner::Systemd(addr) => fmt::Display::fmt(addr, f),
17
dfb727367934 Allow specifying systemd name directly
Martin Habovstiak <martin.habovstiak@gmail.com>
parents: 16
diff changeset
550 SocketAddrInner::SystemdNoPrefix(addr) => write!(f, "{}{}", SYSTEMD_PREFIX, addr),
4
66c0e10c89fc Support resolving hostnames
Martin Habovstiak <martin.habovstiak@gmail.com>
parents: 3
diff changeset
551 SocketAddrInner::WithHostname(addr) => fmt::Display::fmt(addr, f),
0
a65053246c29 Initial commit
Martin Habovstiak <martin.habovstiak@gmail.com>
parents:
diff changeset
552 }
a65053246c29 Initial commit
Martin Habovstiak <martin.habovstiak@gmail.com>
parents:
diff changeset
553 }
a65053246c29 Initial commit
Martin Habovstiak <martin.habovstiak@gmail.com>
parents:
diff changeset
554 }
a65053246c29 Initial commit
Martin Habovstiak <martin.habovstiak@gmail.com>
parents:
diff changeset
555
a65053246c29 Initial commit
Martin Habovstiak <martin.habovstiak@gmail.com>
parents:
diff changeset
556 // PartialEq for testing, I'm not convinced it should be exposed
a65053246c29 Initial commit
Martin Habovstiak <martin.habovstiak@gmail.com>
parents:
diff changeset
557 #[derive(Debug, PartialEq)]
a65053246c29 Initial commit
Martin Habovstiak <martin.habovstiak@gmail.com>
parents:
diff changeset
558 enum SocketAddrInner {
a65053246c29 Initial commit
Martin Habovstiak <martin.habovstiak@gmail.com>
parents:
diff changeset
559 Ordinary(std::net::SocketAddr),
4
66c0e10c89fc Support resolving hostnames
Martin Habovstiak <martin.habovstiak@gmail.com>
parents: 3
diff changeset
560 WithHostname(resolv_addr::ResolvAddr),
16
bc76507dd878 Fixed conditional compilation based on OS
Martin Habovstiak <martin.habovstiak@gmail.com>
parents: 13
diff changeset
561 #[cfg(all(target_os = "linux", feature = "enable_systemd"))]
0
a65053246c29 Initial commit
Martin Habovstiak <martin.habovstiak@gmail.com>
parents:
diff changeset
562 Systemd(String),
16
bc76507dd878 Fixed conditional compilation based on OS
Martin Habovstiak <martin.habovstiak@gmail.com>
parents: 13
diff changeset
563 #[cfg(not(all(target_os = "linux", feature = "enable_systemd")))]
6
a7893294e9b2 Make the crate compilable on non-linux systems
Martin Habovstiak <martin.habovstiak@gmail.com>
parents: 4
diff changeset
564 #[allow(dead_code)]
a7893294e9b2 Make the crate compilable on non-linux systems
Martin Habovstiak <martin.habovstiak@gmail.com>
parents: 4
diff changeset
565 Systemd(Never),
17
dfb727367934 Allow specifying systemd name directly
Martin Habovstiak <martin.habovstiak@gmail.com>
parents: 16
diff changeset
566 #[cfg(all(target_os = "linux", feature = "enable_systemd"))]
dfb727367934 Allow specifying systemd name directly
Martin Habovstiak <martin.habovstiak@gmail.com>
parents: 16
diff changeset
567 #[allow(dead_code)]
dfb727367934 Allow specifying systemd name directly
Martin Habovstiak <martin.habovstiak@gmail.com>
parents: 16
diff changeset
568 SystemdNoPrefix(String),
dfb727367934 Allow specifying systemd name directly
Martin Habovstiak <martin.habovstiak@gmail.com>
parents: 16
diff changeset
569 #[cfg(not(all(target_os = "linux", feature = "enable_systemd")))]
dfb727367934 Allow specifying systemd name directly
Martin Habovstiak <martin.habovstiak@gmail.com>
parents: 16
diff changeset
570 #[allow(dead_code)]
dfb727367934 Allow specifying systemd name directly
Martin Habovstiak <martin.habovstiak@gmail.com>
parents: 16
diff changeset
571 SystemdNoPrefix(Never),
0
a65053246c29 Initial commit
Martin Habovstiak <martin.habovstiak@gmail.com>
parents:
diff changeset
572 }
a65053246c29 Initial commit
Martin Habovstiak <martin.habovstiak@gmail.com>
parents:
diff changeset
573
a65053246c29 Initial commit
Martin Habovstiak <martin.habovstiak@gmail.com>
parents:
diff changeset
574 const SYSTEMD_PREFIX: &str = "systemd://";
a65053246c29 Initial commit
Martin Habovstiak <martin.habovstiak@gmail.com>
parents:
diff changeset
575
11
13e2a5545167 Implement From conversions
Martin Habovstiak <martin.habovstiak@gmail.com>
parents: 9
diff changeset
576 impl<I: Into<std::net::IpAddr>> From<(I, u16)> for SocketAddr {
13e2a5545167 Implement From conversions
Martin Habovstiak <martin.habovstiak@gmail.com>
parents: 9
diff changeset
577 fn from(value: (I, u16)) -> Self {
13e2a5545167 Implement From conversions
Martin Habovstiak <martin.habovstiak@gmail.com>
parents: 9
diff changeset
578 SocketAddr(SocketAddrInner::Ordinary(value.into()))
13e2a5545167 Implement From conversions
Martin Habovstiak <martin.habovstiak@gmail.com>
parents: 9
diff changeset
579 }
13e2a5545167 Implement From conversions
Martin Habovstiak <martin.habovstiak@gmail.com>
parents: 9
diff changeset
580 }
13e2a5545167 Implement From conversions
Martin Habovstiak <martin.habovstiak@gmail.com>
parents: 9
diff changeset
581
18
db1dc99252e2 Added From<std::net::SocketAddr>
Martin Habovstiak <martin.habovstiak@gmail.com>
parents: 17
diff changeset
582 impl From<std::net::SocketAddr> for SocketAddr {
db1dc99252e2 Added From<std::net::SocketAddr>
Martin Habovstiak <martin.habovstiak@gmail.com>
parents: 17
diff changeset
583 fn from(value: std::net::SocketAddr) -> Self {
db1dc99252e2 Added From<std::net::SocketAddr>
Martin Habovstiak <martin.habovstiak@gmail.com>
parents: 17
diff changeset
584 SocketAddr(SocketAddrInner::Ordinary(value))
db1dc99252e2 Added From<std::net::SocketAddr>
Martin Habovstiak <martin.habovstiak@gmail.com>
parents: 17
diff changeset
585 }
db1dc99252e2 Added From<std::net::SocketAddr>
Martin Habovstiak <martin.habovstiak@gmail.com>
parents: 17
diff changeset
586 }
db1dc99252e2 Added From<std::net::SocketAddr>
Martin Habovstiak <martin.habovstiak@gmail.com>
parents: 17
diff changeset
587
11
13e2a5545167 Implement From conversions
Martin Habovstiak <martin.habovstiak@gmail.com>
parents: 9
diff changeset
588 impl From<std::net::SocketAddrV4> for SocketAddr {
13e2a5545167 Implement From conversions
Martin Habovstiak <martin.habovstiak@gmail.com>
parents: 9
diff changeset
589 fn from(value: std::net::SocketAddrV4) -> Self {
13e2a5545167 Implement From conversions
Martin Habovstiak <martin.habovstiak@gmail.com>
parents: 9
diff changeset
590 SocketAddr(SocketAddrInner::Ordinary(value.into()))
13e2a5545167 Implement From conversions
Martin Habovstiak <martin.habovstiak@gmail.com>
parents: 9
diff changeset
591 }
13e2a5545167 Implement From conversions
Martin Habovstiak <martin.habovstiak@gmail.com>
parents: 9
diff changeset
592 }
13e2a5545167 Implement From conversions
Martin Habovstiak <martin.habovstiak@gmail.com>
parents: 9
diff changeset
593
13e2a5545167 Implement From conversions
Martin Habovstiak <martin.habovstiak@gmail.com>
parents: 9
diff changeset
594 impl From<std::net::SocketAddrV6> for SocketAddr {
13e2a5545167 Implement From conversions
Martin Habovstiak <martin.habovstiak@gmail.com>
parents: 9
diff changeset
595 fn from(value: std::net::SocketAddrV6) -> Self {
13e2a5545167 Implement From conversions
Martin Habovstiak <martin.habovstiak@gmail.com>
parents: 9
diff changeset
596 SocketAddr(SocketAddrInner::Ordinary(value.into()))
13e2a5545167 Implement From conversions
Martin Habovstiak <martin.habovstiak@gmail.com>
parents: 9
diff changeset
597 }
13e2a5545167 Implement From conversions
Martin Habovstiak <martin.habovstiak@gmail.com>
parents: 9
diff changeset
598 }
13e2a5545167 Implement From conversions
Martin Habovstiak <martin.habovstiak@gmail.com>
parents: 9
diff changeset
599
0
a65053246c29 Initial commit
Martin Habovstiak <martin.habovstiak@gmail.com>
parents:
diff changeset
600 impl std::str::FromStr for SocketAddr {
a65053246c29 Initial commit
Martin Habovstiak <martin.habovstiak@gmail.com>
parents:
diff changeset
601 type Err = ParseError;
a65053246c29 Initial commit
Martin Habovstiak <martin.habovstiak@gmail.com>
parents:
diff changeset
602
a65053246c29 Initial commit
Martin Habovstiak <martin.habovstiak@gmail.com>
parents:
diff changeset
603 fn from_str(s: &str) -> Result<Self, Self::Err> {
a65053246c29 Initial commit
Martin Habovstiak <martin.habovstiak@gmail.com>
parents:
diff changeset
604 SocketAddr::try_from_generic(s)
a65053246c29 Initial commit
Martin Habovstiak <martin.habovstiak@gmail.com>
parents:
diff changeset
605 }
a65053246c29 Initial commit
Martin Habovstiak <martin.habovstiak@gmail.com>
parents:
diff changeset
606 }
a65053246c29 Initial commit
Martin Habovstiak <martin.habovstiak@gmail.com>
parents:
diff changeset
607
a65053246c29 Initial commit
Martin Habovstiak <martin.habovstiak@gmail.com>
parents:
diff changeset
608 impl<'a> TryFrom<&'a str> for SocketAddr {
a65053246c29 Initial commit
Martin Habovstiak <martin.habovstiak@gmail.com>
parents:
diff changeset
609 type Error = ParseError;
a65053246c29 Initial commit
Martin Habovstiak <martin.habovstiak@gmail.com>
parents:
diff changeset
610
a65053246c29 Initial commit
Martin Habovstiak <martin.habovstiak@gmail.com>
parents:
diff changeset
611 fn try_from(s: &'a str) -> Result<Self, Self::Error> {
a65053246c29 Initial commit
Martin Habovstiak <martin.habovstiak@gmail.com>
parents:
diff changeset
612 SocketAddr::try_from_generic(s)
a65053246c29 Initial commit
Martin Habovstiak <martin.habovstiak@gmail.com>
parents:
diff changeset
613 }
a65053246c29 Initial commit
Martin Habovstiak <martin.habovstiak@gmail.com>
parents:
diff changeset
614 }
a65053246c29 Initial commit
Martin Habovstiak <martin.habovstiak@gmail.com>
parents:
diff changeset
615
a65053246c29 Initial commit
Martin Habovstiak <martin.habovstiak@gmail.com>
parents:
diff changeset
616 impl TryFrom<String> for SocketAddr {
a65053246c29 Initial commit
Martin Habovstiak <martin.habovstiak@gmail.com>
parents:
diff changeset
617 type Error = ParseError;
a65053246c29 Initial commit
Martin Habovstiak <martin.habovstiak@gmail.com>
parents:
diff changeset
618
a65053246c29 Initial commit
Martin Habovstiak <martin.habovstiak@gmail.com>
parents:
diff changeset
619 fn try_from(s: String) -> Result<Self, Self::Error> {
a65053246c29 Initial commit
Martin Habovstiak <martin.habovstiak@gmail.com>
parents:
diff changeset
620 SocketAddr::try_from_generic(s)
a65053246c29 Initial commit
Martin Habovstiak <martin.habovstiak@gmail.com>
parents:
diff changeset
621 }
a65053246c29 Initial commit
Martin Habovstiak <martin.habovstiak@gmail.com>
parents:
diff changeset
622 }
a65053246c29 Initial commit
Martin Habovstiak <martin.habovstiak@gmail.com>
parents:
diff changeset
623
a65053246c29 Initial commit
Martin Habovstiak <martin.habovstiak@gmail.com>
parents:
diff changeset
624 impl<'a> TryFrom<&'a OsStr> for SocketAddr {
a65053246c29 Initial commit
Martin Habovstiak <martin.habovstiak@gmail.com>
parents:
diff changeset
625 type Error = ParseOsStrError;
a65053246c29 Initial commit
Martin Habovstiak <martin.habovstiak@gmail.com>
parents:
diff changeset
626
a65053246c29 Initial commit
Martin Habovstiak <martin.habovstiak@gmail.com>
parents:
diff changeset
627 fn try_from(s: &'a OsStr) -> Result<Self, Self::Error> {
a65053246c29 Initial commit
Martin Habovstiak <martin.habovstiak@gmail.com>
parents:
diff changeset
628 s.to_str().ok_or(ParseOsStrError::InvalidUtf8)?.try_into().map_err(Into::into)
a65053246c29 Initial commit
Martin Habovstiak <martin.habovstiak@gmail.com>
parents:
diff changeset
629 }
a65053246c29 Initial commit
Martin Habovstiak <martin.habovstiak@gmail.com>
parents:
diff changeset
630 }
a65053246c29 Initial commit
Martin Habovstiak <martin.habovstiak@gmail.com>
parents:
diff changeset
631
a65053246c29 Initial commit
Martin Habovstiak <martin.habovstiak@gmail.com>
parents:
diff changeset
632 impl TryFrom<OsString> for SocketAddr {
a65053246c29 Initial commit
Martin Habovstiak <martin.habovstiak@gmail.com>
parents:
diff changeset
633 type Error = ParseOsStrError;
a65053246c29 Initial commit
Martin Habovstiak <martin.habovstiak@gmail.com>
parents:
diff changeset
634
a65053246c29 Initial commit
Martin Habovstiak <martin.habovstiak@gmail.com>
parents:
diff changeset
635 fn try_from(s: OsString) -> Result<Self, Self::Error> {
a65053246c29 Initial commit
Martin Habovstiak <martin.habovstiak@gmail.com>
parents:
diff changeset
636 s.into_string().map_err(|_| ParseOsStrError::InvalidUtf8)?.try_into().map_err(Into::into)
a65053246c29 Initial commit
Martin Habovstiak <martin.habovstiak@gmail.com>
parents:
diff changeset
637 }
a65053246c29 Initial commit
Martin Habovstiak <martin.habovstiak@gmail.com>
parents:
diff changeset
638 }
a65053246c29 Initial commit
Martin Habovstiak <martin.habovstiak@gmail.com>
parents:
diff changeset
639
a65053246c29 Initial commit
Martin Habovstiak <martin.habovstiak@gmail.com>
parents:
diff changeset
640 #[cfg(feature = "serde")]
a65053246c29 Initial commit
Martin Habovstiak <martin.habovstiak@gmail.com>
parents:
diff changeset
641 impl<'a> TryFrom<serde_str_helpers::DeserBorrowStr<'a>> for SocketAddr {
a65053246c29 Initial commit
Martin Habovstiak <martin.habovstiak@gmail.com>
parents:
diff changeset
642 type Error = ParseError;
a65053246c29 Initial commit
Martin Habovstiak <martin.habovstiak@gmail.com>
parents:
diff changeset
643
a65053246c29 Initial commit
Martin Habovstiak <martin.habovstiak@gmail.com>
parents:
diff changeset
644 fn try_from(s: serde_str_helpers::DeserBorrowStr<'a>) -> Result<Self, Self::Error> {
9
4fb70ca820a6 Upgrade serde_str_helpers
Martin Habovstiak <martin.habovstiak@gmail.com>
parents: 7
diff changeset
645 SocketAddr::try_from_generic(s)
0
a65053246c29 Initial commit
Martin Habovstiak <martin.habovstiak@gmail.com>
parents:
diff changeset
646 }
a65053246c29 Initial commit
Martin Habovstiak <martin.habovstiak@gmail.com>
parents:
diff changeset
647 }
a65053246c29 Initial commit
Martin Habovstiak <martin.habovstiak@gmail.com>
parents:
diff changeset
648
a65053246c29 Initial commit
Martin Habovstiak <martin.habovstiak@gmail.com>
parents:
diff changeset
649 #[cfg(feature = "parse_arg")]
a65053246c29 Initial commit
Martin Habovstiak <martin.habovstiak@gmail.com>
parents:
diff changeset
650 impl parse_arg::ParseArg for SocketAddr {
a65053246c29 Initial commit
Martin Habovstiak <martin.habovstiak@gmail.com>
parents:
diff changeset
651 type Error = ParseOsStrError;
a65053246c29 Initial commit
Martin Habovstiak <martin.habovstiak@gmail.com>
parents:
diff changeset
652
a65053246c29 Initial commit
Martin Habovstiak <martin.habovstiak@gmail.com>
parents:
diff changeset
653 fn describe_type<W: fmt::Write>(mut writer: W) -> fmt::Result {
a65053246c29 Initial commit
Martin Habovstiak <martin.habovstiak@gmail.com>
parents:
diff changeset
654 std::net::SocketAddr::describe_type(&mut writer)?;
a65053246c29 Initial commit
Martin Habovstiak <martin.habovstiak@gmail.com>
parents:
diff changeset
655 write!(writer, " or a systemd socket name prefixed with systemd://")
a65053246c29 Initial commit
Martin Habovstiak <martin.habovstiak@gmail.com>
parents:
diff changeset
656 }
a65053246c29 Initial commit
Martin Habovstiak <martin.habovstiak@gmail.com>
parents:
diff changeset
657
a65053246c29 Initial commit
Martin Habovstiak <martin.habovstiak@gmail.com>
parents:
diff changeset
658 fn parse_arg(arg: &OsStr) -> Result<Self, Self::Error> {
a65053246c29 Initial commit
Martin Habovstiak <martin.habovstiak@gmail.com>
parents:
diff changeset
659 arg.try_into()
a65053246c29 Initial commit
Martin Habovstiak <martin.habovstiak@gmail.com>
parents:
diff changeset
660 }
a65053246c29 Initial commit
Martin Habovstiak <martin.habovstiak@gmail.com>
parents:
diff changeset
661
a65053246c29 Initial commit
Martin Habovstiak <martin.habovstiak@gmail.com>
parents:
diff changeset
662 fn parse_owned_arg(arg: OsString) -> Result<Self, Self::Error> {
a65053246c29 Initial commit
Martin Habovstiak <martin.habovstiak@gmail.com>
parents:
diff changeset
663 arg.try_into()
a65053246c29 Initial commit
Martin Habovstiak <martin.habovstiak@gmail.com>
parents:
diff changeset
664 }
a65053246c29 Initial commit
Martin Habovstiak <martin.habovstiak@gmail.com>
parents:
diff changeset
665 }
a65053246c29 Initial commit
Martin Habovstiak <martin.habovstiak@gmail.com>
parents:
diff changeset
666
a65053246c29 Initial commit
Martin Habovstiak <martin.habovstiak@gmail.com>
parents:
diff changeset
667 #[cfg(test)]
a65053246c29 Initial commit
Martin Habovstiak <martin.habovstiak@gmail.com>
parents:
diff changeset
668 mod tests {
a65053246c29 Initial commit
Martin Habovstiak <martin.habovstiak@gmail.com>
parents:
diff changeset
669 use super::{SocketAddr, SocketAddrInner};
a65053246c29 Initial commit
Martin Habovstiak <martin.habovstiak@gmail.com>
parents:
diff changeset
670
a65053246c29 Initial commit
Martin Habovstiak <martin.habovstiak@gmail.com>
parents:
diff changeset
671 #[test]
a65053246c29 Initial commit
Martin Habovstiak <martin.habovstiak@gmail.com>
parents:
diff changeset
672 fn parse_ordinary() {
a65053246c29 Initial commit
Martin Habovstiak <martin.habovstiak@gmail.com>
parents:
diff changeset
673 assert_eq!("127.0.0.1:42".parse::<SocketAddr>().unwrap().0, SocketAddrInner::Ordinary(([127, 0, 0, 1], 42).into()));
a65053246c29 Initial commit
Martin Habovstiak <martin.habovstiak@gmail.com>
parents:
diff changeset
674 }
a65053246c29 Initial commit
Martin Habovstiak <martin.habovstiak@gmail.com>
parents:
diff changeset
675
a65053246c29 Initial commit
Martin Habovstiak <martin.habovstiak@gmail.com>
parents:
diff changeset
676 #[test]
16
bc76507dd878 Fixed conditional compilation based on OS
Martin Habovstiak <martin.habovstiak@gmail.com>
parents: 13
diff changeset
677 #[cfg(all(target_os = "linux", feature = "enable_systemd"))]
0
a65053246c29 Initial commit
Martin Habovstiak <martin.habovstiak@gmail.com>
parents:
diff changeset
678 fn parse_systemd() {
a65053246c29 Initial commit
Martin Habovstiak <martin.habovstiak@gmail.com>
parents:
diff changeset
679 assert_eq!("systemd://foo".parse::<SocketAddr>().unwrap().0, SocketAddrInner::Systemd("systemd://foo".to_owned()));
a65053246c29 Initial commit
Martin Habovstiak <martin.habovstiak@gmail.com>
parents:
diff changeset
680 }
2
cabc4aafdd85 Added length check and a few tests
Martin Habovstiak <martin.habovstiak@gmail.com>
parents: 0
diff changeset
681
cabc4aafdd85 Added length check and a few tests
Martin Habovstiak <martin.habovstiak@gmail.com>
parents: 0
diff changeset
682 #[test]
16
bc76507dd878 Fixed conditional compilation based on OS
Martin Habovstiak <martin.habovstiak@gmail.com>
parents: 13
diff changeset
683 #[cfg(not(all(target_os = "linux", feature = "enable_systemd")))]
7
9731ff589d9c Fix tests on non-linux systems
Martin Habovstiak <martin.habovstiak@gmail.com>
parents: 6
diff changeset
684 #[should_panic]
9731ff589d9c Fix tests on non-linux systems
Martin Habovstiak <martin.habovstiak@gmail.com>
parents: 6
diff changeset
685 fn parse_systemd() {
9731ff589d9c Fix tests on non-linux systems
Martin Habovstiak <martin.habovstiak@gmail.com>
parents: 6
diff changeset
686 "systemd://foo".parse::<SocketAddr>().unwrap();
9731ff589d9c Fix tests on non-linux systems
Martin Habovstiak <martin.habovstiak@gmail.com>
parents: 6
diff changeset
687 }
9731ff589d9c Fix tests on non-linux systems
Martin Habovstiak <martin.habovstiak@gmail.com>
parents: 6
diff changeset
688
9731ff589d9c Fix tests on non-linux systems
Martin Habovstiak <martin.habovstiak@gmail.com>
parents: 6
diff changeset
689 #[test]
2
cabc4aafdd85 Added length check and a few tests
Martin Habovstiak <martin.habovstiak@gmail.com>
parents: 0
diff changeset
690 #[should_panic]
cabc4aafdd85 Added length check and a few tests
Martin Habovstiak <martin.habovstiak@gmail.com>
parents: 0
diff changeset
691 fn parse_systemd_fail_control() {
cabc4aafdd85 Added length check and a few tests
Martin Habovstiak <martin.habovstiak@gmail.com>
parents: 0
diff changeset
692 "systemd://foo\n".parse::<SocketAddr>().unwrap();
cabc4aafdd85 Added length check and a few tests
Martin Habovstiak <martin.habovstiak@gmail.com>
parents: 0
diff changeset
693 }
cabc4aafdd85 Added length check and a few tests
Martin Habovstiak <martin.habovstiak@gmail.com>
parents: 0
diff changeset
694
cabc4aafdd85 Added length check and a few tests
Martin Habovstiak <martin.habovstiak@gmail.com>
parents: 0
diff changeset
695 #[test]
cabc4aafdd85 Added length check and a few tests
Martin Habovstiak <martin.habovstiak@gmail.com>
parents: 0
diff changeset
696 #[should_panic]
cabc4aafdd85 Added length check and a few tests
Martin Habovstiak <martin.habovstiak@gmail.com>
parents: 0
diff changeset
697 fn parse_systemd_fail_colon() {
cabc4aafdd85 Added length check and a few tests
Martin Habovstiak <martin.habovstiak@gmail.com>
parents: 0
diff changeset
698 "systemd://foo:".parse::<SocketAddr>().unwrap();
cabc4aafdd85 Added length check and a few tests
Martin Habovstiak <martin.habovstiak@gmail.com>
parents: 0
diff changeset
699 }
cabc4aafdd85 Added length check and a few tests
Martin Habovstiak <martin.habovstiak@gmail.com>
parents: 0
diff changeset
700
cabc4aafdd85 Added length check and a few tests
Martin Habovstiak <martin.habovstiak@gmail.com>
parents: 0
diff changeset
701 #[test]
cabc4aafdd85 Added length check and a few tests
Martin Habovstiak <martin.habovstiak@gmail.com>
parents: 0
diff changeset
702 #[should_panic]
cabc4aafdd85 Added length check and a few tests
Martin Habovstiak <martin.habovstiak@gmail.com>
parents: 0
diff changeset
703 fn parse_systemd_fail_non_ascii() {
cabc4aafdd85 Added length check and a few tests
Martin Habovstiak <martin.habovstiak@gmail.com>
parents: 0
diff changeset
704 "systemd://fooá".parse::<SocketAddr>().unwrap();
cabc4aafdd85 Added length check and a few tests
Martin Habovstiak <martin.habovstiak@gmail.com>
parents: 0
diff changeset
705 }
cabc4aafdd85 Added length check and a few tests
Martin Habovstiak <martin.habovstiak@gmail.com>
parents: 0
diff changeset
706
cabc4aafdd85 Added length check and a few tests
Martin Habovstiak <martin.habovstiak@gmail.com>
parents: 0
diff changeset
707 #[test]
cabc4aafdd85 Added length check and a few tests
Martin Habovstiak <martin.habovstiak@gmail.com>
parents: 0
diff changeset
708 #[should_panic]
cabc4aafdd85 Added length check and a few tests
Martin Habovstiak <martin.habovstiak@gmail.com>
parents: 0
diff changeset
709 fn parse_systemd_fail_too_long() {
cabc4aafdd85 Added length check and a few tests
Martin Habovstiak <martin.habovstiak@gmail.com>
parents: 0
diff changeset
710 "systemd://xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx".parse::<SocketAddr>().unwrap();
cabc4aafdd85 Added length check and a few tests
Martin Habovstiak <martin.habovstiak@gmail.com>
parents: 0
diff changeset
711 }
17
dfb727367934 Allow specifying systemd name directly
Martin Habovstiak <martin.habovstiak@gmail.com>
parents: 16
diff changeset
712
dfb727367934 Allow specifying systemd name directly
Martin Habovstiak <martin.habovstiak@gmail.com>
parents: 16
diff changeset
713 #[test]
dfb727367934 Allow specifying systemd name directly
Martin Habovstiak <martin.habovstiak@gmail.com>
parents: 16
diff changeset
714 #[cfg_attr(not(all(target_os = "linux", feature = "enable_systemd")), should_panic)]
dfb727367934 Allow specifying systemd name directly
Martin Habovstiak <martin.habovstiak@gmail.com>
parents: 16
diff changeset
715 fn no_prefix_parse_systemd() {
dfb727367934 Allow specifying systemd name directly
Martin Habovstiak <martin.habovstiak@gmail.com>
parents: 16
diff changeset
716 SocketAddr::from_systemd_name("foo").unwrap();
dfb727367934 Allow specifying systemd name directly
Martin Habovstiak <martin.habovstiak@gmail.com>
parents: 16
diff changeset
717 }
dfb727367934 Allow specifying systemd name directly
Martin Habovstiak <martin.habovstiak@gmail.com>
parents: 16
diff changeset
718
dfb727367934 Allow specifying systemd name directly
Martin Habovstiak <martin.habovstiak@gmail.com>
parents: 16
diff changeset
719 #[test]
dfb727367934 Allow specifying systemd name directly
Martin Habovstiak <martin.habovstiak@gmail.com>
parents: 16
diff changeset
720 #[should_panic]
dfb727367934 Allow specifying systemd name directly
Martin Habovstiak <martin.habovstiak@gmail.com>
parents: 16
diff changeset
721 fn no_prefix_parse_systemd_fail_non_ascii() {
dfb727367934 Allow specifying systemd name directly
Martin Habovstiak <martin.habovstiak@gmail.com>
parents: 16
diff changeset
722 SocketAddr::from_systemd_name("fooá").unwrap();
dfb727367934 Allow specifying systemd name directly
Martin Habovstiak <martin.habovstiak@gmail.com>
parents: 16
diff changeset
723 }
dfb727367934 Allow specifying systemd name directly
Martin Habovstiak <martin.habovstiak@gmail.com>
parents: 16
diff changeset
724
dfb727367934 Allow specifying systemd name directly
Martin Habovstiak <martin.habovstiak@gmail.com>
parents: 16
diff changeset
725 #[test]
dfb727367934 Allow specifying systemd name directly
Martin Habovstiak <martin.habovstiak@gmail.com>
parents: 16
diff changeset
726 #[should_panic]
dfb727367934 Allow specifying systemd name directly
Martin Habovstiak <martin.habovstiak@gmail.com>
parents: 16
diff changeset
727 fn no_prefix_parse_systemd_fail_too_long() {
dfb727367934 Allow specifying systemd name directly
Martin Habovstiak <martin.habovstiak@gmail.com>
parents: 16
diff changeset
728 SocketAddr::from_systemd_name("xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx").unwrap();
dfb727367934 Allow specifying systemd name directly
Martin Habovstiak <martin.habovstiak@gmail.com>
parents: 16
diff changeset
729 }
0
a65053246c29 Initial commit
Martin Habovstiak <martin.habovstiak@gmail.com>
parents:
diff changeset
730 }