commit
e18abb4008
8 changed files with 81 additions and 27 deletions
|
@ -10,7 +10,7 @@ cache:
|
||||||
before_install:
|
before_install:
|
||||||
- sudo apt-get update -qq
|
- sudo apt-get update -qq
|
||||||
- sudo apt-get install -qq build-essential dnsutils iproute nginx bc
|
- sudo apt-get install -qq build-essential dnsutils iproute nginx bc
|
||||||
- sudo dd if=/dev/urandom of=/usr/share/nginx/www/file bs=1M count=10
|
- sudo dd if=/dev/urandom of=/usr/share/nginx/html/file bs=1M count=10
|
||||||
- sudo sh -c "echo '127.0.0.1 localhost' > /etc/hosts"
|
- sudo sh -c "echo '127.0.0.1 localhost' > /etc/hosts"
|
||||||
- sudo service nginx restart
|
- sudo service nginx restart
|
||||||
- pip install pep8 pyflakes nose coverage PySocks
|
- pip install pep8 pyflakes nose coverage PySocks
|
||||||
|
|
11
README.md
11
README.md
|
@ -28,6 +28,10 @@ CentOS:
|
||||||
yum install python-setuptools && easy_install pip
|
yum install python-setuptools && easy_install pip
|
||||||
pip install git+https://github.com/shadowsocks/shadowsocks.git@master
|
pip install git+https://github.com/shadowsocks/shadowsocks.git@master
|
||||||
|
|
||||||
|
Linux distributions with [snap](http://snapcraft.io/):
|
||||||
|
|
||||||
|
snap install shadowsocks
|
||||||
|
|
||||||
Windows:
|
Windows:
|
||||||
|
|
||||||
See [Install Shadowsocks Server on Windows](https://github.com/shadowsocks/shadowsocks/wiki/Install-Shadowsocks-Server-on-Windows).
|
See [Install Shadowsocks Server on Windows](https://github.com/shadowsocks/shadowsocks/wiki/Install-Shadowsocks-Server-on-Windows).
|
||||||
|
@ -51,9 +55,14 @@ To check the log:
|
||||||
Check all the options via `-h`. You can also use a [Configuration] file
|
Check all the options via `-h`. You can also use a [Configuration] file
|
||||||
instead.
|
instead.
|
||||||
|
|
||||||
|
If you installed the [snap](http://snapcraft.io/) package, you have to prefix the commands with `shadowsocks.`,
|
||||||
|
like this:
|
||||||
|
|
||||||
|
shadowsocks.ssserver -p 443 -k password -m aes-256-cfb
|
||||||
|
|
||||||
### Usage with Config File
|
### Usage with Config File
|
||||||
|
|
||||||
[Create configeration file and run](https://github.com/shadowsocks/shadowsocks/wiki/Configuration-via-Config-File)
|
[Create configuration file and run](https://github.com/shadowsocks/shadowsocks/wiki/Configuration-via-Config-File)
|
||||||
|
|
||||||
To start:
|
To start:
|
||||||
|
|
||||||
|
|
|
@ -155,9 +155,6 @@ class AeadCryptoBase(object):
|
||||||
# n, n > 0, waiting data
|
# n, n > 0, waiting data
|
||||||
self._chunk = {'mlen': AEAD_MSG_LEN_UNKNOWN, 'data': b''}
|
self._chunk = {'mlen': AEAD_MSG_LEN_UNKNOWN, 'data': b''}
|
||||||
|
|
||||||
self.encrypt_once = self.aead_encrypt
|
|
||||||
self.decrypt_once = self.aead_decrypt
|
|
||||||
|
|
||||||
# load libsodium for nonce increment
|
# load libsodium for nonce increment
|
||||||
if not sodium_loaded:
|
if not sodium_loaded:
|
||||||
crypto_path = dict(crypto_path) if crypto_path else dict()
|
crypto_path = dict(crypto_path) if crypto_path else dict()
|
||||||
|
|
|
@ -107,8 +107,11 @@ class OpenSSLCryptoBase(object):
|
||||||
if not self._ctx:
|
if not self._ctx:
|
||||||
raise Exception('can not create cipher context')
|
raise Exception('can not create cipher context')
|
||||||
|
|
||||||
self.encrypt_once = self.update
|
def encrypt_once(self, data):
|
||||||
self.decrypt_once = self.update
|
return self.update(data)
|
||||||
|
|
||||||
|
def decrypt_once(self, data):
|
||||||
|
return self.update(data)
|
||||||
|
|
||||||
def update(self, data):
|
def update(self, data):
|
||||||
"""
|
"""
|
||||||
|
@ -136,6 +139,7 @@ class OpenSSLCryptoBase(object):
|
||||||
if self._ctx:
|
if self._ctx:
|
||||||
ctx_cleanup(self._ctx)
|
ctx_cleanup(self._ctx)
|
||||||
libcrypto.EVP_CIPHER_CTX_free(self._ctx)
|
libcrypto.EVP_CIPHER_CTX_free(self._ctx)
|
||||||
|
self._ctx = None
|
||||||
|
|
||||||
|
|
||||||
class OpenSSLAeadCrypto(OpenSSLCryptoBase, AeadCryptoBase):
|
class OpenSSLAeadCrypto(OpenSSLCryptoBase, AeadCryptoBase):
|
||||||
|
@ -267,6 +271,12 @@ class OpenSSLAeadCrypto(OpenSSLCryptoBase, AeadCryptoBase):
|
||||||
self.cipher_ctx_init()
|
self.cipher_ctx_init()
|
||||||
return plaintext
|
return plaintext
|
||||||
|
|
||||||
|
def encrypt_once(self, data):
|
||||||
|
return self.aead_encrypt(data)
|
||||||
|
|
||||||
|
def decrypt_once(self, data):
|
||||||
|
return self.aead_decrypt(data)
|
||||||
|
|
||||||
|
|
||||||
class OpenSSLStreamCrypto(OpenSSLCryptoBase):
|
class OpenSSLStreamCrypto(OpenSSLCryptoBase):
|
||||||
"""
|
"""
|
||||||
|
@ -281,8 +291,12 @@ class OpenSSLStreamCrypto(OpenSSLCryptoBase):
|
||||||
if not r:
|
if not r:
|
||||||
self.clean()
|
self.clean()
|
||||||
raise Exception('can not initialize cipher context')
|
raise Exception('can not initialize cipher context')
|
||||||
self.encrypt = self.update
|
|
||||||
self.decrypt = self.update
|
def encrypt(self, data):
|
||||||
|
return self.update(data)
|
||||||
|
|
||||||
|
def decrypt(self, data):
|
||||||
|
return self.update(data)
|
||||||
|
|
||||||
|
|
||||||
ciphers = {
|
ciphers = {
|
||||||
|
|
|
@ -192,10 +192,18 @@ class SodiumCrypto(object):
|
||||||
raise Exception('Unknown cipher')
|
raise Exception('Unknown cipher')
|
||||||
# byte counter, not block counter
|
# byte counter, not block counter
|
||||||
self.counter = 0
|
self.counter = 0
|
||||||
self.encrypt = self.update
|
|
||||||
self.decrypt = self.update
|
def encrypt(self, data):
|
||||||
self.encrypt_once = self.update
|
return self.update(data)
|
||||||
self.decrypt_once = self.update
|
|
||||||
|
def decrypt(self, data):
|
||||||
|
return self.update(data)
|
||||||
|
|
||||||
|
def encrypt_once(self, data):
|
||||||
|
return self.update(data)
|
||||||
|
|
||||||
|
def decrypt_once(self, data):
|
||||||
|
return self.update(data)
|
||||||
|
|
||||||
def update(self, data):
|
def update(self, data):
|
||||||
global buf_size, buf
|
global buf_size, buf
|
||||||
|
@ -300,6 +308,12 @@ class SodiumAeadCrypto(AeadCryptoBase):
|
||||||
self.cipher_ctx_init()
|
self.cipher_ctx_init()
|
||||||
return buf.raw[:cipher_out_len.value]
|
return buf.raw[:cipher_out_len.value]
|
||||||
|
|
||||||
|
def encrypt_once(self, data):
|
||||||
|
return self.aead_encrypt(data)
|
||||||
|
|
||||||
|
def decrypt_once(self, data):
|
||||||
|
return self.aead_decrypt(data)
|
||||||
|
|
||||||
|
|
||||||
ciphers = {
|
ciphers = {
|
||||||
'salsa20': (32, 8, SodiumCrypto),
|
'salsa20': (32, 8, SodiumCrypto),
|
||||||
|
|
|
@ -79,18 +79,15 @@ class LRUCache(collections.MutableMapping):
|
||||||
least = self._last_visits[0]
|
least = self._last_visits[0]
|
||||||
if now - least <= self.timeout:
|
if now - least <= self.timeout:
|
||||||
break
|
break
|
||||||
if self.close_callback is not None:
|
|
||||||
for key in self._time_to_keys[least]:
|
|
||||||
if key in self._store:
|
|
||||||
if now - self._keys_to_last_time[key] > self.timeout:
|
|
||||||
value = self._store[key]
|
|
||||||
if value not in self._closed_values:
|
|
||||||
self.close_callback(value)
|
|
||||||
self._closed_values.add(value)
|
|
||||||
self._last_visits.popleft()
|
self._last_visits.popleft()
|
||||||
for key in self._time_to_keys[least]:
|
for key in self._time_to_keys[least]:
|
||||||
if key in self._store:
|
if key in self._store:
|
||||||
if now - self._keys_to_last_time[key] > self.timeout:
|
if now - self._keys_to_last_time[key] > self.timeout:
|
||||||
|
if self.close_callback is not None:
|
||||||
|
value = self._store[key]
|
||||||
|
if value not in self._closed_values:
|
||||||
|
self.close_callback(value)
|
||||||
|
self._closed_values.add(value)
|
||||||
del self._store[key]
|
del self._store[key]
|
||||||
del self._keys_to_last_time[key]
|
del self._keys_to_last_time[key]
|
||||||
c += 1
|
c += 1
|
||||||
|
@ -140,6 +137,7 @@ def test():
|
||||||
|
|
||||||
c = LRUCache(timeout=0.1, close_callback=close_cb)
|
c = LRUCache(timeout=0.1, close_callback=close_cb)
|
||||||
c['s'] = 1
|
c['s'] = 1
|
||||||
|
c['t'] = 1
|
||||||
c['s']
|
c['s']
|
||||||
time.sleep(0.1)
|
time.sleep(0.1)
|
||||||
c['s']
|
c['s']
|
||||||
|
|
23
snapcraft.yaml
Normal file
23
snapcraft.yaml
Normal file
|
@ -0,0 +1,23 @@
|
||||||
|
name: shadowsocks
|
||||||
|
version: 2.9.1-1
|
||||||
|
summary: A fast tunnel proxy that helps you bypass firewalls
|
||||||
|
description: A fast tunnel proxy that helps you bypass firewalls
|
||||||
|
confinement: strict
|
||||||
|
grade: stable
|
||||||
|
|
||||||
|
apps:
|
||||||
|
sslocal:
|
||||||
|
command: bin/sslocal
|
||||||
|
plugs: [network, network-bind]
|
||||||
|
aliases: [sslocal]
|
||||||
|
|
||||||
|
ssserver:
|
||||||
|
command: bin/ssserver
|
||||||
|
plugs: [network, network-bind]
|
||||||
|
aliases: [ssserver]
|
||||||
|
|
||||||
|
parts:
|
||||||
|
shadowsocks:
|
||||||
|
plugin: python
|
||||||
|
python-version: python2
|
||||||
|
source: https://github.com/shadowsocks/shadowsocks/archive/2.9.1.tar.gz
|
|
@ -102,11 +102,10 @@ fi
|
||||||
run_test tests/test_udp_src.sh
|
run_test tests/test_udp_src.sh
|
||||||
run_test tests/test_command.sh
|
run_test tests/test_command.sh
|
||||||
|
|
||||||
coverage combine && coverage report --include=shadowsocks/*
|
# coverage combine && coverage report --include=shadowsocks/*
|
||||||
rm -rf htmlcov
|
# rm -rf htmlcov
|
||||||
rm -rf tmp
|
# rm -rf tmp
|
||||||
coverage html --include=shadowsocks/*
|
# coverage html --include=shadowsocks/*
|
||||||
|
# coverage report --include=shadowsocks/* | tail -n1 | rev | cut -d' ' -f 1 | rev > /tmp/shadowsocks-coverage
|
||||||
coverage report --include=shadowsocks/* | tail -n1 | rev | cut -d' ' -f 1 | rev > /tmp/shadowsocks-coverage
|
|
||||||
|
|
||||||
exit $result
|
exit $result
|
||||||
|
|
Loading…
Reference in a new issue