-
Notifications
You must be signed in to change notification settings - Fork 64
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Signed-off-by: Yuwei Ba <[email protected]> Co-authored-by: Yuwei Ba <[email protected]>
- Loading branch information
Showing
14 changed files
with
1,563 additions
and
7,281 deletions.
There are no files selected for viewing
Large diffs are not rendered by default.
Oops, something went wrong.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,57 @@ | ||
--- | ||
port: 8891 | ||
socks-port: 8889 | ||
mixed-port: 8888 | ||
|
||
|
||
dns: | ||
enable: true | ||
listen: 127.0.0.1:53533 | ||
# ipv6: false # when the false, response to AAAA questions will be empty | ||
|
||
# These nameservers are used to resolve the DNS nameserver hostnames below. | ||
# Specify IP addresses only | ||
default-nameserver: | ||
- 114.114.114.114 | ||
- 8.8.8.8 | ||
enhanced-mode: fake-ip # or fake-ip | ||
fake-ip-range: 198.18.0.1/16 # Fake IP addresses pool CIDR | ||
# use-hosts: true # lookup hosts and return IP record | ||
|
||
# Hostnames in this list will not be resolved with fake IPs | ||
# i.e. questions to these domain names will always be answered with their | ||
# real IP addresses | ||
# fake-ip-filter: | ||
# - '*.lan' | ||
# - localhost.ptlogin2.qq.com | ||
|
||
# Supports UDP, TCP, DoT, DoH. You can specify the port to connect to. | ||
# All DNS questions are sent directly to the nameserver, without proxies | ||
# involved. Clash answers the DNS question with the first result gathered. | ||
nameserver: | ||
- 114.114.114.114 # default value | ||
- 8.8.8.8 # default value | ||
# - tls://dns.google:853 # DNS over TLS | ||
# - https://1.1.1.1/dns-query # DNS over HTTPS | ||
# - dhcp://en0 # dns from dhcp | ||
|
||
allow-lan: true | ||
mode: rule | ||
log-level: debug | ||
external-controller: 127.0.0.1:6170 | ||
experimental: | ||
ignore-resolve-fail: true | ||
|
||
proxies: | ||
- name: "local" | ||
type: hysteria2 | ||
server: 127.0.0.1 | ||
port: 10086 | ||
password: "passwd" | ||
sni: example.com | ||
skip-cert-verify: true | ||
obfs: salamander | ||
obfs-password: "obfs" | ||
|
||
rules: | ||
- MATCH, local |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,142 @@ | ||
use std::{ | ||
num::{NonZeroU16, ParseIntError}, | ||
ops::RangeInclusive, | ||
sync::Arc, | ||
}; | ||
|
||
use rand::Rng; | ||
|
||
use crate::{ | ||
config::internal::proxy::OutboundHysteria2, | ||
proxy::{ | ||
hysteria2::{Handler, HystOption}, | ||
AnyOutboundHandler, | ||
}, | ||
session::SocksAddr, | ||
}; | ||
#[derive(Clone)] | ||
pub struct PortGenrateor { | ||
// must have a default port | ||
pub default: u16, | ||
ports: Vec<u16>, | ||
range: Vec<RangeInclusive<u16>>, | ||
} | ||
|
||
impl PortGenrateor { | ||
pub fn new(port: u16) -> Self { | ||
PortGenrateor { | ||
default: port, | ||
ports: vec![], | ||
range: vec![], | ||
} | ||
} | ||
|
||
pub fn add_single(&mut self, port: u16) { | ||
self.ports.push(port); | ||
} | ||
|
||
fn add_range(&mut self, start: u16, end: u16) { | ||
self.range.push(start..=end); | ||
} | ||
|
||
pub fn get(&self) -> u16 { | ||
let mut rng = rand::thread_rng(); | ||
let len = | ||
1 + self.ports.len() + self.range.iter().map(|r| r.len()).sum::<usize>(); | ||
let idx = rng.gen_range(0..len); | ||
match idx { | ||
0 => self.default, | ||
idx if idx <= self.ports.len() => self.ports[idx - 1], | ||
idx => { | ||
let mut x = self.range.iter().cloned().flatten(); | ||
x.nth(idx - 1 - self.ports.len()).unwrap() | ||
} | ||
} | ||
} | ||
|
||
pub fn parse_ports_str(self, ports: &str) -> Result<Self, ParseIntError> { | ||
if ports.is_empty() { | ||
return Ok(self); | ||
} | ||
ports | ||
.split(',') | ||
.map(|s| s.trim()) | ||
.try_fold(self, |mut acc, ports| { | ||
let x: Result<_, ParseIntError> = ports | ||
.parse::<u16>() | ||
.map(|p| acc.add_single(p)) | ||
.or_else(|e| { | ||
let mut iter = ports.split('-'); | ||
let start = iter.next().ok_or(e.clone())?; | ||
let end = iter.next().ok_or(e)?; | ||
let start = start.parse::<NonZeroU16>()?; | ||
let end = end.parse::<NonZeroU16>()?; | ||
acc.add_range(start.get(), end.get()); | ||
Ok(()) | ||
}) | ||
.map(|_| acc); | ||
x | ||
}) | ||
} | ||
} | ||
|
||
impl TryFrom<OutboundHysteria2> for AnyOutboundHandler { | ||
type Error = crate::Error; | ||
|
||
fn try_from(value: OutboundHysteria2) -> Result<Self, Self::Error> { | ||
let addr = SocksAddr::try_from((value.server, value.port))?; | ||
let obfs_passwd = match value.obfs { | ||
Some(_) => value | ||
.obfs_password | ||
.ok_or(crate::Error::InvalidConfig( | ||
"hysteria2 found obfs enable, but obfs password is none" | ||
.to_owned(), | ||
))? | ||
.into(), | ||
None => None, | ||
}; | ||
|
||
let ports_gen = if let Some(ports) = value.ports { | ||
Some( | ||
PortGenrateor::new(value.port) | ||
.parse_ports_str(&ports) | ||
.map_err(|e| { | ||
crate::Error::InvalidConfig(format!( | ||
"hysteria2 parse ports error: {:?}, ports: {:?}", | ||
e, ports | ||
)) | ||
})?, | ||
) | ||
} else { | ||
None | ||
}; | ||
let opts = HystOption { | ||
name: value.name, | ||
sni: value.sni.or(addr.domain().map(|s| s.to_owned())), | ||
addr, | ||
alpn: value.alpn.unwrap_or_default(), | ||
ca: value.ca.map(|s| s.into()), | ||
fingerprint: value.fingerprint, | ||
skip_cert_verify: value.skip_cert_verify, | ||
passwd: value.password, | ||
ports: ports_gen, | ||
salamander: obfs_passwd, | ||
up_down: value.up.zip(value.down), | ||
ca_str: value.ca_str, | ||
cwnd: value.cwnd, | ||
}; | ||
|
||
let c = Handler::new(opts).unwrap(); | ||
Ok(Arc::new(c)) | ||
} | ||
} | ||
|
||
#[test] | ||
fn test_port_gen() { | ||
let p = PortGenrateor::new(1000).parse_ports_str("").unwrap(); | ||
let p = p.parse_ports_str("1001,1002,1003, 5000-5001").unwrap(); | ||
|
||
for _ in 0..100 { | ||
println!("{}", p.get()); | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,3 +1,4 @@ | ||
pub mod hysteria2; | ||
#[cfg(feature = "shadowsocks")] | ||
pub mod shadowsocks; | ||
pub mod socks5; | ||
|
Oops, something went wrong.