aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--CHANGELOG.md2
-rw-r--r--README.md2
-rw-r--r--src/config.rs34
3 files changed, 28 insertions, 10 deletions
diff --git a/CHANGELOG.md b/CHANGELOG.md
index 28fc616..44bc707 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -17,6 +17,8 @@ SPDX-License-Identifier: CC-BY-SA-4.0
* Ability to specify program paths or arguments which contain non-UTF8 sequences
by using `{ b64 = "BaSe64==" }` in place of a string in the config.
* The simple `./install` script.
+* TLS and Unix socket support with the `transport` configurable set to `tls` or
+ `unix` respectively.
## [0.3.0] - 2025-07-10
diff --git a/README.md b/README.md
index 03ef930..5685f12 100644
--- a/README.md
+++ b/README.md
@@ -36,6 +36,7 @@ minimum a set of routes. The following is the default configuration:
```toml
host = "localhost" # MQTT server host
port = 1883 # MQTT server port
+transport = "tcp" # The transport protocol, (tcp, tls or unix)
qos = "exactly-once" # Default subscription QoS
# at-least-once (=0), at-most-once (=1), exactly-once (=2)
timeout = 10.5 # Timeout in seconds (0 means (effectively) no timeout)
@@ -92,7 +93,6 @@ it being ran every time a new MQTT message is published to this topic.
## Missing Features
-* TLS
* mTLS
* Graceful signal handling
* Graceful program stdout/stderr handling
diff --git a/src/config.rs b/src/config.rs
index 570994c..d56ac8e 100644
--- a/src/config.rs
+++ b/src/config.rs
@@ -44,10 +44,6 @@ fn default_host() -> String {
"localhost".to_string()
}
-fn default_port() -> u16 {
- 1883
-}
-
fn default_qos() -> QoS {
QoS::ExactlyOnce
}
@@ -76,12 +72,22 @@ pub struct Route {
pub qos: Option<QoS>,
}
+#[derive(Deserialize, Debug, PartialEq, Default)]
+#[serde(rename_all = "kebab-case")]
+pub enum Transport {
+ #[default]
+ Tcp,
+ Tls,
+ Unix,
+}
+
#[derive(Deserialize, Debug)]
pub struct Config {
#[serde(default = "default_host")]
pub host: String,
- #[serde(default = "default_port")]
- pub port: u16,
+ pub port: Option<u16>,
+ #[serde(default)]
+ pub transport: Transport,
#[serde(with = "QoSDef", default = "default_qos")]
pub qos: QoS,
#[serde(default = "default_timeout", deserialize_with = "deserialize_timeout")]
@@ -97,10 +103,17 @@ pub struct Config {
impl Config {
pub fn mqtt_client(&self) -> (AsyncClient, EventLoop) {
let client_id = self.id.to_string();
- let mut options = MqttOptions::new(client_id, &self.host, self.port);
+ let (transport, default_port) = match self.transport {
+ Transport::Tcp => (rumqttc::Transport::tcp(), 1883),
+ Transport::Tls => (rumqttc::Transport::tls_with_default_config(), 8883),
+ Transport::Unix => (rumqttc::Transport::unix(), 0),
+ };
+ let mut options =
+ MqttOptions::new(client_id, &self.host, self.port.unwrap_or(default_port));
if let Some(credentials) = &self.credentials {
options.set_credentials(&credentials.username, &credentials.password);
}
+ options.set_transport(transport);
// TODO: Make configurable
options.set_keep_alive(Duration::from_secs(5));
options.set_max_packet_size(10 * 1024 * 1024, 10 * 1024 * 1024);
@@ -158,6 +171,7 @@ mod tests {
qos = "at-most-once"
id = "custom-id"
timeout = 15.5
+ transport = "tls"
[credentials]
username = "testuser"
@@ -182,10 +196,11 @@ mod tests {
let config: Config = toml::from_str(toml_str).expect("Failed to parse full config");
assert_eq!(config.host, "foo.bar.baz");
- assert_eq!(config.port, 1234);
+ assert_eq!(config.port, Some(1234));
assert_eq!(config.qos, QoS::AtMostOnce);
assert_eq!(config.id, "custom-id");
assert_eq!(config.timeout, Duration::from_secs_f64(15.5));
+ assert_eq!(config.transport, Transport::Tls);
let creds = config.credentials.expect("Credentials should be present");
assert_eq!(creds.username, "testuser");
@@ -225,10 +240,11 @@ mod tests {
let config: Config = toml::from_str("[routes]").expect("Failed to parse minimal config");
assert_eq!(config.host, default_host());
- assert_eq!(config.port, default_port());
+ assert_eq!(config.port, None);
assert_eq!(config.qos, default_qos());
assert_eq!(config.id, default_id());
assert_eq!(config.timeout, default_timeout());
+ assert_eq!(config.transport, Transport::default());
assert!(config.credentials.is_none());
assert_eq!(config.log, Logging::default());
assert!(config.routes.is_empty());