Skip to content

Commit

Permalink
fucking vmess
Browse files Browse the repository at this point in the history
  • Loading branch information
ibigbug committed Aug 22, 2023
1 parent 045e945 commit 1fc266e
Show file tree
Hide file tree
Showing 8 changed files with 443 additions and 433 deletions.
3 changes: 2 additions & 1 deletion .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,8 @@ jobs:
test:
strategy:
matrix:
os: [ubuntu-22.04, macos-13]
# os: [ubuntu-22.04, macos-13] linux not supported yet
os: [macos-13]
runs-on: ${{ matrix.os }}

steps:
Expand Down
3 changes: 2 additions & 1 deletion Cargo.Bazel.lock
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
{
"checksum": "c276c2878d903a25eb90b45923963b54d7fb82e6a7001b774fcbda205a49198a",
"checksum": "4c7d42924b2314ce069523e5915170a57d8303ede8bae1fcc0f5cbcfcb256e1a",
"crates": {
"addr2line 0.20.0": {
"name": "addr2line",
Expand Down Expand Up @@ -14904,6 +14904,7 @@
"common": [
"codec",
"default",
"io",
"net",
"tracing"
],
Expand Down
2 changes: 1 addition & 1 deletion clash_lib/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ default = ["shadowsocks"]

[dependencies]
tokio = { version = "1", features = ["full"] }
tokio-util = { version = "0.7", features = ["net", "codec"] }
tokio-util = { version = "0.7", features = ["net", "codec", "io"] }
tokio-rustls = "0.23.4"
thiserror = "1.0"
async-trait = "0.1"
Expand Down
17 changes: 10 additions & 7 deletions clash_lib/src/app/dispatcher.rs
Original file line number Diff line number Diff line change
Expand Up @@ -69,13 +69,16 @@ impl Dispatcher {
sess, up, down
);
}
Err(err) => {
warn!("connection {} closed with error {}", sess, err);
lhs.shutdown()
.await
.map(|x| debug!("local shutdown: {:?}", x))
.ok();
}
Err(err) => match err.kind() {
std::io::ErrorKind::UnexpectedEof
| std::io::ErrorKind::ConnectionReset
| std::io::ErrorKind::BrokenPipe => {
debug!("connection {} closed with error {}", sess, err);
}
_ => {
warn!("connection {} closed with error {}", sess, err);
}
},
}
}
Err(err) => {
Expand Down
237 changes: 0 additions & 237 deletions clash_lib/src/proxy/vmess/vmess_impl/aead.rs

This file was deleted.

97 changes: 97 additions & 0 deletions clash_lib/src/proxy/vmess/vmess_impl/cipher.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,97 @@
use aes_gcm::Aes128Gcm;
use bytes::Bytes;
use chacha20poly1305::ChaCha20Poly1305;

use crate::common::crypto::AeadCipherHelper;

pub enum VmessSecurity {
Aes128Gcm(Aes128Gcm),
ChaCha20Poly1305(ChaCha20Poly1305),
}

impl VmessSecurity {
#[inline(always)]
pub fn overhead_len(&self) -> usize {
16
}
#[inline(always)]
pub fn nonce_len(&self) -> usize {
12
}
}

pub(crate) struct AeadCipher {
pub security: VmessSecurity,
nonce: [u8; 32],
iv: Bytes,
count: u16,
}

impl AeadCipher {
pub fn new(iv: &[u8], security: VmessSecurity) -> Self {
Self {
security,
nonce: [0u8; 32],
iv: Bytes::copy_from_slice(iv),
count: 0,
}
}

pub fn decrypt_inplace(&mut self, buf: &mut [u8]) -> std::io::Result<()> {
let mut nonce = self.nonce;
let security = &self.security;
let iv = &self.iv;
let count = &mut self.count;

nonce[..2].copy_from_slice(&count.to_be_bytes());
nonce[2..12].copy_from_slice(&iv[2..12]);
*count += 1;

let nonce = &nonce[..security.nonce_len()];
match security {
VmessSecurity::Aes128Gcm(cipher) => {
let dec = cipher.decrypt_in_place_with_slice(nonce.into(), &[], &mut buf[..]);
if dec.is_err() {
return Err(std::io::Error::new(
std::io::ErrorKind::InvalidData,
dec.unwrap_err().to_string(),
));
}
}
VmessSecurity::ChaCha20Poly1305(cipher) => {
let dec = cipher.decrypt_in_place_with_slice(nonce.into(), &[], &mut buf[..]);
if dec.is_err() {
return Err(std::io::Error::new(
std::io::ErrorKind::InvalidData,
dec.unwrap_err().to_string(),
));
}
}
}

Ok(())
}

pub fn encrypt_inplace(&mut self, buf: &mut [u8]) -> std::io::Result<()> {
let mut nonce = self.nonce;
let security = &self.security;
let iv = &self.iv;
let count = &mut self.count;

nonce[..2].copy_from_slice(&count.to_be_bytes());
nonce[2..12].copy_from_slice(&iv[2..12]);
*count += 1;

let nonce = &nonce[..security.nonce_len()];
match security {
VmessSecurity::Aes128Gcm(cipher) => {
cipher.encrypt_in_place_with_slice(nonce.into(), &[], &mut buf[..]);
}
VmessSecurity::ChaCha20Poly1305(cipher) => {
cipher.encrypt_in_place_with_slice(nonce.into(), &[], &mut buf[..]);
}
}

Ok(())
}
}
Loading

0 comments on commit 1fc266e

Please sign in to comment.