Commit be928600 authored by nanamicat's avatar nanamicat

clean

parent ac5a65b5
...@@ -451,6 +451,15 @@ dependencies = [ ...@@ -451,6 +451,15 @@ dependencies = [
"tower-service", "tower-service",
] ]
[[package]]
name = "ipnet"
version = "2.11.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "469fb0b9cefa57e3ef31275ee7cacb78f2fdca44e4765491884a2b119d4eb130"
dependencies = [
"serde",
]
[[package]] [[package]]
name = "itertools" name = "itertools"
version = "0.14.0" version = "0.14.0"
...@@ -689,6 +698,7 @@ dependencies = [ ...@@ -689,6 +698,7 @@ dependencies = [
"axum", "axum",
"bincode", "bincode",
"config", "config",
"ipnet",
"itertools", "itertools",
"rand", "rand",
"serde", "serde",
......
...@@ -19,3 +19,4 @@ tracing-subscriber = "0.3.22" ...@@ -19,3 +19,4 @@ tracing-subscriber = "0.3.22"
rand = "0.9.2" rand = "0.9.2"
string-interner = "0.19.0" string-interner = "0.19.0"
itertools = "0.14.0" itertools = "0.14.0"
ipnet = { version = "2.11.0", features = ["serde"] }
#![allow(dead_code)]
use bincode::{Decode, Encode}; use bincode::{Decode, Encode};
use ipnet::Ipv4Net;
use itertools::{EitherOrBoth, Itertools}; use itertools::{EitherOrBoth, Itertools};
use serde::{Deserialize, Serialize}; use serde::{Deserialize, Serialize};
use std::{collections::BTreeMap, fmt::Debug, sync::OnceLock}; use std::{
collections::BTreeMap,
fmt::{Debug, Display},
net::Ipv4Addr,
sync::OnceLock,
};
use string_interner::{StringInterner, Symbol, backend::StringBackend}; use string_interner::{StringInterner, Symbol, backend::StringBackend};
#[derive(Serialize, Deserialize, Clone)] #[derive(Serialize, Deserialize, Clone)]
#[serde(rename_all = "camelCase")]
pub struct Router { pub struct Router {
pub id: RouterID, pub id: RouterID,
pub name: String, pub name: String,
pub location: String, pub location: String,
// pub host: String, pub address: Ipv4Addr,
// #[serde(default)] }
// pub ssh_port: u16,
// pub user: String, #[derive(Serialize, Deserialize, Clone, Debug)]
#[serde(rename_all = "camelCase")]
pub struct Subnet {
pub router: RouterID,
pub subnet: Ipv4Net,
} }
#[derive(Serialize, Deserialize, Clone)] #[derive(Serialize, Deserialize, Clone)]
pub struct Gateway { pub struct Gateway {
pub id: GatewayID, pub id: GatewayID,
...@@ -64,6 +78,12 @@ impl Symbol for RouterID { ...@@ -64,6 +78,12 @@ impl Symbol for RouterID {
} }
} }
impl Display for RouterID {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
f.write_str(ROUTER_ID_REGISTRY.get().and_then(|r| r.resolve(*self)).ok_or(std::fmt::Error)?)
}
}
#[derive(Serialize, Deserialize, Encode, Decode, Clone, Copy, Default, Ord, PartialOrd, Eq, PartialEq, Debug)] #[derive(Serialize, Deserialize, Encode, Decode, Clone, Copy, Default, Ord, PartialOrd, Eq, PartialEq, Debug)]
pub struct GatewayID(pub u8); pub struct GatewayID(pub u8);
......
...@@ -2,10 +2,8 @@ use crate::api::create_app; ...@@ -2,10 +2,8 @@ use crate::api::create_app;
use crate::data::{DATABASE, GatewayGroupID, RouterID}; use crate::data::{DATABASE, GatewayGroupID, RouterID};
use crate::protocol::{Downlink, Uplink}; use crate::protocol::{Downlink, Uplink};
use crate::router::Router; use crate::router::Router;
use crate::settings::{Settings, TIMEOUT}; use crate::settings::{CONFIG, TIMEOUT};
use ::config::Config;
use anyhow::{Context, Result}; use anyhow::{Context, Result};
use config::Environment;
use net::SocketAddr; use net::SocketAddr;
use std::collections::BTreeMap; use std::collections::BTreeMap;
use std::net; use std::net;
...@@ -31,7 +29,6 @@ pub struct UpdatingState { ...@@ -31,7 +29,6 @@ pub struct UpdatingState {
#[tokio::main] #[tokio::main]
async fn main() -> Result<()> { async fn main() -> Result<()> {
tracing_subscriber::fmt::init(); tracing_subscriber::fmt::init();
let config: Settings = Config::builder().add_source(Environment::default()).build()?.try_deserialize()?;
let gateways_group: BTreeMap<GatewayGroupID, Vec<&data::Gateway>> = DATABASE let gateways_group: BTreeMap<GatewayGroupID, Vec<&data::Gateway>> = DATABASE
.gateway_groups .gateway_groups
...@@ -45,7 +42,7 @@ async fn main() -> Result<()> { ...@@ -45,7 +42,7 @@ async fn main() -> Result<()> {
let routers: BTreeMap<RouterID, Router> = DATABASE.routers.iter().map(|c| (c.id, Router::new(c, &gateways_group))).collect(); let routers: BTreeMap<RouterID, Router> = DATABASE.routers.iter().map(|c| (c.id, Router::new(c, &gateways_group))).collect();
let routers = Arc::new(RwLock::new(routers)); let routers = Arc::new(RwLock::new(routers));
let listener = tokio::net::TcpListener::bind(config.http_bind).await?; let listener = tokio::net::TcpListener::bind(CONFIG.http_bind).await?;
let app = create_app(routers.clone()); let app = create_app(routers.clone());
tokio::spawn(async move { tokio::spawn(async move {
...@@ -55,8 +52,8 @@ async fn main() -> Result<()> { ...@@ -55,8 +52,8 @@ async fn main() -> Result<()> {
let mut updating: UpdatingState = UpdatingState::default(); let mut updating: UpdatingState = UpdatingState::default();
let socket = UdpSocket::bind(config.udp_bind).await?; let socket = UdpSocket::bind(CONFIG.udp_bind).await?;
println!("UDP listening on {}", config.udp_bind); println!("UDP listening on {}", CONFIG.udp_bind);
let mut buf = [0u8; u16::MAX as usize]; // Max UDP size let mut buf = [0u8; u16::MAX as usize]; // Max UDP size
let start = Instant::now(); let start = Instant::now();
......
...@@ -52,10 +52,7 @@ impl Router { ...@@ -52,10 +52,7 @@ impl Router {
.map(|(r, _)| { .map(|(r, _)| {
( (
RegionID(r as u8), RegionID(r as u8),
gateway_groups gateway_groups.iter().map(|(&id, g)| (id, g.iter().min_by_key(|gw| Self::guess(data, gw, r)).unwrap().id)).collect(),
.iter()
.map(|(&gid, gws)| (gid, gws.iter().min_by_key(|gw| Self::guess_metric(data, gw, r)).unwrap().id))
.collect(),
) )
}) })
.collect(), .collect(),
...@@ -65,7 +62,7 @@ impl Router { ...@@ -65,7 +62,7 @@ impl Router {
} }
} }
fn guess_metric(data: &data::Router, gw: &data::Gateway, region: usize) -> i32 { fn guess(data: &data::Router, gw: &data::Gateway, region: usize) -> i32 {
gw.metrics[region].saturating_add(gw.cost_outbound).saturating_add(if gw.router == data.id { 0 } else { 100 }) gw.metrics[region].saturating_add(gw.cost_outbound).saturating_add(if gw.router == data.id { 0 } else { 100 })
} }
......
...@@ -12,3 +12,8 @@ pub const TIMEOUT: Duration = Duration::from_secs(20); ...@@ -12,3 +12,8 @@ pub const TIMEOUT: Duration = Duration::from_secs(20);
pub const HALF_LIFE: Duration = Duration::from_secs(60); pub const HALF_LIFE: Duration = Duration::from_secs(60);
pub const PENALTY: i32 = 100; pub const PENALTY: i32 = 100;
pub const PENALTY_MIN: i32 = 10; pub const PENALTY_MIN: i32 = 10;
use ::config::Config;
use config::Environment;
pub static CONFIG: std::sync::LazyLock<Settings> = std::sync::LazyLock::new(|| Config::builder().add_source(Environment::default()).build().unwrap().try_deserialize().unwrap());
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment