fast open
This commit is contained in:
parent
0b9ff0557f
commit
2a172bea6a
1 changed files with 52 additions and 23 deletions
|
@ -50,6 +50,9 @@ import utils
|
||||||
import udprelay
|
import udprelay
|
||||||
|
|
||||||
|
|
||||||
|
MSG_FASTOPEN = 0x20000000
|
||||||
|
|
||||||
|
|
||||||
def send_all(sock, data):
|
def send_all(sock, data):
|
||||||
bytes_sent = 0
|
bytes_sent = 0
|
||||||
while True:
|
while True:
|
||||||
|
@ -84,18 +87,30 @@ class Socks5Server(SocketServer.StreamRequestHandler):
|
||||||
aPort = int(r.group(2))
|
aPort = int(r.group(2))
|
||||||
return (aServer, aPort)
|
return (aServer, aPort)
|
||||||
|
|
||||||
def handle_tcp(self, sock, remote):
|
def handle_tcp(self, sock, remote, pending_data=None, server=None, port=None):
|
||||||
|
connected = False
|
||||||
try:
|
try:
|
||||||
fdset = [sock, remote]
|
if FAST_OPEN:
|
||||||
|
fdset = [sock]
|
||||||
|
else:
|
||||||
|
fdset = [sock, remote]
|
||||||
while True:
|
while True:
|
||||||
r, w, e = select.select(fdset, [], [])
|
r, w, e = select.select(fdset, [], [])
|
||||||
if sock in r:
|
if sock in r:
|
||||||
data = self.encrypt(sock.recv(4096))
|
if not connected and FAST_OPEN:
|
||||||
if len(data) <= 0:
|
data = sock.recv(4096)
|
||||||
break
|
data = self.encrypt(pending_data + data)
|
||||||
result = send_all(remote, data)
|
remote.sendto(data, MSG_FASTOPEN, (server, port))
|
||||||
if result < len(data):
|
connected = True
|
||||||
raise Exception('failed to send all data')
|
fdset = [sock, remote]
|
||||||
|
logging.info('fast open %s:%d' % (server, port))
|
||||||
|
else:
|
||||||
|
data = self.encrypt(sock.recv(4096))
|
||||||
|
if len(data) <= 0:
|
||||||
|
break
|
||||||
|
result = send_all(remote, data)
|
||||||
|
if result < len(data):
|
||||||
|
raise Exception('failed to send all data')
|
||||||
|
|
||||||
if remote in r:
|
if remote in r:
|
||||||
data = self.decrypt(remote.recv(4096))
|
data = self.decrypt(remote.recv(4096))
|
||||||
|
@ -202,24 +217,37 @@ class Socks5Server(SocketServer.StreamRequestHandler):
|
||||||
self.wfile.write(reply)
|
self.wfile.write(reply)
|
||||||
# reply immediately
|
# reply immediately
|
||||||
aServer, aPort = self.getServer()
|
aServer, aPort = self.getServer()
|
||||||
MSG_FASTOPEN = 0x20000000
|
addrs = socket.getaddrinfo(aServer, aPort)
|
||||||
remote = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
|
if addrs:
|
||||||
# remote = socket.create_connection((aServer, aPort))
|
af, socktype, proto, canonname, sa = addrs[0]
|
||||||
remote.setsockopt(socket.IPPROTO_TCP, socket.TCP_NODELAY, 1)
|
if FAST_OPEN:
|
||||||
data = self.encrypt(addr_to_send)
|
remote = socket.socket(af, socktype, proto)
|
||||||
remote.sendto(data, MSG_FASTOPEN, (aServer, aPort))
|
# remote.setsockopt(socket.IPPROTO_TCP,
|
||||||
# self.send_encrypt(remote, addr_to_send)
|
# socket.TCP_NODELAY, 1)
|
||||||
logging.info('connecting %s:%d' % (addr, port[0]))
|
self.handle_tcp(sock, remote, addr_to_send, aServer,
|
||||||
except socket.error, e:
|
aPort)
|
||||||
logging.warn(e)
|
else:
|
||||||
return
|
remote = socket.create_connection((aServer, aPort))
|
||||||
self.handle_tcp(sock, remote)
|
remote.setsockopt(socket.IPPROTO_TCP,
|
||||||
except socket.error, e:
|
socket.TCP_NODELAY, 1)
|
||||||
logging.warn(e)
|
self.send_encrypt(remote, addr_to_send)
|
||||||
|
logging.info('connecting %s:%d' % (addr, port[0]))
|
||||||
|
self.handle_tcp(sock, remote)
|
||||||
|
finally:
|
||||||
|
pass
|
||||||
|
# except socket.error, e:
|
||||||
|
# raise e
|
||||||
|
# logging.warn(e)
|
||||||
|
# return
|
||||||
|
finally:
|
||||||
|
pass
|
||||||
|
# except socket.error, e:
|
||||||
|
# raise e
|
||||||
|
# logging.warn(e)
|
||||||
|
|
||||||
|
|
||||||
def main():
|
def main():
|
||||||
global SERVER, REMOTE_PORT, KEY, METHOD
|
global SERVER, REMOTE_PORT, KEY, METHOD, FAST_OPEN
|
||||||
|
|
||||||
logging.basicConfig(level=logging.DEBUG,
|
logging.basicConfig(level=logging.DEBUG,
|
||||||
format='%(asctime)s %(levelname)-8s %(message)s',
|
format='%(asctime)s %(levelname)-8s %(message)s',
|
||||||
|
@ -289,6 +317,7 @@ def main():
|
||||||
METHOD = config.get('method', None)
|
METHOD = config.get('method', None)
|
||||||
LOCAL = config.get('local_address', '127.0.0.1')
|
LOCAL = config.get('local_address', '127.0.0.1')
|
||||||
TIMEOUT = config.get('timeout', 600)
|
TIMEOUT = config.get('timeout', 600)
|
||||||
|
FAST_OPEN = config.get('fast_open', False)
|
||||||
|
|
||||||
if not KEY and not config_path:
|
if not KEY and not config_path:
|
||||||
sys.exit('config not specified, please read '
|
sys.exit('config not specified, please read '
|
||||||
|
|
Loading…
Reference in a new issue