girl 3.6.0 → 4.1.0
Sign up to get free protection for your applications and to get access to all the features.
Potentially problematic release.
This version of girl might be problematic. Click here for more details.
- checksums.yaml +4 -4
- data/girl.gemspec +1 -0
- data/lib/girl/concurrent_hash.rb +26 -22
- data/lib/girl/custom.rb +11 -0
- data/lib/girl/head.rb +11 -1
- data/lib/girl/proxy.rb +30 -31
- data/lib/girl/proxy_custom.rb +16 -13
- data/lib/girl/proxy_worker.rb +497 -579
- data/lib/girl/proxyd.rb +1 -15
- data/lib/girl/proxyd_custom.rb +12 -9
- data/lib/girl/proxyd_worker.rb +512 -467
- data/lib/girl/relay.rb +0 -1
- data/lib/girl/relay_worker.rb +467 -557
- data/lib/girl/resolvd_worker.rb +1 -1
- data/lib/girl/ssl.rb +1 -14
- data/lib/girl/ssl_worker.rb +121 -92
- data/lib/girl/version.rb +1 -1
- metadata +3 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 836b54e1549dfed638c775a99d128c18ce079d91bc508933635a8a8cbdfb3c2e
|
4
|
+
data.tar.gz: 7c1f1bab96cab7395e49b2dd71ec5dfc1073b57ffa6611bff7abeb1a3ef8162b
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 61a0a02a8a480343cd27f295d82dda48ab93e0d0c486a0d2cb82e8961477bffcc20e219238d794db8056ec00cb175955eb7c1a111b35d4fd189edec069a7390d
|
7
|
+
data.tar.gz: 694ea8625f406e0e2293c20b7144398ac2a09978f510d91387e3caa76d967c72dfc712334d0d1994bf8ac2822ed0b27552d7c88924b449c1fad9ff965e4293be
|
data/girl.gemspec
CHANGED
data/lib/girl/concurrent_hash.rb
CHANGED
@@ -1,22 +1,26 @@
|
|
1
|
-
class ConcurrentHash < Hash
|
2
|
-
def initialize
|
3
|
-
super
|
4
|
-
@mutex = Mutex.new
|
5
|
-
end
|
6
|
-
|
7
|
-
def []( *args )
|
8
|
-
@mutex.synchronize { super }
|
9
|
-
end
|
10
|
-
|
11
|
-
def []=( *args )
|
12
|
-
@mutex.synchronize { super }
|
13
|
-
end
|
14
|
-
|
15
|
-
def delete( *args )
|
16
|
-
@mutex.synchronize { super }
|
17
|
-
end
|
18
|
-
|
19
|
-
def each( *args )
|
20
|
-
@mutex.synchronize { super }
|
21
|
-
end
|
22
|
-
|
1
|
+
class ConcurrentHash < Hash
|
2
|
+
def initialize
|
3
|
+
super
|
4
|
+
@mutex = Mutex.new
|
5
|
+
end
|
6
|
+
|
7
|
+
def []( *args )
|
8
|
+
@mutex.synchronize { super }
|
9
|
+
end
|
10
|
+
|
11
|
+
def []=( *args )
|
12
|
+
@mutex.synchronize { super }
|
13
|
+
end
|
14
|
+
|
15
|
+
def delete( *args )
|
16
|
+
@mutex.synchronize { super }
|
17
|
+
end
|
18
|
+
|
19
|
+
def each( *args )
|
20
|
+
@mutex.synchronize { super }
|
21
|
+
end
|
22
|
+
|
23
|
+
def clear( *args )
|
24
|
+
@mutex.synchronize { super }
|
25
|
+
end
|
26
|
+
end
|
data/lib/girl/custom.rb
ADDED
data/lib/girl/head.rb
CHANGED
@@ -1,14 +1,17 @@
|
|
1
1
|
module Girl
|
2
|
-
READ_SIZE = 1024 * 1024 # 一次读多少
|
2
|
+
READ_SIZE = 1024 * 1024 # atun, btun一次读多少
|
3
3
|
WBUFF_LIMIT = 50 * 1024 * 1024 # 写前上限,超过上限暂停读
|
4
4
|
RESUME_BELOW = WBUFF_LIMIT / 2 # 降到多少以下恢复读
|
5
5
|
EXPIRE_NEW = 5 # 多久没有建立通道,过期
|
6
6
|
EXPIRE_AFTER = 300 # 多久没有新流量,过期
|
7
|
+
EXPIRE_CTL = 86400 # 多久没有ctlmsg来,过期
|
7
8
|
RESET_TRAFF_DAY = 1 # 流量计数重置日,0为不重置
|
8
9
|
CHECK_TRAFF_INTERVAL = 86400 # 检查今天是否是流量计数重置日间隔
|
9
10
|
CHECK_EXPIRE_INTERVAL = 5 # 检查过期间隔
|
10
11
|
CHECK_RESUME_INTERVAL = 1 # 检查恢复读间隔
|
11
12
|
RESOLV_CACHE_EXPIRE = 300 # dns查询结果缓存多久过期
|
13
|
+
RESEND_LIMIT = 5 # ctlmsg重传次数
|
14
|
+
RESEND_INTERVAL = 1 # ctlmsg重传间隔
|
12
15
|
HELLO = 1
|
13
16
|
TUND_PORT = 2
|
14
17
|
A_NEW_SOURCE = 3
|
@@ -31,6 +34,8 @@ module Girl
|
|
31
34
|
RESOLV = 20
|
32
35
|
RESOLVED = 21
|
33
36
|
HEARTBEAT = 22
|
37
|
+
UNKNOWN_CTL_ADDR = 23
|
38
|
+
CTL_FIN = 24
|
34
39
|
TRAFF_INFOS = 101
|
35
40
|
SEPARATE = "\r\n\r\n"
|
36
41
|
HTTP_OK = "HTTP/1.1 200 OK\r\n\r\n"
|
@@ -49,8 +54,13 @@ EOF
|
|
49
54
|
RESUME_BELOW
|
50
55
|
EXPIRE_NEW
|
51
56
|
EXPIRE_AFTER
|
57
|
+
EXPIRE_CTL
|
58
|
+
RESET_TRAFF_DAY
|
59
|
+
CHECK_TRAFF_INTERVAL
|
52
60
|
CHECK_EXPIRE_INTERVAL
|
53
61
|
CHECK_RESUME_INTERVAL
|
54
62
|
RESOLV_CACHE_EXPIRE
|
63
|
+
RESEND_LIMIT
|
64
|
+
RESEND_INTERVAL
|
55
65
|
]
|
56
66
|
end
|
data/lib/girl/proxy.rb
CHANGED
@@ -6,7 +6,6 @@ require 'girl/proxy_worker'
|
|
6
6
|
require 'girl/version'
|
7
7
|
require 'ipaddr'
|
8
8
|
require 'json'
|
9
|
-
require 'openssl'
|
10
9
|
require 'socket'
|
11
10
|
|
12
11
|
##
|
@@ -14,29 +13,34 @@ require 'socket'
|
|
14
13
|
#
|
15
14
|
#
|
16
15
|
=begin
|
17
|
-
C: 1 hello
|
18
|
-
2 tund port
|
19
|
-
3 a new source
|
20
|
-
4 paired
|
21
|
-
5 dest status
|
22
|
-
6 source status
|
23
|
-
7 miss
|
24
|
-
8 fin1
|
25
|
-
9 confirm fin1
|
26
|
-
10 fin2
|
27
|
-
11 confirm fin2
|
28
|
-
12 tund fin
|
29
|
-
13 tun fin
|
30
|
-
14 tun ip changed
|
31
|
-
15 single miss
|
32
|
-
16 range miss
|
33
|
-
17 continue
|
34
|
-
18 is resend ready
|
35
|
-
19 resend ready
|
36
|
-
20 resolv
|
37
|
-
21 resolved
|
16
|
+
C: 1 hello -> hello
|
17
|
+
2 tund port -> n: tund port
|
18
|
+
3 a new source -> Q>: src id -> encoded destination address
|
19
|
+
4 paired -> Q>: src id -> n: dst id
|
20
|
+
5 dest status NOT USE
|
21
|
+
6 source status NOT USE
|
22
|
+
7 miss NOT USE
|
23
|
+
8 fin1 NOT USE
|
24
|
+
9 confirm fin1 NOT USE
|
25
|
+
10 fin2 NOT USE
|
26
|
+
11 confirm fin2 NOT USE
|
27
|
+
12 tund fin NOT USE
|
28
|
+
13 tun fin NOT USE
|
29
|
+
14 tun ip changed NOT USE
|
30
|
+
15 single miss NOT USE
|
31
|
+
16 range miss NOT USE
|
32
|
+
17 continue NOT USE
|
33
|
+
18 is resend ready NOT USE
|
34
|
+
19 resend ready NOT USE
|
35
|
+
20 resolv -> Q>: src id -> encoded domain
|
36
|
+
21 resolved -> Q>: src id -> encoded ip
|
37
|
+
22 heartbeat NOT USE
|
38
|
+
23 unknown ctl addr
|
39
|
+
24 ctl fin
|
40
|
+
25 source eof -> Q>: dst id
|
41
|
+
26 dest eof -> Q>: src id
|
38
42
|
101 traff infos
|
39
|
-
101 traff infos
|
43
|
+
101 traff infos -> [ C: im len -> im -> Q>: traff in -> Q>: traff out ]
|
40
44
|
=end
|
41
45
|
|
42
46
|
module Girl
|
@@ -56,7 +60,6 @@ module Girl
|
|
56
60
|
direct_path = conf[ :direct_path ]
|
57
61
|
remote_path = conf[ :remote_path ]
|
58
62
|
im = conf[ :im ]
|
59
|
-
use_remote_resolv = conf[ :use_remote_resolv ]
|
60
63
|
worker_count = conf[ :worker_count ]
|
61
64
|
|
62
65
|
unless redir_port then
|
@@ -87,10 +90,6 @@ module Girl
|
|
87
90
|
im = 'girl'
|
88
91
|
end
|
89
92
|
|
90
|
-
unless use_remote_resolv then
|
91
|
-
use_remote_resolv = false
|
92
|
-
end
|
93
|
-
|
94
93
|
nprocessors = Etc.nprocessors
|
95
94
|
|
96
95
|
if worker_count.nil? || worker_count <= 0 || worker_count > nprocessors then
|
@@ -105,7 +104,7 @@ module Girl
|
|
105
104
|
|
106
105
|
title = "girl proxy #{ Girl::VERSION }"
|
107
106
|
puts title
|
108
|
-
puts "redir port #{ redir_port } proxyd host #{ proxyd_host } proxyd port #{ proxyd_port } im #{ im }
|
107
|
+
puts "redir port #{ redir_port } proxyd host #{ proxyd_host } proxyd port #{ proxyd_port } im #{ im } worker count #{ worker_count }"
|
109
108
|
puts "#{ direct_path } #{ directs.size } directs"
|
110
109
|
puts "#{ remote_path } #{ remotes.size } remotes"
|
111
110
|
|
@@ -116,7 +115,7 @@ module Girl
|
|
116
115
|
worker_count.times do | i |
|
117
116
|
workers << fork do
|
118
117
|
$0 = 'girl proxy worker'
|
119
|
-
worker = Girl::ProxyWorker.new( redir_port, proxyd_host, proxyd_port, directs, remotes, im
|
118
|
+
worker = Girl::ProxyWorker.new( redir_port, proxyd_host, proxyd_port, directs, remotes, im )
|
120
119
|
|
121
120
|
Signal.trap( :TERM ) do
|
122
121
|
puts "w#{ i } exit"
|
@@ -140,7 +139,7 @@ module Girl
|
|
140
139
|
|
141
140
|
Process.waitall
|
142
141
|
else
|
143
|
-
Girl::ProxyWorker.new( redir_port, proxyd_host, proxyd_port, directs, remotes, im
|
142
|
+
Girl::ProxyWorker.new( redir_port, proxyd_host, proxyd_port, directs, remotes, im ).looping
|
144
143
|
end
|
145
144
|
end
|
146
145
|
|
data/lib/girl/proxy_custom.rb
CHANGED
@@ -1,13 +1,16 @@
|
|
1
|
-
|
2
|
-
|
3
|
-
|
4
|
-
|
5
|
-
|
6
|
-
|
7
|
-
|
8
|
-
|
9
|
-
|
10
|
-
|
11
|
-
|
12
|
-
|
13
|
-
end
|
1
|
+
require 'girl/custom'
|
2
|
+
|
3
|
+
module Girl
|
4
|
+
class ProxyCustom
|
5
|
+
include Custom
|
6
|
+
|
7
|
+
def initialize( im )
|
8
|
+
@im = im
|
9
|
+
end
|
10
|
+
|
11
|
+
def hello
|
12
|
+
@im
|
13
|
+
end
|
14
|
+
|
15
|
+
end
|
16
|
+
end
|
data/lib/girl/proxy_worker.rb
CHANGED
@@ -4,28 +4,27 @@ module Girl
|
|
4
4
|
##
|
5
5
|
# initialize
|
6
6
|
#
|
7
|
-
def initialize( redir_port, proxyd_host, proxyd_port, directs, remotes, im
|
7
|
+
def initialize( redir_port, proxyd_host, proxyd_port, directs, remotes, im )
|
8
8
|
@proxyd_host = proxyd_host
|
9
9
|
@proxyd_addr = Socket.sockaddr_in( proxyd_port, proxyd_host )
|
10
10
|
@directs = directs
|
11
11
|
@remotes = remotes
|
12
12
|
@custom = Girl::ProxyCustom.new( im )
|
13
|
-
@use_remote_resolv = use_remote_resolv
|
14
13
|
@reads = []
|
15
14
|
@writes = []
|
16
15
|
@closing_srcs = []
|
17
16
|
@paused_srcs = []
|
18
17
|
@paused_dsts = []
|
19
|
-
@
|
18
|
+
@paused_btuns = []
|
20
19
|
@resume_srcs = []
|
21
20
|
@resume_dsts = []
|
22
|
-
@
|
21
|
+
@resume_btuns = []
|
23
22
|
@pending_srcs = [] # 还没配到tund,暂存的src
|
24
|
-
@roles = ConcurrentHash.new # sock => :dotr / :redir / :
|
23
|
+
@roles = ConcurrentHash.new # sock => :dotr / :redir / :ctl / :src / :dst / :atun / :btun
|
25
24
|
@src_infos = ConcurrentHash.new # src => {}
|
26
25
|
@dst_infos = ConcurrentHash.new # dst => {}
|
27
|
-
@
|
28
|
-
@
|
26
|
+
@atun_infos = ConcurrentHash.new # atun => {}
|
27
|
+
@btun_infos = ConcurrentHash.new # btun => {}
|
29
28
|
@resolv_caches = ConcurrentHash.new # domain => [ ip, created_at ]
|
30
29
|
@is_direct_caches = ConcurrentHash.new # ip => true / false
|
31
30
|
@srcs = ConcurrentHash.new # src_id => src
|
@@ -54,31 +53,27 @@ module Girl
|
|
54
53
|
read_dotr( sock )
|
55
54
|
when :redir then
|
56
55
|
read_redir( sock )
|
57
|
-
when :
|
58
|
-
|
56
|
+
when :ctl then
|
57
|
+
read_ctl( sock )
|
59
58
|
when :src then
|
60
59
|
read_src( sock )
|
61
60
|
when :dst then
|
62
61
|
read_dst( sock )
|
63
|
-
when :
|
64
|
-
|
62
|
+
when :btun then
|
63
|
+
read_btun( sock )
|
65
64
|
end
|
66
65
|
end
|
67
66
|
|
68
67
|
ws.each do | sock |
|
69
68
|
case @roles[ sock ]
|
70
|
-
when :proxy then
|
71
|
-
write_proxy( sock )
|
72
69
|
when :src then
|
73
70
|
write_src( sock )
|
74
71
|
when :dst then
|
75
72
|
write_dst( sock )
|
76
|
-
when :
|
77
|
-
|
78
|
-
when :
|
79
|
-
|
80
|
-
when :pre_tun then
|
81
|
-
write_pre_tun( sock )
|
73
|
+
when :atun then
|
74
|
+
write_atun( sock )
|
75
|
+
when :btun then
|
76
|
+
write_btun( sock )
|
82
77
|
end
|
83
78
|
end
|
84
79
|
end
|
@@ -91,13 +86,8 @@ module Girl
|
|
91
86
|
# quit!
|
92
87
|
#
|
93
88
|
def quit!
|
94
|
-
|
95
|
-
|
96
|
-
data = [ TUN_FIN ].pack( 'C' )
|
97
|
-
@proxy.write( data )
|
98
|
-
end
|
99
|
-
|
100
|
-
# puts "debug1 exit"
|
89
|
+
# puts "debug exit"
|
90
|
+
send_ctlmsg( [ CTL_FIN ].pack( 'C' ) )
|
101
91
|
exit
|
102
92
|
end
|
103
93
|
|
@@ -111,8 +101,24 @@ module Girl
|
|
111
101
|
destination_domain = src_info[ :destination_domain ]
|
112
102
|
destination_port = src_info[ :destination_port ]
|
113
103
|
domain_port = [ destination_domain, destination_port ].join( ':' )
|
114
|
-
|
115
|
-
|
104
|
+
# puts "debug add a new source #{ src_info[ :id ] } #{ domain_port }"
|
105
|
+
key = [ A_NEW_SOURCE, src_info[ :id ] ].pack( 'CQ>' )
|
106
|
+
add_ctlmsg( key, domain_port )
|
107
|
+
end
|
108
|
+
|
109
|
+
##
|
110
|
+
# add atun wbuff
|
111
|
+
#
|
112
|
+
def add_atun_wbuff( atun, data )
|
113
|
+
return if atun.closed?
|
114
|
+
atun_info = @atun_infos[ atun ]
|
115
|
+
atun_info[ :wbuff ] << data
|
116
|
+
add_write( atun )
|
117
|
+
|
118
|
+
if atun_info[ :wbuff ].bytesize >= WBUFF_LIMIT then
|
119
|
+
puts "p#{ Process.pid } #{ Time.new } pause tunnel src #{ atun_info[ :domain ] }"
|
120
|
+
add_paused_src( atun_info[ :src ] )
|
121
|
+
end
|
116
122
|
end
|
117
123
|
|
118
124
|
##
|
@@ -127,16 +133,18 @@ module Girl
|
|
127
133
|
##
|
128
134
|
# add ctlmsg
|
129
135
|
#
|
130
|
-
def add_ctlmsg( data )
|
131
|
-
|
132
|
-
|
133
|
-
|
136
|
+
def add_ctlmsg( key, data )
|
137
|
+
ctlmsg = "#{ key }#{ data }"
|
138
|
+
send_ctlmsg( ctlmsg )
|
139
|
+
@ctl_info[ :resends ][ key ] = 0
|
140
|
+
loop_resend_ctlmsg( key, ctlmsg )
|
134
141
|
end
|
135
142
|
|
136
143
|
##
|
137
144
|
# add dst wbuff
|
138
145
|
#
|
139
146
|
def add_dst_wbuff( dst, data )
|
147
|
+
return if dst.closed?
|
140
148
|
dst_info = @dst_infos[ dst ]
|
141
149
|
dst_info[ :wbuff ] << data
|
142
150
|
add_write( dst )
|
@@ -147,6 +155,15 @@ module Girl
|
|
147
155
|
end
|
148
156
|
end
|
149
157
|
|
158
|
+
##
|
159
|
+
# add paused btun
|
160
|
+
#
|
161
|
+
def add_paused_btun( btun )
|
162
|
+
return if btun.closed? || @paused_btuns.include?( btun )
|
163
|
+
@reads.delete( btun )
|
164
|
+
@paused_btuns << btun
|
165
|
+
end
|
166
|
+
|
150
167
|
##
|
151
168
|
# add paused dst
|
152
169
|
#
|
@@ -165,15 +182,6 @@ module Girl
|
|
165
182
|
@paused_srcs << src
|
166
183
|
end
|
167
184
|
|
168
|
-
##
|
169
|
-
# add paused tun
|
170
|
-
#
|
171
|
-
def add_paused_tun( tun )
|
172
|
-
return if tun.closed? || @paused_tuns.include?( tun )
|
173
|
-
@reads.delete( tun )
|
174
|
-
@paused_tuns << tun
|
175
|
-
end
|
176
|
-
|
177
185
|
##
|
178
186
|
# add read
|
179
187
|
#
|
@@ -188,6 +196,15 @@ module Girl
|
|
188
196
|
next_tick
|
189
197
|
end
|
190
198
|
|
199
|
+
##
|
200
|
+
# add resume btun
|
201
|
+
#
|
202
|
+
def add_resume_btun( btun )
|
203
|
+
return if @resume_btuns.include?( btun )
|
204
|
+
@resume_btuns << btun
|
205
|
+
next_tick
|
206
|
+
end
|
207
|
+
|
191
208
|
##
|
192
209
|
# add resume dst
|
193
210
|
#
|
@@ -206,15 +223,6 @@ module Girl
|
|
206
223
|
next_tick
|
207
224
|
end
|
208
225
|
|
209
|
-
##
|
210
|
-
# add resume tun
|
211
|
-
#
|
212
|
-
def add_resume_tun( tun )
|
213
|
-
return if @resume_tuns.include?( tun )
|
214
|
-
@resume_tuns << tun
|
215
|
-
next_tick
|
216
|
-
end
|
217
|
-
|
218
226
|
##
|
219
227
|
# add socks5 conn reply
|
220
228
|
#
|
@@ -226,7 +234,7 @@ module Girl
|
|
226
234
|
# +----+-----+-------+------+----------+----------+
|
227
235
|
redir_ip, redir_port = @redir_local_address.ip_unpack
|
228
236
|
data = [ [ 5, 0, 0, 1 ].pack( 'C4' ), IPAddr.new( redir_ip ).hton, [ redir_port ].pack( 'n' ) ].join
|
229
|
-
# puts "
|
237
|
+
# puts "debug add src.wbuff socks5 conn reply #{ data.inspect }"
|
230
238
|
add_src_wbuff( src, data )
|
231
239
|
end
|
232
240
|
|
@@ -238,7 +246,7 @@ module Girl
|
|
238
246
|
src_info[ :rbuff ] << data
|
239
247
|
|
240
248
|
if src_info[ :rbuff ].bytesize >= WBUFF_LIMIT then
|
241
|
-
# puts "
|
249
|
+
# puts "debug src.rbuff full"
|
242
250
|
add_closing_src( src )
|
243
251
|
end
|
244
252
|
end
|
@@ -260,30 +268,16 @@ module Girl
|
|
260
268
|
puts "p#{ Process.pid } #{ Time.new } pause dst #{ src_info[ :destination_domain ] }"
|
261
269
|
add_paused_dst( dst )
|
262
270
|
else
|
263
|
-
|
271
|
+
btun = src_info[ :btun ]
|
264
272
|
|
265
|
-
if
|
266
|
-
puts "p#{ Process.pid } #{ Time.new } pause
|
267
|
-
|
273
|
+
if btun then
|
274
|
+
puts "p#{ Process.pid } #{ Time.new } pause btun #{ src_info[ :destination_domain ] }"
|
275
|
+
add_paused_btun( btun )
|
268
276
|
end
|
269
277
|
end
|
270
278
|
end
|
271
279
|
end
|
272
280
|
|
273
|
-
##
|
274
|
-
# add tun wbuff
|
275
|
-
#
|
276
|
-
def add_tun_wbuff( tun, data )
|
277
|
-
tun_info = @tun_infos[ tun ]
|
278
|
-
tun_info[ :wbuff ] << data
|
279
|
-
add_write( tun )
|
280
|
-
|
281
|
-
if tun_info[ :wbuff ].bytesize >= WBUFF_LIMIT then
|
282
|
-
puts "p#{ Process.pid } #{ Time.new } pause tunnel src #{ tun_info[ :domain ] }"
|
283
|
-
add_paused_src( tun_info[ :src ] )
|
284
|
-
end
|
285
|
-
end
|
286
|
-
|
287
281
|
##
|
288
282
|
# add write
|
289
283
|
#
|
@@ -294,32 +288,36 @@ module Girl
|
|
294
288
|
end
|
295
289
|
|
296
290
|
##
|
297
|
-
# close
|
291
|
+
# close atun
|
298
292
|
#
|
299
|
-
def
|
300
|
-
return if
|
301
|
-
# puts "
|
302
|
-
close_sock(
|
293
|
+
def close_atun( atun )
|
294
|
+
return if atun.closed?
|
295
|
+
# puts "debug close atun"
|
296
|
+
close_sock( atun )
|
297
|
+
atun_info = @atun_infos.delete( atun )
|
298
|
+
src = atun_info[ :src ]
|
299
|
+
|
300
|
+
if src then
|
301
|
+
@paused_srcs.delete( src )
|
302
|
+
end
|
303
303
|
end
|
304
304
|
|
305
305
|
##
|
306
|
-
# close
|
306
|
+
# close btun
|
307
307
|
#
|
308
|
-
def
|
309
|
-
return if
|
310
|
-
# puts "
|
311
|
-
close_sock(
|
312
|
-
|
308
|
+
def close_btun( btun )
|
309
|
+
return if btun.closed?
|
310
|
+
# puts "debug close btun"
|
311
|
+
close_sock( btun )
|
312
|
+
del_btun_info( btun )
|
313
313
|
end
|
314
314
|
|
315
315
|
##
|
316
|
-
# close
|
316
|
+
# close ctl
|
317
317
|
#
|
318
|
-
def
|
319
|
-
|
320
|
-
|
321
|
-
close_sock( proxy )
|
322
|
-
close_pre_proxy( @pre_proxy )
|
318
|
+
def close_ctl( ctl )
|
319
|
+
close_sock( ctl )
|
320
|
+
@ctl_info[ :resends ].clear
|
323
321
|
end
|
324
322
|
|
325
323
|
##
|
@@ -327,20 +325,15 @@ module Girl
|
|
327
325
|
#
|
328
326
|
def close_read_dst( dst )
|
329
327
|
return if dst.closed?
|
330
|
-
# puts "
|
328
|
+
# puts "debug close read dst"
|
331
329
|
dst.close_read
|
332
330
|
@reads.delete( dst )
|
333
331
|
|
334
332
|
if dst.closed? then
|
335
|
-
# puts "debug1 delete dst info"
|
336
333
|
@writes.delete( dst )
|
337
334
|
@roles.delete( dst )
|
338
|
-
|
339
|
-
else
|
340
|
-
dst_info = @dst_infos[ dst ]
|
335
|
+
del_dst_info( dst )
|
341
336
|
end
|
342
|
-
|
343
|
-
dst_info
|
344
337
|
end
|
345
338
|
|
346
339
|
##
|
@@ -348,39 +341,15 @@ module Girl
|
|
348
341
|
#
|
349
342
|
def close_read_src( src )
|
350
343
|
return if src.closed?
|
351
|
-
# puts "
|
344
|
+
# puts "debug close read src"
|
352
345
|
src.close_read
|
353
346
|
@reads.delete( src )
|
354
347
|
|
355
348
|
if src.closed? then
|
356
|
-
# puts "debug1 delete src info"
|
357
349
|
@writes.delete( src )
|
358
350
|
@roles.delete( src )
|
359
|
-
|
360
|
-
else
|
361
|
-
src_info = @src_infos[ src ]
|
362
|
-
end
|
363
|
-
|
364
|
-
src_info
|
365
|
-
end
|
366
|
-
|
367
|
-
##
|
368
|
-
# close read tun
|
369
|
-
#
|
370
|
-
def close_read_tun( tun )
|
371
|
-
return if tun.closed?
|
372
|
-
# puts "debug1 close read tun"
|
373
|
-
tun_info = @tun_infos[ tun ]
|
374
|
-
tun_info[ :close_read ] = true
|
375
|
-
|
376
|
-
if tun_info[ :close_write ] then
|
377
|
-
# puts "debug1 close tun"
|
378
|
-
close_tun( tun )
|
379
|
-
else
|
380
|
-
@reads.delete( tun )
|
351
|
+
del_src_info( src )
|
381
352
|
end
|
382
|
-
|
383
|
-
tun_info
|
384
353
|
end
|
385
354
|
|
386
355
|
##
|
@@ -398,59 +367,44 @@ module Girl
|
|
398
367
|
#
|
399
368
|
def close_src( src )
|
400
369
|
return if src.closed?
|
401
|
-
# puts "
|
370
|
+
# puts "debug close src"
|
402
371
|
close_sock( src )
|
403
372
|
src_info = del_src_info( src )
|
404
373
|
dst = src_info[ :dst ]
|
405
374
|
|
406
375
|
if dst then
|
407
376
|
close_sock( dst )
|
408
|
-
|
377
|
+
del_dst_info( dst )
|
409
378
|
else
|
410
|
-
|
379
|
+
atun = src_info[ :atun ]
|
380
|
+
btun = src_info[ :btun ]
|
411
381
|
|
412
|
-
if
|
413
|
-
|
414
|
-
|
415
|
-
|
382
|
+
if atun then
|
383
|
+
close_sock( atun )
|
384
|
+
@atun_infos.delete( atun )
|
385
|
+
end
|
416
386
|
|
417
|
-
|
418
|
-
|
419
|
-
|
387
|
+
if btun then
|
388
|
+
close_sock( btun )
|
389
|
+
del_btun_info( btun )
|
420
390
|
end
|
421
391
|
end
|
422
392
|
end
|
423
393
|
|
424
|
-
##
|
425
|
-
# close tun
|
426
|
-
#
|
427
|
-
def close_tun( tun )
|
428
|
-
return if tun.closed?
|
429
|
-
# puts "debug1 close tun"
|
430
|
-
close_sock( tun )
|
431
|
-
tun_info = @tun_infos.delete( tun )
|
432
|
-
close_pre_tun( tun_info[ :pre_tun ] )
|
433
|
-
end
|
434
|
-
|
435
394
|
##
|
436
395
|
# close write dst
|
437
396
|
#
|
438
397
|
def close_write_dst( dst )
|
439
398
|
return if dst.closed?
|
440
|
-
# puts "
|
399
|
+
# puts "debug close write dst"
|
441
400
|
dst.close_write
|
442
401
|
@writes.delete( dst )
|
443
402
|
|
444
403
|
if dst.closed? then
|
445
|
-
# puts "debug1 delete dst info"
|
446
404
|
@reads.delete( dst )
|
447
405
|
@roles.delete( dst )
|
448
|
-
|
449
|
-
else
|
450
|
-
dst_info = @dst_infos[ dst ]
|
406
|
+
del_dst_info( dst )
|
451
407
|
end
|
452
|
-
|
453
|
-
dst_info
|
454
408
|
end
|
455
409
|
|
456
410
|
##
|
@@ -458,39 +412,15 @@ module Girl
|
|
458
412
|
#
|
459
413
|
def close_write_src( src )
|
460
414
|
return if src.closed?
|
461
|
-
# puts "
|
415
|
+
# puts "debug close write src"
|
462
416
|
src.close_write
|
463
417
|
@writes.delete( src )
|
464
418
|
|
465
419
|
if src.closed? then
|
466
|
-
# puts "debug1 delete src info"
|
467
420
|
@reads.delete( src )
|
468
421
|
@roles.delete( src )
|
469
|
-
|
470
|
-
else
|
471
|
-
src_info = @src_infos[ src ]
|
472
|
-
end
|
473
|
-
|
474
|
-
src_info
|
475
|
-
end
|
476
|
-
|
477
|
-
##
|
478
|
-
# close write tun
|
479
|
-
#
|
480
|
-
def close_write_tun( tun )
|
481
|
-
return if tun.closed?
|
482
|
-
# puts "debug1 close write tun"
|
483
|
-
tun_info = @tun_infos[ tun ]
|
484
|
-
tun_info[ :close_write ] = true
|
485
|
-
|
486
|
-
if tun_info[ :close_read ] then
|
487
|
-
# puts "debug1 close tun"
|
488
|
-
close_tun( tun )
|
489
|
-
else
|
490
|
-
@writes.delete( tun )
|
422
|
+
del_src_info( src )
|
491
423
|
end
|
492
|
-
|
493
|
-
tun_info
|
494
424
|
end
|
495
425
|
|
496
426
|
##
|
@@ -525,23 +455,45 @@ module Girl
|
|
525
455
|
end
|
526
456
|
|
527
457
|
if is_direct then
|
528
|
-
# puts "
|
458
|
+
# puts "debug #{ ip_info.inspect } hit directs"
|
529
459
|
new_a_dst( src, ip_info )
|
530
460
|
else
|
531
461
|
# 走远端
|
532
|
-
# puts "
|
462
|
+
# puts "debug #{ ip_info.inspect } go tunnel"
|
533
463
|
set_proxy_type_tunnel( src )
|
534
464
|
end
|
535
465
|
end
|
536
466
|
|
467
|
+
##
|
468
|
+
# del btun info
|
469
|
+
#
|
470
|
+
def del_btun_info( btun )
|
471
|
+
@btun_infos.delete( btun )
|
472
|
+
@paused_btuns.delete( btun )
|
473
|
+
@resume_btuns.delete( btun )
|
474
|
+
end
|
475
|
+
|
476
|
+
##
|
477
|
+
# del dst info
|
478
|
+
#
|
479
|
+
def del_dst_info( dst )
|
480
|
+
# puts "debug delete dst info"
|
481
|
+
dst_info = @dst_infos.delete( dst )
|
482
|
+
@paused_dsts.delete( dst )
|
483
|
+
@resume_dsts.delete( dst )
|
484
|
+
dst_info
|
485
|
+
end
|
486
|
+
|
537
487
|
##
|
538
488
|
# del src info
|
539
489
|
#
|
540
490
|
def del_src_info( src )
|
491
|
+
# puts "debug delete src info"
|
541
492
|
src_info = @src_infos.delete( src )
|
542
493
|
@srcs.delete( src_info[ :id ] )
|
543
494
|
@pending_srcs.delete( src )
|
544
|
-
|
495
|
+
@paused_srcs.delete( src )
|
496
|
+
@resume_srcs.delete( src )
|
545
497
|
src_info
|
546
498
|
end
|
547
499
|
|
@@ -554,39 +506,23 @@ module Girl
|
|
554
506
|
sleep CHECK_EXPIRE_INTERVAL
|
555
507
|
now = Time.new
|
556
508
|
|
557
|
-
if @
|
558
|
-
|
559
|
-
if @proxy_info[ :last_recv_at ] then
|
560
|
-
last_recv_at = @proxy_info[ :last_recv_at ]
|
561
|
-
expire_after = EXPIRE_AFTER
|
562
|
-
else
|
563
|
-
last_recv_at = @proxy_info[ :created_at ]
|
564
|
-
expire_after = EXPIRE_NEW
|
565
|
-
end
|
509
|
+
if @ctl && !@ctl.closed? then
|
510
|
+
last_recv_at = @ctl_info[ :last_recv_at ] || @ctl_info[ :created_at ]
|
566
511
|
|
567
|
-
|
568
|
-
|
569
|
-
|
570
|
-
|
571
|
-
else
|
572
|
-
# puts "debug1 #{ Time.new } send heartbeat"
|
573
|
-
data = [ HEARTBEAT ].pack( 'C' )
|
574
|
-
add_ctlmsg( data )
|
575
|
-
end
|
512
|
+
if now - last_recv_at >= EXPIRE_AFTER then
|
513
|
+
puts "p#{ Process.pid } #{ Time.new } expire ctl"
|
514
|
+
@ctl_info[ :closing ] = true
|
515
|
+
next_tick
|
576
516
|
end
|
577
|
-
elsif @pre_proxy && !@pre_proxy.closed? && ( now - @pre_proxy_info[ :created_at ] > EXPIRE_NEW ) then
|
578
|
-
puts "p#{ Process.pid } #{ Time.new } expire pre proxy"
|
579
|
-
@pre_proxy_info[ :closing ] = true
|
580
|
-
next_tick
|
581
517
|
end
|
582
518
|
|
583
519
|
@src_infos.each do | src, src_info |
|
584
520
|
last_recv_at = src_info[ :last_recv_at ] || src_info[ :created_at ]
|
585
521
|
last_sent_at = src_info[ :last_sent_at ] || src_info[ :created_at ]
|
586
|
-
expire_after = ( src_info[ :dst ] || src_info[ :
|
522
|
+
expire_after = ( src_info[ :dst ] || src_info[ :atun ] ) ? EXPIRE_AFTER : EXPIRE_NEW
|
587
523
|
|
588
524
|
if ( now - last_recv_at >= expire_after ) && ( now - last_sent_at >= expire_after ) then
|
589
|
-
puts "p#{ Process.pid } #{ Time.new } expire src #{ expire_after } #{ src_info[ :destination_domain ] }"
|
525
|
+
puts "p#{ Process.pid } #{ Time.new } expire src #{ expire_after } #{ src_info[ :id ] } #{ src_info[ :destination_domain ] }"
|
590
526
|
add_closing_src( src )
|
591
527
|
|
592
528
|
unless src_info[ :rbuff ].empty? then
|
@@ -607,24 +543,25 @@ module Girl
|
|
607
543
|
sleep CHECK_RESUME_INTERVAL
|
608
544
|
|
609
545
|
@paused_srcs.each do | src |
|
610
|
-
|
611
|
-
|
612
|
-
else
|
613
|
-
src_info = @src_infos[ src ]
|
614
|
-
dst = src_info[ :dst ]
|
546
|
+
src_info = @src_infos[ src ]
|
547
|
+
dst = src_info[ :dst ]
|
615
548
|
|
616
|
-
|
549
|
+
if dst then
|
550
|
+
if !dst.closed? then
|
617
551
|
dst_info = @dst_infos[ dst ]
|
618
552
|
|
619
553
|
if dst_info[ :wbuff ].size < RESUME_BELOW then
|
620
554
|
puts "p#{ Process.pid } #{ Time.new } resume direct src #{ src_info[ :destination_domain ] }"
|
621
555
|
add_resume_src( src )
|
622
556
|
end
|
623
|
-
|
624
|
-
|
625
|
-
|
557
|
+
end
|
558
|
+
else
|
559
|
+
atun = src_info[ :atun ]
|
626
560
|
|
627
|
-
|
561
|
+
if atun && !atun.closed? then
|
562
|
+
atun_info = @atun_infos[ atun ]
|
563
|
+
|
564
|
+
if atun_info[ :wbuff ].size < RESUME_BELOW then
|
628
565
|
puts "p#{ Process.pid } #{ Time.new } resume tunnel src #{ src_info[ :destination_domain ] }"
|
629
566
|
add_resume_src( src )
|
630
567
|
end
|
@@ -633,11 +570,10 @@ module Girl
|
|
633
570
|
end
|
634
571
|
|
635
572
|
@paused_dsts.each do | dst |
|
636
|
-
|
637
|
-
|
638
|
-
|
639
|
-
|
640
|
-
src = dst_info[ :src ]
|
573
|
+
dst_info = @dst_infos[ dst ]
|
574
|
+
src = dst_info[ :src ]
|
575
|
+
|
576
|
+
if src && !src.closed? then
|
641
577
|
src_info = @src_infos[ src ]
|
642
578
|
|
643
579
|
if src_info[ :wbuff ].size < RESUME_BELOW then
|
@@ -647,17 +583,16 @@ module Girl
|
|
647
583
|
end
|
648
584
|
end
|
649
585
|
|
650
|
-
@
|
651
|
-
|
652
|
-
|
653
|
-
|
654
|
-
|
655
|
-
src = tun_info[ :src ]
|
586
|
+
@paused_btuns.each do | btun |
|
587
|
+
btun_info = @btun_infos[ btun ]
|
588
|
+
src = btun_info[ :src ]
|
589
|
+
|
590
|
+
if src && !src.closed? then
|
656
591
|
src_info = @src_infos[ src ]
|
657
592
|
|
658
593
|
if src_info[ :wbuff ].size < RESUME_BELOW then
|
659
|
-
puts "p#{ Process.pid } #{ Time.new } resume
|
660
|
-
|
594
|
+
puts "p#{ Process.pid } #{ Time.new } resume btun #{ btun_info[ :domain ] }"
|
595
|
+
add_resume_btun( btun )
|
661
596
|
end
|
662
597
|
end
|
663
598
|
end
|
@@ -665,6 +600,31 @@ module Girl
|
|
665
600
|
end
|
666
601
|
end
|
667
602
|
|
603
|
+
##
|
604
|
+
# loop resend ctlmsg
|
605
|
+
#
|
606
|
+
def loop_resend_ctlmsg( key, ctlmsg )
|
607
|
+
Thread.new do
|
608
|
+
loop do
|
609
|
+
sleep RESEND_INTERVAL
|
610
|
+
|
611
|
+
resend = @ctl_info[ :resends ][ key ]
|
612
|
+
break unless resend
|
613
|
+
|
614
|
+
puts "p#{ Process.pid } #{ Time.new } resend #{ ctlmsg.inspect }"
|
615
|
+
send_ctlmsg( ctlmsg )
|
616
|
+
resend += 1
|
617
|
+
|
618
|
+
if resend >= RESEND_LIMIT then
|
619
|
+
@ctl_info[ :resends ].delete( key )
|
620
|
+
break
|
621
|
+
end
|
622
|
+
|
623
|
+
@ctl_info[ :resends ][ key ] = resend
|
624
|
+
end
|
625
|
+
end
|
626
|
+
end
|
627
|
+
|
668
628
|
##
|
669
629
|
# new a dst
|
670
630
|
#
|
@@ -674,7 +634,6 @@ module Girl
|
|
674
634
|
domain = src_info[ :destination_domain ]
|
675
635
|
destination_addr = Socket.sockaddr_in( src_info[ :destination_port ], ip_info.ip_address )
|
676
636
|
dst = Socket.new( ip_info.ipv4? ? Socket::AF_INET : Socket::AF_INET6, Socket::SOCK_STREAM, 0 )
|
677
|
-
dst.setsockopt( Socket::SOL_TCP, Socket::TCP_NODELAY, 1 ) if RUBY_PLATFORM.include?( 'linux' )
|
678
637
|
|
679
638
|
begin
|
680
639
|
dst.connect_nonblock( destination_addr )
|
@@ -687,7 +646,7 @@ module Girl
|
|
687
646
|
return
|
688
647
|
end
|
689
648
|
|
690
|
-
# puts "
|
649
|
+
# puts "debug a new dst #{ dst.local_address.inspect }"
|
691
650
|
dst_info = {
|
692
651
|
src: src, # 对应src
|
693
652
|
domain: domain, # 目的地
|
@@ -702,10 +661,10 @@ module Girl
|
|
702
661
|
|
703
662
|
if src_info[ :proxy_proto ] == :http then
|
704
663
|
if src_info[ :is_connect ] then
|
705
|
-
# puts "
|
664
|
+
# puts "debug add src.wbuff http ok"
|
706
665
|
add_src_wbuff( src, HTTP_OK )
|
707
666
|
elsif src_info[ :rbuff ] then
|
708
|
-
# puts "
|
667
|
+
# puts "debug move src.rbuff to dst.wbuff"
|
709
668
|
dst_info[ :wbuff ] << src_info[ :rbuff ]
|
710
669
|
add_write( dst )
|
711
670
|
end
|
@@ -715,65 +674,31 @@ module Girl
|
|
715
674
|
end
|
716
675
|
|
717
676
|
##
|
718
|
-
# new a
|
677
|
+
# new a ctl
|
719
678
|
#
|
720
|
-
def
|
721
|
-
|
722
|
-
pre_proxy.setsockopt( Socket::SOL_SOCKET, Socket::SO_REUSEADDR, 1 )
|
679
|
+
def new_a_ctl
|
680
|
+
ctl = Socket.new( Socket::AF_INET, Socket::SOCK_DGRAM, 0 )
|
723
681
|
|
724
682
|
if RUBY_PLATFORM.include?( 'linux' ) then
|
725
|
-
|
726
|
-
pre_proxy.setsockopt( Socket::SOL_TCP, Socket::TCP_NODELAY, 1 )
|
683
|
+
ctl.setsockopt( Socket::SOL_SOCKET, Socket::SO_REUSEPORT, 1 )
|
727
684
|
end
|
728
685
|
|
729
|
-
|
730
|
-
|
731
|
-
rescue IO::WaitWritable
|
732
|
-
rescue Exception => e
|
733
|
-
puts "p#{ Process.pid } #{ Time.new } connect proxyd #{ e.class }, close pre proxy"
|
734
|
-
pre_proxy.close
|
735
|
-
return
|
736
|
-
end
|
686
|
+
@ctl = ctl
|
687
|
+
add_read( ctl, :ctl )
|
737
688
|
|
738
|
-
@
|
739
|
-
|
740
|
-
|
741
|
-
|
742
|
-
|
689
|
+
@ctl_info = {
|
690
|
+
resends: ConcurrentHash.new, # key => count
|
691
|
+
atund_addr: nil, # atund地址,src->dst
|
692
|
+
btund_addr: nil, # btund地址,dst->src
|
693
|
+
closing: false, # 准备关闭
|
694
|
+
created_at: Time.new, # 创建时间
|
695
|
+
last_recv_at: nil # 最近一次收到数据时间
|
743
696
|
}
|
744
|
-
add_write( pre_proxy )
|
745
|
-
end
|
746
|
-
|
747
|
-
##
|
748
|
-
# new a pre tun
|
749
|
-
#
|
750
|
-
def new_a_pre_tun( src_id, dst_id )
|
751
|
-
src = @srcs[ src_id ]
|
752
|
-
return if src.nil? || src.closed?
|
753
|
-
src_info = @src_infos[ src ]
|
754
|
-
return if src_info[ :dst_id ]
|
755
|
-
|
756
|
-
pre_tun = Socket.new( Socket::AF_INET, Socket::SOCK_STREAM, 0 )
|
757
|
-
pre_tun.setsockopt( Socket::SOL_TCP, Socket::TCP_NODELAY, 1 ) if RUBY_PLATFORM.include?( 'linux' )
|
758
697
|
|
759
|
-
|
760
|
-
|
761
|
-
|
762
|
-
|
763
|
-
puts "p#{ Process.pid } #{ Time.new } connect tund #{ e.class }, close pre tun"
|
764
|
-
pre_tun.close
|
765
|
-
return
|
766
|
-
end
|
767
|
-
|
768
|
-
src_info[ :pre_tun ] = pre_tun
|
769
|
-
src_info[ :dst_id ] = dst_id
|
770
|
-
@pre_tun_infos[ pre_tun ] = {
|
771
|
-
src: src,
|
772
|
-
destination_domain: src_info[ :destination_domain ],
|
773
|
-
created_at: Time.new
|
774
|
-
}
|
775
|
-
@roles[ pre_tun ] = :pre_tun
|
776
|
-
add_write( pre_tun )
|
698
|
+
hello = @custom.hello
|
699
|
+
puts "p#{ Process.pid } #{ Time.new } hello i'm #{ hello.inspect }"
|
700
|
+
key = [ HELLO ].pack( 'C' )
|
701
|
+
add_ctlmsg( key, hello )
|
777
702
|
end
|
778
703
|
|
779
704
|
##
|
@@ -785,7 +710,6 @@ module Girl
|
|
785
710
|
|
786
711
|
if RUBY_PLATFORM.include?( 'linux' ) then
|
787
712
|
redir.setsockopt( Socket::SOL_SOCKET, Socket::SO_REUSEPORT, 1 )
|
788
|
-
redir.setsockopt( Socket::SOL_TCP, Socket::TCP_NODELAY, 1 )
|
789
713
|
end
|
790
714
|
|
791
715
|
redir.bind( Socket.sockaddr_in( redir_port, '0.0.0.0' ) )
|
@@ -796,6 +720,84 @@ module Girl
|
|
796
720
|
@redir_local_address = redir.local_address
|
797
721
|
end
|
798
722
|
|
723
|
+
##
|
724
|
+
# new tuns
|
725
|
+
#
|
726
|
+
def new_tuns( src_id, dst_id )
|
727
|
+
src = @srcs[ src_id ]
|
728
|
+
return if src.nil? || src.closed?
|
729
|
+
src_info = @src_infos[ src ]
|
730
|
+
return if src_info[ :dst_id ]
|
731
|
+
|
732
|
+
# puts "debug new atun and btun"
|
733
|
+
atun = Socket.new( Socket::AF_INET, Socket::SOCK_STREAM, 0 )
|
734
|
+
|
735
|
+
begin
|
736
|
+
atun.connect_nonblock( @ctl_info[ :atund_addr ] )
|
737
|
+
rescue IO::WaitWritable
|
738
|
+
rescue Exception => e
|
739
|
+
puts "p#{ Process.pid } #{ Time.new } connect atund #{ e.class }, close atun"
|
740
|
+
atun.close
|
741
|
+
return
|
742
|
+
end
|
743
|
+
|
744
|
+
btun = Socket.new( Socket::AF_INET, Socket::SOCK_STREAM, 0 )
|
745
|
+
|
746
|
+
begin
|
747
|
+
btun.connect_nonblock( @ctl_info[ :btund_addr ] )
|
748
|
+
rescue IO::WaitWritable
|
749
|
+
rescue Exception => e
|
750
|
+
puts "p#{ Process.pid } #{ Time.new } connect btund #{ e.class }, close btun"
|
751
|
+
btun.close
|
752
|
+
return
|
753
|
+
end
|
754
|
+
|
755
|
+
domain = src_info[ :destination_domain ]
|
756
|
+
atun_wbuff = [ dst_id ].pack( 'n' )
|
757
|
+
|
758
|
+
until src_info[ :rbuff ].empty? do
|
759
|
+
data = src_info[ :rbuff ][ 0, 65535 ]
|
760
|
+
data_size = data.bytesize
|
761
|
+
# puts "debug move src.rbuff #{ data_size } to atun.wbuff"
|
762
|
+
atun_wbuff << pack_a_chunk( data )
|
763
|
+
src_info[ :rbuff ] = src_info[ :rbuff ][ data_size..-1 ]
|
764
|
+
end
|
765
|
+
|
766
|
+
@atun_infos[ atun ] = {
|
767
|
+
src: src, # 对应src
|
768
|
+
domain: domain, # 目的地
|
769
|
+
wbuff: atun_wbuff, # 写前
|
770
|
+
closing: false # 准备关闭
|
771
|
+
}
|
772
|
+
|
773
|
+
btun_wbuff = [ dst_id ].pack( 'n' )
|
774
|
+
|
775
|
+
@btun_infos[ btun ] = {
|
776
|
+
src: src, # 对应src
|
777
|
+
domain: domain, # 目的地
|
778
|
+
wbuff: btun_wbuff, # 写前
|
779
|
+
rbuff: '', # 暂存当前块没收全的流量
|
780
|
+
wait_bytes: 0 # 还差多少字节收全当前块
|
781
|
+
}
|
782
|
+
|
783
|
+
src_info[ :dst_id ] = dst_id
|
784
|
+
src_info[ :atun ] = atun
|
785
|
+
src_info[ :btun ] = btun
|
786
|
+
add_read( atun, :atun )
|
787
|
+
add_read( btun, :btun )
|
788
|
+
add_write( atun )
|
789
|
+
add_write( btun )
|
790
|
+
|
791
|
+
if src_info[ :proxy_proto ] == :http then
|
792
|
+
if src_info[ :is_connect ] then
|
793
|
+
# puts "debug add src.wbuff http ok"
|
794
|
+
add_src_wbuff( src, HTTP_OK )
|
795
|
+
end
|
796
|
+
elsif src_info[ :proxy_proto ] == :socks5 then
|
797
|
+
add_socks5_conn_reply( src )
|
798
|
+
end
|
799
|
+
end
|
800
|
+
|
799
801
|
##
|
800
802
|
# next tick
|
801
803
|
#
|
@@ -803,6 +805,15 @@ module Girl
|
|
803
805
|
@dotw.write( '.' )
|
804
806
|
end
|
805
807
|
|
808
|
+
##
|
809
|
+
# pack a chunk
|
810
|
+
#
|
811
|
+
def pack_a_chunk( data )
|
812
|
+
# puts "debug pack a chunk"
|
813
|
+
data = @custom.encode( data )
|
814
|
+
"#{ [ data.bytesize ].pack( 'n' ) }#{ data }"
|
815
|
+
end
|
816
|
+
|
806
817
|
##
|
807
818
|
# resolve domain
|
808
819
|
#
|
@@ -819,24 +830,18 @@ module Girl
|
|
819
830
|
ip_info, created_at = resolv_cache
|
820
831
|
|
821
832
|
if Time.new - created_at < RESOLV_CACHE_EXPIRE then
|
822
|
-
# puts "
|
833
|
+
# puts "debug #{ domain } hit resolv cache #{ ip_info.inspect }"
|
823
834
|
deal_with_destination_ip( src, ip_info )
|
824
835
|
return
|
825
836
|
end
|
826
837
|
|
827
|
-
# puts "
|
838
|
+
# puts "debug expire #{ domain } resolv cache"
|
828
839
|
@resolv_caches.delete( domain )
|
829
840
|
end
|
830
841
|
|
831
842
|
src_info = @src_infos[ src ]
|
832
843
|
src_info[ :proxy_type ] = :checking
|
833
844
|
|
834
|
-
if @use_remote_resolv then
|
835
|
-
data = "#{ [ RESOLV, src_info[ :id ] ].pack( 'CQ>' ) }#{ domain }"
|
836
|
-
add_ctlmsg( data )
|
837
|
-
return
|
838
|
-
end
|
839
|
-
|
840
845
|
Thread.new do
|
841
846
|
begin
|
842
847
|
ip_info = Addrinfo.ip( domain )
|
@@ -854,6 +859,33 @@ module Girl
|
|
854
859
|
end
|
855
860
|
end
|
856
861
|
|
862
|
+
##
|
863
|
+
# send ctlmsg
|
864
|
+
#
|
865
|
+
def send_ctlmsg( data )
|
866
|
+
return if @ctl.nil? || @ctl.closed?
|
867
|
+
|
868
|
+
begin
|
869
|
+
@ctl.sendmsg( data, 0, @proxyd_addr )
|
870
|
+
@ctl_info[ :last_sent_at ] = Time.new
|
871
|
+
rescue Exception => e
|
872
|
+
puts "p#{ Process.pid } #{ Time.new } sendmsg #{ e.class }"
|
873
|
+
close_ctl( @ctl )
|
874
|
+
end
|
875
|
+
end
|
876
|
+
|
877
|
+
##
|
878
|
+
# set atun closing
|
879
|
+
#
|
880
|
+
def set_atun_closing( atun )
|
881
|
+
return if atun.closed?
|
882
|
+
atun_info = @atun_infos[ atun ]
|
883
|
+
return if atun_info[ :closing ]
|
884
|
+
# puts "debug set atun closing"
|
885
|
+
atun_info[ :closing ] = true
|
886
|
+
add_write( atun )
|
887
|
+
end
|
888
|
+
|
857
889
|
##
|
858
890
|
# set dst closing write
|
859
891
|
#
|
@@ -861,6 +893,7 @@ module Girl
|
|
861
893
|
return if dst.closed?
|
862
894
|
dst_info = @dst_infos[ dst ]
|
863
895
|
return if dst_info[ :closing_write ]
|
896
|
+
# puts "debug set dst closing write"
|
864
897
|
dst_info[ :closing_write ] = true
|
865
898
|
add_write( dst )
|
866
899
|
end
|
@@ -874,7 +907,7 @@ module Girl
|
|
874
907
|
src_info[ :proxy_type ] = :tunnel
|
875
908
|
src_id = src_info[ :id ]
|
876
909
|
|
877
|
-
if @
|
910
|
+
if @ctl && !@ctl.closed? && @ctl_info[ :atund_addr ] then
|
878
911
|
add_a_new_source( src )
|
879
912
|
else
|
880
913
|
@pending_srcs << src
|
@@ -892,17 +925,6 @@ module Girl
|
|
892
925
|
add_write( src )
|
893
926
|
end
|
894
927
|
|
895
|
-
##
|
896
|
-
# set tun closing write
|
897
|
-
#
|
898
|
-
def set_tun_closing_write( tun )
|
899
|
-
return if tun.closed?
|
900
|
-
tun_info = @tun_infos[ tun ]
|
901
|
-
return if tun_info[ :closing_write ]
|
902
|
-
tun_info[ :closing_write ] = true
|
903
|
-
add_write( tun )
|
904
|
-
end
|
905
|
-
|
906
928
|
##
|
907
929
|
# sub http request
|
908
930
|
#
|
@@ -916,7 +938,7 @@ module Girl
|
|
916
938
|
if proto && url && proto[ 0, 4 ] == 'HTTP' && url[ 0, 7 ] == 'http://' then
|
917
939
|
domain_port = url.split( '/' )[ 2 ]
|
918
940
|
data = data.sub( "http://#{ domain_port }", '' )
|
919
|
-
# puts "
|
941
|
+
# puts "debug subed #{ data.inspect } #{ domain_port }"
|
920
942
|
end
|
921
943
|
|
922
944
|
[ data, domain_port ]
|
@@ -926,14 +948,11 @@ module Girl
|
|
926
948
|
# read dotr
|
927
949
|
#
|
928
950
|
def read_dotr( dotr )
|
929
|
-
dotr.read_nonblock(
|
951
|
+
dotr.read_nonblock( 65535 )
|
930
952
|
|
931
|
-
if @
|
932
|
-
|
933
|
-
|
934
|
-
end
|
935
|
-
elsif @pre_proxy && !@pre_proxy.closed? && @pre_proxy_info[ :closing ] then
|
936
|
-
close_pre_proxy( @pre_proxy )
|
953
|
+
if @ctl_info && @ctl_info[ :closing ] then
|
954
|
+
send_ctlmsg( [ CTL_FIN ].pack( 'C' ) )
|
955
|
+
close_ctl( @ctl )
|
937
956
|
end
|
938
957
|
|
939
958
|
if @closing_srcs.any? then
|
@@ -959,13 +978,13 @@ module Girl
|
|
959
978
|
@resume_dsts.clear
|
960
979
|
end
|
961
980
|
|
962
|
-
if @
|
963
|
-
@
|
964
|
-
add_read(
|
965
|
-
@
|
981
|
+
if @resume_btuns.any? then
|
982
|
+
@resume_btuns.each do | btun |
|
983
|
+
add_read( btun )
|
984
|
+
@paused_btuns.delete( btun )
|
966
985
|
end
|
967
986
|
|
968
|
-
@
|
987
|
+
@resume_btuns.clear
|
969
988
|
end
|
970
989
|
end
|
971
990
|
|
@@ -981,7 +1000,7 @@ module Girl
|
|
981
1000
|
end
|
982
1001
|
|
983
1002
|
src_id = rand( ( 2 ** 64 ) - 2 ) + 1
|
984
|
-
# puts "
|
1003
|
+
# puts "debug accept a src #{ src_id } #{ addrinfo.ip_unpack.inspect }"
|
985
1004
|
|
986
1005
|
@srcs[ src_id ] = src
|
987
1006
|
@src_infos[ src ] = {
|
@@ -993,10 +1012,11 @@ module Girl
|
|
993
1012
|
is_connect: true, # 代理协议是http的场合,是否是CONNECT
|
994
1013
|
rbuff: '', # 读到的流量
|
995
1014
|
dst: nil, # :direct的场合,对应的dst
|
996
|
-
|
997
|
-
|
1015
|
+
ctl: nil, # :tunnel的场合,对应的ctl
|
1016
|
+
atun: nil, # :tunnel的场合,对应的atun
|
1017
|
+
btun: nil, # :tunnel的场合,对应的btun
|
998
1018
|
dst_id: nil, # 远端dst id
|
999
|
-
wbuff: '', # 从dst/
|
1019
|
+
wbuff: '', # 从dst/btun读到的流量
|
1000
1020
|
created_at: Time.new, # 创建时间
|
1001
1021
|
last_recv_at: nil, # 上一次收到新流量(由dst收到,或者由tun收到)的时间
|
1002
1022
|
last_sent_at: nil, # 上一次发出流量(由dst发出,或者由tun发出)的时间
|
@@ -1005,75 +1025,50 @@ module Girl
|
|
1005
1025
|
|
1006
1026
|
add_read( src, :src )
|
1007
1027
|
|
1008
|
-
|
1009
|
-
|
1010
|
-
new_a_pre_proxy
|
1028
|
+
if @ctl.nil? || @ctl.closed? then
|
1029
|
+
new_a_ctl
|
1011
1030
|
end
|
1012
1031
|
end
|
1013
1032
|
|
1014
1033
|
##
|
1015
|
-
# read
|
1034
|
+
# read ctl
|
1016
1035
|
#
|
1017
|
-
def
|
1018
|
-
if proxy.closed? then
|
1019
|
-
puts "p#{ Process.pid } #{ Time.new } read proxy but proxy closed?"
|
1020
|
-
return
|
1021
|
-
end
|
1022
|
-
|
1036
|
+
def read_ctl( ctl )
|
1023
1037
|
begin
|
1024
|
-
data =
|
1025
|
-
rescue IO::WaitReadable
|
1026
|
-
return
|
1027
|
-
rescue Errno::EINTR
|
1028
|
-
puts e.class
|
1029
|
-
return
|
1038
|
+
data, addrinfo, rflags, *controls = ctl.recvmsg
|
1030
1039
|
rescue Exception => e
|
1031
|
-
|
1032
|
-
|
1040
|
+
puts "p#{ Process.pid } #{ Time.new } recvmsg #{ e.class }"
|
1041
|
+
close_ctl( ctl )
|
1033
1042
|
return
|
1034
1043
|
end
|
1035
1044
|
|
1036
|
-
|
1037
|
-
|
1038
|
-
data.split( SEPARATE ).each do | ctlmsg |
|
1039
|
-
next unless ctlmsg[ 0 ]
|
1040
|
-
|
1041
|
-
ctl_num = ctlmsg[ 0 ].unpack( 'C' ).first
|
1045
|
+
ctl_num = data[ 0 ].unpack( 'C' ).first
|
1042
1046
|
|
1043
|
-
|
1044
|
-
|
1045
|
-
|
1046
|
-
|
1047
|
-
|
1048
|
-
|
1047
|
+
case ctl_num
|
1048
|
+
when TUND_PORT then
|
1049
|
+
return if @ctl_info[ :atund_addr ] || data.size != 5
|
1050
|
+
atund_port, btund_port = data[ 1, 4 ].unpack( 'nn' )
|
1051
|
+
puts "p#{ Process.pid } #{ Time.new } got tund port #{ atund_port } #{ btund_port }"
|
1052
|
+
@ctl_info[ :resends ].delete( [ HELLO ].pack( 'C' ) )
|
1053
|
+
@ctl_info[ :atund_addr ] = Socket.sockaddr_in( atund_port, @proxyd_host )
|
1054
|
+
@ctl_info[ :btund_addr ] = Socket.sockaddr_in( btund_port, @proxyd_host )
|
1055
|
+
@ctl_info[ :last_recv_at ] = Time.new
|
1049
1056
|
|
1050
|
-
|
1051
|
-
|
1052
|
-
|
1053
|
-
|
1054
|
-
end
|
1055
|
-
when PAIRED then
|
1056
|
-
next if ctlmsg.size != 11
|
1057
|
-
src_id, dst_id = ctlmsg[ 1, 10 ].unpack( 'Q>n' )
|
1058
|
-
# puts "debug1 got paired #{ src_id } #{ dst_id }"
|
1059
|
-
new_a_pre_tun( src_id, dst_id )
|
1060
|
-
when RESOLVED then
|
1061
|
-
next if ctlmsg.size <= 9
|
1062
|
-
src_id = ctlmsg[ 1, 8 ].unpack( 'Q>' ).first
|
1063
|
-
src = @srcs[ src_id ]
|
1064
|
-
next if src.nil? || src.closed?
|
1065
|
-
src_info = @src_infos[ src ]
|
1066
|
-
ip = ctlmsg[ 9..-1 ]
|
1067
|
-
puts "p#{ Process.pid } #{ Time.new } remote resolved #{ src_info[ :destination_domain ] } #{ ip }"
|
1068
|
-
ip_info = Addrinfo.ip( ip )
|
1069
|
-
deal_with_destination_ip( src, ip_info )
|
1070
|
-
when TUND_FIN then
|
1071
|
-
puts "p#{ Process.pid } #{ Time.new } got tund fin"
|
1072
|
-
close_proxy( proxy )
|
1073
|
-
return
|
1074
|
-
when HEARTBEAT
|
1075
|
-
# puts "debug1 #{ Time.new } got heartbeat"
|
1057
|
+
if @pending_srcs.any? then
|
1058
|
+
puts "p#{ Process.pid } #{ Time.new } send pending sources"
|
1059
|
+
@pending_srcs.each { | src | add_a_new_source( src ) }
|
1060
|
+
@pending_srcs.clear
|
1076
1061
|
end
|
1062
|
+
when PAIRED then
|
1063
|
+
return if @ctl_info[ :atund_addr ].nil? || @ctl_info[ :btund_addr ].nil? || data.size != 11
|
1064
|
+
src_id, dst_id = data[ 1, 10 ].unpack( 'Q>n' )
|
1065
|
+
# puts "debug got paired #{ src_id } #{ dst_id }"
|
1066
|
+
@ctl_info[ :resends ].delete( [ A_NEW_SOURCE, src_id ].pack( 'CQ>' ) )
|
1067
|
+
@ctl_info[ :last_recv_at ] = Time.new
|
1068
|
+
new_tuns( src_id, dst_id )
|
1069
|
+
when UNKNOWN_CTL_ADDR then
|
1070
|
+
puts "p#{ Process.pid } #{ Time.new } got unknown ctl addr, close ctl"
|
1071
|
+
close_ctl( ctl )
|
1077
1072
|
end
|
1078
1073
|
end
|
1079
1074
|
|
@@ -1086,33 +1081,38 @@ module Girl
|
|
1086
1081
|
return
|
1087
1082
|
end
|
1088
1083
|
|
1084
|
+
src_info = @src_infos[ src ]
|
1085
|
+
|
1089
1086
|
begin
|
1090
|
-
data = src.read_nonblock(
|
1091
|
-
rescue IO::WaitReadable
|
1087
|
+
data = src.read_nonblock( 65535 )
|
1088
|
+
rescue IO::WaitReadable
|
1092
1089
|
print 'r'
|
1093
1090
|
return
|
1094
1091
|
rescue Exception => e
|
1095
|
-
# puts "
|
1096
|
-
|
1092
|
+
# puts "debug read src #{ e.class }"
|
1093
|
+
close_read_src( src )
|
1097
1094
|
dst = src_info[ :dst ]
|
1098
1095
|
|
1099
1096
|
if dst then
|
1100
1097
|
set_dst_closing_write( dst )
|
1101
1098
|
else
|
1102
|
-
|
1103
|
-
|
1099
|
+
atun = src_info[ :atun ]
|
1100
|
+
|
1101
|
+
if atun then
|
1102
|
+
set_atun_closing( atun )
|
1103
|
+
end
|
1104
1104
|
end
|
1105
1105
|
|
1106
1106
|
return
|
1107
1107
|
end
|
1108
1108
|
|
1109
|
-
|
1109
|
+
# puts "debug read src #{ data.bytesize }"
|
1110
1110
|
proxy_type = src_info[ :proxy_type ]
|
1111
1111
|
|
1112
1112
|
case proxy_type
|
1113
1113
|
when :uncheck then
|
1114
1114
|
if data[ 0, 7 ] == 'CONNECT' then
|
1115
|
-
# puts "
|
1115
|
+
# puts "debug CONNECT"
|
1116
1116
|
domain_port = data.split( "\r\n" )[ 0 ].split( ' ' )[ 1 ]
|
1117
1117
|
|
1118
1118
|
unless domain_port then
|
@@ -1121,7 +1121,7 @@ module Girl
|
|
1121
1121
|
return
|
1122
1122
|
end
|
1123
1123
|
elsif data[ 0 ].unpack( 'C' ).first == 5 then
|
1124
|
-
# puts "
|
1124
|
+
# puts "debug socks5 #{ data.inspect }"
|
1125
1125
|
|
1126
1126
|
# https://tools.ietf.org/html/rfc1928
|
1127
1127
|
#
|
@@ -1150,11 +1150,11 @@ module Girl
|
|
1150
1150
|
src_info[ :proxy_type ] = :negotiation
|
1151
1151
|
return
|
1152
1152
|
else
|
1153
|
-
# puts "
|
1153
|
+
# puts "debug not CONNECT #{ data.inspect }"
|
1154
1154
|
host_line = data.split( "\r\n" ).find { | _line | _line[ 0, 6 ] == 'Host: ' }
|
1155
1155
|
|
1156
1156
|
unless host_line then
|
1157
|
-
# puts "
|
1157
|
+
# puts "debug not found host line"
|
1158
1158
|
add_closing_src( src )
|
1159
1159
|
return
|
1160
1160
|
end
|
@@ -1162,7 +1162,7 @@ module Girl
|
|
1162
1162
|
data, domain_port = sub_http_request( data )
|
1163
1163
|
|
1164
1164
|
unless domain_port then
|
1165
|
-
# puts "
|
1165
|
+
# puts "debug not HTTP"
|
1166
1166
|
domain_port = host_line.split( ' ' )[ 1 ]
|
1167
1167
|
|
1168
1168
|
unless domain_port then
|
@@ -1185,7 +1185,7 @@ module Girl
|
|
1185
1185
|
|
1186
1186
|
resolve_domain( src, domain )
|
1187
1187
|
when :checking then
|
1188
|
-
# puts "
|
1188
|
+
# puts "debug add src rbuff before resolved #{ data.inspect }"
|
1189
1189
|
src_info[ :rbuff ] << data
|
1190
1190
|
when :negotiation then
|
1191
1191
|
# +----+-----+-------+------+----------+----------+
|
@@ -1193,11 +1193,11 @@ module Girl
|
|
1193
1193
|
# +----+-----+-------+------+----------+----------+
|
1194
1194
|
# | 1 | 1 | X'00' | 1 | Variable | 2 |
|
1195
1195
|
# +----+-----+-------+------+----------+----------+
|
1196
|
-
# puts "
|
1196
|
+
# puts "debug negotiation #{ data.inspect }"
|
1197
1197
|
ver, cmd, rsv, atyp = data[ 0, 4 ].unpack( 'C4' )
|
1198
1198
|
|
1199
1199
|
if cmd == 1 then
|
1200
|
-
# puts "
|
1200
|
+
# puts "debug socks5 CONNECT"
|
1201
1201
|
|
1202
1202
|
if atyp == 1 then
|
1203
1203
|
destination_host, destination_port = data[ 4, 6 ].unpack( 'Nn' )
|
@@ -1206,7 +1206,7 @@ module Girl
|
|
1206
1206
|
destination_ip = destination_addrinfo.ip_address
|
1207
1207
|
src_info[ :destination_domain ] = destination_ip
|
1208
1208
|
src_info[ :destination_port ] = destination_port
|
1209
|
-
# puts "
|
1209
|
+
# puts "debug IP V4 address #{ destination_addrinfo.ip_unpack.inspect }"
|
1210
1210
|
deal_with_destination_ip( src, destination_addrinfo )
|
1211
1211
|
elsif atyp == 3 then
|
1212
1212
|
domain_len = data[ 4 ].unpack( 'C' ).first
|
@@ -1216,7 +1216,7 @@ module Girl
|
|
1216
1216
|
port = data[ ( 5 + domain_len ), 2 ].unpack( 'n' ).first
|
1217
1217
|
src_info[ :destination_domain ] = domain
|
1218
1218
|
src_info[ :destination_port ] = port
|
1219
|
-
# puts "
|
1219
|
+
# puts "debug DOMAINNAME #{ domain } #{ port }"
|
1220
1220
|
resolve_domain( src, domain )
|
1221
1221
|
end
|
1222
1222
|
end
|
@@ -1224,35 +1224,29 @@ module Girl
|
|
1224
1224
|
puts "p#{ Process.pid } #{ Time.new } socks5 cmd #{ cmd } not implement"
|
1225
1225
|
end
|
1226
1226
|
when :tunnel then
|
1227
|
-
|
1227
|
+
atun = src_info[ :atun ]
|
1228
1228
|
|
1229
|
-
if
|
1230
|
-
|
1231
|
-
|
1232
|
-
data, _ = sub_http_request( data )
|
1233
|
-
end
|
1229
|
+
if atun && !src_info[ :is_connect ] then
|
1230
|
+
data, _ = sub_http_request( data )
|
1231
|
+
end
|
1234
1232
|
|
1235
|
-
|
1236
|
-
|
1237
|
-
end
|
1233
|
+
if atun then
|
1234
|
+
add_atun_wbuff( atun, pack_a_chunk( data ) )
|
1238
1235
|
else
|
1239
|
-
# puts "
|
1236
|
+
# puts "debug add src.rbuff #{ data.bytesize }"
|
1240
1237
|
add_src_rbuff( src, data )
|
1241
1238
|
end
|
1242
1239
|
when :direct then
|
1243
1240
|
dst = src_info[ :dst ]
|
1244
1241
|
|
1245
1242
|
if dst then
|
1246
|
-
unless
|
1247
|
-
|
1248
|
-
data, _ = sub_http_request( data )
|
1249
|
-
end
|
1250
|
-
|
1251
|
-
# puts "debug2 add dst.wbuff #{ data.bytesize }"
|
1252
|
-
add_dst_wbuff( dst, data )
|
1243
|
+
unless src_info[ :is_connect ] then
|
1244
|
+
data, _ = sub_http_request( data )
|
1253
1245
|
end
|
1246
|
+
|
1247
|
+
add_dst_wbuff( dst, data )
|
1254
1248
|
else
|
1255
|
-
# puts "
|
1249
|
+
# puts "debug add src.rbuff #{ data.bytesize }"
|
1256
1250
|
add_src_rbuff( src, data )
|
1257
1251
|
end
|
1258
1252
|
end
|
@@ -1267,82 +1261,88 @@ module Girl
|
|
1267
1261
|
return
|
1268
1262
|
end
|
1269
1263
|
|
1264
|
+
dst_info = @dst_infos[ dst ]
|
1265
|
+
src = dst_info[ :src ]
|
1266
|
+
|
1270
1267
|
begin
|
1271
|
-
data = dst.read_nonblock(
|
1272
|
-
rescue IO::WaitReadable
|
1268
|
+
data = dst.read_nonblock( 65535 )
|
1269
|
+
rescue IO::WaitReadable
|
1273
1270
|
print 'r'
|
1274
1271
|
return
|
1275
1272
|
rescue Exception => e
|
1276
|
-
# puts "
|
1277
|
-
|
1278
|
-
src = dst_info[ :src ]
|
1273
|
+
# puts "debug read dst #{ e.class }"
|
1274
|
+
close_read_dst( dst )
|
1279
1275
|
set_src_closing_write( src )
|
1280
1276
|
return
|
1281
1277
|
end
|
1282
1278
|
|
1283
|
-
|
1284
|
-
src = dst_info[ :src ]
|
1279
|
+
# puts "debug read dst #{ data.bytesize }"
|
1285
1280
|
add_src_wbuff( src, data )
|
1286
1281
|
end
|
1287
1282
|
|
1288
1283
|
##
|
1289
|
-
# read
|
1284
|
+
# read btun
|
1290
1285
|
#
|
1291
|
-
def
|
1292
|
-
if
|
1293
|
-
puts "p#{ Process.pid } #{ Time.new } read
|
1286
|
+
def read_btun( btun )
|
1287
|
+
if btun.closed? then
|
1288
|
+
puts "p#{ Process.pid } #{ Time.new } read btun but btun closed?"
|
1294
1289
|
return
|
1295
1290
|
end
|
1296
1291
|
|
1292
|
+
btun_info = @btun_infos[ btun ]
|
1293
|
+
src = btun_info[ :src ]
|
1294
|
+
|
1297
1295
|
begin
|
1298
|
-
data =
|
1299
|
-
rescue IO::WaitReadable
|
1300
|
-
return
|
1301
|
-
rescue Errno::EINTR
|
1302
|
-
puts e.class
|
1303
|
-
return
|
1296
|
+
data = btun.read_nonblock( READ_SIZE )
|
1304
1297
|
rescue Exception => e
|
1305
|
-
# puts "
|
1306
|
-
|
1307
|
-
src = tun_info[ :src ]
|
1308
|
-
set_src_closing_write( src )
|
1309
|
-
return
|
1310
|
-
end
|
1298
|
+
# puts "debug read btun #{ btun_info[ :im ] } #{ e.class }"
|
1299
|
+
close_btun( btun )
|
1311
1300
|
|
1312
|
-
|
1313
|
-
|
1314
|
-
|
1315
|
-
add_src_wbuff( src, data )
|
1316
|
-
end
|
1301
|
+
if src then
|
1302
|
+
set_src_closing_write( src )
|
1303
|
+
end
|
1317
1304
|
|
1318
|
-
##
|
1319
|
-
# write proxy
|
1320
|
-
#
|
1321
|
-
def write_proxy( proxy )
|
1322
|
-
if proxy.closed? then
|
1323
|
-
puts "p#{ Process.pid } #{ Time.new } write proxy but proxy closed?"
|
1324
1305
|
return
|
1325
1306
|
end
|
1326
1307
|
|
1327
|
-
|
1328
|
-
|
1308
|
+
until data.empty? do
|
1309
|
+
rbuff = btun_info[ :rbuff ]
|
1310
|
+
wait_bytes = btun_info[ :wait_bytes ]
|
1329
1311
|
|
1330
|
-
|
1331
|
-
|
1332
|
-
|
1333
|
-
|
1334
|
-
|
1335
|
-
|
1336
|
-
|
1337
|
-
|
1338
|
-
|
1339
|
-
|
1312
|
+
if wait_bytes > 0 then
|
1313
|
+
len = wait_bytes
|
1314
|
+
# puts "debug wait bytes #{ len }"
|
1315
|
+
else
|
1316
|
+
if data.bytesize <= 2 then
|
1317
|
+
# puts "debug unexpect data length #{ data.bytesize }"
|
1318
|
+
close_btun( btun )
|
1319
|
+
return
|
1320
|
+
end
|
1321
|
+
|
1322
|
+
len = data[ 0, 2 ].unpack( 'n' ).first
|
1323
|
+
# puts "debug read len #{ len }"
|
1324
|
+
data = data[ 2..-1 ]
|
1340
1325
|
end
|
1341
1326
|
|
1342
|
-
|
1343
|
-
|
1327
|
+
chunk = data[ 0, len ]
|
1328
|
+
chunk_size = chunk.bytesize
|
1329
|
+
|
1330
|
+
if chunk_size == len then
|
1331
|
+
# 取完整了
|
1332
|
+
chunk = @custom.decode( "#{ rbuff }#{ chunk }" )
|
1333
|
+
# puts "debug decode and add src.wbuff #{ chunk.bytesize }"
|
1334
|
+
add_src_wbuff( src, chunk )
|
1335
|
+
btun_info[ :rbuff ].clear
|
1336
|
+
btun_info[ :wait_bytes ] = 0
|
1337
|
+
else
|
1338
|
+
# 暂存
|
1339
|
+
# puts "debug add btun.rbuff #{ chunk_size } wait bytes #{ len - chunk_size }"
|
1340
|
+
btun_info[ :rbuff ] << chunk
|
1341
|
+
btun_info[ :wait_bytes ] = len - chunk_size
|
1342
|
+
end
|
1344
1343
|
|
1345
|
-
|
1344
|
+
data = data[ chunk_size..-1 ]
|
1345
|
+
end
|
1346
1346
|
end
|
1347
1347
|
|
1348
1348
|
##
|
@@ -1372,24 +1372,27 @@ module Girl
|
|
1372
1372
|
# 写入
|
1373
1373
|
begin
|
1374
1374
|
written = src.write_nonblock( data )
|
1375
|
-
rescue IO::WaitWritable
|
1375
|
+
rescue IO::WaitWritable
|
1376
1376
|
print 'w'
|
1377
1377
|
return
|
1378
1378
|
rescue Exception => e
|
1379
|
-
# puts "
|
1379
|
+
# puts "debug write src #{ e.class }"
|
1380
1380
|
close_write_src( src )
|
1381
1381
|
|
1382
1382
|
if dst then
|
1383
1383
|
close_read_dst( dst )
|
1384
1384
|
else
|
1385
|
-
|
1386
|
-
|
1385
|
+
btun = src_info[ :btun ]
|
1386
|
+
|
1387
|
+
if btun then
|
1388
|
+
close_btun( btun )
|
1389
|
+
end
|
1387
1390
|
end
|
1388
1391
|
|
1389
1392
|
return
|
1390
1393
|
end
|
1391
1394
|
|
1392
|
-
# puts "
|
1395
|
+
# puts "debug write src #{ written }"
|
1393
1396
|
data = data[ written..-1 ]
|
1394
1397
|
src_info[ :wbuff ] = data
|
1395
1398
|
end
|
@@ -1421,11 +1424,11 @@ module Girl
|
|
1421
1424
|
# 写入
|
1422
1425
|
begin
|
1423
1426
|
written = dst.write_nonblock( data )
|
1424
|
-
rescue IO::WaitWritable
|
1427
|
+
rescue IO::WaitWritable
|
1425
1428
|
print 'w'
|
1426
1429
|
return
|
1427
1430
|
rescue Exception => e
|
1428
|
-
# puts "
|
1431
|
+
# puts "debug write dst #{ e.class }"
|
1429
1432
|
close_write_dst( dst )
|
1430
1433
|
close_read_src( src )
|
1431
1434
|
return
|
@@ -1441,24 +1444,24 @@ module Girl
|
|
1441
1444
|
end
|
1442
1445
|
|
1443
1446
|
##
|
1444
|
-
# write
|
1447
|
+
# write atun
|
1445
1448
|
#
|
1446
|
-
def
|
1447
|
-
if
|
1448
|
-
puts "p#{ Process.pid } #{ Time.new } write
|
1449
|
+
def write_atun( atun )
|
1450
|
+
if atun.closed? then
|
1451
|
+
puts "p#{ Process.pid } #{ Time.new } write atun but atun closed?"
|
1449
1452
|
return
|
1450
1453
|
end
|
1451
1454
|
|
1452
|
-
|
1453
|
-
src =
|
1454
|
-
data =
|
1455
|
+
atun_info = @atun_infos[ atun ]
|
1456
|
+
src = atun_info[ :src ]
|
1457
|
+
data = atun_info[ :wbuff ]
|
1455
1458
|
|
1456
1459
|
# 写前为空,处理关闭写
|
1457
1460
|
if data.empty? then
|
1458
|
-
if
|
1459
|
-
|
1461
|
+
if atun_info[ :closing ] then
|
1462
|
+
close_atun( atun )
|
1460
1463
|
else
|
1461
|
-
@writes.delete(
|
1464
|
+
@writes.delete( atun )
|
1462
1465
|
end
|
1463
1466
|
|
1464
1467
|
return
|
@@ -1466,23 +1469,20 @@ module Girl
|
|
1466
1469
|
|
1467
1470
|
# 写入
|
1468
1471
|
begin
|
1469
|
-
written =
|
1470
|
-
rescue IO::
|
1471
|
-
# OpenSSL::SSL::SSLErrorWaitReadable
|
1472
|
-
return
|
1473
|
-
rescue IO::WaitWritable, Errno::EINTR
|
1472
|
+
written = atun.write_nonblock( data )
|
1473
|
+
rescue IO::WaitWritable
|
1474
1474
|
print 'w'
|
1475
1475
|
return
|
1476
1476
|
rescue Exception => e
|
1477
|
-
# puts "
|
1478
|
-
|
1477
|
+
# puts "debug write atun #{ e.class }"
|
1478
|
+
close_atun( atun )
|
1479
1479
|
close_read_src( src )
|
1480
1480
|
return
|
1481
1481
|
end
|
1482
1482
|
|
1483
|
-
# puts "
|
1483
|
+
# puts "debug write atun #{ written }"
|
1484
1484
|
data = data[ written..-1 ]
|
1485
|
-
|
1485
|
+
atun_info[ :wbuff ] = data
|
1486
1486
|
|
1487
1487
|
unless src.closed? then
|
1488
1488
|
src_info = @src_infos[ src ]
|
@@ -1491,112 +1491,30 @@ module Girl
|
|
1491
1491
|
end
|
1492
1492
|
|
1493
1493
|
##
|
1494
|
-
# write
|
1495
|
-
#
|
1496
|
-
def write_pre_proxy( pre_proxy )
|
1497
|
-
if pre_proxy.closed? then
|
1498
|
-
puts "p#{ Process.pid } #{ Time.new } write pre proxy but pre proxy closed?"
|
1499
|
-
return
|
1500
|
-
end
|
1501
|
-
|
1502
|
-
proxy = OpenSSL::SSL::SSLSocket.new pre_proxy
|
1503
|
-
|
1504
|
-
begin
|
1505
|
-
proxy.connect_nonblock
|
1506
|
-
rescue IO::WaitReadable
|
1507
|
-
rescue IO::WaitWritable
|
1508
|
-
rescue Exception => e
|
1509
|
-
puts "p#{ Process.pid } #{ Time.new } proxy connect #{ e.class }, close proxy"
|
1510
|
-
proxy.close
|
1511
|
-
close_pre_proxy( pre_proxy )
|
1512
|
-
return
|
1513
|
-
end
|
1514
|
-
|
1515
|
-
@proxy = proxy
|
1516
|
-
@proxy_info = {
|
1517
|
-
ctlmsgs: [], # ctlmsg
|
1518
|
-
tund_addr: nil, # tund地址
|
1519
|
-
created_at: Time.new, # 创建时间
|
1520
|
-
last_recv_at: nil, # 上一次收到流量的时间
|
1521
|
-
closing: false # 是否准备关闭
|
1522
|
-
}
|
1523
|
-
add_read( proxy, :proxy )
|
1524
|
-
hello = @custom.hello
|
1525
|
-
puts "p#{ Process.pid } #{ Time.new } tunnel #{ hello.inspect }"
|
1526
|
-
data = "#{ [ HELLO ].pack( 'C' ) }#{ hello }"
|
1527
|
-
add_ctlmsg( data )
|
1528
|
-
|
1529
|
-
@roles.delete( pre_proxy )
|
1530
|
-
@writes.delete( pre_proxy )
|
1531
|
-
end
|
1532
|
-
|
1533
|
-
##
|
1534
|
-
# write pre tun
|
1494
|
+
# write btun
|
1535
1495
|
#
|
1536
|
-
def
|
1537
|
-
if
|
1538
|
-
puts "p#{ Process.pid } #{ Time.new } write
|
1496
|
+
def write_btun( btun )
|
1497
|
+
if btun.closed? then
|
1498
|
+
puts "p#{ Process.pid } #{ Time.new } write btun but btun closed?"
|
1539
1499
|
return
|
1540
1500
|
end
|
1541
1501
|
|
1542
|
-
|
1543
|
-
|
1544
|
-
|
1545
|
-
if src.closed? then
|
1546
|
-
puts "p#{ Process.pid } #{ Time.new } new a tun but src closed?"
|
1547
|
-
return
|
1548
|
-
end
|
1549
|
-
|
1550
|
-
tun = OpenSSL::SSL::SSLSocket.new pre_tun
|
1502
|
+
btun_info = @btun_infos[ btun ]
|
1503
|
+
data = btun_info[ :wbuff ]
|
1551
1504
|
|
1505
|
+
# 写入dst id
|
1552
1506
|
begin
|
1553
|
-
|
1554
|
-
rescue IO::WaitReadable
|
1555
|
-
rescue IO::WaitWritable
|
1507
|
+
written = btun.write( data )
|
1556
1508
|
rescue Exception => e
|
1557
|
-
puts "
|
1558
|
-
|
1559
|
-
|
1509
|
+
# puts "debug write btun #{ e.class }"
|
1510
|
+
src = btun_info[ :src ]
|
1511
|
+
close_btun( btun )
|
1512
|
+
add_closing_src( src )
|
1560
1513
|
return
|
1561
1514
|
end
|
1562
1515
|
|
1563
|
-
|
1564
|
-
|
1565
|
-
# puts "debug1 set tun.wbuff #{ dst_id }"
|
1566
|
-
data = [ dst_id ].pack( 'n' )
|
1567
|
-
|
1568
|
-
unless src_info[ :rbuff ].empty? then
|
1569
|
-
# puts "debug1 move src.rbuff to tun.wbuff"
|
1570
|
-
data << src_info[ :rbuff ]
|
1571
|
-
end
|
1572
|
-
|
1573
|
-
domain = src_info[ :destination_domain ]
|
1574
|
-
@tun_infos[ tun ] = {
|
1575
|
-
pre_tun: pre_tun, # 对应pre tun
|
1576
|
-
src: src, # 对应src
|
1577
|
-
domain: domain, # 目的地
|
1578
|
-
wbuff: data, # 写前
|
1579
|
-
closing_write: false, # 准备关闭写
|
1580
|
-
close_read: false, # 已经关闭读
|
1581
|
-
close_write: false # 已经关闭写
|
1582
|
-
}
|
1583
|
-
|
1584
|
-
src_info[ :tun ] = tun
|
1585
|
-
add_read( tun, :tun )
|
1586
|
-
add_write( tun )
|
1587
|
-
|
1588
|
-
if src_info[ :proxy_proto ] == :http then
|
1589
|
-
if src_info[ :is_connect ] then
|
1590
|
-
# puts "debug1 add src.wbuff http ok"
|
1591
|
-
add_src_wbuff( src, HTTP_OK )
|
1592
|
-
end
|
1593
|
-
elsif src_info[ :proxy_proto ] == :socks5 then
|
1594
|
-
add_socks5_conn_reply( src )
|
1595
|
-
end
|
1596
|
-
|
1597
|
-
@pre_tun_infos.delete( pre_tun )
|
1598
|
-
@roles.delete( pre_tun )
|
1599
|
-
@writes.delete( pre_tun )
|
1516
|
+
# puts "debug write btun #{ written }"
|
1517
|
+
@writes.delete( btun )
|
1600
1518
|
end
|
1601
1519
|
|
1602
1520
|
end
|