|
@ -40,6 +40,8 @@ import select |
|
|
import SocketServer |
|
|
import SocketServer |
|
|
import struct |
|
|
import struct |
|
|
import os |
|
|
import os |
|
|
|
|
|
import random |
|
|
|
|
|
import re |
|
|
import logging |
|
|
import logging |
|
|
import getopt |
|
|
import getopt |
|
|
import encrypt |
|
|
import encrypt |
|
@ -62,6 +64,24 @@ class ThreadingTCPServer(SocketServer.ThreadingMixIn, SocketServer.TCPServer): |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
class Socks5Server(SocketServer.StreamRequestHandler): |
|
|
class Socks5Server(SocketServer.StreamRequestHandler): |
|
|
|
|
|
def getServer(self): |
|
|
|
|
|
aPort = REMOTE_PORT |
|
|
|
|
|
aServer = SERVER |
|
|
|
|
|
if isinstance(REMOTE_PORT, list): |
|
|
|
|
|
# support config like "server_port": [8081, 8082] |
|
|
|
|
|
aPort = random.choice(REMOTE_PORT) |
|
|
|
|
|
if isinstance(SERVER, list): |
|
|
|
|
|
# support config like "server": ["123.123.123.1", "123.123.123.2"] |
|
|
|
|
|
aServer = random.choice(SERVER) |
|
|
|
|
|
|
|
|
|
|
|
r = re.match(r'^(.*)\:(\d+)$', aServer) |
|
|
|
|
|
if r: |
|
|
|
|
|
# support config like "server": "123.123.123.1:8381" |
|
|
|
|
|
# or "server": ["123.123.123.1:8381", "123.123.123.2:8381", "123.123.123.2:8382"] |
|
|
|
|
|
aServer = r.group(1) |
|
|
|
|
|
aPort = int(r.group(2)) |
|
|
|
|
|
return (aServer, aPort) |
|
|
|
|
|
|
|
|
def handle_tcp(self, sock, remote): |
|
|
def handle_tcp(self, sock, remote): |
|
|
try: |
|
|
try: |
|
|
fdset = [sock, remote] |
|
|
fdset = [sock, remote] |
|
@ -132,7 +152,8 @@ class Socks5Server(SocketServer.StreamRequestHandler): |
|
|
reply += socket.inet_aton('0.0.0.0') + struct.pack(">H", 2222) |
|
|
reply += socket.inet_aton('0.0.0.0') + struct.pack(">H", 2222) |
|
|
self.wfile.write(reply) |
|
|
self.wfile.write(reply) |
|
|
# reply immediately |
|
|
# reply immediately |
|
|
remote = socket.create_connection((SERVER, REMOTE_PORT)) |
|
|
aServer, aPort = self.getServer() |
|
|
|
|
|
remote = socket.create_connection((aServer, aPort)) |
|
|
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])) |
|
|
except socket.error, e: |
|
|
except socket.error, e: |
|
@ -144,8 +165,8 @@ class Socks5Server(SocketServer.StreamRequestHandler): |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
def main(): |
|
|
def main(): |
|
|
global SERVER, REMOTE_PORT, PORT, KEY, METHOD, LOCAL, IPv6 |
|
|
global SERVER, REMOTE_PORT, KEY, METHOD |
|
|
|
|
|
|
|
|
logging.basicConfig(level=logging.DEBUG, |
|
|
logging.basicConfig(level=logging.DEBUG, |
|
|
format='%(asctime)s %(levelname)-8s %(message)s', |
|
|
format='%(asctime)s %(levelname)-8s %(message)s', |
|
|
datefmt='%Y-%m-%d %H:%M:%S', filemode='a+') |
|
|
datefmt='%Y-%m-%d %H:%M:%S', filemode='a+') |
|
@ -167,7 +188,7 @@ def main(): |
|
|
METHOD = None |
|
|
METHOD = None |
|
|
LOCAL = '' |
|
|
LOCAL = '' |
|
|
IPv6 = False |
|
|
IPv6 = False |
|
|
|
|
|
|
|
|
config_path = utils.find_config() |
|
|
config_path = utils.find_config() |
|
|
optlist, args = getopt.getopt(sys.argv[1:], 's:b:p:k:l:m:c:6') |
|
|
optlist, args = getopt.getopt(sys.argv[1:], 's:b:p:k:l:m:c:6') |
|
|
for key, value in optlist: |
|
|
for key, value in optlist: |
|
@ -209,7 +230,7 @@ def main(): |
|
|
sys.exit('config not specified, please read https://github.com/clowwindy/shadowsocks') |
|
|
sys.exit('config not specified, please read https://github.com/clowwindy/shadowsocks') |
|
|
|
|
|
|
|
|
utils.check_config(config) |
|
|
utils.check_config(config) |
|
|
|
|
|
|
|
|
encrypt.init_table(KEY, METHOD) |
|
|
encrypt.init_table(KEY, METHOD) |
|
|
|
|
|
|
|
|
try: |
|
|
try: |
|
@ -223,6 +244,6 @@ def main(): |
|
|
except KeyboardInterrupt: |
|
|
except KeyboardInterrupt: |
|
|
server.shutdown() |
|
|
server.shutdown() |
|
|
sys.exit(0) |
|
|
sys.exit(0) |
|
|
|
|
|
|
|
|
if __name__ == '__main__': |
|
|
if __name__ == '__main__': |
|
|
main() |
|
|
main() |
|
|