Commit b7883357 authored by nanamicat's avatar nanamicat

http

parent 04c50739
......@@ -25,6 +25,79 @@ dependencies = [
"syn",
]
[[package]]
name = "atomic-waker"
version = "1.1.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "1505bd5d3d116872e7271a6d4e16d81d0c8570876c8de68093a09ac269d8aac0"
[[package]]
name = "axum"
version = "0.7.9"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "edca88bc138befd0323b20752846e6587272d3b03b0343c8ea28a6f819e6e71f"
dependencies = [
"async-trait",
"axum-core",
"axum-macros",
"bytes",
"futures-util",
"http",
"http-body",
"http-body-util",
"hyper",
"hyper-util",
"itoa",
"matchit",
"memchr",
"mime",
"percent-encoding",
"pin-project-lite",
"rustversion",
"serde",
"serde_json",
"serde_path_to_error",
"serde_urlencoded",
"sync_wrapper",
"tokio",
"tower",
"tower-layer",
"tower-service",
"tracing",
]
[[package]]
name = "axum-core"
version = "0.4.5"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "09f2bd6146b97ae3359fa0cc6d6b376d9539582c7b4220f041a33ec24c226199"
dependencies = [
"async-trait",
"bytes",
"futures-util",
"http",
"http-body",
"http-body-util",
"mime",
"pin-project-lite",
"rustversion",
"sync_wrapper",
"tower-layer",
"tower-service",
"tracing",
]
[[package]]
name = "axum-macros"
version = "0.4.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "57d123550fa8d071b7255cb0cc04dc302baa6c8c4a79f55701552684d8399bce"
dependencies = [
"proc-macro2",
"quote",
"syn",
]
[[package]]
name = "bincode"
version = "2.0.1"
......@@ -194,6 +267,15 @@ version = "0.1.5"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "d9c4f5dac5e15c24eb999c26181a6ca40b39fe946cbe4c263c7209467bc83af2"
[[package]]
name = "form_urlencoded"
version = "1.2.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "cb4cb245038516f5f85277875cdaa4f7d2c9a0fa0468de06ed190163b1581fcf"
dependencies = [
"percent-encoding",
]
[[package]]
name = "futures"
version = "0.3.31"
......@@ -328,6 +410,88 @@ dependencies = [
"hashbrown 0.15.5",
]
[[package]]
name = "http"
version = "1.4.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "e3ba2a386d7f85a81f119ad7498ebe444d2e22c2af0b86b069416ace48b3311a"
dependencies = [
"bytes",
"itoa",
]
[[package]]
name = "http-body"
version = "1.0.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "1efedce1fb8e6913f23e0c92de8e62cd5b772a67e7b3946df930a62566c93184"
dependencies = [
"bytes",
"http",
]
[[package]]
name = "http-body-util"
version = "0.1.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "b021d93e26becf5dc7e1b75b1bed1fd93124b374ceb73f43d4d4eafec896a64a"
dependencies = [
"bytes",
"futures-core",
"http",
"http-body",
"pin-project-lite",
]
[[package]]
name = "httparse"
version = "1.10.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "6dbf3de79e51f3d586ab4cb9d5c3e2c14aa28ed23d180cf89b4df0454a69cc87"
[[package]]
name = "httpdate"
version = "1.0.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "df3b46402a9d5adb4c86a0cf463f42e19994e3ee891101b1841f30a545cb49a9"
[[package]]
name = "hyper"
version = "1.8.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "2ab2d4f250c3d7b1c9fcdff1cece94ea4e2dfbec68614f7b87cb205f24ca9d11"
dependencies = [
"atomic-waker",
"bytes",
"futures-channel",
"futures-core",
"http",
"http-body",
"httparse",
"httpdate",
"itoa",
"pin-project-lite",
"pin-utils",
"smallvec",
"tokio",
]
[[package]]
name = "hyper-util"
version = "0.1.19"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "727805d60e7938b76b826a6ef209eb70eaa1812794f9424d4a4e2d740662df5f"
dependencies = [
"bytes",
"futures-core",
"http",
"http-body",
"hyper",
"pin-project-lite",
"tokio",
"tower-service",
]
[[package]]
name = "itoa"
version = "1.0.15"
......@@ -360,12 +524,30 @@ dependencies = [
"scopeguard",
]
[[package]]
name = "log"
version = "0.4.29"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "5e5032e24019045c762d3c0f28f5b6b8bbf38563a65908389bf7978758920897"
[[package]]
name = "matchit"
version = "0.7.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "0e7465ac9959cc2b1404e8e2367b43684a6d13790fe23056cc8c6c5a6b7bcb94"
[[package]]
name = "memchr"
version = "2.7.6"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "f52b00d39961fc5b2736ea853c9cc86238e165017a493d1d5c8eac6bdc4cc273"
[[package]]
name = "mime"
version = "0.3.17"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "6877bb514081ee2a7ff5ef9de3281f14a4dd4bceac4c09388074a6b5df8a139a"
[[package]]
name = "mio"
version = "1.1.1"
......@@ -422,6 +604,12 @@ version = "0.2.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "df94ce210e5bc13cb6651479fa48d14f601d9858cfe0467f43ae157023b938d3"
[[package]]
name = "percent-encoding"
version = "2.3.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "9b4f627cb1b25917193a259e49bdad08f671f8d9708acfd5fe0a8c1455d87220"
[[package]]
name = "pest"
version = "2.8.4"
......@@ -500,6 +688,7 @@ name = "railgun-routing-server"
version = "0.1.0"
dependencies = [
"anyhow",
"axum",
"bincode",
"config",
"futures",
......@@ -541,6 +730,12 @@ dependencies = [
"ordered-multimap",
]
[[package]]
name = "rustversion"
version = "1.0.22"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "b39cdef0fa800fc44525c84ccb54a029961a8215f9619753635a9c0d2538d46d"
[[package]]
name = "ryu"
version = "1.0.20"
......@@ -608,6 +803,17 @@ dependencies = [
"serde_core",
]
[[package]]
name = "serde_path_to_error"
version = "0.1.20"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "10a9ff822e371bb5403e391ecd83e182e0e77ba7f6fe0160b795797109d1b457"
dependencies = [
"itoa",
"serde",
"serde_core",
]
[[package]]
name = "serde_spanned"
version = "1.0.3"
......@@ -617,6 +823,18 @@ dependencies = [
"serde_core",
]
[[package]]
name = "serde_urlencoded"
version = "0.7.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "d3491c14715ca2294c4d6a88f15e84739788c1d030eed8c110436aafdaa2f3fd"
dependencies = [
"form_urlencoded",
"itoa",
"ryu",
"serde",
]
[[package]]
name = "sha2"
version = "0.10.9"
......@@ -670,6 +888,12 @@ dependencies = [
"unicode-ident",
]
[[package]]
name = "sync_wrapper"
version = "1.0.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "0bf256ce5efdfa370213c1dabab5935a12e49f2c58d15e9eac2870d3b4f27263"
[[package]]
name = "tiny-keccak"
version = "2.0.2"
......@@ -738,6 +962,54 @@ dependencies = [
"winnow",
]
[[package]]
name = "tower"
version = "0.5.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "d039ad9159c98b70ecfd540b2573b97f7f52c3e8d9f8ad57a24b916a536975f9"
dependencies = [
"futures-core",
"futures-util",
"pin-project-lite",
"sync_wrapper",
"tokio",
"tower-layer",
"tower-service",
"tracing",
]
[[package]]
name = "tower-layer"
version = "0.3.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "121c2a6cda46980bb0fcd1647ffaf6cd3fc79a013de288782836f6df9c48780e"
[[package]]
name = "tower-service"
version = "0.3.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "8df9b6e13f2d32c91b9bd719c00d1958837bc7dec474d94952798cc8e69eeec3"
[[package]]
name = "tracing"
version = "0.1.43"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "2d15d90a0b5c19378952d479dc858407149d7bb45a14de0142f6c534b16fc647"
dependencies = [
"log",
"pin-project-lite",
"tracing-core",
]
[[package]]
name = "tracing-core"
version = "0.1.35"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "7a04e24fab5c89c6a36eb8558c9656f30d81de51dfa4d3b45f26b21d61fa0a6c"
dependencies = [
"once_cell",
]
[[package]]
name = "typeid"
version = "1.0.3"
......
......@@ -11,5 +11,6 @@ serde_json = "1.0.145"
serde = { version = "1.0.228", features = ["derive", "rc"] }
tokio = { version = "1.48", features = ["full"] }
anyhow = "1.0.100"
axum = { version = "0.7", features = ["macros"] }
bincode = "2.0.1"
futures = "0.3.31"
import assert from 'assert';
export class Quality {
static unreachable = new Quality(0, 0, 0, 0);
constructor(public delay = 0, public jitter = 0, public reliability = 1, public cost = 0) {}
concat(delay: number, jitter: number, reliability: number, cost: number) {
this.delay += delay;
this.jitter += jitter;
this.reliability *= reliability;
this.cost += cost;
return this;
}
// 若 reliability = 0,metric 应为 +∞
// 对于两条路线,同时连接任何一个相同的(reliability > 0的)线路,大小关系不变
metric() {
assert(this.jitter >= 0);
assert(0 <= this.reliability && this.reliability <= 1);
assert(this.cost >= 0);
if (this.reliability === 0) {
return Infinity;
} else {
// 公式
return this.delay + (1 - this.reliability) * 1000 + this.cost * 0.1;
}
}
}
use axum::{extract::State, routing::get, Json};
use std::collections::BTreeMap;
use std::sync::Arc;
use tokio::sync::RwLock;
use crate::data::ConnectionData;
use crate::router::Router;
#[derive(Clone)]
pub struct AppState {
pub routers: Arc<RwLock<BTreeMap<u8, Router>>>,
pub connections: Arc<BTreeMap<u8, BTreeMap<u8, ConnectionData>>>,
}
pub fn create_app(routers: Arc<RwLock<BTreeMap<u8, Router>>>, connections: Arc<BTreeMap<u8, BTreeMap<u8, ConnectionData>>>) -> axum::Router {
axum::Router::new()
.route("/connections", get(get_connections))
.route("/routers", get(get_routers))
.with_state(AppState { routers, connections })
}
async fn get_connections(State(state): State<AppState>) -> Json<BTreeMap<u8, BTreeMap<u8, ConnectionData>>> {
Json(state.connections.as_ref().clone())
}
async fn get_routers(State(state): State<AppState>) -> Json<BTreeMap<u8, Router>> {
Json(state.routers.read().await.clone())
}
......@@ -11,7 +11,7 @@ pub struct RouterData {
pub user: String,
}
#[derive(Serialize,Deserialize)]
#[derive(Serialize, Deserialize, Clone)]
pub struct ConnectionData {
pub metric: u32,
}
use crate::api::create_app;
use crate::data::{ConnectionData, RouterData};
use crate::protocol::{Change, Report};
use crate::router::Router;
use crate::settings::{Settings, TIMEOUT};
use anyhow::Result;
use ::config::Config;
use anyhow::Result;
use config::{Environment, File};
use std::collections::BTreeMap;
use std::sync::Arc;
use tokio::net::UdpSocket;
use tokio::select;
use tokio::time::{interval, Duration};
use tokio::sync::RwLock;
use tokio::time::{Duration, interval};
mod api;
mod data;
mod gateway_group;
mod protocol;
......@@ -33,7 +37,9 @@ async fn main() -> Result<()> {
let routers_data: Vec<RouterData> = serde_json::from_str(&std::fs::read_to_string("../import/data/Router.json")?)?;
let connections: BTreeMap<u8, BTreeMap<u8, ConnectionData>> = serde_json::from_str(&std::fs::read_to_string("../import/connections.json")?)?;
let mut routers: BTreeMap<u8, Router> = routers_data.into_iter().map(|c| (c.id, Router::new(c, &connections))).collect();
let connections = Arc::new(connections);
let routers: BTreeMap<u8, Router> = routers_data.into_iter().map(|c| (c.id, Router::new(c, &connections))).collect();
let routers = Arc::new(RwLock::new(routers));
// let gateway_groups_data: Vec<GatewayGroup> = serde_json::from_str(&std::fs::read_to_string(
// "../import/data/GatewayGroup.json",
// )?)?;
......@@ -48,18 +54,12 @@ async fn main() -> Result<()> {
let mut updating: UpdatingState = UpdatingState::default();
// let (status_tx, status_rx) = watch::channel(Status {
// tick: 0,
// last_update_ms: now_ms(),
// msg: "starting".to_string(),
// });
// let app = axum::Router::new()
// .with_state();
let listener = tokio::net::TcpListener::bind(config.http_bind).await?;
let app = create_app(routers.clone(), connections.clone());
// let listener = tokio::net::TcpListener::bind().await?;
// let _ = axum::serve(listener, app);
tokio::spawn(async move {
axum::serve(listener, app).await.unwrap();
});
let socket = UdpSocket::bind(config.udp_bind).await?;
println!("UDP listening on {}", config.udp_bind);
......@@ -75,16 +75,19 @@ async fn main() -> Result<()> {
let (len, addr) = result?;
if let Ok((report, _)) =
bincode::decode_from_slice::<Report, _>(&buf[..len], bincode::config::standard())
&& let Some(router) = routers.get_mut(&report.id)
{
if let Some(change) = router.on_message(report, addr, &mut updating) {
let len = bincode::encode_into_slice(change, &mut buf, bincode::config::standard())?;
let _ = socket.send_to(&buf[..len], addr).await;
}
let mut routers = routers.write().await;
if let Some(router) = routers.get_mut(&report.id) {
if let Some(change) = router.on_message(report, addr, &mut updating) {
let len = bincode::encode_into_slice(change, &mut buf, bincode::config::standard())?;
let _ = socket.send_to(&buf[..len], addr).await;
}
}
}
}
now = interval.tick() => {
let mut routers = routers.write().await;
if updating.router_id != 0 {
let router = routers.get_mut(&updating.router_id).expect("updating router_id should exist");
if now.duration_since(router.time) < TIMEOUT {
......
......@@ -9,7 +9,7 @@ pub struct Report {
pub peers: Vec<PeerQuality>,
}
#[derive(Encode, Decode, Copy, Clone)]
#[derive(Encode, Decode, Copy, Clone, serde::Serialize)]
pub struct PeerQuality {
pub delay: i16,
pub reliability: u8,
......
use crate::UpdatingState;
use crate::data::{ConnectionData, RouterData};
use crate::protocol::{Change, PeerQuality, Report};
use crate::quality::Quality;
use crate::settings::THROTTLE;
use crate::UpdatingState;
use serde::Serialize;
use std::collections::BTreeMap;
use std::net::SocketAddr;
use tokio::time::Instant;
#[derive(Serialize, Clone)]
pub struct Router {
pub id: u8,
pub seq: u8,
......@@ -14,7 +16,8 @@ pub struct Router {
pub peers: BTreeMap<u8, PeerQuality>,
pub via: BTreeMap<u8, u8>, // dst router_id -> next hop router_id
pub plan: BTreeMap<u8, BTreeMap<u8, u8>>, // group id -> region id -> gateway_id
pub time: Instant, // ms
#[serde(skip)]
pub time: Instant, // ms
pub addr: Option<SocketAddr>,
// Static config
// pub config: RouterData,
......
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