Compare commits
7 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
9ce32284fb | ||
|
|
fdd4fab348 | ||
|
|
fa72ab315e | ||
|
|
b5011c6b6b | ||
|
|
da5c041c97 | ||
|
|
533dfae715 | ||
|
|
9a6f28c0bc |
@@ -1,6 +1,6 @@
|
||||
[package]
|
||||
name = "leaf-bin"
|
||||
version = "0.9.0"
|
||||
version = "0.9.2"
|
||||
authors = ["eycorsican <eric.y.corsican@gmail.com>"]
|
||||
edition = "2021"
|
||||
|
||||
|
||||
@@ -30,26 +30,28 @@ fn log_request(
|
||||
handshake_time: Option<u128>,
|
||||
) {
|
||||
let hs = handshake_time.map_or("failed".to_string(), |hs| format!("{}ms", hs));
|
||||
if !*crate::option::LOG_NO_COLOR {
|
||||
let (network, outbound_tag) = if !*crate::option::LOG_NO_COLOR {
|
||||
use colored::Colorize;
|
||||
let network_color = match sess.network {
|
||||
Network::Tcp => colored::Color::Blue,
|
||||
Network::Udp => colored::Color::Yellow,
|
||||
};
|
||||
info!(
|
||||
"[{}] [{}] [{}] [{}] {}",
|
||||
&sess.inbound_tag,
|
||||
sess.network.to_string().color(network_color),
|
||||
outbound_tag.color(*outbound_tag_color),
|
||||
hs,
|
||||
&sess.destination,
|
||||
);
|
||||
(
|
||||
sess.network.to_string().color(network_color).to_string(),
|
||||
outbound_tag.color(*outbound_tag_color).to_string(),
|
||||
)
|
||||
} else {
|
||||
info!(
|
||||
"[{}] [{}] [{}] [{}] {}",
|
||||
sess.network, &sess.inbound_tag, outbound_tag, hs, &sess.destination,
|
||||
);
|
||||
}
|
||||
(sess.network.to_string(), outbound_tag.to_string())
|
||||
};
|
||||
info!(
|
||||
"[{}] [{}] [{}] [{}] [{}] [{}]",
|
||||
sess.forwarded_source.unwrap_or_else(|| sess.source.ip()),
|
||||
network,
|
||||
&sess.inbound_tag,
|
||||
outbound_tag,
|
||||
hs,
|
||||
&sess.destination,
|
||||
);
|
||||
}
|
||||
|
||||
pub struct Dispatcher {
|
||||
|
||||
@@ -163,6 +163,22 @@ impl Counter {
|
||||
}
|
||||
}
|
||||
|
||||
#[inline]
|
||||
fn log_session_end(c: &Counter) {
|
||||
log::info!(
|
||||
"[{}] [{}] [{}] [{}] [{}] [{}] [{}] [END]",
|
||||
c.sess
|
||||
.forwarded_source
|
||||
.unwrap_or_else(|| c.sess.source.ip()),
|
||||
c.sess.network,
|
||||
c.sess.inbound_tag,
|
||||
c.sess.outbound_tag,
|
||||
c.sess.destination,
|
||||
c.bytes_sent(),
|
||||
c.bytes_recvd(),
|
||||
);
|
||||
}
|
||||
|
||||
pub struct StatManager {
|
||||
pub counters: Vec<Counter>,
|
||||
}
|
||||
@@ -182,7 +198,8 @@ impl StatManager {
|
||||
let mut i = 0;
|
||||
while i < sm.counters.len() {
|
||||
if sm.counters[i].recv_completed() && sm.counters[i].send_completed() {
|
||||
sm.counters.swap_remove(i);
|
||||
let c = sm.counters.swap_remove(i);
|
||||
log_session_end(&c);
|
||||
} else {
|
||||
i += 1;
|
||||
}
|
||||
|
||||
@@ -989,6 +989,7 @@ pub fn to_internal(conf: &mut Config) -> Result<internal::Config> {
|
||||
if let Some(ext_sni) = &ext_proxy.sni {
|
||||
quic_settings.server_name = ext_sni.clone();
|
||||
}
|
||||
quic_settings.alpn = vec!["http/1.1".to_string()];
|
||||
if let Some(ext_tls_cert) = &ext_proxy.tls_cert {
|
||||
let cert = Path::new(ext_tls_cert);
|
||||
if cert.is_absolute() {
|
||||
|
||||
@@ -96,6 +96,8 @@ impl OutboundDatagramHandler for Handler {
|
||||
|
||||
let schedule = self.schedule.lock().await.clone();
|
||||
|
||||
// Use the last resort outbound if all outbounds have failed in
|
||||
// the last health check.
|
||||
if schedule.is_empty() && self.last_resort.is_some() {
|
||||
let a = &self.last_resort.as_ref().unwrap();
|
||||
debug!(
|
||||
@@ -163,6 +165,23 @@ impl OutboundDatagramHandler for Handler {
|
||||
}
|
||||
}
|
||||
|
||||
// Use the last resort outbound if all scheduled outbounds have
|
||||
// failed.
|
||||
if let Some(a) = self.last_resort.as_ref() {
|
||||
debug!(
|
||||
"failover handles udp [{}] to last resort [{}]",
|
||||
sess.destination,
|
||||
a.tag()
|
||||
);
|
||||
return a
|
||||
.datagram()?
|
||||
.handle(
|
||||
sess,
|
||||
connect_datagram_outbound(sess, self.dns_client.clone(), a).await?,
|
||||
)
|
||||
.await;
|
||||
}
|
||||
|
||||
Err(io::Error::new(
|
||||
io::ErrorKind::Other,
|
||||
"all outbound attempts failed",
|
||||
|
||||
@@ -135,6 +135,8 @@ impl OutboundStreamHandler for Handler {
|
||||
|
||||
let schedule = self.schedule.lock().await.clone();
|
||||
|
||||
// Use the last resort outbound if all outbounds have failed in
|
||||
// the last health check.
|
||||
if schedule.is_empty() && self.last_resort.is_some() {
|
||||
let a = &self.last_resort.as_ref().unwrap();
|
||||
debug!(
|
||||
@@ -212,6 +214,21 @@ impl OutboundStreamHandler for Handler {
|
||||
}
|
||||
}
|
||||
|
||||
if let Some(a) = self.last_resort.as_ref() {
|
||||
debug!(
|
||||
"failover handles tcp [{}] to last resort [{}]",
|
||||
sess.destination,
|
||||
a.tag()
|
||||
);
|
||||
return a
|
||||
.stream()?
|
||||
.handle(
|
||||
sess,
|
||||
connect_stream_outbound(sess, self.dns_client.clone(), a).await?,
|
||||
)
|
||||
.await;
|
||||
}
|
||||
|
||||
Err(io::Error::new(
|
||||
io::ErrorKind::Other,
|
||||
"all outbound attempts failed",
|
||||
|
||||
@@ -149,7 +149,7 @@ impl Manager {
|
||||
self.dns_client
|
||||
.read()
|
||||
.await
|
||||
.lookup(&self.address)
|
||||
.direct_lookup(&self.address)
|
||||
.map_err(|e| {
|
||||
io::Error::new(
|
||||
io::ErrorKind::Other,
|
||||
|
||||
@@ -31,7 +31,7 @@ mod dangerous {
|
||||
use std::time::SystemTime;
|
||||
use tokio_rustls::rustls::{
|
||||
client::{ServerCertVerified, ServerCertVerifier},
|
||||
Certificate, ServerName,
|
||||
Certificate, Error, ServerName,
|
||||
};
|
||||
|
||||
pub(super) struct NotVerified;
|
||||
@@ -45,7 +45,7 @@ mod dangerous {
|
||||
_scts: &mut dyn Iterator<Item = &[u8]>,
|
||||
_ocsp_response: &[u8],
|
||||
_now: SystemTime,
|
||||
) -> core::result::Result<ServerCertVerified, rustls::Error> {
|
||||
) -> core::result::Result<ServerCertVerified, Error> {
|
||||
log::debug!("TLS cert for {:?} not verified", server_name);
|
||||
Ok(ServerCertVerified::assertion())
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user