diff --git a/Cargo.lock b/Cargo.lock index ab8bc7c9e..f9fc05716 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -1201,7 +1201,7 @@ dependencies = [ "public-suffix", "quinn", "quinn-proto", - "rand 0.8.5", + "rand 0.9.0", "regex", "register-count", "ring-compat", @@ -3428,7 +3428,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "fc2f4eb4bc735547cfed7c0a4922cbd04a4655978c09b54f1f7b228750664c34" dependencies = [ "cfg-if", - "windows-targets 0.52.6", + "windows-targets 0.48.5", ] [[package]] diff --git a/clash_lib/Cargo.toml b/clash_lib/Cargo.toml index 5f573c716..eaa8daafa 100644 --- a/clash_lib/Cargo.toml +++ b/clash_lib/Cargo.toml @@ -106,7 +106,7 @@ hickory-proto = { version = "0.25.0-alpha.2", features = ["dns-over-rustls", "dn dhcproto = "0.12" ring-compat = { version = "0.8", features = ["aead"] } -rand = "0.8" +rand = "0.9" tracing = "0.1" tracing-subscriber = { version = "0.3", features = ["env-filter"] } tracing-appender = "0.2" diff --git a/clash_lib/src/app/dns/resolver/enhanced.rs b/clash_lib/src/app/dns/resolver/enhanced.rs index 5eb310efb..626e9751e 100644 --- a/clash_lib/src/app/dns/resolver/enhanced.rs +++ b/clash_lib/src/app/dns/resolver/enhanced.rs @@ -1,6 +1,6 @@ use async_trait::async_trait; use futures::{FutureExt, TryFutureExt}; -use rand::prelude::SliceRandom; +use rand::seq::IndexedRandom; use std::{ net, sync::{ @@ -531,7 +531,7 @@ impl ClashResolver for EnhancedResolver { } match self.lookup_ip(host, rr::RecordType::A).await { - Ok(result) => match result.choose(&mut rand::thread_rng()).unwrap() { + Ok(result) => match result.choose(&mut rand::rng()).unwrap() { net::IpAddr::V4(v4) => Ok(Some(*v4)), _ => unreachable!("invalid IP family"), }, @@ -564,7 +564,7 @@ impl ClashResolver for EnhancedResolver { } match self.lookup_ip(host, rr::RecordType::AAAA).await { - Ok(result) => match result.choose(&mut rand::thread_rng()).unwrap() { + Ok(result) => match result.choose(&mut rand::rng()).unwrap() { net::IpAddr::V6(v6) => Ok(Some(*v6)), _ => unreachable!("invalid IP family"), }, diff --git a/clash_lib/src/app/dns/resolver/system_linux.rs b/clash_lib/src/app/dns/resolver/system_linux.rs index 099d18355..3ccc8d14a 100644 --- a/clash_lib/src/app/dns/resolver/system_linux.rs +++ b/clash_lib/src/app/dns/resolver/system_linux.rs @@ -33,7 +33,7 @@ impl ClashResolver for SystemResolver { Ok(response .iter() .filter(|x| self.ipv6() || x.is_ipv4()) - .choose(&mut rand::thread_rng())) + .choose(&mut rand::rng())) } async fn resolve_v4( @@ -42,7 +42,7 @@ impl ClashResolver for SystemResolver { _: bool, ) -> anyhow::Result> { let response = self.inner.ipv4_lookup(host).await?; - Ok(response.iter().map(|x| x.0).choose(&mut rand::thread_rng())) + Ok(response.iter().map(|x| x.0).choose(&mut rand::rng())) } async fn resolve_v6( @@ -51,7 +51,7 @@ impl ClashResolver for SystemResolver { _: bool, ) -> anyhow::Result> { let response = self.inner.ipv6_lookup(host).await?; - Ok(response.iter().map(|x| x.0).choose(&mut rand::thread_rng())) + Ok(response.iter().map(|x| x.0).choose(&mut rand::rng())) } async fn cached_for(&self, _: std::net::IpAddr) -> Option { diff --git a/clash_lib/src/app/dns/resolver/system_non_linux.rs b/clash_lib/src/app/dns/resolver/system_non_linux.rs index 88df66bf4..d137d8e09 100644 --- a/clash_lib/src/app/dns/resolver/system_non_linux.rs +++ b/clash_lib/src/app/dns/resolver/system_non_linux.rs @@ -39,7 +39,7 @@ impl ClashResolver for SystemResolver { } }) .collect::>(); - Ok(response.into_iter().choose(&mut rand::thread_rng())) + Ok(response.into_iter().choose(&mut rand::rng())) } async fn resolve_v4( @@ -54,7 +54,7 @@ impl ClashResolver for SystemResolver { _ => None, }) .collect::>(); - Ok(response.into_iter().choose(&mut rand::thread_rng())) + Ok(response.into_iter().choose(&mut rand::rng())) } async fn resolve_v6( @@ -72,7 +72,7 @@ impl ClashResolver for SystemResolver { _ => None, }) .collect::>(); - Ok(response.into_iter().choose(&mut rand::thread_rng())) + Ok(response.into_iter().choose(&mut rand::rng())) } async fn cached_for(&self, _: std::net::IpAddr) -> Option { diff --git a/clash_lib/src/common/utils.rs b/clash_lib/src/common/utils.rs index f121a1917..526500bdf 100644 --- a/clash_lib/src/common/utils.rs +++ b/clash_lib/src/common/utils.rs @@ -5,7 +5,7 @@ use std::{fmt::Write, num::ParseIntError, path::Path}; use crate::{common::errors::new_io_error, Error}; use rand::{ - distributions::uniform::{SampleRange, SampleUniform}, + distr::uniform::{SampleRange, SampleUniform}, Fill, Rng, }; use sha2::Digest; @@ -16,15 +16,15 @@ where T: SampleUniform, R: SampleRange, { - let mut rng = rand::thread_rng(); - rng.gen_range(range) + let mut rng = rand::rng(); + rng.random_range(range) } pub fn rand_fill(buf: &mut T) where T: Fill + ?Sized, { - let mut rng = rand::thread_rng(); + let mut rng = rand::rng(); rng.fill(buf) } diff --git a/clash_lib/src/proxy/converters/hysteria2.rs b/clash_lib/src/proxy/converters/hysteria2.rs index cb587881a..f7f888684 100644 --- a/clash_lib/src/proxy/converters/hysteria2.rs +++ b/clash_lib/src/proxy/converters/hysteria2.rs @@ -40,10 +40,10 @@ impl PortGenrateor { } pub fn get(&self) -> u16 { - let mut rng = rand::thread_rng(); + let mut rng = rand::rng(); let len = 1 + self.ports.len() + self.range.iter().map(|r| r.len()).sum::(); - let idx = rng.gen_range(0..len); + let idx = rng.random_range(0..len); match idx { 0 => self.default, idx if idx <= self.ports.len() => self.ports[idx - 1], diff --git a/clash_lib/src/proxy/hysteria2/codec.rs b/clash_lib/src/proxy/hysteria2/codec.rs index ab58609cb..6c83e14e1 100644 --- a/clash_lib/src/proxy/hysteria2/codec.rs +++ b/clash_lib/src/proxy/hysteria2/codec.rs @@ -2,7 +2,7 @@ use std::io::ErrorKind; use bytes::{Buf, BufMut, BytesMut}; use quinn_proto::{coding::Codec, VarInt}; -use rand::distributions::Alphanumeric; +use rand::distr::Alphanumeric; use tokio_util::codec::{Decoder, Encoder}; use crate::session::SocksAddr; @@ -64,8 +64,8 @@ impl Decoder for Hy2TcpCodec { #[inline] pub fn padding(range: std::ops::RangeInclusive) -> Vec { use rand::Rng; - let mut rng = rand::thread_rng(); - let len = rng.gen_range(range) as usize; + let mut rng = rand::rng(); + let len = rng.random_range(range) as usize; rng.sample_iter(Alphanumeric).take(len).collect() } diff --git a/clash_lib/src/proxy/hysteria2/salamander.rs b/clash_lib/src/proxy/hysteria2/salamander.rs index adb0b782f..e3149e081 100644 --- a/clash_lib/src/proxy/hysteria2/salamander.rs +++ b/clash_lib/src/proxy/hysteria2/salamander.rs @@ -42,7 +42,7 @@ impl SalamanderObfs { } fn encrypt(&self, data: &mut [u8]) -> Bytes { - let salt: [u8; 8] = rand::thread_rng().gen(); + let salt: [u8; 8] = rand::rng().random(); let mut res = BytesMut::with_capacity(8 + data.len()); res.put_slice(&salt); diff --git a/clash_lib/src/proxy/shadowsocks/shadow_tls/connector.rs b/clash_lib/src/proxy/shadowsocks/shadow_tls/connector.rs index 909265e04..6f3b0629f 100644 --- a/clash_lib/src/proxy/shadowsocks/shadow_tls/connector.rs +++ b/clash_lib/src/proxy/shadowsocks/shadow_tls/connector.rs @@ -2,7 +2,7 @@ use std::{io, ptr::copy_nonoverlapping, sync::Arc}; use rand::Rng; -use rand::distributions::Distribution; +use rand::distr::Distribution; use tokio::io::{AsyncReadExt, AsyncWrite, AsyncWriteExt}; use tokio_rustls::{client::TlsStream, TlsConnector}; @@ -119,7 +119,7 @@ fn generate_session_id(hmac: &Hmac, buf: &[u8]) -> [u8; TLS_SESSION_ID_SIZE] { } let mut session_id = [0; TLS_SESSION_ID_SIZE]; - rand::thread_rng().fill(&mut session_id[..TLS_SESSION_ID_SIZE - HMAC_SIZE]); + rand::rng().fill(&mut session_id[..TLS_SESSION_ID_SIZE - HMAC_SIZE]); let mut hmac = hmac.to_owned(); hmac.update(&buf[0..SESSION_ID_START]); hmac.update(&session_id); @@ -143,13 +143,13 @@ async fn fake_request( ) -> std::io::Result<()> { const HEADER: &[u8; 207] = b"GET / HTTP/1.1\nUser-Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/109.0.0.0 Safari/537.36\nAccept: gzip, deflate, br\nConnection: Close\nCookie: sessionid="; const FAKE_REQUEST_LENGTH_RANGE: (usize, usize) = (16, 64); - let cnt = rand::thread_rng() - .gen_range(FAKE_REQUEST_LENGTH_RANGE.0..FAKE_REQUEST_LENGTH_RANGE.1); + let cnt = rand::rng() + .random_range(FAKE_REQUEST_LENGTH_RANGE.0..FAKE_REQUEST_LENGTH_RANGE.1); let mut buffer = Vec::with_capacity(cnt + HEADER.len() + 1); buffer.extend_from_slice(HEADER); - rand::distributions::Alphanumeric - .sample_iter(rand::thread_rng()) + rand::distr::Alphanumeric + .sample_iter(rand::rng()) .take(cnt) .for_each(|c| buffer.push(c)); buffer.push(b'\n'); diff --git a/clash_lib/src/proxy/shadowsocks/simple_obfs/http.rs b/clash_lib/src/proxy/shadowsocks/simple_obfs/http.rs index dc09649ab..37a3b89d0 100644 --- a/clash_lib/src/proxy/shadowsocks/simple_obfs/http.rs +++ b/clash_lib/src/proxy/shadowsocks/simple_obfs/http.rs @@ -3,6 +3,7 @@ use std::pin::Pin; use crate::proxy::AnyStream; use base64::Engine; use bytes::{BufMut, BytesMut}; +use rand::Rng; use tokio::io::{AsyncRead, AsyncWrite}; #[derive(Debug)] @@ -41,8 +42,8 @@ impl AsyncWrite for HTTPObfs { buffer.put_slice( format!( "User-Agent: curl/7.{}.{}\r\n", - rand::random::() % 54, - rand::random::() % 2 + rand::rng().random_range(0..54), + rand::rng().random_range(0..2), ) .as_bytes(), ); diff --git a/clash_lib/src/proxy/transport/h2.rs b/clash_lib/src/proxy/transport/h2.rs index bcc2d0b78..1860ed698 100644 --- a/clash_lib/src/proxy/transport/h2.rs +++ b/clash_lib/src/proxy/transport/h2.rs @@ -4,7 +4,7 @@ use bytes::{Bytes, BytesMut}; use futures::ready; use h2::{RecvStream, SendStream}; use http::Request; -use rand::random; +use rand::Rng; use tokio::io::{AsyncRead, AsyncWrite}; use tracing::error; @@ -20,7 +20,7 @@ pub struct Http2Config { impl Http2Config { fn req(&self) -> std::io::Result> { - let uri_idx = random::() % self.hosts.len(); + let uri_idx = rand::rng().random_range(0..self.hosts.len()); let uri = { http::Uri::builder() .scheme("https") diff --git a/clash_lib/src/proxy/wg/device.rs b/clash_lib/src/proxy/wg/device.rs index a604a0f24..033646c70 100644 --- a/clash_lib/src/proxy/wg/device.rs +++ b/clash_lib/src/proxy/wg/device.rs @@ -8,7 +8,7 @@ use std::{ use bytes::{BufMut, Bytes, BytesMut}; use futures::{SinkExt, StreamExt}; -use rand::seq::SliceRandom; +use rand::seq::IndexedRandom; use smoltcp::{ iface::{Config, Interface, SocketHandle, SocketSet}, phy::Device, @@ -488,7 +488,7 @@ impl DeviceManager { if let Ok(ip) = domain.parse::() { ip } else { - let dns_server = self.dns_servers.choose(&mut rand::thread_rng()); + let dns_server = self.dns_servers.choose(&mut rand::rng()); if let Some(dns_server) = dns_server { let ip = self.look_up_dns(domain, *dns_server).await; if let Some(ip) = ip { diff --git a/clash_lib/src/proxy/wg/mod.rs b/clash_lib/src/proxy/wg/mod.rs index 6c028e025..4fbd22932 100644 --- a/clash_lib/src/proxy/wg/mod.rs +++ b/clash_lib/src/proxy/wg/mod.rs @@ -29,7 +29,7 @@ use async_trait::async_trait; use futures::TryFutureExt; use ipnet::IpNet; -use rand::seq::SliceRandom; +use rand::seq::IndexedRandom; use tokio::sync::OnceCell; use tracing::debug; @@ -268,7 +268,7 @@ impl OutboundHandler for Handler { .dns .as_ref() .unwrap() - .choose(&mut rand::thread_rng()) + .choose(&mut rand::rng()) .unwrap(); inner diff --git a/clash_lib/src/proxy/wg/ports.rs b/clash_lib/src/proxy/wg/ports.rs index 75499dcb6..58de412d5 100644 --- a/clash_lib/src/proxy/wg/ports.rs +++ b/clash_lib/src/proxy/wg/ports.rs @@ -1,7 +1,7 @@ use std::{collections::VecDeque, ops::Range, sync::Arc}; use anyhow::Context; -use rand::{seq::SliceRandom, thread_rng}; +use rand::seq::SliceRandom; const MIN_PORT: u16 = 1025; const MAX_PORT: u16 = 60000; @@ -24,7 +24,7 @@ impl PortPool { pub fn new() -> Self { let mut inner = TcpPortPoolInner::default(); let mut ports: Vec = PORT_RANGE.collect(); - ports.shuffle(&mut thread_rng()); + ports.shuffle(&mut rand::rng()); ports .into_iter() .for_each(|p| inner.queue.push_back(p) as ());