93 lines
3.1 KiB
Diff
93 lines
3.1 KiB
Diff
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]
|