From 1da074aeb9b9336e60381d7821aaa19d88198b57 Mon Sep 17 00:00:00 2001 From: dev0 Date: Mon, 28 Aug 2023 05:36:16 +1000 Subject: [PATCH] fix vmess host --- .gitignore | 1 + clash/tests/data/config/cache.db | Bin 65536 -> 0 bytes clash/tests/data/config/rules.yaml | 12 +++++--- clash_lib/src/app/dns/resolver.rs | 11 +++++++- clash_lib/src/proxy/mod.rs | 7 +++++ clash_lib/src/proxy/selector/mod.rs | 3 +- .../src/proxy/transport/websocket/mod.rs | 26 ++++++++---------- .../proxy/transport/websocket/websocket.rs | 2 +- clash_lib/src/proxy/urltest/mod.rs | 9 ++++-- clash_lib/src/proxy/vmess/mod.rs | 7 ++--- .../src/proxy/vmess/vmess_impl/stream.rs | 2 +- 11 files changed, 52 insertions(+), 28 deletions(-) delete mode 100644 clash/tests/data/config/cache.db diff --git a/.gitignore b/.gitignore index a8f0121a..ad5513cf 100644 --- a/.gitignore +++ b/.gitignore @@ -28,3 +28,4 @@ venv/ # don't check in this real config ignore.yaml +cache.db \ No newline at end of file diff --git a/clash/tests/data/config/cache.db b/clash/tests/data/config/cache.db deleted file mode 100644 index 0b745ffbe25a171b4d479164d835d88951b09ce8..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 65536 zcmeI)yA8rH5CBk)pOzV=d80{Z>N-7 zQ{pskr|L640RjXF5FkK+ z009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBly zK!5-N0t5)GE>M?>@ejc27f_G@0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&U pAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&UNH3Sk510S| diff --git a/clash/tests/data/config/rules.yaml b/clash/tests/data/config/rules.yaml index d04a9dc8..abfe59b9 100644 --- a/clash/tests/data/config/rules.yaml +++ b/clash/tests/data/config/rules.yaml @@ -134,13 +134,17 @@ proxies: Host: www.amazon.com - name: vmess-altid type: vmess - server: 10.0.0.13 - port: 16823 - uuid: b831381d-6324-4d53-ad4f-8cda48b30811 + server: tw-1.ac.laowanxiang.com + port: 153 + uuid: 46dd0dd3-2cc0-3f55-907c-d94e54877687 alterId: 64 cipher: auto udp: true - skip-cert-verify: true + network: ws + ws-opts: + path: /api/v3/download.getFile + headers: + Host: 5607b9d187e655736f563fee87d7283994721.laowanxiang.com rules: - DOMAIN,ipinfo.io,relay diff --git a/clash_lib/src/app/dns/resolver.rs b/clash_lib/src/app/dns/resolver.rs index 874df9db..0bb8cc5c 100644 --- a/clash_lib/src/app/dns/resolver.rs +++ b/clash_lib/src/app/dns/resolver.rs @@ -70,7 +70,7 @@ impl Resolver { ) -> anyhow::Result> { let mut m = op::Message::new(); let mut q = op::Query::new(); - let name = rr::Name::from_str(host) + let name = rr::Name::from_str_relaxed(host) .map_err(|_x| anyhow!("invalid domain: {}", host))? .append_domain(&rr::Name::root())?; // makes it FQDN q.set_name(name); @@ -429,6 +429,15 @@ mod tests { use trust_dns_client::op; use trust_dns_proto::rr; + #[test] + fn test_bad_labels() { + let name = rr::Name::from_str_relaxed("some_domain.understore") + .unwrap() + .append_domain(&rr::Name::root()) + .unwrap(); + assert_eq!(name.to_string(), "some_domain.understore"); + } + #[tokio::test] async fn test_udp_resolve() { let c = DnsClient::new(Opts { diff --git a/clash_lib/src/proxy/mod.rs b/clash_lib/src/proxy/mod.rs index 65d3be77..84839cfa 100644 --- a/clash_lib/src/proxy/mod.rs +++ b/clash_lib/src/proxy/mod.rs @@ -38,6 +38,13 @@ mod transport; #[cfg(test)] pub mod mocks; +#[macro_export] +macro_rules! p_debug { + ($($arg:tt)*) => { + debug!(target: "proxy", $($arg)*) + }; +} + #[derive(thiserror::Error, Debug)] pub enum ProxyError { #[error(transparent)] diff --git a/clash_lib/src/proxy/selector/mod.rs b/clash_lib/src/proxy/selector/mod.rs index c801790b..e84b1b4e 100644 --- a/clash_lib/src/proxy/selector/mod.rs +++ b/clash_lib/src/proxy/selector/mod.rs @@ -9,6 +9,7 @@ use crate::{ app::{ proxy_manager::providers::proxy_provider::ThreadSafeProxyProvider, ThreadSafeDNSResolver, }, + p_debug, session::{Session, SocksAddr}, Error, }; @@ -69,7 +70,7 @@ impl Handler { let proxies = get_proxies_from_providers(&self.providers, touch).await; for proxy in proxies { if proxy.name() == self.inner.lock().await.current { - debug!("{} selected {}", self.name(), proxy.name()); + p_debug!("{} selected {}", self.name(), proxy.name()); return proxy; } } diff --git a/clash_lib/src/proxy/transport/websocket/mod.rs b/clash_lib/src/proxy/transport/websocket/mod.rs index e74bd052..0d536a33 100644 --- a/clash_lib/src/proxy/transport/websocket/mod.rs +++ b/clash_lib/src/proxy/transport/websocket/mod.rs @@ -22,7 +22,9 @@ macro_rules! ws_debug { } pub struct WebsocketStreamBuilder { - uri: Uri, + server: String, + port: u16, + path: String, headers: HashMap, ws_config: Option, max_early_data: usize, @@ -31,14 +33,18 @@ pub struct WebsocketStreamBuilder { impl WebsocketStreamBuilder { pub fn new( - uri: Uri, + server: String, + port: u16, + path: String, headers: HashMap, ws_config: Option, max_early_data: usize, early_data_header_name: String, ) -> Self { Self { - uri, + server, + port, + path, headers, ws_config, max_early_data, @@ -47,27 +53,19 @@ impl WebsocketStreamBuilder { } fn req(&self) -> Request<()> { - let authority = self.uri.authority().unwrap().as_str(); - let host = authority - .find('@') - .map(|idx| authority.split_at(idx + 1).1) - .unwrap_or_else(|| authority); let mut request = Request::builder() .method("GET") - .header("Host", host) .header("Connection", "Upgrade") .header("Upgrade", "websocket") .header("Sec-WebSocket-Version", "13") .header("Sec-WebSocket-Key", generate_key()) - .uri(self.uri.clone()); + .uri(format!("ws://{}:{}{}", self.server, self.port, self.path)); for (k, v) in self.headers.iter() { - if k != "Host" { - request = request.header(k.as_str(), v.as_str()); - } + request = request.header(k.as_str(), v.as_str()); } if self.max_early_data > 0 { // we will replace this field later - request = request.header(self.early_data_header_name.as_str(), "s"); + request = request.header(self.early_data_header_name.as_str(), "xxoo"); } request.body(()).unwrap() } diff --git a/clash_lib/src/proxy/transport/websocket/websocket.rs b/clash_lib/src/proxy/transport/websocket/websocket.rs index d45097f0..c2e9f443 100644 --- a/clash_lib/src/proxy/transport/websocket/websocket.rs +++ b/clash_lib/src/proxy/transport/websocket/websocket.rs @@ -1,6 +1,6 @@ use std::{fmt::Debug, pin::Pin, task::Poll}; -use bytes::{Buf, Bytes, BytesMut}; +use bytes::BytesMut; use futures::{ready, Sink, Stream}; use tokio::io::{AsyncRead, AsyncWrite}; use tokio_tungstenite::{tungstenite::Message, WebSocketStream}; diff --git a/clash_lib/src/proxy/urltest/mod.rs b/clash_lib/src/proxy/urltest/mod.rs index ac206798..40370d94 100644 --- a/clash_lib/src/proxy/urltest/mod.rs +++ b/clash_lib/src/proxy/urltest/mod.rs @@ -11,6 +11,7 @@ use crate::{ }, ThreadSafeDNSResolver, }, + p_debug, session::{Session, SocksAddr}, }; @@ -104,14 +105,18 @@ impl Handler { } } - debug!( + p_debug!( "{} fastest {} is {}", self.name(), fastest.name(), fastest_delay ); - return inner.fastest_proxy.as_ref().unwrap().clone(); + return inner + .fastest_proxy + .as_ref() + .unwrap_or(proxies.first().unwrap()) + .clone(); } } diff --git a/clash_lib/src/proxy/vmess/mod.rs b/clash_lib/src/proxy/vmess/mod.rs index 0790545a..e2b936e4 100644 --- a/clash_lib/src/proxy/vmess/mod.rs +++ b/clash_lib/src/proxy/vmess/mod.rs @@ -89,11 +89,10 @@ impl Handler { let underlying = match self.opts.transport { Some(VmessTransport::Ws(ref opt)) => { - let uri = format!("ws://{}:{}{}", self.opts.server, self.opts.port, opt.path) - .parse::() - .map_err(|e| io::Error::new(io::ErrorKind::InvalidInput, e))?; let ws_builder = transport::WebsocketStreamBuilder::new( - uri, + self.opts.server.clone(), + self.opts.port, + opt.path.clone(), opt.headers.clone(), None, opt.max_early_data, diff --git a/clash_lib/src/proxy/vmess/vmess_impl/stream.rs b/clash_lib/src/proxy/vmess/vmess_impl/stream.rs index 01d0452c..3ddd4dfd 100644 --- a/clash_lib/src/proxy/vmess/vmess_impl/stream.rs +++ b/clash_lib/src/proxy/vmess/vmess_impl/stream.rs @@ -309,7 +309,7 @@ where mbuf.put_slice(data.as_slice()); let out = mbuf.freeze(); - vmess_debug!("send non aead handshake request for user{}", id.uuid); + vmess_debug!("send non aead handshake request for user {}", id.uuid); stream.write_all(&out).await?; } else { let out = header::seal_vmess_aead_header(id.cmd_key, buf.freeze().to_vec(), now)