initial commit
flake-check / flake-check (push) Canceled after 0s
lint / lint (push) Canceled after 0s
diff-tag / dix (push) Canceled after 0s

This commit is contained in:
Floweynt
2026-08-31 08:41:45 -05:00
commit 76fa38e34c
54 changed files with 6747 additions and 0 deletions
+92
View File
@@ -0,0 +1,92 @@
diff --git a/src/config/router.rs b/src/config/router.rs
index cfee4f8..9247cc3 100644
--- a/src/config/router.rs
+++ b/src/config/router.rs
@@ -58,11 +58,10 @@ impl Router for RouterConfig {
.or(self.default.as_ref())
.ok_or(RouterError::NoServer)?;
- let address: SocketAddr = match route.ip {
- RouteType::Simple(address) => address.into(),
- RouteType::Balanced(ref list) => {
- let hash = client.hash();
- list.get(hash as usize)
+ let address: SocketAddr = match &route.ip {
+ RouteType::Simple(addr) => addr.resolve().ok_or(RouterError::Unavailable)?,
+ RouteType::Balanced(list) => {
+ list.get(client.hash() as usize).ok_or(RouterError::Unavailable)?
}
};
diff --git a/src/config/router/balancer.rs b/src/config/router/balancer.rs
index 770a01b..b2e2491 100644
--- a/src/config/router/balancer.rs
+++ b/src/config/router/balancer.rs
@@ -22,7 +22,7 @@ pub struct Balanced {
// }
impl Balanced {
- pub(super) fn get(&self, n: usize) -> SocketAddr {
- self.servers[n & self.servers.len()].into()
+ pub(super) fn get(&self, n: usize) -> Option<SocketAddr> {
+ self.servers[n % self.servers.len()].resolve()
}
}
diff --git a/src/config/router/resolver.rs b/src/config/router/resolver.rs
index b66a16a..8fd3b0d 100644
--- a/src/config/router/resolver.rs
+++ b/src/config/router/resolver.rs
@@ -2,26 +2,26 @@ use std::net::{SocketAddr, ToSocketAddrs};
use serde::{Deserialize, Deserializer};
-#[derive(Deserialize, Debug, Clone, Copy)]
-pub(super) struct ResolvableAddr(#[serde(deserialize_with = "resolve_hostname")] SocketAddr);
+#[derive(Deserialize, Debug, Clone)]
+pub(super) struct ResolvableAddr(#[serde(deserialize_with = "parse_addr_string")] String);
-fn resolve_hostname<'de, D>(deserializer: D) -> Result<SocketAddr, D::Error>
+fn parse_addr_string<'de, D>(deserializer: D) -> Result<String, D::Error>
where
D: Deserializer<'de>,
{
use serde::de::Error;
- let inner = <String>::deserialize(deserializer)?;
-
- let mut addr = inner
- .to_socket_addrs()
- .map_err(|err| Error::custom(format!("invalid hostname format: {err}")))?;
-
- addr.next().ok_or_else(|| Error::missing_field("address"))
+ let s = String::deserialize(deserializer)?;
+ if !s.contains(':') {
+ return Err(Error::custom(format!(
+ "invalid socket address syntax, expected host:port: {s}"
+ )));
+ }
+ Ok(s)
}
-impl From<ResolvableAddr> for SocketAddr {
- fn from(addr: ResolvableAddr) -> Self {
- addr.0
+impl ResolvableAddr {
+ pub fn resolve(&self) -> Option<SocketAddr> {
+ self.0.to_socket_addrs().ok()?.next()
}
}
diff --git a/src/server/router.rs b/src/server/router.rs
index 4aae8e7..ad2849b 100644
--- a/src/server/router.rs
+++ b/src/server/router.rs
@@ -7,6 +7,9 @@ use thiserror::Error;
pub enum RouterError {
#[error("no server with such hostname has been found")]
NoServer,
+
+ #[error("backend server is currently unavailable")]
+ Unavailable,
}
// #[async_trait::async_trait]