merge from dev

This commit is contained in:
clowwindy 2012-12-30 15:29:54 +08:00
commit 6763a94a1d
3 changed files with 77 additions and 14 deletions

View file

@ -1,6 +1,8 @@
shadowsocks shadowsocks
=========== ===========
Current version: 0.9
shadowsocks is a lightweight tunnel proxy which can help you get through firewalls shadowsocks is a lightweight tunnel proxy which can help you get through firewalls
usage usage
@ -11,6 +13,7 @@ First, make sure you have Python 2.6 or 2.7.
$ python --version $ python --version
Python 2.6.8 Python 2.6.8
Then edit `config.json`, change the following values: Then edit `config.json`, change the following values:
server your server ip or hostname server your server ip or hostname
@ -35,6 +38,13 @@ You can use args to override settings from `config.json`.
python local.py -s server_name -p server_port -l local_port -k password python local.py -s server_name -p server_port -l local_port -k password
python server.py -p server_port -k password python server.py -p server_port -k password
You may want to install gevent for better performance.
$ apt-get install python-gevent
Or:
$ sudo easy_install gevent
troubleshooting troubleshooting
--------------- ---------------

View file

@ -20,6 +20,14 @@
# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
# SOFTWARE. # SOFTWARE.
import sys
try:
import gevent, gevent.monkey
gevent.monkey.patch_all(dns=gevent.version_info[0]>=1)
except ImportError:
gevent = None
print >>sys.stderr, 'warning: gevent not found, using threading instead'
import socket import socket
import select import select
@ -27,7 +35,6 @@ import SocketServer
import struct import struct
import string import string
import hashlib import hashlib
import sys
import os import os
import json import json
import logging import logging
@ -43,9 +50,18 @@ def get_table(key):
table.sort(lambda x, y: int(a % (ord(x) + i) - a % (ord(y) + i))) table.sort(lambda x, y: int(a % (ord(x) + i) - a % (ord(y) + i)))
return table return table
def send_all(sock, data):
bytes_sent = 0
while True:
r = sock.send(data[bytes_sent:])
if r < 0:
return r
bytes_sent += r
if bytes_sent == len(data):
return bytes_sent
class ThreadingTCPServer(SocketServer.ThreadingMixIn, SocketServer.TCPServer): class ThreadingTCPServer(SocketServer.ThreadingMixIn, SocketServer.TCPServer):
pass allow_reuse_address = True
class Socks5Server(SocketServer.StreamRequestHandler): class Socks5Server(SocketServer.StreamRequestHandler):
@ -55,11 +71,20 @@ class Socks5Server(SocketServer.StreamRequestHandler):
while True: while True:
r, w, e = select.select(fdset, [], []) r, w, e = select.select(fdset, [], [])
if sock in r: if sock in r:
if remote.send(self.encrypt(sock.recv(4096))) <= 0: data = sock.recv(4096)
if len(data) <= 0:
break break
result = send_all(remote, self.encrypt(data))
if result < len(data):
raise Exception('failed to send all data')
if remote in r: if remote in r:
if sock.send(self.decrypt(remote.recv(4096))) <= 0: data = remote.recv(4096)
if len(data) <= 0:
break break
result = send_all(sock, self.decrypt(data))
if result < len(data):
raise Exception('failed to send all data')
finally: finally:
sock.close() sock.close()
remote.close() remote.close()
@ -90,7 +115,7 @@ class Socks5Server(SocketServer.StreamRequestHandler):
addr = socket.inet_ntoa(addr_ip) addr = socket.inet_ntoa(addr_ip)
addr_to_send += addr_ip addr_to_send += addr_ip
elif addrtype == 3: elif addrtype == 3:
addr_len = sock.recv(1) addr_len = self.rfile.read(1)
addr = self.rfile.read(ord(addr_len)) addr = self.rfile.read(ord(addr_len))
addr_to_send += addr_len + addr addr_to_send += addr_len + addr
else: else:
@ -103,12 +128,13 @@ class Socks5Server(SocketServer.StreamRequestHandler):
try: try:
reply = "\x05\x00\x00\x01" reply = "\x05\x00\x00\x01"
reply += socket.inet_aton('0.0.0.0') + struct.pack(">H", 2222) reply += socket.inet_aton('0.0.0.0') + struct.pack(">H", 2222)
sock.send(reply) self.wfile.write(reply)
# reply immediately # reply immediately
if '-6' in sys.argv[1:]: if '-6' in sys.argv[1:]:
remote = socket.socket(socket.AF_INET6, socket.SOCK_STREAM) remote = socket.socket(socket.AF_INET6, socket.SOCK_STREAM)
else: else:
remote = socket.socket(socket.AF_INET, socket.SOCK_STREAM) remote = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
remote.setsockopt(socket.IPPROTO_TCP, socket.TCP_NODELAY, 1)
remote.connect((SERVER, REMOTE_PORT)) remote.connect((SERVER, REMOTE_PORT))
self.send_encrypt(remote, addr_to_send) self.send_encrypt(remote, addr_to_send)
logging.info('connecting %s:%d' % (addr, port[0])) logging.info('connecting %s:%d' % (addr, port[0]))
@ -122,6 +148,7 @@ class Socks5Server(SocketServer.StreamRequestHandler):
if __name__ == '__main__': if __name__ == '__main__':
os.chdir(os.path.dirname(__file__) or '.') os.chdir(os.path.dirname(__file__) or '.')
print 'shadowsocks v0.9'
with open('config.json', 'rb') as f: with open('config.json', 'rb') as f:
config = json.load(f) config = json.load(f)
@ -148,7 +175,6 @@ if __name__ == '__main__':
decrypt_table = string.maketrans(encrypt_table, string.maketrans('', '')) decrypt_table = string.maketrans(encrypt_table, string.maketrans('', ''))
try: try:
server = ThreadingTCPServer(('', PORT), Socks5Server) server = ThreadingTCPServer(('', PORT), Socks5Server)
server.allow_reuse_address = True
logging.info("starting server at port %d ..." % PORT) logging.info("starting server at port %d ..." % PORT)
server.serve_forever() server.serve_forever()
except socket.error, e: except socket.error, e:

View file

@ -20,6 +20,14 @@
# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
# SOFTWARE. # SOFTWARE.
import sys
try:
import gevent, gevent.monkey
gevent.monkey.patch_all(dns=gevent.version_info[0]>=1)
except ImportError:
gevent = None
print >>sys.stderr, 'warning: gevent not found, using threading instead'
import socket import socket
import select import select
@ -27,7 +35,6 @@ import SocketServer
import struct import struct
import string import string
import hashlib import hashlib
import sys
import os import os
import json import json
import logging import logging
@ -43,9 +50,18 @@ def get_table(key):
table.sort(lambda x, y: int(a % (ord(x) + i) - a % (ord(y) + i))) table.sort(lambda x, y: int(a % (ord(x) + i) - a % (ord(y) + i)))
return table return table
def send_all(sock, data):
bytes_sent = 0
while True:
r = sock.send(data[bytes_sent:])
if r < 0:
return r
bytes_sent += r
if bytes_sent == len(data):
return bytes_sent
class ThreadingTCPServer(SocketServer.ThreadingMixIn, SocketServer.TCPServer): class ThreadingTCPServer(SocketServer.ThreadingMixIn, SocketServer.TCPServer):
pass allow_reuse_address = True
class Socks5Server(SocketServer.StreamRequestHandler): class Socks5Server(SocketServer.StreamRequestHandler):
@ -55,11 +71,20 @@ class Socks5Server(SocketServer.StreamRequestHandler):
while True: while True:
r, w, e = select.select(fdset, [], []) r, w, e = select.select(fdset, [], [])
if sock in r: if sock in r:
if remote.send(self.decrypt(sock.recv(4096))) <= 0: data = sock.recv(4096)
if len(data) <= 0:
break break
result = send_all(remote, self.decrypt(data))
if result < len(data):
raise Exception('failed to send all data')
if remote in r: if remote in r:
if sock.send(self.encrypt(remote.recv(4096))) <= 0: data = remote.recv(4096)
if len(data) <= 0:
break break
result = send_all(sock, self.encrypt(data))
if result < len(data):
raise Exception('failed to send all data')
finally: finally:
sock.close() sock.close()
remote.close() remote.close()
@ -87,6 +112,7 @@ class Socks5Server(SocketServer.StreamRequestHandler):
try: try:
logging.info('connecting %s:%d' % (addr, port[0])) logging.info('connecting %s:%d' % (addr, port[0]))
remote = socket.socket(socket.AF_INET, socket.SOCK_STREAM) remote = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
remote.setsockopt(socket.IPPROTO_TCP, socket.TCP_NODELAY, 1)
remote.connect((addr, port[0])) remote.connect((addr, port[0]))
except socket.error, e: except socket.error, e:
# Connection refused # Connection refused
@ -99,6 +125,8 @@ class Socks5Server(SocketServer.StreamRequestHandler):
if __name__ == '__main__': if __name__ == '__main__':
os.chdir(os.path.dirname(__file__) or '.') os.chdir(os.path.dirname(__file__) or '.')
print 'shadowsocks v0.9'
with open('config.json', 'rb') as f: with open('config.json', 'rb') as f:
config = json.load(f) config = json.load(f)
@ -122,7 +150,6 @@ if __name__ == '__main__':
ThreadingTCPServer.address_family = socket.AF_INET6 ThreadingTCPServer.address_family = socket.AF_INET6
try: try:
server = ThreadingTCPServer(('', PORT), Socks5Server) server = ThreadingTCPServer(('', PORT), Socks5Server)
server.allow_reuse_address = True
logging.info("starting server at port %d ..." % PORT) logging.info("starting server at port %d ..." % PORT)
server.serve_forever() server.serve_forever()
except socket.error, e: except socket.error, e: