diff --git a/README.md b/README.md
index 63d8fac7..432e45d1 100644
--- a/README.md
+++ b/README.md
@@ -1,6 +1,7 @@
# shadowsocks-rust
[](https://travis-ci.org/zonyitoo/shadowsocks-rust)
+[](https://ci.appveyor.com/project/zonyitoo/shadowsocks-rust)
[](https://github.com/zonyitoo/shadowsocks-rust)
[](https://crates.io/crates/shadowsocks-rust)
@@ -8,8 +9,6 @@ This is a port of [shadowsocks](https://github.com/shadowsocks/shadowsocks).
shadowsocks is a fast tunnel proxy that helps you bypass firewalls.
-It is **unstable**! If you encounter any problems, please open an issue.
-
## Dependencies
* libcrypto (OpenSSL)
@@ -34,12 +33,6 @@ cargo build
Then `sslocal` and `ssserver` will appear in `./target`, it works similarly as the two binaries in
the official ShadowSocks' implementation.
-Enable more crypto algorithms by passing the name `cipher-[name]` via command line argument `--features`
-
-```bash
-cargo build --features "cipher-aes-ctr"
-```
-
Read `Cargo.toml` for more details.
## Getting Started
diff --git a/src/crypto/aead.rs b/src/crypto/aead.rs
index 675783c0..af0a09ba 100644
--- a/src/crypto/aead.rs
+++ b/src/crypto/aead.rs
@@ -29,11 +29,15 @@ use rust_crypto::hkdf::{hkdf_expand, hkdf_extract};
use rust_crypto::sha1::Sha1;
use rust_crypto::digest::Digest;
+/// Encryptor API for AEAD ciphers
pub trait AeadEncryptor {
+ /// Encrypt `input` to `output` with `tag`. `output.len()` should equals to `input.len()`.
fn encrypt(&mut self, input: &[u8], output: &mut [u8], tag: &mut [u8]);
}
+/// Decryptor API for AEAD ciphers
pub trait AeadDecryptor {
+ /// Decrypt `input` to `output` with `tag`. `output.len()` should equals to `input.len()`.
fn decrypt(&mut self, input: &[u8], output: &mut [u8], tag: &[u8]) -> CipherResult<()>;
}
@@ -65,6 +69,33 @@ pub fn new_aead_decryptor(t: CipherType, key: &[u8], nounce: &[u8]) -> Box Vec {
assert!(t.category() == CipherCategory::Aead);
diff --git a/src/crypto/cipher.rs b/src/crypto/cipher.rs
index 94301ebc..55d27151 100644
--- a/src/crypto/cipher.rs
+++ b/src/crypto/cipher.rs
@@ -135,9 +135,12 @@ pub enum CipherType {
Aes256Gcm,
}
+/// Category of ciphers
#[derive(Debug, Copy, Clone, Eq, PartialEq)]
pub enum CipherCategory {
+ /// Stream ciphers is used for OLD ShadowSocks protocol, which uses stream ciphers to encrypt data payloads
Stream,
+ /// AEAD ciphers is used in modern ShadowSocks protocol, which sends data in separate packets
Aead,
}
diff --git a/src/crypto/crypto.rs b/src/crypto/crypto.rs
index bc341d2e..6d4e9711 100644
--- a/src/crypto/crypto.rs
+++ b/src/crypto/crypto.rs
@@ -73,10 +73,14 @@ impl StreamCipher for CryptoCipher {
}
}
+/// AEAD ciphers provided by Rust-Crypto
pub enum CryptoAeadCryptoVariant {
AesGcm(AesGcm<'static>),
}
+/// AEAD Cipher context
+///
+/// According to SIP004, the `nounce` has to incr 1 after each encrypt/decrypt.
pub struct CryptoAeadCrypto {
cipher: CryptoAeadCryptoVariant,
cipher_type: CipherType,
@@ -85,6 +89,7 @@ pub struct CryptoAeadCrypto {
}
impl CryptoAeadCrypto {
+ /// Initialize context
pub fn new(t: CipherType, key: &[u8], salt: &[u8]) -> CryptoAeadCrypto {
// TODO: Check if salt is duplicated
diff --git a/src/relay/tcprelay/crypto_io.rs b/src/relay/tcprelay/crypto_io.rs
index 4001bdb5..b717aaa6 100644
--- a/src/relay/tcprelay/crypto_io.rs
+++ b/src/relay/tcprelay/crypto_io.rs
@@ -12,6 +12,10 @@ use tokio_core::io::{copy, Copy};
use super::BUFFER_SIZE;
use super::utils::{copy_timeout, copy_timeout_opt, CopyTimeout, CopyTimeoutOpt};
+/// Reader to read data from ShadowSocks protocol
+///
+/// This trait requires `BufRead`, because obviously this reader has to contain a buffer inside,
+/// which stores the decrypted data.
pub trait DecryptedRead: BufRead {
/// Copies all data to `w`
fn copy(self, w: W) -> Copy
@@ -38,8 +42,12 @@ pub trait DecryptedRead: BufRead {
}
}
+/// Writer that encrypt data and write it as ShadowSocks protocol
+///
+/// The writer cannot implement `io::Write`, because you cannot ensure that you can write all the data in a batch
+/// in non-blocking I/O environment.
pub trait EncryptedWrite {
- /// Writes raw bytes directly to the writer directly
+ /// Writes raw bytes directly to the writer
fn write_raw(&mut self, data: &[u8]) -> io::Result;
/// Flush the writer
fn flush(&mut self) -> io::Result<()>;