mirror of
https://gitlab.com/veloren/veloren.git
synced 2024-08-30 18:12:32 +00:00
Merge branch 'dequbed/srv-lookup' into 'master'
Add SRV lookup functionality to voxygen See merge request veloren/veloren!4310
This commit is contained in:
commit
ba0fc08f8d
143
Cargo.lock
generated
143
Cargo.lock
generated
@ -1718,7 +1718,7 @@ dependencies = [
|
|||||||
"tokio",
|
"tokio",
|
||||||
"tracing",
|
"tracing",
|
||||||
"url",
|
"url",
|
||||||
"winreg",
|
"winreg 0.51.0",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
@ -1847,6 +1847,18 @@ version = "0.1.2"
|
|||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "c34f04666d835ff5d62e058c3995147c06f42fe86ff053337632bca83e42702d"
|
checksum = "c34f04666d835ff5d62e058c3995147c06f42fe86ff053337632bca83e42702d"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "enum-as-inner"
|
||||||
|
version = "0.6.0"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "5ffccbb6966c05b32ef8fbac435df276c4ae4d3dc55a8cd0eb9745e6c12f546a"
|
||||||
|
dependencies = [
|
||||||
|
"heck 0.4.1",
|
||||||
|
"proc-macro2 1.0.78",
|
||||||
|
"quote 1.0.35",
|
||||||
|
"syn 2.0.48",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "enum-iterator"
|
name = "enum-iterator"
|
||||||
version = "0.7.0"
|
version = "0.7.0"
|
||||||
@ -2750,6 +2762,51 @@ dependencies = [
|
|||||||
"rayon",
|
"rayon",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "hickory-proto"
|
||||||
|
version = "0.24.0"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "091a6fbccf4860009355e3efc52ff4acf37a63489aad7435372d44ceeb6fbbcf"
|
||||||
|
dependencies = [
|
||||||
|
"async-trait",
|
||||||
|
"cfg-if 1.0.0",
|
||||||
|
"data-encoding",
|
||||||
|
"enum-as-inner",
|
||||||
|
"futures-channel",
|
||||||
|
"futures-io",
|
||||||
|
"futures-util",
|
||||||
|
"idna 0.4.0",
|
||||||
|
"ipnet",
|
||||||
|
"once_cell",
|
||||||
|
"rand 0.8.5",
|
||||||
|
"thiserror",
|
||||||
|
"tinyvec",
|
||||||
|
"tokio",
|
||||||
|
"tracing",
|
||||||
|
"url",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "hickory-resolver"
|
||||||
|
version = "0.24.0"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "35b8f021164e6a984c9030023544c57789c51760065cd510572fedcfb04164e8"
|
||||||
|
dependencies = [
|
||||||
|
"cfg-if 1.0.0",
|
||||||
|
"futures-util",
|
||||||
|
"hickory-proto",
|
||||||
|
"ipconfig",
|
||||||
|
"lru-cache",
|
||||||
|
"once_cell",
|
||||||
|
"parking_lot 0.12.1",
|
||||||
|
"rand 0.8.5",
|
||||||
|
"resolv-conf",
|
||||||
|
"smallvec",
|
||||||
|
"thiserror",
|
||||||
|
"tokio",
|
||||||
|
"tracing",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "home"
|
name = "home"
|
||||||
version = "0.5.9"
|
version = "0.5.9"
|
||||||
@ -2759,6 +2816,17 @@ dependencies = [
|
|||||||
"windows-sys 0.52.0",
|
"windows-sys 0.52.0",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "hostname"
|
||||||
|
version = "0.3.1"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "3c731c3e10504cc8ed35cfe2f1db4c9274c3d35fa486e3b31df46f068ef3e867"
|
||||||
|
dependencies = [
|
||||||
|
"libc",
|
||||||
|
"match_cfg",
|
||||||
|
"winapi",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "http"
|
name = "http"
|
||||||
version = "0.2.11"
|
version = "0.2.11"
|
||||||
@ -2937,6 +3005,16 @@ version = "1.0.1"
|
|||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "b9e0384b61958566e926dc50660321d12159025e767c18e043daf26b70104c39"
|
checksum = "b9e0384b61958566e926dc50660321d12159025e767c18e043daf26b70104c39"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "idna"
|
||||||
|
version = "0.4.0"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "7d20d6b07bfbc108882d88ed8e37d39636dcc260e15e30c45e6ba089610b917c"
|
||||||
|
dependencies = [
|
||||||
|
"unicode-bidi",
|
||||||
|
"unicode-normalization",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "idna"
|
name = "idna"
|
||||||
version = "0.5.0"
|
version = "0.5.0"
|
||||||
@ -3070,6 +3148,24 @@ dependencies = [
|
|||||||
"mach2",
|
"mach2",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "ipconfig"
|
||||||
|
version = "0.3.2"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "b58db92f96b720de98181bbbe63c831e87005ab460c1bf306eb2622b4707997f"
|
||||||
|
dependencies = [
|
||||||
|
"socket2",
|
||||||
|
"widestring",
|
||||||
|
"windows-sys 0.48.0",
|
||||||
|
"winreg 0.50.0",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "ipnet"
|
||||||
|
version = "2.9.0"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "8f518f335dce6725a761382244631d86cf0ccb2863413590b31338feb467f9c3"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "is-terminal"
|
name = "is-terminal"
|
||||||
version = "0.4.10"
|
version = "0.4.10"
|
||||||
@ -3399,6 +3495,15 @@ dependencies = [
|
|||||||
"hashbrown 0.14.3",
|
"hashbrown 0.14.3",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "lru-cache"
|
||||||
|
version = "0.1.2"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "31e24f1ad8321ca0e8a1e0ac13f23cb668e6f5466c2c57319f6a5cf1cc8e3b1c"
|
||||||
|
dependencies = [
|
||||||
|
"linked-hash-map",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "lz-fear"
|
name = "lz-fear"
|
||||||
version = "0.1.1"
|
version = "0.1.1"
|
||||||
@ -3455,6 +3560,12 @@ dependencies = [
|
|||||||
"libc",
|
"libc",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "match_cfg"
|
||||||
|
version = "0.1.0"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "ffbee8634e0d45d258acb448e7eaab3fce7a0a467395d4d9f228e3c1f01fb2e4"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "matchers"
|
name = "matchers"
|
||||||
version = "0.1.0"
|
version = "0.1.0"
|
||||||
@ -4695,6 +4806,12 @@ dependencies = [
|
|||||||
"unicase",
|
"unicase",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "quick-error"
|
||||||
|
version = "1.2.3"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "a1d01941d82fa2ab50be1e79e6714289dd7cde78eba4c074bc5a4374f650dfe0"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "quick-xml"
|
name = "quick-xml"
|
||||||
version = "0.30.0"
|
version = "0.30.0"
|
||||||
@ -5103,6 +5220,16 @@ version = "1.0.0"
|
|||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "216080ab382b992234dda86873c18d4c48358f5cfcb70fd693d7f6f2131b628b"
|
checksum = "216080ab382b992234dda86873c18d4c48358f5cfcb70fd693d7f6f2131b628b"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "resolv-conf"
|
||||||
|
version = "0.7.0"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "52e44394d2086d010551b14b53b1f24e31647570cd1deb0379e2c21b329aba00"
|
||||||
|
dependencies = [
|
||||||
|
"hostname",
|
||||||
|
"quick-error",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "ring"
|
name = "ring"
|
||||||
version = "0.16.20"
|
version = "0.16.20"
|
||||||
@ -6778,7 +6905,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
|
|||||||
checksum = "31e6302e3bb753d46e83516cae55ae196fc0c309407cf11ab35cc51a4c2a4633"
|
checksum = "31e6302e3bb753d46e83516cae55ae196fc0c309407cf11ab35cc51a4c2a4633"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"form_urlencoded",
|
"form_urlencoded",
|
||||||
"idna",
|
"idna 0.5.0",
|
||||||
"percent-encoding",
|
"percent-encoding",
|
||||||
]
|
]
|
||||||
|
|
||||||
@ -6852,11 +6979,13 @@ dependencies = [
|
|||||||
"byteorder",
|
"byteorder",
|
||||||
"clap",
|
"clap",
|
||||||
"hashbrown 0.13.2",
|
"hashbrown 0.13.2",
|
||||||
|
"hickory-resolver",
|
||||||
"image",
|
"image",
|
||||||
"num 0.4.1",
|
"num 0.4.1",
|
||||||
"quinn",
|
"quinn",
|
||||||
"rayon",
|
"rayon",
|
||||||
"ron",
|
"ron",
|
||||||
|
"rustls",
|
||||||
"rustyline",
|
"rustyline",
|
||||||
"serde",
|
"serde",
|
||||||
"specs",
|
"specs",
|
||||||
@ -8423,6 +8552,16 @@ dependencies = [
|
|||||||
"memchr",
|
"memchr",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "winreg"
|
||||||
|
version = "0.50.0"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "524e57b2c537c0f9b1e69f1965311ec12182b4122e45035b1508cd24d2adadb1"
|
||||||
|
dependencies = [
|
||||||
|
"cfg-if 1.0.0",
|
||||||
|
"windows-sys 0.48.0",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "winreg"
|
name = "winreg"
|
||||||
version = "0.51.0"
|
version = "0.51.0"
|
||||||
|
@ -23,7 +23,9 @@ network = { package = "veloren-network", path = "../network", features = ["compr
|
|||||||
|
|
||||||
byteorder = "1.3.2"
|
byteorder = "1.3.2"
|
||||||
tokio = { workspace = true, features = ["rt-multi-thread"] }
|
tokio = { workspace = true, features = ["rt-multi-thread"] }
|
||||||
quinn = "0.10"
|
quinn = { version = "0.10", features = ["rustls"] }
|
||||||
|
rustls = { version = "0.21.6", features = ["dangerous_configuration"] }
|
||||||
|
hickory-resolver = { version = "0.24.0", features = ["system-config", "tokio-runtime"] }
|
||||||
image = { workspace = true }
|
image = { workspace = true }
|
||||||
num = { workspace = true }
|
num = { workspace = true }
|
||||||
tracing = { workspace = true }
|
tracing = { workspace = true }
|
||||||
|
@ -8,12 +8,24 @@ pub enum ConnectionArgs {
|
|||||||
Quic {
|
Quic {
|
||||||
hostname: String,
|
hostname: String,
|
||||||
prefer_ipv6: bool,
|
prefer_ipv6: bool,
|
||||||
|
validate_tls: bool,
|
||||||
},
|
},
|
||||||
///hostname: (hostname|ip):[<port>]
|
///hostname: (hostname|ip):[<port>]
|
||||||
Tcp {
|
Tcp {
|
||||||
hostname: String,
|
hostname: String,
|
||||||
prefer_ipv6: bool,
|
prefer_ipv6: bool,
|
||||||
},
|
},
|
||||||
|
/// SRV lookup
|
||||||
|
///
|
||||||
|
/// SRV lookups can not contain a port, but will be able to connect to
|
||||||
|
/// configured port automatically. If a connection with a port is given,
|
||||||
|
/// this will gracefully fall back to TCP.
|
||||||
|
Srv {
|
||||||
|
hostname: String,
|
||||||
|
prefer_ipv6: bool,
|
||||||
|
validate_tls: bool,
|
||||||
|
use_quic: bool,
|
||||||
|
},
|
||||||
Mpsc(u64),
|
Mpsc(u64),
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -51,6 +63,7 @@ pub(crate) async fn resolve(
|
|||||||
pub(crate) async fn try_connect<F>(
|
pub(crate) async fn try_connect<F>(
|
||||||
network: &network::Network,
|
network: &network::Network,
|
||||||
address: &str,
|
address: &str,
|
||||||
|
override_port: Option<u16>,
|
||||||
prefer_ipv6: bool,
|
prefer_ipv6: bool,
|
||||||
f: F,
|
f: F,
|
||||||
) -> Result<network::Participant, crate::error::Error>
|
) -> Result<network::Participant, crate::error::Error>
|
||||||
@ -59,10 +72,15 @@ where
|
|||||||
{
|
{
|
||||||
use crate::error::Error;
|
use crate::error::Error;
|
||||||
let mut participant = None;
|
let mut participant = None;
|
||||||
for addr in resolve(address, prefer_ipv6)
|
for mut addr in resolve(address, prefer_ipv6)
|
||||||
.await
|
.await
|
||||||
.map_err(Error::HostnameLookupFailed)?
|
.map_err(Error::HostnameLookupFailed)?
|
||||||
{
|
{
|
||||||
|
// Override the port if one was passed. Used for SRV lookups which get port info
|
||||||
|
// out-of-band
|
||||||
|
if let Some(port) = override_port {
|
||||||
|
addr.set_port(port);
|
||||||
|
}
|
||||||
match network.connect(f(addr)).await {
|
match network.connect(f(addr)).await {
|
||||||
Ok(p) => {
|
Ok(p) => {
|
||||||
participant = Some(Ok(p));
|
participant = Some(Ok(p));
|
||||||
|
@ -68,16 +68,22 @@ use common_state::State;
|
|||||||
use common_systems::add_local_systems;
|
use common_systems::add_local_systems;
|
||||||
use comp::BuffKind;
|
use comp::BuffKind;
|
||||||
use hashbrown::{HashMap, HashSet};
|
use hashbrown::{HashMap, HashSet};
|
||||||
|
use hickory_resolver::{
|
||||||
|
config::{ResolverConfig, ResolverOpts},
|
||||||
|
AsyncResolver,
|
||||||
|
};
|
||||||
use image::DynamicImage;
|
use image::DynamicImage;
|
||||||
use network::{ConnectAddr, Network, Participant, Pid, Stream};
|
use network::{ConnectAddr, Network, Participant, Pid, Stream};
|
||||||
use num::traits::FloatConst;
|
use num::traits::FloatConst;
|
||||||
use rayon::prelude::*;
|
use rayon::prelude::*;
|
||||||
|
use rustls::client::ServerCertVerified;
|
||||||
use specs::Component;
|
use specs::Component;
|
||||||
use std::{
|
use std::{
|
||||||
collections::{BTreeMap, VecDeque},
|
collections::{BTreeMap, VecDeque},
|
||||||
|
fmt::Debug,
|
||||||
mem,
|
mem,
|
||||||
sync::Arc,
|
sync::Arc,
|
||||||
time::{Duration, Instant},
|
time::{Duration, Instant, SystemTime},
|
||||||
};
|
};
|
||||||
use tokio::runtime::Runtime;
|
use tokio::runtime::Runtime;
|
||||||
use tracing::{debug, error, trace, warn};
|
use tracing::{debug, error, trace, warn};
|
||||||
@ -327,6 +333,50 @@ pub struct CharacterList {
|
|||||||
pub loading: bool,
|
pub loading: bool,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
async fn connect_quic(
|
||||||
|
network: &Network,
|
||||||
|
hostname: String,
|
||||||
|
override_port: Option<u16>,
|
||||||
|
prefer_ipv6: bool,
|
||||||
|
validate_tls: bool,
|
||||||
|
) -> Result<network::Participant, crate::error::Error> {
|
||||||
|
let config = if validate_tls {
|
||||||
|
quinn::ClientConfig::with_native_roots()
|
||||||
|
} else {
|
||||||
|
warn!(
|
||||||
|
"skipping validation of server identity. There is no guarantee that the server you're \
|
||||||
|
connected to is the one you expect to be connecting to."
|
||||||
|
);
|
||||||
|
struct Verifier;
|
||||||
|
impl rustls::client::ServerCertVerifier for Verifier {
|
||||||
|
fn verify_server_cert(
|
||||||
|
&self,
|
||||||
|
_: &rustls::Certificate,
|
||||||
|
_: &[rustls::Certificate],
|
||||||
|
_: &rustls::ServerName,
|
||||||
|
_: &mut dyn Iterator<Item = &[u8]>,
|
||||||
|
_: &[u8],
|
||||||
|
_: SystemTime,
|
||||||
|
) -> Result<ServerCertVerified, rustls::Error> {
|
||||||
|
Ok(ServerCertVerified::assertion())
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
let mut cfg = rustls::ClientConfig::builder()
|
||||||
|
.with_safe_defaults()
|
||||||
|
.with_custom_certificate_verifier(Arc::new(Verifier))
|
||||||
|
.with_no_client_auth();
|
||||||
|
cfg.enable_early_data = true;
|
||||||
|
|
||||||
|
quinn::ClientConfig::new(Arc::new(cfg))
|
||||||
|
};
|
||||||
|
|
||||||
|
addr::try_connect(network, &hostname, override_port, prefer_ipv6, |a| {
|
||||||
|
ConnectAddr::Quic(a, config.clone(), hostname.clone())
|
||||||
|
})
|
||||||
|
.await
|
||||||
|
}
|
||||||
|
|
||||||
impl Client {
|
impl Client {
|
||||||
pub async fn new(
|
pub async fn new(
|
||||||
addr: ConnectionArgs,
|
addr: ConnectionArgs,
|
||||||
@ -343,24 +393,132 @@ impl Client {
|
|||||||
let network = Network::new(Pid::new(), &runtime);
|
let network = Network::new(Pid::new(), &runtime);
|
||||||
|
|
||||||
init_stage_update(ClientInitStage::ConnectionEstablish);
|
init_stage_update(ClientInitStage::ConnectionEstablish);
|
||||||
|
|
||||||
let mut participant = match addr {
|
let mut participant = match addr {
|
||||||
|
ConnectionArgs::Srv {
|
||||||
|
hostname,
|
||||||
|
prefer_ipv6,
|
||||||
|
validate_tls,
|
||||||
|
use_quic,
|
||||||
|
} => {
|
||||||
|
// Try to create a resolver backed by /etc/resolv.conf or the Windows Registry
|
||||||
|
// first. If that fails, create a resolver being hard-coded to
|
||||||
|
// Google's 8.8.8.8 public resolver.
|
||||||
|
let resolver = AsyncResolver::tokio_from_system_conf().unwrap_or_else(|error| {
|
||||||
|
error!("Failed to create DNS resolver using system configuration: {error:?}");
|
||||||
|
warn!("Falling back to a default configured resolver.");
|
||||||
|
AsyncResolver::tokio(ResolverConfig::default(), ResolverOpts::default())
|
||||||
|
});
|
||||||
|
|
||||||
|
let quic_service_host = format!("_veloren._udp.{hostname}");
|
||||||
|
let quic_lookup_future = resolver.srv_lookup(quic_service_host);
|
||||||
|
let tcp_service_host = format!("_veloren._tcp.{hostname}");
|
||||||
|
let tcp_lookup_future = resolver.srv_lookup(tcp_service_host);
|
||||||
|
let (quic_rr, tcp_rr) = tokio::join!(quic_lookup_future, tcp_lookup_future);
|
||||||
|
|
||||||
|
#[derive(Eq, PartialEq)]
|
||||||
|
enum ConnMode {
|
||||||
|
Quic,
|
||||||
|
Tcp,
|
||||||
|
}
|
||||||
|
|
||||||
|
// Push the results of both futures into `srv_rr`. This uses map_or_else purely
|
||||||
|
// for side effects.
|
||||||
|
let mut srv_rr = Vec::new();
|
||||||
|
let () = quic_rr.map_or_else(
|
||||||
|
|error| {
|
||||||
|
warn!("QUIC SRV lookup failed: {error:?}");
|
||||||
|
},
|
||||||
|
|srv_lookup| {
|
||||||
|
srv_rr.extend(srv_lookup.iter().cloned().map(|srv| (ConnMode::Quic, srv)))
|
||||||
|
},
|
||||||
|
);
|
||||||
|
let () = tcp_rr.map_or_else(
|
||||||
|
|error| {
|
||||||
|
warn!("TCP SRV lookup failed: {error:?}");
|
||||||
|
},
|
||||||
|
|srv_lookup| {
|
||||||
|
srv_rr.extend(srv_lookup.iter().cloned().map(|srv| (ConnMode::Tcp, srv)))
|
||||||
|
},
|
||||||
|
);
|
||||||
|
|
||||||
|
// SRV records have a priority; lowest priority hosts MUST be contacted first.
|
||||||
|
let srv_rr_slice = srv_rr.as_mut_slice();
|
||||||
|
srv_rr_slice.sort_by_key(|(_, srv)| srv.priority());
|
||||||
|
|
||||||
|
let mut iter = srv_rr_slice.iter();
|
||||||
|
|
||||||
|
// This loops exits as soon as the above iter over `srv_rr_slice` is exhausted
|
||||||
|
loop {
|
||||||
|
if let Some((conn_mode, srv_rr)) = iter.next() {
|
||||||
|
let hostname = format!("{}", srv_rr.target());
|
||||||
|
let port = Some(srv_rr.port());
|
||||||
|
let conn_result = match conn_mode {
|
||||||
|
ConnMode::Quic => {
|
||||||
|
connect_quic(&network, hostname, port, prefer_ipv6, validate_tls)
|
||||||
|
.await
|
||||||
|
},
|
||||||
|
ConnMode::Tcp => {
|
||||||
|
addr::try_connect(
|
||||||
|
&network,
|
||||||
|
&hostname,
|
||||||
|
port,
|
||||||
|
prefer_ipv6,
|
||||||
|
ConnectAddr::Tcp,
|
||||||
|
)
|
||||||
|
.await
|
||||||
|
},
|
||||||
|
};
|
||||||
|
match conn_result {
|
||||||
|
Ok(c) => break c,
|
||||||
|
Err(error) => {
|
||||||
|
warn!("Failed to connect to host {}: {error:?}", srv_rr.target())
|
||||||
|
},
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
warn!(
|
||||||
|
"No SRV hosts succeeded connection, falling back to direct connection"
|
||||||
|
);
|
||||||
|
// This case is also hit if no SRV host was returned from the query, so we
|
||||||
|
// check for QUIC/TCP preference.
|
||||||
|
let c = if use_quic {
|
||||||
|
connect_quic(&network, hostname, None, prefer_ipv6, validate_tls)
|
||||||
|
.await?
|
||||||
|
} else {
|
||||||
|
match addr::try_connect(
|
||||||
|
&network,
|
||||||
|
&hostname,
|
||||||
|
None,
|
||||||
|
prefer_ipv6,
|
||||||
|
ConnectAddr::Tcp,
|
||||||
|
)
|
||||||
|
.await
|
||||||
|
{
|
||||||
|
Ok(c) => c,
|
||||||
|
Err(error) => return Err(error),
|
||||||
|
}
|
||||||
|
};
|
||||||
|
break c;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
ConnectionArgs::Tcp {
|
ConnectionArgs::Tcp {
|
||||||
hostname,
|
hostname,
|
||||||
prefer_ipv6,
|
prefer_ipv6,
|
||||||
} => addr::try_connect(&network, &hostname, prefer_ipv6, ConnectAddr::Tcp).await?,
|
} => {
|
||||||
|
addr::try_connect(&network, &hostname, None, prefer_ipv6, ConnectAddr::Tcp).await?
|
||||||
|
},
|
||||||
ConnectionArgs::Quic {
|
ConnectionArgs::Quic {
|
||||||
hostname,
|
hostname,
|
||||||
prefer_ipv6,
|
prefer_ipv6,
|
||||||
|
validate_tls,
|
||||||
} => {
|
} => {
|
||||||
warn!(
|
warn!(
|
||||||
"QUIC is enabled. This is experimental and you won't be able to connect to \
|
"QUIC is enabled. This is experimental and you won't be able to connect to \
|
||||||
TCP servers unless deactivated"
|
TCP servers unless deactivated"
|
||||||
);
|
);
|
||||||
let config = quinn::ClientConfig::with_native_roots();
|
|
||||||
addr::try_connect(&network, &hostname, prefer_ipv6, |a| {
|
connect_quic(&network, hostname, None, prefer_ipv6, validate_tls).await?
|
||||||
ConnectAddr::Quic(a, config.clone(), hostname.clone())
|
|
||||||
})
|
|
||||||
.await?
|
|
||||||
},
|
},
|
||||||
ConnectionArgs::Mpsc(id) => network.connect(ConnectAddr::Mpsc(id)).await?,
|
ConnectionArgs::Mpsc(id) => network.connect(ConnectAddr::Mpsc(id)).await?,
|
||||||
};
|
};
|
||||||
|
@ -334,7 +334,9 @@ impl PlayState for MainMenuState {
|
|||||||
server_address,
|
server_address,
|
||||||
} => {
|
} => {
|
||||||
let net_settings = &mut global_state.settings.networking;
|
let net_settings = &mut global_state.settings.networking;
|
||||||
|
let use_srv = net_settings.use_srv;
|
||||||
let use_quic = net_settings.use_quic;
|
let use_quic = net_settings.use_quic;
|
||||||
|
let validate_tls = net_settings.validate_tls;
|
||||||
net_settings.username = username.clone();
|
net_settings.username = username.clone();
|
||||||
net_settings.default_server = server_address.clone();
|
net_settings.default_server = server_address.clone();
|
||||||
if !net_settings.servers.contains(&server_address) {
|
if !net_settings.servers.contains(&server_address) {
|
||||||
@ -344,10 +346,18 @@ impl PlayState for MainMenuState {
|
|||||||
.settings
|
.settings
|
||||||
.save_to_file_warn(&global_state.config_dir);
|
.save_to_file_warn(&global_state.config_dir);
|
||||||
|
|
||||||
let connection_args = if use_quic {
|
let connection_args = if use_srv {
|
||||||
|
ConnectionArgs::Srv {
|
||||||
|
hostname: server_address,
|
||||||
|
prefer_ipv6: false,
|
||||||
|
validate_tls,
|
||||||
|
use_quic,
|
||||||
|
}
|
||||||
|
} else if use_quic {
|
||||||
ConnectionArgs::Quic {
|
ConnectionArgs::Quic {
|
||||||
hostname: server_address,
|
hostname: server_address,
|
||||||
prefer_ipv6: false,
|
prefer_ipv6: false,
|
||||||
|
validate_tls,
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
ConnectionArgs::Tcp {
|
ConnectionArgs::Tcp {
|
||||||
|
@ -9,7 +9,9 @@ pub struct NetworkingSettings {
|
|||||||
pub servers: Vec<String>,
|
pub servers: Vec<String>,
|
||||||
pub default_server: String,
|
pub default_server: String,
|
||||||
pub trusted_auth_servers: HashSet<String>,
|
pub trusted_auth_servers: HashSet<String>,
|
||||||
|
pub use_srv: bool,
|
||||||
pub use_quic: bool,
|
pub use_quic: bool,
|
||||||
|
pub validate_tls: bool,
|
||||||
pub player_physics_behavior: bool,
|
pub player_physics_behavior: bool,
|
||||||
pub lossy_terrain_compression: bool,
|
pub lossy_terrain_compression: bool,
|
||||||
pub enable_discord_integration: bool,
|
pub enable_discord_integration: bool,
|
||||||
@ -25,7 +27,9 @@ impl Default for NetworkingSettings {
|
|||||||
.iter()
|
.iter()
|
||||||
.map(|s| s.to_string())
|
.map(|s| s.to_string())
|
||||||
.collect(),
|
.collect(),
|
||||||
|
use_srv: true,
|
||||||
use_quic: false,
|
use_quic: false,
|
||||||
|
validate_tls: true,
|
||||||
player_physics_behavior: false,
|
player_physics_behavior: false,
|
||||||
lossy_terrain_compression: false,
|
lossy_terrain_compression: false,
|
||||||
enable_discord_integration: true,
|
enable_discord_integration: true,
|
||||||
|
Loading…
Reference in New Issue
Block a user