forked from EastonLee/python-socks5
-
Notifications
You must be signed in to change notification settings - Fork 0
/
socks5.py
173 lines (148 loc) · 4.26 KB
/
socks5.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
#!/usr/bin/python2.7
#encoding=utf-8
import socket
from threading import Thread
import sys
import signal
SOCKTIMEOUT=5#客户端连接超时(秒)
RESENDTIMEOUT=300#转发超时(秒)
VER="\x05"
METHOD="\x00"
SUCCESS="\x00"
SOCKFAIL="\x01"
NETWORKFAIL="\x02"
HOSTFAIL="\x04"
REFUSED="\x05"
TTLEXPIRED="\x06"
UNSUPPORTCMD="\x07"
ADDRTYPEUNSPPORT="\x08"
UNASSIGNED="\x09"
_LOGGER=None
class Log:
WARN="[WARN:]"
INFO="[INFO:]"
ERROR="[ERROR:]"
def write(self,message,level):
pass
class SimpleLog(Log):
import sys
def __init__(self,output=sys.stdout):
self.__output=output
self.show_log=True
def write(self,message,level=Log.INFO):
if self.show_log:
self.__output.write("%s\t%s\n" %(level,message))
def getLogger(output=sys.stdout):
global _LOGGER
if not _LOGGER:
_LOGGER=SimpleLog(output)
return _LOGGER
class SocketTransform(Thread):
def __init__(self,src,dest_ip,dest_port,bind=False):
Thread.__init__(self)
self.dest_ip=dest_ip
self.dest_port=dest_port
self.src=src
self.bind=bind
self.setDaemon(True)
def run(self):
try:
self.resend()
except Exception,e:
getLogger().write("Error on SocketTransform %s" %(e.message,),Log.ERROR)
self.sock.close()
self.dest.close()
def resend(self):
self.sock=self.src
self.dest=socket.socket(socket.AF_INET,socket.SOCK_STREAM)
self.dest.connect((self.dest_ip,self.dest_port))
if self.bind:
getLogger().write("Waiting for the client")
self.sock,info=sock.accept()
getLogger().write("Client connected")
getLogger().write("Starting Resending")
self.sock.settimeout(RESENDTIMEOUT)
self.dest.settimeout(RESENDTIMEOUT)
Resender(self.sock,self.dest).start()
Resender(self.dest,self.sock).start()
class Resender(Thread):
def __init__(self,src,dest):
Thread.__init__(self)
self.src=src
self.setDaemon(True)
self.dest=dest
def run(self):
try:
self.resend(self.src,self.dest)
except Exception,e:
getLogger().write("Connection lost %s" %(e.message,),Log.ERROR)
self.src.close()
self.dest.close()
def resend(self,src,dest):
data=src.recv(10)
while data:
dest.sendall(data)
data=src.recv(10)
src.close()
dest.close()
getLogger().write("Client quit normally\n")
def create_server(ip,port):
transformer=socket.socket(socket.AF_INET,socket.SOCK_STREAM)
transformer.bind((ip,port))
signal.signal(signal.SIGTERM,OnExit(transformer).exit)
transformer.listen(1000)
while True:
sock,addr_info=transformer.accept()
sock.settimeout(SOCKTIMEOUT)
getLogger().write("Got one client connection")
try:
ver,nmethods,methods=(sock.recv(1),sock.recv(1),sock.recv(1))
sock.sendall(VER+METHOD)
ver,cmd,rsv,atyp=(sock.recv(1),sock.recv(1),sock.recv(1),sock.recv(1))
dst_addr=None
dst_port=None
if atyp=="\x01":#IPV4
dst_addr,dst_port=sock.recv(4),sock.recv(2)
dst_addr=".".join([str(ord(i)) for i in dst_addr])
elif atyp=="\x03":#Domain
addr_len=ord(sock.recv(1))#域名的长度
dst_addr,dst_port=sock.recv(addr_len),sock.recv(2)
dst_addr="".join([unichr(ord(i)) for i in dst_addr])
elif atyp=="\x04":#IPV6
dst_addr,dst_port=sock.recv(16),sock.recv(2)
tmp_addr=[]
for i in xrange(len(dst_addr)/2):
tmp_addr.append(unichr(ord(dst_addr[2*i])*256+ord(dst_addr[2*i+1])))
dst_addr=":".join(tmp_addr)
dst_port=ord(dst_port[0])*256+ord(dst_port[1])
getLogger().write("Client wants to connect to %s:%d" %(dst_addr,dst_port))
server_sock=sock
server_ip="".join([chr(int(i)) for i in ip.split(".")])
if cmd=="\x02":#BIND
#Unimplement
sock.close()
elif cmd=="\x03":#UDP
#Unimplement
sock.close()
elif cmd=="\x01":#CONNECT
sock.sendall(VER+SUCCESS+"\x00"+"\x01"+server_ip+chr(port/256)+chr(port%256))
getLogger().write("Starting transform thread")
SocketTransform(server_sock,dst_addr,dst_port).start()
else:#Unspport Command
sock.sendall(VER+UNSPPORTCMD+server_ip+chr(port/256)+chr(port%256))
sock.close()
except Exception,e:
getLogger().write("Error on starting transform:"+e.message,Log.ERROR)
sock.close()
class OnExit:
def __init__(self,sock):
self.sock=sock
def exit(self):
self.sock.close()
if __name__=='__main__':
try:
ip="0.0.0.0"
port=8080
create_server(ip,port)
except Exception,e:
getLogger().write("Error on create server:"+e.message,Log.ERROR)