1
0

deserialize config fields to final type in parsing

This commit is contained in:
EAimTY 2023-06-03 22:05:35 +09:00
parent 8274dae7c3
commit 3ef16eb5db
6 changed files with 66 additions and 30 deletions

View File

@ -12,6 +12,7 @@ use std::{
net::{IpAddr, SocketAddr},
path::PathBuf,
str::FromStr,
sync::Arc,
time::Duration,
};
use thiserror::Error;
@ -45,7 +46,8 @@ pub struct Relay {
pub uuid: Uuid,
pub password: String,
#[serde(deserialize_with = "deserialize_password")]
pub password: Arc<[u8]>,
pub ip: Option<IpAddr>,
@ -64,8 +66,11 @@ pub struct Relay {
)]
pub congestion_control: CongestionControl,
#[serde(default = "default::relay::alpn")]
pub alpn: Vec<String>,
#[serde(
default = "default::relay::alpn",
deserialize_with = "deserialize_alpn"
)]
pub alpn: Vec<Vec<u8>>,
#[serde(default = "default::relay::zero_rtt_handshake")]
pub zero_rtt_handshake: bool,
@ -112,9 +117,11 @@ pub struct Relay {
pub struct Local {
pub server: SocketAddr,
pub username: Option<String>,
#[serde(deserialize_with = "deserialize_optional_bytes")]
pub username: Option<Vec<u8>>,
pub password: Option<String>,
#[serde(deserialize_with = "deserialize_optional_bytes")]
pub password: Option<Vec<u8>>,
pub dual_stack: Option<bool>,
@ -172,7 +179,7 @@ mod default {
CongestionControl::Cubic
}
pub fn alpn() -> Vec<String> {
pub fn alpn() -> Vec<Vec<u8>> {
Vec::new()
}
@ -250,6 +257,30 @@ where
}
}
pub fn deserialize_password<'de, D>(deserializer: D) -> Result<Arc<[u8]>, D::Error>
where
D: Deserializer<'de>,
{
let s = String::deserialize(deserializer)?;
Ok(Arc::from(s.into_bytes().into_boxed_slice()))
}
pub fn deserialize_alpn<'de, D>(deserializer: D) -> Result<Vec<Vec<u8>>, D::Error>
where
D: Deserializer<'de>,
{
let s = Vec::<String>::deserialize(deserializer)?;
Ok(s.into_iter().map(|alpn| alpn.into_bytes()).collect())
}
pub fn deserialize_optional_bytes<'de, D>(deserializer: D) -> Result<Option<Vec<u8>>, D::Error>
where
D: Deserializer<'de>,
{
let s = Option::<String>::deserialize(deserializer)?;
Ok(s.map(|s| s.into_bytes()))
}
pub fn deserialize_duration<'de, D>(deserializer: D) -> Result<Duration, D::Error>
where
D: Deserializer<'de>,

View File

@ -60,7 +60,7 @@ impl Connection {
.with_root_certificates(certs)
.with_no_client_auth();
crypto.alpn_protocols = cfg.alpn.into_iter().map(|alpn| alpn.into_bytes()).collect();
crypto.alpn_protocols = cfg.alpn;
crypto.enable_early_data = true;
crypto.enable_sni = !cfg.disable_sni;
@ -108,7 +108,7 @@ impl Connection {
ep,
server: ServerAddr::new(cfg.server.0, cfg.server.1, cfg.ip),
uuid: cfg.uuid,
password: Arc::from(cfg.password.into_bytes().into_boxed_slice()),
password: cfg.password,
udp_relay_mode: cfg.udp_relay_mode,
zero_rtt_handshake: cfg.zero_rtt_handshake,
heartbeat: cfg.heartbeat,

View File

@ -37,8 +37,8 @@ impl Server {
cfg.server,
cfg.dual_stack,
cfg.max_packet_size,
cfg.username.map(|s| s.into_bytes()),
cfg.password.map(|s| s.into_bytes()),
cfg.username,
cfg.password,
)?)
.map_err(|_| "failed initializing socks5 server")
.unwrap();

View File

@ -26,7 +26,7 @@ pub struct Config {
pub server: SocketAddr,
#[serde(deserialize_with = "deserialize_users")]
pub users: HashMap<Uuid, String>,
pub users: HashMap<Uuid, Box<[u8]>>,
pub certificate: PathBuf,
@ -38,8 +38,8 @@ pub struct Config {
)]
pub congestion_control: CongestionControl,
#[serde(default = "default::alpn")]
pub alpn: Vec<String>,
#[serde(default = "default::alpn", deserialize_with = "deserialize_alpn")]
pub alpn: Vec<Vec<u8>>,
#[serde(default = "default::udp_relay_ipv6")]
pub udp_relay_ipv6: bool,
@ -132,7 +132,7 @@ mod default {
CongestionControl::Cubic
}
pub fn alpn() -> Vec<String> {
pub fn alpn() -> Vec<Vec<u8>> {
Vec::new()
}
@ -191,17 +191,28 @@ where
T::from_str(&s).map_err(DeError::custom)
}
pub fn deserialize_users<'de, D>(deserializer: D) -> Result<HashMap<Uuid, String>, D::Error>
pub fn deserialize_users<'de, D>(deserializer: D) -> Result<HashMap<Uuid, Box<[u8]>>, D::Error>
where
D: Deserializer<'de>,
{
let map = HashMap::<Uuid, String>::deserialize(deserializer)?;
let users = HashMap::<Uuid, String>::deserialize(deserializer)?;
if map.is_empty() {
if users.is_empty() {
return Err(DeError::custom("users cannot be empty"));
}
Ok(map)
Ok(users
.into_iter()
.map(|(k, v)| (k, v.into_bytes().into_boxed_slice()))
.collect())
}
pub fn deserialize_alpn<'de, D>(deserializer: D) -> Result<Vec<Vec<u8>>, D::Error>
where
D: Deserializer<'de>,
{
let s = Vec::<String>::deserialize(deserializer)?;
Ok(s.into_iter().map(|alpn| alpn.into_bytes()).collect())
}
pub fn deserialize_duration<'de, D>(deserializer: D) -> Result<Duration, D::Error>

View File

@ -25,7 +25,7 @@ pub const DEFAULT_CONCURRENT_STREAMS: u32 = 32;
pub struct Connection {
inner: QuinnConnection,
model: Model<side::Server>,
users: Arc<HashMap<Uuid, Vec<u8>>>,
users: Arc<HashMap<Uuid, Box<[u8]>>>,
udp_relay_ipv6: bool,
auth: Authenticated,
task_negotiation_timeout: Duration,
@ -42,7 +42,7 @@ pub struct Connection {
impl Connection {
pub async fn handle(
conn: Connecting,
users: Arc<HashMap<Uuid, Vec<u8>>>,
users: Arc<HashMap<Uuid, Box<[u8]>>>,
udp_relay_ipv6: bool,
zero_rtt_handshake: bool,
auth_timeout: Duration,
@ -135,7 +135,7 @@ impl Connection {
fn new(
conn: QuinnConnection,
users: Arc<HashMap<Uuid, Vec<u8>>>,
users: Arc<HashMap<Uuid, Box<[u8]>>>,
udp_relay_ipv6: bool,
task_negotiation_timeout: Duration,
max_external_pkt_size: usize,

View File

@ -20,7 +20,7 @@ use uuid::Uuid;
pub struct Server {
ep: Endpoint,
users: Arc<HashMap<Uuid, Vec<u8>>>,
users: Arc<HashMap<Uuid, Box<[u8]>>>,
udp_relay_ipv6: bool,
zero_rtt_handshake: bool,
auth_timeout: Duration,
@ -43,7 +43,7 @@ impl Server {
.with_no_client_auth()
.with_single_cert(certs, priv_key)?;
crypto.alpn_protocols = cfg.alpn.into_iter().map(|alpn| alpn.into_bytes()).collect();
crypto.alpn_protocols = cfg.alpn;
crypto.max_early_data_size = u32::MAX;
crypto.send_half_rtt_data = cfg.zero_rtt_handshake;
@ -102,15 +102,9 @@ impl Server {
Arc::new(TokioRuntime),
)?;
let users = cfg
.users
.into_iter()
.map(|(uuid, password)| (uuid, password.into_bytes()))
.collect();
Ok(Self {
ep,
users: Arc::new(users),
users: Arc::new(cfg.users),
udp_relay_ipv6: cfg.udp_relay_ipv6,
zero_rtt_handshake: cfg.zero_rtt_handshake,
auth_timeout: cfg.auth_timeout,