Skip to content

Commit

Permalink
fix: fix param parse, keep alive and server shutdown
Browse files Browse the repository at this point in the history
  • Loading branch information
eareimu authored and huster-zhangpeng committed Feb 18, 2025
1 parent 82a8bff commit 167950a
Show file tree
Hide file tree
Showing 14 changed files with 227 additions and 67 deletions.
4 changes: 2 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -83,7 +83,7 @@ let quic_client = QuicClient::builder()
// instead of initiating a new connection every time.
.reuse_connection()
// Keep the connection alive when it is idle
.keep_alive(Durnation::from_secs(30))
.defer_idle_timeout(HeartbeatConfig::new(Durnation::from_secs(30)))
// The QUIC version negotiation mechanism prioritizes using the earlier versions,
// currently only supporting V1.
.prefer_versions([1u32])
Expand Down Expand Up @@ -112,7 +112,7 @@ The QUIC server provides SNI(Server Name Indication) support in TLS, allowing th
```rust
let quic_server = QuicServer::builder()
// Keep the accepted connection alive when it is idle
.keep_alive(Durnation::from_secs(30))
.defer_idle_timeout(HeartbeatConfig::new(Durnation::from_secs(30)))
.with_supported_versions([1u32])
.without_cert_verifier() // Generally, client identity is not verified
.enable_sni()
Expand Down
4 changes: 2 additions & 2 deletions README_CN.md
Original file line number Diff line number Diff line change
Expand Up @@ -72,7 +72,7 @@ let quic_client = QuicClient::builder()
// 允许复用到服务器的连接,而不是每次都发起新连接
.reuse_connection()
// 自动在连接空闲时发送数据包保持连接活跃
.keep_alive(Durnation::from_secs(30))
.defer_idle_timeout(HeartbeatConfig::new(Durnation::from_secs(30)))
.prefer_versions([1u32]) // QUIC的版本协商机制,会优先使用靠前的版本,目前仅支持V1
// .with_parameter(&client_parameters) // 不设置即为使用默认参数
// .with_token_sink(token_sink) // 管理各服务器颁发的Token
Expand All @@ -98,7 +98,7 @@ QUIC服务端支持SNI(Server Name Indication),可以设置多台Server的
```rust
let quic_server = QuicServer::builder()
// 同client
.keep_alive(Durnation::from_secs(30))
.defer_idle_timeout(HeartbeatConfig::new(Durnation::from_secs(30)))
.with_supported_versions([1u32])
.without_cert_verifier() // 一般不验证客户端身份
.enable_sni()
Expand Down
1 change: 0 additions & 1 deletion gm-quic/examples/http/server.rs
Original file line number Diff line number Diff line change
Expand Up @@ -44,7 +44,6 @@ async fn run(options: Opt) -> Result<(), Box<dyn std::error::Error>> {
let server = QuicServer::builder()
.with_supported_versions([0x00000001u32])
.without_cert_verifier()
// .keep_alive()
.with_single_cert(options.cert.as_path(), options.key.as_path())
.listen(options.bind)?;

Expand Down
15 changes: 7 additions & 8 deletions gm-quic/src/client.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,6 @@ use std::{
io,
net::{IpAddr, Ipv4Addr, Ipv6Addr, SocketAddr, ToSocketAddrs},
sync::{Arc, LazyLock},
time::Duration,
};

use dashmap::DashMap;
Expand All @@ -28,7 +27,7 @@ type TlsClientConfigBuilder<T> = ConfigBuilder<TlsClientConfig, T>;
pub struct QuicClient {
// be different from QuicServer, QuicClient is not arc
bind_interfaces: Option<Arc<DashMap<SocketAddr, Arc<dyn QuicInterface>>>>,
defer_idle_timeout: Duration,
defer_idle_timeout: HeartbeatConfig,
// TODO: 好像得创建2个quic连接,一个用ipv4,一个用ipv6
// 然后看谁先收到服务器的响应比较好
_enable_happy_eyepballs: bool,
Expand Down Expand Up @@ -76,8 +75,8 @@ impl QuicClient {
reuse_connection: false,
enable_happy_eyepballs: false,
prefer_versions: vec![1],
defer_idle_timeout: Duration::MAX,
quic_iface_binder: Box::new(|addr| Ok(Arc::new(Usc::bind(addr)?))),
defer_idle_timeout: HeartbeatConfig::default(),
parameters: ClientParameters::default(),
tls_config: TlsClientConfig::builder_with_protocol_versions(&[&rustls::version::TLS13]),
streams_controller: Box::new(|bi, uni| Box::new(ConsistentConcurrency::new(bi, uni))),
Expand All @@ -95,8 +94,8 @@ impl QuicClient {
reuse_connection: false,
enable_happy_eyepballs: false,
prefer_versions: vec![1],
defer_idle_timeout: Duration::MAX,
quic_iface_binder: Box::new(|addr| Ok(Arc::new(Usc::bind(addr)?))),
defer_idle_timeout: HeartbeatConfig::default(),
parameters: ClientParameters::default(),
tls_config: TlsClientConfig::builder_with_provider(provider)
.with_protocol_versions(&[&rustls::version::TLS13])
Expand All @@ -116,7 +115,7 @@ impl QuicClient {
reuse_connection: false,
enable_happy_eyepballs: false,
prefer_versions: vec![1],
defer_idle_timeout: Duration::MAX,
defer_idle_timeout: HeartbeatConfig::default(),
quic_iface_binder: Box::new(|addr| Ok(Arc::new(Usc::bind(addr)?))),
parameters: ClientParameters::default(),
tls_config,
Expand Down Expand Up @@ -294,8 +293,8 @@ pub struct QuicClientBuilder<T> {
reuse_connection: bool,
enable_happy_eyepballs: bool,
prefer_versions: Vec<u32>,
defer_idle_timeout: Duration,
quic_iface_binder: Box<dyn Fn(SocketAddr) -> io::Result<Arc<dyn QuicInterface>> + Send + Sync>,
defer_idle_timeout: HeartbeatConfig,
parameters: ClientParameters,
tls_config: T,
streams_controller: Box<dyn Fn(u64, u64) -> Box<dyn ControlConcurrency> + Send + Sync>,
Expand Down Expand Up @@ -425,8 +424,8 @@ impl<T> QuicClientBuilder<T> {
/// See [Deferring Idle Timeout](https://datatracker.ietf.org/doc/html/rfc9000#name-deferring-idle-timeout)
/// of [RFC 9000](https://datatracker.ietf.org/doc/html/rfc9000)
/// for more information.
pub fn keep_alive(mut self, duration: Duration) -> Self {
self.defer_idle_timeout = duration;
pub fn defer_idle_timeout(mut self, config: HeartbeatConfig) -> Self {
self.defer_idle_timeout = config;
self
}

Expand Down
2 changes: 1 addition & 1 deletion gm-quic/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ mod client;
mod interfaces;
mod server;
#[cfg(test)]
pub mod tests;
mod tests;
mod util;

pub mod prelude {
Expand Down
39 changes: 20 additions & 19 deletions gm-quic/src/server.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,6 @@ use std::{
io::{self},
net::{SocketAddr, ToSocketAddrs},
sync::{Arc, LazyLock, RwLock, Weak},
time::Duration,
};

use dashmap::DashMap;
Expand Down Expand Up @@ -56,7 +55,7 @@ impl ResolvesServerCert for VirtualHosts {
/// calling the [`QuicServer::accept`] method.
pub struct QuicServer {
bind_interfaces: DashMap<SocketAddr, Arc<dyn QuicInterface>>,
defer_idle_timeout: Duration,
defer_idle_timeout: HeartbeatConfig,
listener: Arc<Channel<(Arc<Connection>, Pathway)>>,
parameters: ServerParameters,
passive_listening: bool,
Expand All @@ -73,7 +72,7 @@ impl QuicServer {
QuicServerBuilder {
passive_listening: false,
supported_versions: Vec::with_capacity(2),
defer_idle_timeout: Duration::MAX,
defer_idle_timeout: HeartbeatConfig::default(),
quic_iface_binder: Box::new(|addr| Ok(Arc::new(Usc::bind(addr)?))),
parameters: ServerParameters::default(),
tls_config: TlsServerConfig::builder_with_protocol_versions(&[&rustls::version::TLS13]),
Expand All @@ -89,8 +88,8 @@ impl QuicServer {
QuicServerBuilder {
passive_listening: false,
supported_versions: Vec::with_capacity(2),
defer_idle_timeout: Duration::MAX,
quic_iface_binder: Box::new(|addr| Ok(Arc::new(Usc::bind(addr)?))),
defer_idle_timeout: HeartbeatConfig::default(),
parameters: ServerParameters::default(),
tls_config,
streams_controller: Box::new(|bi, uni| Box::new(ConsistentConcurrency::new(bi, uni))),
Expand All @@ -105,8 +104,8 @@ impl QuicServer {
QuicServerBuilder {
passive_listening: false,
supported_versions: Vec::with_capacity(2),
defer_idle_timeout: Duration::MAX,
quic_iface_binder: Box::new(|addr| Ok(Arc::new(Usc::bind(addr)?))),
defer_idle_timeout: HeartbeatConfig::default(),
parameters: ServerParameters::default(),
tls_config: TlsServerConfig::builder_with_provider(provider)
.with_protocol_versions(&[&rustls::version::TLS13])
Expand Down Expand Up @@ -206,7 +205,7 @@ impl QuicServer {
);
}

fn shutdown(&self) {
pub fn shutdown(&self) {
if self.listener.close().is_none() {
// already closed
return;
Expand Down Expand Up @@ -234,8 +233,8 @@ struct Host {
pub struct QuicServerBuilder<T> {
supported_versions: Vec<u32>,
passive_listening: bool,
defer_idle_timeout: Duration,
quic_iface_binder: Box<dyn Fn(SocketAddr) -> io::Result<Arc<dyn QuicInterface>> + Send + Sync>,
defer_idle_timeout: HeartbeatConfig,
parameters: ServerParameters,
tls_config: T,
streams_controller:
Expand All @@ -248,8 +247,8 @@ pub struct QuicServerSniBuilder<T> {
supported_versions: Vec<u32>,
passive_listening: bool,
hosts: Arc<DashMap<String, Host>>,
defer_idle_timeout: Duration,
quic_iface_binder: Box<dyn Fn(SocketAddr) -> io::Result<Arc<dyn QuicInterface>> + Send + Sync>,
defer_idle_timeout: HeartbeatConfig,
parameters: ServerParameters,
tls_config: T,
streams_controller:
Expand Down Expand Up @@ -303,8 +302,8 @@ impl<T> QuicServerBuilder<T> {
/// See [Deferring Idle Timeout](https://datatracker.ietf.org/doc/html/rfc9000#name-deferring-idle-timeout)
/// of [RFC 9000](https://datatracker.ietf.org/doc/html/rfc9000)
/// for more information.
pub fn keep_alive(mut self, duration: Duration) -> Self {
self.defer_idle_timeout = duration;
pub fn defer_idle_timeout(mut self, config: HeartbeatConfig) -> Self {
self.defer_idle_timeout = config;
self
}

Expand Down Expand Up @@ -376,8 +375,8 @@ impl QuicServerBuilder<TlsServerConfigBuilder<WantsVerifier>> {
QuicServerBuilder {
passive_listening: self.passive_listening,
supported_versions: self.supported_versions,
defer_idle_timeout: self.defer_idle_timeout,
quic_iface_binder: self.quic_iface_binder,
defer_idle_timeout: self.defer_idle_timeout,
parameters: self.parameters,
tls_config: self
.tls_config
Expand All @@ -402,8 +401,8 @@ impl QuicServerBuilder<TlsServerConfigBuilder<WantsServerCert>> {
QuicServerBuilder {
passive_listening: self.passive_listening,
supported_versions: self.supported_versions,
defer_idle_timeout: self.defer_idle_timeout,
quic_iface_binder: self.quic_iface_binder,
defer_idle_timeout: self.defer_idle_timeout,
parameters: self.parameters,
tls_config: self
.tls_config
Expand All @@ -428,8 +427,8 @@ impl QuicServerBuilder<TlsServerConfigBuilder<WantsServerCert>> {
QuicServerBuilder {
passive_listening: self.passive_listening,
supported_versions: self.supported_versions,
defer_idle_timeout: self.defer_idle_timeout,
quic_iface_binder: self.quic_iface_binder,
defer_idle_timeout: self.defer_idle_timeout,
parameters: self.parameters,
tls_config: self
.tls_config
Expand All @@ -450,8 +449,8 @@ impl QuicServerBuilder<TlsServerConfigBuilder<WantsServerCert>> {
QuicServerSniBuilder {
passive_listening: self.passive_listening,
supported_versions: self.supported_versions,
defer_idle_timeout: self.defer_idle_timeout,
quic_iface_binder: self.quic_iface_binder,
defer_idle_timeout: self.defer_idle_timeout,
parameters: self.parameters,
tls_config: self
.tls_config
Expand Down Expand Up @@ -535,11 +534,13 @@ impl QuicServerBuilder<TlsServerConfig> {
/// Although all given addresses are failed to bind, the server can still accept connections from other addresses.
pub fn listen(self, addresses: impl ToSocketAddrs) -> io::Result<Arc<QuicServer>> {
let mut server = SERVER.write().unwrap();
if server.strong_count() != 0 {
return Err(io::Error::new(
io::ErrorKind::AddrInUse,
"There is already a server running",
));
if let Some(server) = server.upgrade() {
if !server.listener.is_closed() {
return Err(io::Error::new(
io::ErrorKind::AlreadyExists,
"There is already a active server running",
));
}
}

// 不接受出现错误,出现错误直接让listen返回Err
Expand Down
Loading

0 comments on commit 167950a

Please sign in to comment.