girl 3.9.0 → 4.4.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 -1
- data/lib/girl/concurrent_hash.rb +4 -0
- data/lib/girl/{custom_dns_query.rb → custom.rb} +1 -1
- data/lib/girl/head.rb +11 -1
- data/lib/girl/proxy.rb +28 -31
- data/lib/girl/proxy_custom.rb +16 -13
- data/lib/girl/proxy_worker.rb +529 -604
- data/lib/girl/proxyd.rb +1 -15
- data/lib/girl/proxyd_custom.rb +12 -9
- data/lib/girl/proxyd_worker.rb +550 -472
- data/lib/girl/relay.rb +1 -2
- data/lib/girl/relay_worker.rb +498 -585
- data/lib/girl/resolv_custom.rb +2 -2
- data/lib/girl/resolvd_worker.rb +4 -4
- data/lib/girl/ssl.rb +1 -14
- data/lib/girl/ssl_worker.rb +131 -91
- data/lib/girl/version.rb +1 -1
- metadata +3 -3
data/lib/girl/proxyd.rb
CHANGED
@@ -5,7 +5,6 @@ require 'girl/proxyd_custom'
|
|
5
5
|
require 'girl/proxyd_worker'
|
6
6
|
require 'girl/version'
|
7
7
|
require 'json'
|
8
|
-
require 'openssl'
|
9
8
|
require 'socket'
|
10
9
|
|
11
10
|
##
|
@@ -47,26 +46,13 @@ module Girl
|
|
47
46
|
puts title
|
48
47
|
puts "proxyd port #{ proxyd_port } infod port #{ infod_port } worker count #{ worker_count }"
|
49
48
|
|
50
|
-
now = Time.new
|
51
|
-
name = OpenSSL::X509::Name.new
|
52
|
-
key = OpenSSL::PKey::RSA.new 2048
|
53
|
-
cert = OpenSSL::X509::Certificate.new
|
54
|
-
cert.version = 2
|
55
|
-
cert.serial = 0
|
56
|
-
cert.not_before = now
|
57
|
-
cert.not_after = now + 365 * 24 * 60 * 60
|
58
|
-
cert.public_key = key.public_key
|
59
|
-
cert.subject = name
|
60
|
-
cert.issuer = name
|
61
|
-
cert.sign key, OpenSSL::Digest.new('SHA1')
|
62
|
-
|
63
49
|
$0 = title
|
64
50
|
workers = []
|
65
51
|
|
66
52
|
worker_count.times do | i |
|
67
53
|
workers << fork do
|
68
54
|
$0 = 'girl proxyd worker'
|
69
|
-
worker = Girl::ProxydWorker.new( proxyd_port, infod_port
|
55
|
+
worker = Girl::ProxydWorker.new( proxyd_port, infod_port )
|
70
56
|
|
71
57
|
Signal.trap( :TERM ) do
|
72
58
|
puts "w#{ i } exit"
|
data/lib/girl/proxyd_custom.rb
CHANGED
@@ -1,9 +1,12 @@
|
|
1
|
-
|
2
|
-
|
3
|
-
|
4
|
-
|
5
|
-
|
6
|
-
|
7
|
-
|
8
|
-
|
9
|
-
end
|
1
|
+
require 'girl/custom'
|
2
|
+
|
3
|
+
module Girl
|
4
|
+
class ProxydCustom
|
5
|
+
include Custom
|
6
|
+
|
7
|
+
def check( data, addrinfo )
|
8
|
+
:success
|
9
|
+
end
|
10
|
+
|
11
|
+
end
|
12
|
+
end
|
data/lib/girl/proxyd_worker.rb
CHANGED
@@ -4,34 +4,31 @@ module Girl
|
|
4
4
|
##
|
5
5
|
# initialize
|
6
6
|
#
|
7
|
-
def initialize( proxyd_port, infod_port
|
7
|
+
def initialize( proxyd_port, infod_port )
|
8
8
|
@custom = Girl::ProxydCustom.new
|
9
9
|
@reads = []
|
10
10
|
@writes = []
|
11
|
-
@
|
11
|
+
@deleting_ctl_infos = []
|
12
12
|
@closing_dsts = []
|
13
|
-
@closing_tuns = []
|
14
13
|
@paused_dsts = []
|
15
|
-
@
|
14
|
+
@paused_atuns = []
|
16
15
|
@resume_dsts = []
|
17
|
-
@
|
18
|
-
@roles = ConcurrentHash.new # sock => :dotr / :
|
19
|
-
@
|
16
|
+
@resume_atuns = []
|
17
|
+
@roles = ConcurrentHash.new # sock => :dotr / :ctld / :ctl / :infod / :dst / :atund / :btund / :atun / :btun
|
18
|
+
@ctl_infos = ConcurrentHash.new # ctl => {}
|
20
19
|
@dst_infos = ConcurrentHash.new # dst => {}
|
21
|
-
@
|
22
|
-
@
|
20
|
+
@atund_infos = ConcurrentHash.new # atund => {}
|
21
|
+
@btund_infos = ConcurrentHash.new # btund => {}
|
22
|
+
@atun_infos = ConcurrentHash.new # atun => {}
|
23
|
+
@btun_infos = ConcurrentHash.new # btun => {}
|
23
24
|
@resolv_caches = ConcurrentHash.new # domain => [ ip, created_at ]
|
24
25
|
@traff_ins = ConcurrentHash.new # im => 0
|
25
26
|
@traff_outs = ConcurrentHash.new # im => 0
|
26
27
|
|
27
|
-
context = OpenSSL::SSL::SSLContext.new
|
28
|
-
context.add_certificate( cert, key )
|
29
|
-
@context = context
|
30
|
-
|
31
28
|
dotr, dotw = IO.pipe
|
32
29
|
@dotw = dotw
|
33
30
|
add_read( dotr, :dotr )
|
34
|
-
|
31
|
+
new_a_ctld( proxyd_port )
|
35
32
|
new_a_infod( infod_port )
|
36
33
|
end
|
37
34
|
|
@@ -51,29 +48,29 @@ module Girl
|
|
51
48
|
case @roles[ sock ]
|
52
49
|
when :dotr then
|
53
50
|
read_dotr( sock )
|
54
|
-
when :
|
55
|
-
|
56
|
-
when :proxy then
|
57
|
-
read_proxy( sock )
|
51
|
+
when :ctld then
|
52
|
+
read_ctld( sock )
|
58
53
|
when :infod then
|
59
54
|
read_infod( sock )
|
60
55
|
when :dst then
|
61
56
|
read_dst( sock )
|
62
|
-
when :
|
63
|
-
|
64
|
-
when :
|
65
|
-
|
57
|
+
when :atund then
|
58
|
+
read_atund( sock )
|
59
|
+
when :btund then
|
60
|
+
read_btund( sock )
|
61
|
+
when :atun then
|
62
|
+
read_atun( sock )
|
63
|
+
when :btun then
|
64
|
+
read_btun( sock )
|
66
65
|
end
|
67
66
|
end
|
68
67
|
|
69
68
|
ws.each do | sock |
|
70
69
|
case @roles[ sock ]
|
71
|
-
when :proxy then
|
72
|
-
write_proxy( sock )
|
73
70
|
when :dst then
|
74
71
|
write_dst( sock )
|
75
|
-
when :
|
76
|
-
|
72
|
+
when :btun then
|
73
|
+
write_btun( sock )
|
77
74
|
end
|
78
75
|
end
|
79
76
|
end
|
@@ -86,26 +83,25 @@ module Girl
|
|
86
83
|
# quit!
|
87
84
|
#
|
88
85
|
def quit!
|
89
|
-
|
90
|
-
# puts "debug1 send tund fin"
|
91
|
-
data = [ TUND_FIN ].pack( 'C' )
|
92
|
-
proxy.write( data )
|
93
|
-
end
|
94
|
-
|
95
|
-
# puts "debug1 exit"
|
86
|
+
# puts "debug exit"
|
96
87
|
exit
|
97
88
|
end
|
98
89
|
|
99
90
|
private
|
100
91
|
|
101
92
|
##
|
102
|
-
# add
|
93
|
+
# add btun wbuff
|
103
94
|
#
|
104
|
-
def
|
105
|
-
return if
|
106
|
-
|
107
|
-
|
108
|
-
add_write(
|
95
|
+
def add_btun_wbuff( btun, data )
|
96
|
+
return if btun.closed?
|
97
|
+
btun_info = @btun_infos[ btun ]
|
98
|
+
btun_info[ :wbuff ] << data
|
99
|
+
add_write( btun )
|
100
|
+
|
101
|
+
if btun_info[ :wbuff ].bytesize >= WBUFF_LIMIT then
|
102
|
+
puts "p#{ Process.pid } #{ Time.new } pause dst #{ btun_info[ :domain_port ] }"
|
103
|
+
add_paused_dst( btun_info[ :dst ] )
|
104
|
+
end
|
109
105
|
end
|
110
106
|
|
111
107
|
##
|
@@ -116,7 +112,7 @@ module Girl
|
|
116
112
|
dst_info[ :rbuff ] << data
|
117
113
|
|
118
114
|
if dst_info[ :rbuff ].bytesize >= WBUFF_LIMIT then
|
119
|
-
# puts "
|
115
|
+
# puts "debug dst.rbuff full"
|
120
116
|
close_dst( dst )
|
121
117
|
end
|
122
118
|
end
|
@@ -132,11 +128,20 @@ module Girl
|
|
132
128
|
add_write( dst )
|
133
129
|
|
134
130
|
if dst_info[ :wbuff ].bytesize >= WBUFF_LIMIT then
|
135
|
-
puts "p#{ Process.pid } #{ Time.new } pause
|
136
|
-
|
131
|
+
puts "p#{ Process.pid } #{ Time.new } pause atun #{ dst_info[ :domain_port ] }"
|
132
|
+
add_paused_atun( dst_info[ :atun ] )
|
137
133
|
end
|
138
134
|
end
|
139
135
|
|
136
|
+
##
|
137
|
+
# add paused atun
|
138
|
+
#
|
139
|
+
def add_paused_atun( atun )
|
140
|
+
return if tun.closed? || @paused_atuns.include?( atun )
|
141
|
+
@reads.delete( atun )
|
142
|
+
@paused_atuns << atun
|
143
|
+
end
|
144
|
+
|
140
145
|
##
|
141
146
|
# add paused dst
|
142
147
|
#
|
@@ -146,15 +151,6 @@ module Girl
|
|
146
151
|
@paused_dsts << dst
|
147
152
|
end
|
148
153
|
|
149
|
-
##
|
150
|
-
# add paused tun
|
151
|
-
#
|
152
|
-
def add_paused_tun( tun )
|
153
|
-
return if tun.closed? || @paused_tuns.include?( tun )
|
154
|
-
@reads.delete( tun )
|
155
|
-
@paused_tuns << tun
|
156
|
-
end
|
157
|
-
|
158
154
|
##
|
159
155
|
# add read
|
160
156
|
#
|
@@ -169,6 +165,15 @@ module Girl
|
|
169
165
|
next_tick
|
170
166
|
end
|
171
167
|
|
168
|
+
##
|
169
|
+
# add resume atun
|
170
|
+
#
|
171
|
+
def add_resume_atun( atun )
|
172
|
+
return if @resume_atuns.include?( atun )
|
173
|
+
@resume_atuns << atun
|
174
|
+
next_tick
|
175
|
+
end
|
176
|
+
|
172
177
|
##
|
173
178
|
# add resume dst
|
174
179
|
#
|
@@ -179,36 +184,57 @@ module Girl
|
|
179
184
|
end
|
180
185
|
|
181
186
|
##
|
182
|
-
# add
|
187
|
+
# add write
|
183
188
|
#
|
184
|
-
def
|
185
|
-
return if @
|
186
|
-
@
|
189
|
+
def add_write( sock )
|
190
|
+
return if sock.closed? || @writes.include?( sock )
|
191
|
+
@writes << sock
|
187
192
|
next_tick
|
188
193
|
end
|
189
194
|
|
190
195
|
##
|
191
|
-
#
|
196
|
+
# close atun
|
192
197
|
#
|
193
|
-
def
|
194
|
-
return if
|
195
|
-
|
196
|
-
|
197
|
-
|
198
|
-
|
199
|
-
|
200
|
-
|
201
|
-
|
198
|
+
def close_atun( atun )
|
199
|
+
return if atun.closed?
|
200
|
+
# puts "debug close atun"
|
201
|
+
close_sock( atun )
|
202
|
+
del_atun_info( atun )
|
203
|
+
end
|
204
|
+
|
205
|
+
##
|
206
|
+
# close atund
|
207
|
+
#
|
208
|
+
def close_atund( atund )
|
209
|
+
return if atund.closed?
|
210
|
+
# puts "debug close atund"
|
211
|
+
close_sock( atund )
|
212
|
+
@atund_infos.delete( atund )
|
213
|
+
end
|
214
|
+
|
215
|
+
##
|
216
|
+
# close btun
|
217
|
+
#
|
218
|
+
def close_btun( btun )
|
219
|
+
return if btun.closed?
|
220
|
+
# puts "debug close btun"
|
221
|
+
close_sock( btun )
|
222
|
+
btun_info = @btun_infos.delete( btun )
|
223
|
+
dst = btun_info[ :dst ]
|
224
|
+
|
225
|
+
if dst then
|
226
|
+
@paused_dsts.delete( dst )
|
202
227
|
end
|
203
228
|
end
|
204
229
|
|
205
230
|
##
|
206
|
-
#
|
231
|
+
# close btund
|
207
232
|
#
|
208
|
-
def
|
209
|
-
return if
|
210
|
-
|
211
|
-
|
233
|
+
def close_btund( btund )
|
234
|
+
return if btund.closed?
|
235
|
+
# puts "debug close btund"
|
236
|
+
close_sock( btund )
|
237
|
+
@btund_infos.delete( btund )
|
212
238
|
end
|
213
239
|
|
214
240
|
##
|
@@ -216,14 +242,20 @@ module Girl
|
|
216
242
|
#
|
217
243
|
def close_dst( dst )
|
218
244
|
return if dst.closed?
|
219
|
-
# puts "
|
245
|
+
# puts "debug close dst"
|
220
246
|
close_sock( dst )
|
221
247
|
dst_info = del_dst_info( dst )
|
222
|
-
|
248
|
+
atun = dst_info[ :atun ]
|
249
|
+
btun = dst_info[ :btun ]
|
250
|
+
|
251
|
+
if atun then
|
252
|
+
close_sock( atun )
|
253
|
+
del_atun_info( atun )
|
254
|
+
end
|
223
255
|
|
224
|
-
if
|
225
|
-
close_sock(
|
226
|
-
@
|
256
|
+
if btun then
|
257
|
+
close_sock( btun )
|
258
|
+
@btun_infos.delete( btun )
|
227
259
|
end
|
228
260
|
end
|
229
261
|
|
@@ -232,40 +264,15 @@ module Girl
|
|
232
264
|
#
|
233
265
|
def close_read_dst( dst )
|
234
266
|
return if dst.closed?
|
235
|
-
# puts "
|
267
|
+
# puts "debug close read dst"
|
236
268
|
dst.close_read
|
237
269
|
@reads.delete( dst )
|
238
270
|
|
239
271
|
if dst.closed? then
|
240
|
-
# puts "debug1 delete dst info"
|
241
272
|
@writes.delete( dst )
|
242
273
|
@roles.delete( dst )
|
243
|
-
|
244
|
-
else
|
245
|
-
dst_info = @dst_infos[ dst ]
|
246
|
-
end
|
247
|
-
|
248
|
-
dst_info
|
249
|
-
end
|
250
|
-
|
251
|
-
##
|
252
|
-
# close read tun
|
253
|
-
#
|
254
|
-
def close_read_tun( tun )
|
255
|
-
return if tun.closed?
|
256
|
-
# puts "debug1 close read tun"
|
257
|
-
tun_info = @tun_infos[ tun ]
|
258
|
-
tun_info[ :close_read ] = true
|
259
|
-
|
260
|
-
if tun_info[ :close_write ] then
|
261
|
-
# puts "debug1 close tun"
|
262
|
-
close_sock( tun )
|
263
|
-
tun_info = @tun_infos.delete( tun )
|
264
|
-
else
|
265
|
-
@reads.delete( tun )
|
274
|
+
del_dst_info( dst )
|
266
275
|
end
|
267
|
-
|
268
|
-
tun_info
|
269
276
|
end
|
270
277
|
|
271
278
|
##
|
@@ -278,85 +285,27 @@ module Girl
|
|
278
285
|
@roles.delete( sock )
|
279
286
|
end
|
280
287
|
|
281
|
-
##
|
282
|
-
# close tun
|
283
|
-
#
|
284
|
-
def close_tun( tun )
|
285
|
-
return if tun.closed?
|
286
|
-
# puts "debug1 close tun"
|
287
|
-
close_sock( tun )
|
288
|
-
tun_info = @tun_infos.delete( tun )
|
289
|
-
dst = tun_info[ :dst ]
|
290
|
-
|
291
|
-
if dst then
|
292
|
-
close_sock( dst )
|
293
|
-
del_dst_info( dst )
|
294
|
-
end
|
295
|
-
end
|
296
|
-
|
297
|
-
##
|
298
|
-
# close proxy
|
299
|
-
#
|
300
|
-
def close_proxy( proxy )
|
301
|
-
return if proxy.closed?
|
302
|
-
# puts "debug1 close proxy"
|
303
|
-
close_sock( proxy )
|
304
|
-
proxy_info = @proxy_infos.delete( proxy )
|
305
|
-
tund = proxy_info[ :tund ]
|
306
|
-
|
307
|
-
if tund then
|
308
|
-
close_sock( tund )
|
309
|
-
@tund_infos.delete( tund )
|
310
|
-
end
|
311
|
-
end
|
312
|
-
|
313
288
|
##
|
314
289
|
# close write dst
|
315
290
|
#
|
316
291
|
def close_write_dst( dst )
|
317
292
|
return if dst.closed?
|
318
|
-
# puts "
|
293
|
+
# puts "debug close write dst"
|
319
294
|
dst.close_write
|
320
295
|
@writes.delete( dst )
|
321
296
|
|
322
297
|
if dst.closed? then
|
323
|
-
# puts "debug1 delete dst info"
|
324
298
|
@reads.delete( dst )
|
325
299
|
@roles.delete( dst )
|
326
300
|
dst_info = del_dst_info( dst )
|
327
|
-
else
|
328
|
-
dst_info = @dst_infos[ dst ]
|
329
|
-
end
|
330
|
-
|
331
|
-
dst_info
|
332
|
-
end
|
333
|
-
|
334
|
-
##
|
335
|
-
# close write tun
|
336
|
-
#
|
337
|
-
def close_write_tun( tun )
|
338
|
-
return if tun.closed?
|
339
|
-
# puts "debug1 close write tun"
|
340
|
-
tun_info = @tun_infos[ tun ]
|
341
|
-
tun_info[ :close_write ] = true
|
342
|
-
|
343
|
-
if tun_info[ :close_read ] then
|
344
|
-
# puts "debug1 close tun"
|
345
|
-
close_sock( tun )
|
346
|
-
tun_info = @tun_infos.delete( tun )
|
347
|
-
else
|
348
|
-
@writes.delete( tun )
|
349
301
|
end
|
350
|
-
|
351
|
-
tun_info
|
352
302
|
end
|
353
303
|
|
354
304
|
##
|
355
305
|
# deal with destination addr
|
356
306
|
#
|
357
|
-
def deal_with_destination_addr(
|
307
|
+
def deal_with_destination_addr( ctl_addr, src_id, destination_addr, domain_port )
|
358
308
|
dst = Socket.new( Addrinfo.new( destination_addr ).ipv4? ? Socket::AF_INET : Socket::AF_INET6, Socket::SOCK_STREAM, 0 )
|
359
|
-
dst.setsockopt( Socket::SOL_TCP, Socket::TCP_NODELAY, 1 )
|
360
309
|
|
361
310
|
begin
|
362
311
|
dst.connect_nonblock( destination_addr )
|
@@ -368,15 +317,16 @@ module Girl
|
|
368
317
|
end
|
369
318
|
|
370
319
|
dst_id = dst.local_address.ip_port
|
371
|
-
|
320
|
+
ctl_info = @ctl_infos[ ctl_addr ]
|
372
321
|
|
373
322
|
@dst_infos[ dst ] = {
|
374
323
|
id: dst_id, # id
|
375
|
-
|
376
|
-
im:
|
324
|
+
ctl_addr: ctl_addr, # 对应ctl
|
325
|
+
im: ctl_info[ :im ], # 标识
|
377
326
|
domain_port: domain_port, # 目的地和端口
|
378
327
|
rbuff: '', # 对应的tun没准备好,暂存读到的流量
|
379
|
-
|
328
|
+
atun: nil, # 对应的atun
|
329
|
+
btun: nil, # 对应的btun
|
380
330
|
wbuff: '', # 从tun读到的流量
|
381
331
|
src_id: src_id, # 近端src id
|
382
332
|
created_at: Time.new, # 创建时间
|
@@ -387,25 +337,47 @@ module Girl
|
|
387
337
|
|
388
338
|
add_read( dst, :dst )
|
389
339
|
|
390
|
-
|
391
|
-
|
340
|
+
ctl_info[ :dst_ids ][ src_id ] = dst_id
|
341
|
+
ctl_info[ :dsts ][ dst_id ] = dst
|
392
342
|
|
393
343
|
data = [ PAIRED, src_id, dst_id ].pack( 'CQ>n' )
|
394
|
-
# puts "
|
395
|
-
|
344
|
+
# puts "debug add ctlmsg paired #{ src_id } #{ dst_id }"
|
345
|
+
send_ctlmsg( data, ctl_addr )
|
346
|
+
end
|
347
|
+
|
348
|
+
##
|
349
|
+
# del atun info
|
350
|
+
#
|
351
|
+
def del_atun_info( atun )
|
352
|
+
@atun_infos.delete( atun )
|
353
|
+
@paused_atuns.delete( atun )
|
354
|
+
@resume_atuns.delete( atun )
|
355
|
+
end
|
356
|
+
|
357
|
+
##
|
358
|
+
# del ctl info
|
359
|
+
#
|
360
|
+
def del_ctl_info( ctl_addr )
|
361
|
+
# puts "debug delete ctl info"
|
362
|
+
ctl_info = @ctl_infos.delete( ctl_addr )
|
363
|
+
close_atund( ctl_info[ :atund ] )
|
364
|
+
close_btund( ctl_info[ :btund ] )
|
396
365
|
end
|
397
366
|
|
398
367
|
##
|
399
368
|
# del dst info
|
400
369
|
#
|
401
370
|
def del_dst_info( dst )
|
371
|
+
# puts "debug delete dst info"
|
402
372
|
dst_info = @dst_infos.delete( dst )
|
403
|
-
|
404
|
-
|
405
|
-
|
406
|
-
|
407
|
-
|
408
|
-
|
373
|
+
@paused_dsts.delete( dst )
|
374
|
+
@resume_dsts.delete( dst )
|
375
|
+
ctl_addr = dst_info[ :ctl_addr ]
|
376
|
+
ctl_info = @ctl_infos[ ctl_addr ]
|
377
|
+
|
378
|
+
if ctl_info then
|
379
|
+
ctl_info[ :dsts ].delete( dst_info[ :id ] )
|
380
|
+
ctl_info[ :dst_ids ].delete( dst_info[ :src_id ] )
|
409
381
|
end
|
410
382
|
|
411
383
|
dst_info
|
@@ -420,14 +392,12 @@ module Girl
|
|
420
392
|
sleep CHECK_EXPIRE_INTERVAL
|
421
393
|
now = Time.new
|
422
394
|
|
423
|
-
@
|
424
|
-
|
395
|
+
@ctl_infos.each do | ctl_addr, ctl_info |
|
396
|
+
if now - ctl_info[ :last_recv_at ] >= EXPIRE_CTL
|
397
|
+
puts "p#{ Process.pid } #{ Time.new } expire ctl #{ EXPIRE_CTL } #{ ctl_info[ :addrinfo ].inspect } tund ports #{ ctl_info[ :atund_port ] } #{ ctl_info[ :btund_port ] }"
|
425
398
|
|
426
|
-
|
427
|
-
|
428
|
-
|
429
|
-
unless @closing_proxys.include?( proxy ) then
|
430
|
-
@closing_proxys << proxy
|
399
|
+
unless @deleting_ctl_infos.include?( ctl_addr ) then
|
400
|
+
@deleting_ctl_infos << ctl_addr
|
431
401
|
next_tick
|
432
402
|
end
|
433
403
|
end
|
@@ -436,7 +406,7 @@ module Girl
|
|
436
406
|
@dst_infos.each do | dst, dst_info |
|
437
407
|
last_recv_at = dst_info[ :last_recv_at ] || dst_info[ :created_at ]
|
438
408
|
last_sent_at = dst_info[ :last_sent_at ] || dst_info[ :created_at ]
|
439
|
-
expire_after = dst_info[ :
|
409
|
+
expire_after = dst_info[ :btun ] ? EXPIRE_AFTER : EXPIRE_NEW
|
440
410
|
|
441
411
|
if ( now - last_recv_at >= expire_after ) && ( now - last_sent_at >= expire_after ) then
|
442
412
|
puts "p#{ Process.pid } #{ Time.new } expire dst #{ expire_after } #{ dst_info[ :domain_port ] }"
|
@@ -460,31 +430,29 @@ module Girl
|
|
460
430
|
sleep CHECK_RESUME_INTERVAL
|
461
431
|
|
462
432
|
@paused_dsts.each do | dst |
|
463
|
-
|
464
|
-
|
465
|
-
else
|
466
|
-
dst_info = @dst_infos[ dst ]
|
467
|
-
tun = dst_info[ :tun ]
|
468
|
-
tun_info = @tun_infos[ tun ]
|
433
|
+
dst_info = @dst_infos[ dst ]
|
434
|
+
btun = dst_info[ :btun ]
|
469
435
|
|
470
|
-
|
436
|
+
if btun && !btun.closed? then
|
437
|
+
btun_info = @btun_infos[ btun ]
|
438
|
+
|
439
|
+
if btun_info[ :wbuff ].size < RESUME_BELOW then
|
471
440
|
puts "p#{ Process.pid } #{ Time.new } resume dst #{ dst_info[ :domain_port ] }"
|
472
441
|
add_resume_dst( dst )
|
473
442
|
end
|
474
443
|
end
|
475
444
|
end
|
476
445
|
|
477
|
-
@
|
478
|
-
|
479
|
-
|
480
|
-
|
481
|
-
|
482
|
-
dst = tun_info[ :dst ]
|
446
|
+
@paused_atuns.each do | atun |
|
447
|
+
atun_info = @atun_infos[ atun ]
|
448
|
+
dst = atun_info[ :dst ]
|
449
|
+
|
450
|
+
if dst && !dst.closed? then
|
483
451
|
dst_info = @dst_infos[ dst ]
|
484
452
|
|
485
453
|
if dst_info[ :wbuff ].size < RESUME_BELOW then
|
486
|
-
puts "p#{ Process.pid } #{ Time.new } resume
|
487
|
-
|
454
|
+
puts "p#{ Process.pid } #{ Time.new } resume atun #{ atun_info[ :domain_port ] }"
|
455
|
+
add_resume_atun( atun )
|
488
456
|
end
|
489
457
|
end
|
490
458
|
end
|
@@ -512,19 +480,15 @@ module Girl
|
|
512
480
|
end
|
513
481
|
|
514
482
|
##
|
515
|
-
# new a
|
483
|
+
# new a ctld
|
516
484
|
#
|
517
|
-
def
|
518
|
-
|
519
|
-
|
520
|
-
|
521
|
-
|
522
|
-
|
523
|
-
|
524
|
-
proxyd = OpenSSL::SSL::SSLServer.new pre_proxyd, @context
|
525
|
-
proxyd.listen( 127 )
|
526
|
-
puts "p#{ Process.pid } #{ Time.new } proxyd listen on #{ proxyd_port }"
|
527
|
-
add_read( proxyd, :proxyd )
|
485
|
+
def new_a_ctld( proxyd_port )
|
486
|
+
ctld = Socket.new( Socket::AF_INET, Socket::SOCK_DGRAM, 0 )
|
487
|
+
ctld.setsockopt( Socket::SOL_SOCKET, Socket::SO_REUSEPORT, 1 )
|
488
|
+
ctld.bind( Socket.sockaddr_in( proxyd_port, '0.0.0.0' ) )
|
489
|
+
puts "p#{ Process.pid } #{ Time.new } ctld bind on #{ proxyd_port }"
|
490
|
+
add_read( ctld, :ctld )
|
491
|
+
@ctld = ctld
|
528
492
|
end
|
529
493
|
|
530
494
|
##
|
@@ -534,11 +498,20 @@ module Girl
|
|
534
498
|
infod = Socket.new( Socket::AF_INET, Socket::SOCK_DGRAM, 0 )
|
535
499
|
infod.setsockopt( Socket::SOL_SOCKET, Socket::SO_REUSEPORT, 1 )
|
536
500
|
infod.bind( Socket.sockaddr_in( infod_port, '127.0.0.1' ) )
|
537
|
-
|
538
501
|
puts "p#{ Process.pid } #{ Time.new } infod bind on #{ infod_port }"
|
539
502
|
add_read( infod, :infod )
|
540
503
|
end
|
541
504
|
|
505
|
+
##
|
506
|
+
# new a tund
|
507
|
+
#
|
508
|
+
def new_a_tund
|
509
|
+
tund = Socket.new( Socket::AF_INET, Socket::SOCK_STREAM, 0 )
|
510
|
+
tund.bind( Socket.sockaddr_in( 0, '0.0.0.0' ) )
|
511
|
+
tund.listen( 127 )
|
512
|
+
tund
|
513
|
+
end
|
514
|
+
|
542
515
|
##
|
543
516
|
# next tick
|
544
517
|
#
|
@@ -546,22 +519,30 @@ module Girl
|
|
546
519
|
@dotw.write( '.' )
|
547
520
|
end
|
548
521
|
|
522
|
+
##
|
523
|
+
# pack a chunk
|
524
|
+
#
|
525
|
+
def pack_a_chunk( data )
|
526
|
+
data = @custom.encode( data )
|
527
|
+
"#{ [ data.bytesize ].pack( 'n' ) }#{ data }"
|
528
|
+
end
|
529
|
+
|
549
530
|
##
|
550
531
|
# resolve domain
|
551
532
|
#
|
552
|
-
def resolve_domain(
|
533
|
+
def resolve_domain( ctl_addr, src_id, domain_port )
|
553
534
|
resolv_cache = @resolv_caches[ domain_port ]
|
554
535
|
|
555
536
|
if resolv_cache then
|
556
537
|
destination_addr, created_at = resolv_cache
|
557
538
|
|
558
539
|
if Time.new - created_at < RESOLV_CACHE_EXPIRE then
|
559
|
-
# puts "
|
560
|
-
deal_with_destination_addr(
|
540
|
+
# puts "debug #{ domain_port } hit resolv cache #{ Addrinfo.new( destination_addr ).inspect }"
|
541
|
+
deal_with_destination_addr( ctl_addr, src_id, destination_addr, domain_port )
|
561
542
|
return
|
562
543
|
end
|
563
544
|
|
564
|
-
# puts "
|
545
|
+
# puts "debug expire #{ domain_port } resolv cache"
|
565
546
|
@resolv_caches.delete( domain_port )
|
566
547
|
end
|
567
548
|
|
@@ -580,16 +561,38 @@ module Girl
|
|
580
561
|
end
|
581
562
|
|
582
563
|
if destination_addr then
|
583
|
-
# puts "
|
564
|
+
# puts "debug resolved #{ domain_port } #{ Addrinfo.new( destination_addr ).inspect }"
|
584
565
|
@resolv_caches[ domain_port ] = [ destination_addr, Time.new ]
|
585
|
-
|
586
|
-
unless proxy.closed? then
|
587
|
-
deal_with_destination_addr( proxy, src_id, destination_addr, domain_port )
|
588
|
-
end
|
566
|
+
deal_with_destination_addr( ctl_addr, src_id, destination_addr, domain_port )
|
589
567
|
end
|
590
568
|
end
|
591
569
|
end
|
592
570
|
|
571
|
+
##
|
572
|
+
# send ctlmsg
|
573
|
+
#
|
574
|
+
def send_ctlmsg( data, to_addr )
|
575
|
+
data = @custom.encode( data )
|
576
|
+
|
577
|
+
begin
|
578
|
+
@ctld.sendmsg( data, 0, to_addr )
|
579
|
+
rescue Exception => e
|
580
|
+
puts "p#{ Process.pid } #{ Time.new } sendmsg #{ e.class }"
|
581
|
+
end
|
582
|
+
end
|
583
|
+
|
584
|
+
##
|
585
|
+
# set btun closing
|
586
|
+
#
|
587
|
+
def set_btun_closing( btun )
|
588
|
+
return if btun.closed?
|
589
|
+
btun_info = @btun_infos[ btun ]
|
590
|
+
return if btun_info[ :closing ]
|
591
|
+
# puts "debug set btun closing"
|
592
|
+
btun_info[ :closing ] = true
|
593
|
+
add_write( btun )
|
594
|
+
end
|
595
|
+
|
593
596
|
##
|
594
597
|
# set dst closing write
|
595
598
|
#
|
@@ -597,31 +600,20 @@ module Girl
|
|
597
600
|
return if dst.closed? || @closing_dsts.include?( dst )
|
598
601
|
dst_info = @dst_infos[ dst ]
|
599
602
|
return if dst_info[ :closing_write ]
|
603
|
+
# puts "debug set dst closing write"
|
600
604
|
dst_info[ :closing_write ] = true
|
601
605
|
add_write( dst )
|
602
606
|
end
|
603
607
|
|
604
|
-
##
|
605
|
-
# set tun closing write
|
606
|
-
#
|
607
|
-
def set_tun_closing_write( tun )
|
608
|
-
return if tun.closed? || @closing_tuns.include?( tun )
|
609
|
-
tun_info = @tun_infos[ tun ]
|
610
|
-
return if tun_info[ :closing_write ]
|
611
|
-
tun_info[ :closing_write ] = true
|
612
|
-
add_write( tun )
|
613
|
-
end
|
614
|
-
|
615
608
|
##
|
616
609
|
# read dotr
|
617
610
|
#
|
618
611
|
def read_dotr( dotr )
|
619
|
-
dotr.read_nonblock(
|
612
|
+
dotr.read_nonblock( 65535 )
|
620
613
|
|
621
|
-
|
622
|
-
|
623
|
-
@
|
624
|
-
@closing_proxys.clear
|
614
|
+
if @deleting_ctl_infos.any? then
|
615
|
+
@deleting_ctl_infos.each { | ctl_addr | del_ctl_info( ctl_addr ) }
|
616
|
+
@deleting_ctl_infos.clear
|
625
617
|
end
|
626
618
|
|
627
619
|
if @closing_dsts.any? then
|
@@ -629,11 +621,6 @@ module Girl
|
|
629
621
|
@closing_dsts.clear
|
630
622
|
end
|
631
623
|
|
632
|
-
if @closing_tuns.any? then
|
633
|
-
@closing_tuns.each { | tun | close_tun( tun ) }
|
634
|
-
@closing_tuns.clear
|
635
|
-
end
|
636
|
-
|
637
624
|
if @resume_dsts.any? then
|
638
625
|
@resume_dsts.each do | dst |
|
639
626
|
add_read( dst )
|
@@ -643,81 +630,33 @@ module Girl
|
|
643
630
|
@resume_dsts.clear
|
644
631
|
end
|
645
632
|
|
646
|
-
if @
|
647
|
-
@
|
648
|
-
add_read(
|
649
|
-
@
|
633
|
+
if @resume_atuns.any? then
|
634
|
+
@resume_atuns.each do | atun |
|
635
|
+
add_read( atun )
|
636
|
+
@paused_atuns.delete( atun )
|
650
637
|
end
|
651
638
|
|
652
|
-
@
|
639
|
+
@resume_atuns.clear
|
653
640
|
end
|
654
641
|
end
|
655
642
|
|
656
643
|
##
|
657
|
-
# read
|
644
|
+
# read ctld
|
658
645
|
#
|
659
|
-
def
|
660
|
-
|
661
|
-
|
662
|
-
|
663
|
-
|
664
|
-
|
665
|
-
rescue Exception => e
|
666
|
-
puts "p#{ Process.pid } #{ Time.new } proxyd accept #{ e.class }"
|
667
|
-
return
|
668
|
-
end
|
669
|
-
|
670
|
-
@proxy_infos[ proxy ] = {
|
671
|
-
addrinfo: proxy.io.remote_address, # proxy地址
|
672
|
-
im: nil, # 标识
|
673
|
-
tund: nil, # 对应tund
|
674
|
-
tund_port: nil, # tund端口
|
675
|
-
ctlmsgs: [], # ctlmsg
|
676
|
-
dsts: ConcurrentHash.new, # dst_id => dst
|
677
|
-
dst_ids: ConcurrentHash.new, # src_id => dst_id
|
678
|
-
created_at: Time.new, # 创建时间
|
679
|
-
last_recv_at: nil # 上一次收到流量的时间
|
680
|
-
}
|
681
|
-
|
682
|
-
puts "p#{ Process.pid } #{ Time.new } accept a proxy #{ proxy.io.remote_address.inspect } #{ proxy.ssl_version }, #{ @proxy_infos.size } proxys"
|
683
|
-
add_read( proxy, :proxy )
|
684
|
-
end
|
685
|
-
|
686
|
-
##
|
687
|
-
# read proxy
|
688
|
-
#
|
689
|
-
def read_proxy( proxy )
|
690
|
-
if proxy.closed? then
|
691
|
-
puts "p#{ Process.pid } #{ Time.new } read proxy but proxy closed?"
|
692
|
-
return
|
693
|
-
end
|
694
|
-
|
695
|
-
begin
|
696
|
-
data = proxy.read_nonblock( READ_SIZE )
|
697
|
-
rescue IO::WaitReadable
|
698
|
-
return
|
699
|
-
rescue Errno::EINTR
|
700
|
-
puts e.class
|
701
|
-
return
|
702
|
-
rescue Exception => e
|
703
|
-
# puts "debug1 read proxy #{ e.class }"
|
704
|
-
close_proxy( proxy )
|
705
|
-
return
|
706
|
-
end
|
707
|
-
|
708
|
-
proxy_info = @proxy_infos[ proxy ]
|
709
|
-
proxy_info[ :last_recv_at ] = Time.new
|
710
|
-
|
711
|
-
data.split( SEPARATE ).each do | ctlmsg |
|
712
|
-
next unless ctlmsg[ 0 ]
|
713
|
-
|
714
|
-
ctl_num = ctlmsg[ 0 ].unpack( 'C' ).first
|
646
|
+
def read_ctld( ctld )
|
647
|
+
data, addrinfo, rflags, *controls = ctld.recvmsg
|
648
|
+
data = @custom.decode( data )
|
649
|
+
ctl_num = data[ 0 ].unpack( 'C' ).first
|
650
|
+
ctl_addr = addrinfo.to_sockaddr
|
651
|
+
ctl_info = @ctl_infos[ ctl_addr ]
|
715
652
|
|
716
|
-
|
717
|
-
|
718
|
-
|
719
|
-
|
720
|
-
|
653
|
+
case ctl_num
|
654
|
+
when HELLO then
|
655
|
+
if ctl_info then
|
656
|
+
atund_port, btund_port = ctl_info[ :atund_port ], ctl_info[ :btund_port ]
|
657
|
+
else
|
658
|
+
return if data.size <= 1
|
659
|
+
im = data[ 1..-1 ]
|
721
660
|
result = @custom.check( im, addrinfo )
|
722
661
|
|
723
662
|
if result != :success then
|
@@ -730,63 +669,65 @@ module Girl
|
|
730
669
|
@traff_outs[ im ] = 0
|
731
670
|
end
|
732
671
|
|
733
|
-
|
734
|
-
|
735
|
-
|
672
|
+
atund = new_a_tund
|
673
|
+
atund_port = atund.local_address.ip_port
|
674
|
+
btund = new_a_tund
|
675
|
+
btund_port = btund.local_address.ip_port
|
676
|
+
add_read( atund, :atund )
|
677
|
+
add_read( btund, :btund )
|
736
678
|
|
737
|
-
|
738
|
-
|
739
|
-
|
740
|
-
|
741
|
-
add_read( tund, :tund )
|
679
|
+
@atund_infos[ atund ] = {
|
680
|
+
ctl_addr: ctl_addr,
|
681
|
+
im: im
|
682
|
+
}
|
742
683
|
|
743
|
-
@
|
744
|
-
|
745
|
-
|
746
|
-
close_write: false
|
684
|
+
@btund_infos[ btund ] = {
|
685
|
+
ctl_addr: ctl_addr,
|
686
|
+
im: im
|
747
687
|
}
|
748
688
|
|
749
|
-
|
750
|
-
|
751
|
-
|
752
|
-
|
753
|
-
|
754
|
-
|
755
|
-
|
756
|
-
|
757
|
-
|
758
|
-
|
759
|
-
|
760
|
-
# puts "debug1 a new source #{ src_id } #{ domain_port }"
|
761
|
-
resolve_domain( proxy, src_id, domain_port )
|
762
|
-
when RESOLV then
|
763
|
-
next if ctlmsg.size <= 9
|
764
|
-
src_id = ctlmsg[ 1, 8 ].unpack( 'Q>' ).first
|
765
|
-
domain = ctlmsg[ 9..-1 ]
|
766
|
-
|
767
|
-
Thread.new do
|
768
|
-
begin
|
769
|
-
ip_info = Addrinfo.ip( domain )
|
770
|
-
rescue Exception => e
|
771
|
-
puts "p#{ Process.pid } #{ Time.new } resolv #{ domain.inspect } #{ e.class }"
|
772
|
-
end
|
689
|
+
@ctl_infos[ ctl_addr ] = {
|
690
|
+
addrinfo: addrinfo, # 地址
|
691
|
+
im: im, # 标识
|
692
|
+
atund: atund, # 对应atund,src->dst
|
693
|
+
atund_port: atund_port, # atund端口
|
694
|
+
btund: btund, # 对应btund,dst->src
|
695
|
+
btund_port: btund_port, # btund端口
|
696
|
+
dsts: ConcurrentHash.new, # dst_id => dst
|
697
|
+
dst_ids: ConcurrentHash.new, # src_id => dst_id
|
698
|
+
last_recv_at: Time.new # 上一次收到流量的时间
|
699
|
+
}
|
773
700
|
|
774
|
-
|
775
|
-
|
776
|
-
|
777
|
-
|
778
|
-
|
779
|
-
|
780
|
-
|
781
|
-
|
782
|
-
|
783
|
-
|
701
|
+
puts "p#{ Process.pid } #{ Time.new } got hello #{ im.inspect }, atund listen on #{ atund_port }, btund listen on #{ btund_port }, ctl infos size #{ @ctl_infos.size }"
|
702
|
+
end
|
703
|
+
|
704
|
+
data2 = [ TUND_PORT, atund_port, btund_port ].pack( 'Cnn' )
|
705
|
+
send_ctlmsg( data2, ctl_addr )
|
706
|
+
when A_NEW_SOURCE then
|
707
|
+
unless ctl_info then
|
708
|
+
send_ctlmsg( [ UNKNOWN_CTL_ADDR ].pack( 'C' ), addrinfo )
|
709
|
+
return
|
710
|
+
end
|
711
|
+
|
712
|
+
return if data.size <= 9
|
713
|
+
src_id = data[ 1, 8 ].unpack( 'Q>' ).first
|
714
|
+
dst_id = ctl_info[ :dst_ids ][ src_id ]
|
715
|
+
|
716
|
+
if dst_id then
|
717
|
+
data2 = [ PAIRED, src_id, dst_id ].pack( 'CQ>n' )
|
718
|
+
# puts "debug dst id exist, send ctlmsg paired #{ src_id } #{ dst_id }"
|
719
|
+
send_ctlmsg( data2, ctl_addr )
|
784
720
|
return
|
785
|
-
when HEARTBEAT
|
786
|
-
# puts "debug1 #{ Time.new } got heartbeat"
|
787
|
-
data2 = [ HEARTBEAT ].pack( 'C' )
|
788
|
-
add_ctlmsg( proxy, data2 )
|
789
721
|
end
|
722
|
+
|
723
|
+
domain_port = data[ 9..-1 ]
|
724
|
+
# puts "debug got a new source #{ src_id } #{ domain_port }"
|
725
|
+
resolve_domain( ctl_addr, src_id, domain_port )
|
726
|
+
ctl_info[ :last_recv_at ] = Time.new
|
727
|
+
when CTL_FIN then
|
728
|
+
return unless ctl_info
|
729
|
+
# puts "debug got ctl fin #{ addrinfo.inspect }"
|
730
|
+
del_ctl_info( ctl_addr )
|
790
731
|
end
|
791
732
|
end
|
792
733
|
|
@@ -796,7 +737,7 @@ module Girl
|
|
796
737
|
def read_infod( infod )
|
797
738
|
data, addrinfo, rflags, *controls = infod.recvmsg
|
798
739
|
ctl_num = data[ 0 ].unpack( 'C' ).first
|
799
|
-
# puts "
|
740
|
+
# puts "debug infod got #{ ctl_num } #{ addrinfo.ip_unpack.inspect }"
|
800
741
|
|
801
742
|
case ctl_num
|
802
743
|
when TRAFF_INFOS then
|
@@ -810,9 +751,9 @@ module Girl
|
|
810
751
|
|
811
752
|
begin
|
812
753
|
infod.sendmsg_nonblock( data2, 0, addrinfo )
|
813
|
-
rescue IO::WaitWritable
|
754
|
+
rescue IO::WaitWritable
|
814
755
|
print 'w'
|
815
|
-
rescue
|
756
|
+
rescue Exception => e
|
816
757
|
puts "p#{ Process.pid } #{ Time.new } infod sendmsg to #{ addrinfo.ip_unpack.inspect } #{ e.class }"
|
817
758
|
end
|
818
759
|
end
|
@@ -827,160 +768,293 @@ module Girl
|
|
827
768
|
return
|
828
769
|
end
|
829
770
|
|
771
|
+
dst_info = @dst_infos[ dst ]
|
772
|
+
btun = dst_info[ :btun ]
|
773
|
+
|
830
774
|
begin
|
831
|
-
data = dst.read_nonblock(
|
832
|
-
rescue IO::WaitReadable
|
775
|
+
data = dst.read_nonblock( 65535 )
|
776
|
+
rescue IO::WaitReadable
|
833
777
|
print 'r'
|
834
778
|
return
|
835
779
|
rescue Exception => e
|
836
|
-
# puts "
|
837
|
-
|
838
|
-
|
839
|
-
|
780
|
+
# puts "debug read dst #{ e.class }"
|
781
|
+
close_read_dst( dst )
|
782
|
+
|
783
|
+
if btun then
|
784
|
+
set_btun_closing( btun )
|
785
|
+
end
|
786
|
+
|
840
787
|
return
|
841
788
|
end
|
842
789
|
|
843
|
-
dst_info = @dst_infos[ dst ]
|
844
790
|
@traff_ins[ dst_info[ :im ] ] += data.bytesize
|
845
|
-
|
791
|
+
# puts "debug read dst #{ data.bytesize }"
|
846
792
|
|
847
|
-
if
|
848
|
-
|
849
|
-
tun_info = @tun_infos[ tun ]
|
850
|
-
# puts "debug2 add tun.wbuff #{ data.bytesize }"
|
851
|
-
add_tun_wbuff( tun, data )
|
852
|
-
end
|
793
|
+
if btun then
|
794
|
+
add_btun_wbuff( btun, pack_a_chunk( data ) )
|
853
795
|
else
|
796
|
+
# puts "debug add dst.rbuff #{ data.bytesize }"
|
854
797
|
add_dst_rbuff( dst, data )
|
855
798
|
end
|
856
799
|
end
|
857
800
|
|
858
801
|
##
|
859
|
-
# read
|
802
|
+
# read atund
|
860
803
|
#
|
861
|
-
def
|
862
|
-
if
|
863
|
-
puts "p#{ Process.pid } #{ Time.new } read
|
804
|
+
def read_atund( atund )
|
805
|
+
if atund.closed? then
|
806
|
+
puts "p#{ Process.pid } #{ Time.new } read atund but atund closed?"
|
864
807
|
return
|
865
808
|
end
|
866
809
|
|
810
|
+
atund_info = @atund_infos[ atund ]
|
811
|
+
|
867
812
|
begin
|
868
|
-
|
869
|
-
rescue IO::WaitReadable, Errno::EINTR
|
870
|
-
print 'r'
|
871
|
-
return
|
813
|
+
atun, _ = atund.accept_nonblock
|
872
814
|
rescue Exception => e
|
873
|
-
puts "p#{ Process.pid } #{ Time.new }
|
815
|
+
puts "p#{ Process.pid } #{ Time.new } atund #{ atund_info[ :im ] } accept #{ e.class }"
|
816
|
+
puts e.full_message
|
874
817
|
return
|
875
818
|
end
|
876
819
|
|
877
|
-
# puts "
|
878
|
-
|
879
|
-
|
880
|
-
|
881
|
-
|
882
|
-
|
883
|
-
|
884
|
-
|
885
|
-
|
886
|
-
|
887
|
-
wbuff: '', # 写前
|
888
|
-
closing_write: false # 准备关闭写
|
820
|
+
# puts "debug accept a atun #{ atund_info[ :im ] }"
|
821
|
+
|
822
|
+
@atun_infos[ atun ] = {
|
823
|
+
ctl_addr: atund_info[ :ctl_addr ], # 对应ctl
|
824
|
+
im: atund_info[ :im ], # 标识
|
825
|
+
dst: nil, # 对应dst
|
826
|
+
domain_port: nil, # dst的目的地和端口
|
827
|
+
rbuff: '', # 暂存当前块没收全的流量
|
828
|
+
wait_bytes: 0, # 还差多少字节收全当前块
|
829
|
+
lbuff: '' # 流量截断在长度前缀处
|
889
830
|
}
|
890
831
|
|
891
|
-
add_read(
|
832
|
+
add_read( atun, :atun )
|
892
833
|
end
|
893
834
|
|
894
835
|
##
|
895
|
-
# read
|
836
|
+
# read btund
|
896
837
|
#
|
897
|
-
def
|
898
|
-
if
|
899
|
-
puts "p#{ Process.pid } #{ Time.new } read
|
838
|
+
def read_btund( btund )
|
839
|
+
if btund.closed? then
|
840
|
+
puts "p#{ Process.pid } #{ Time.new } read btund but btund closed?"
|
900
841
|
return
|
901
842
|
end
|
902
843
|
|
844
|
+
btund_info = @btund_infos[ btund ]
|
845
|
+
|
903
846
|
begin
|
904
|
-
|
905
|
-
rescue
|
847
|
+
btun, _ = btund.accept_nonblock
|
848
|
+
rescue Exception => e
|
849
|
+
puts "p#{ Process.pid } #{ Time.new } btund #{ btund_info[ :im ] } accept #{ e.class }"
|
850
|
+
puts e.full_message
|
906
851
|
return
|
907
|
-
|
908
|
-
|
852
|
+
end
|
853
|
+
|
854
|
+
# puts "debug accept a btun #{ btund_info[ :im ] }"
|
855
|
+
|
856
|
+
@btun_infos[ btun ] = {
|
857
|
+
ctl_addr: btund_info[ :ctl_addr ], # 对应ctl
|
858
|
+
im: btund_info[ :im ], # 标识
|
859
|
+
dst: nil, # 对应dst
|
860
|
+
domain_port: nil, # dst的目的地和端口
|
861
|
+
wbuff: '', # 写前
|
862
|
+
closing: false # 准备关闭
|
863
|
+
}
|
864
|
+
|
865
|
+
add_read( btun, :btun )
|
866
|
+
end
|
867
|
+
|
868
|
+
##
|
869
|
+
# read atun
|
870
|
+
#
|
871
|
+
def read_atun( atun )
|
872
|
+
if atun.closed? then
|
873
|
+
puts "p#{ Process.pid } #{ Time.new } read atun but atun closed?"
|
909
874
|
return
|
875
|
+
end
|
876
|
+
|
877
|
+
atun_info = @atun_infos[ atun ]
|
878
|
+
dst = atun_info[ :dst ]
|
879
|
+
|
880
|
+
begin
|
881
|
+
data = atun.read_nonblock( READ_SIZE )
|
910
882
|
rescue Exception => e
|
911
|
-
# puts "
|
912
|
-
|
913
|
-
|
914
|
-
|
883
|
+
# puts "debug read atun #{ atun_info[ :im ] } #{ e.class }"
|
884
|
+
close_atun( atun )
|
885
|
+
|
886
|
+
if dst then
|
887
|
+
set_dst_closing_write( dst )
|
888
|
+
end
|
889
|
+
|
915
890
|
return
|
916
891
|
end
|
917
892
|
|
918
|
-
tun_info = @tun_infos[ tun ]
|
919
|
-
@traff_ins[ tun_info[ :im ] ] += data.bytesize
|
920
|
-
dst = tun_info[ :dst ]
|
921
|
-
|
922
893
|
unless dst then
|
894
|
+
if data.bytesize < 2 then
|
895
|
+
# puts "debug unexpect data length #{ data.bytesize }"
|
896
|
+
close_atun( atun )
|
897
|
+
end
|
898
|
+
|
923
899
|
dst_id = data[ 0, 2 ].unpack( 'n' ).first
|
924
|
-
|
900
|
+
ctl_addr = atun_info[ :ctl_addr ]
|
901
|
+
ctl_info = @ctl_infos[ ctl_addr ]
|
925
902
|
|
926
|
-
|
927
|
-
|
903
|
+
unless ctl_info then
|
904
|
+
close_atun( atun )
|
928
905
|
return
|
929
906
|
end
|
930
907
|
|
931
|
-
|
932
|
-
dst = proxy_info[ :dsts ][ dst_id ]
|
908
|
+
dst = ctl_info[ :dsts ][ dst_id ]
|
933
909
|
|
934
910
|
unless dst then
|
935
|
-
|
911
|
+
close_atun( atun )
|
936
912
|
return
|
937
913
|
end
|
938
914
|
|
939
|
-
# puts "
|
940
|
-
|
915
|
+
# puts "debug set atun.dst #{ dst_id }"
|
916
|
+
atun_info[ :dst ] = dst
|
941
917
|
dst_info = @dst_infos[ dst ]
|
942
|
-
|
943
|
-
|
944
|
-
unless dst_info[ :rbuff ].empty? then
|
945
|
-
# puts "debug1 move dst.rbuff to tun.wbuff"
|
946
|
-
add_tun_wbuff( tun, dst_info[ :rbuff ] )
|
947
|
-
end
|
918
|
+
atun_info[ :domain_port ] = dst_info[ :domain_port ]
|
919
|
+
dst_info[ :atun ] = atun
|
948
920
|
|
949
|
-
dst_info[ :tun ] = tun
|
950
921
|
data = data[ 2..-1 ]
|
951
|
-
return if data.empty?
|
952
922
|
end
|
953
923
|
|
954
|
-
|
955
|
-
|
924
|
+
until data.empty? do
|
925
|
+
wait_bytes = atun_info[ :wait_bytes ]
|
926
|
+
|
927
|
+
if wait_bytes > 0 then
|
928
|
+
len = wait_bytes
|
929
|
+
# puts "debug wait bytes #{ len }"
|
930
|
+
else
|
931
|
+
lbuff = atun_info[ :lbuff ]
|
932
|
+
|
933
|
+
if lbuff.empty? then
|
934
|
+
# 长度缓存为空,从读到的流量里取长度
|
935
|
+
# 两个字节以下,记进长度缓存
|
936
|
+
if data.bytesize <= 2 then
|
937
|
+
# puts "debug set atun.lbuff #{ data.inspect }"
|
938
|
+
atun_info[ :lbuff ] = data
|
939
|
+
return
|
940
|
+
end
|
941
|
+
|
942
|
+
len = data[ 0, 2 ].unpack( 'n' ).first
|
943
|
+
data = data[ 2..-1 ]
|
944
|
+
elsif lbuff.bytesize == 1 then
|
945
|
+
# 长度缓存记有一个字节,补一个字节
|
946
|
+
lbuff = "#{ lbuff }#{ data[ 0 ] }"
|
947
|
+
|
948
|
+
if data.bytesize == 1 then
|
949
|
+
# puts "debug add atun.lbuff a byte #{ data.inspect }"
|
950
|
+
atun_info[ :lbuff ] = lbuff
|
951
|
+
return
|
952
|
+
end
|
953
|
+
|
954
|
+
# 使用长度缓存
|
955
|
+
len = lbuff.unpack( 'n' ).first
|
956
|
+
atun_info[ :lbuff ].clear
|
957
|
+
data = data[ 1..-1 ]
|
958
|
+
else
|
959
|
+
# 使用长度缓存
|
960
|
+
len = lbuff.unpack( 'n' ).first
|
961
|
+
atun_info[ :lbuff ].clear
|
962
|
+
end
|
963
|
+
end
|
964
|
+
|
965
|
+
chunk = data[ 0, len ]
|
966
|
+
chunk_size = chunk.bytesize
|
967
|
+
|
968
|
+
if chunk_size == len then
|
969
|
+
# 取完整了
|
970
|
+
chunk = @custom.decode( "#{ atun_info[ :rbuff ] }#{ chunk }" )
|
971
|
+
# puts "debug decode and add dst.wbuff #{ chunk.bytesize }"
|
972
|
+
add_dst_wbuff( dst, chunk )
|
973
|
+
atun_info[ :rbuff ].clear
|
974
|
+
atun_info[ :wait_bytes ] = 0
|
975
|
+
else
|
976
|
+
# 暂存
|
977
|
+
# puts "debug add atun.rbuff #{ chunk_size } wait bytes #{ len - chunk_size }"
|
978
|
+
atun_info[ :rbuff ] << chunk
|
979
|
+
atun_info[ :wait_bytes ] = len - chunk_size
|
980
|
+
end
|
981
|
+
|
982
|
+
data = data[ chunk_size..-1 ]
|
983
|
+
end
|
956
984
|
end
|
957
985
|
|
958
986
|
##
|
959
|
-
#
|
987
|
+
# read btun
|
960
988
|
#
|
961
|
-
def
|
962
|
-
|
989
|
+
def read_btun( btun )
|
990
|
+
if btun.closed? then
|
991
|
+
puts "p#{ Process.pid } #{ Time.new } read btun but btun closed?"
|
992
|
+
return
|
993
|
+
end
|
963
994
|
|
964
|
-
|
965
|
-
while proxy_info[ :ctlmsgs ].any? do
|
966
|
-
data = proxy_info[ :ctlmsgs ].map{ | ctlmsg | "#{ ctlmsg }#{ SEPARATE }" }.join
|
995
|
+
btun_info = @btun_infos[ btun ]
|
967
996
|
|
968
|
-
|
969
|
-
|
970
|
-
|
971
|
-
|
972
|
-
|
973
|
-
|
974
|
-
|
975
|
-
|
976
|
-
|
977
|
-
|
997
|
+
begin
|
998
|
+
data = btun.read_nonblock( READ_SIZE )
|
999
|
+
rescue Exception => e
|
1000
|
+
# puts "debug read btun #{ btun_info[ :im ] } #{ e.class }"
|
1001
|
+
close_btun( btun )
|
1002
|
+
return
|
1003
|
+
end
|
1004
|
+
|
1005
|
+
if data.bytesize != 2 then
|
1006
|
+
close_btun( btun )
|
1007
|
+
return
|
1008
|
+
end
|
1009
|
+
|
1010
|
+
# puts "debug read btun #{ data.inspect }"
|
1011
|
+
@traff_ins[ btun_info[ :im ] ] += data.bytesize
|
1012
|
+
dst = btun_info[ :dst ]
|
1013
|
+
|
1014
|
+
if dst then
|
1015
|
+
# puts "debug unexpect data"
|
1016
|
+
close_btun( btun )
|
1017
|
+
return
|
1018
|
+
end
|
1019
|
+
|
1020
|
+
dst_id = data.unpack( 'n' ).first
|
1021
|
+
ctl_addr = btun_info[ :ctl_addr ]
|
1022
|
+
ctl_info = @ctl_infos[ ctl_addr ]
|
1023
|
+
|
1024
|
+
unless ctl_info then
|
1025
|
+
# puts "debug ctl info not found"
|
1026
|
+
close_btun( btun )
|
1027
|
+
return
|
1028
|
+
end
|
1029
|
+
|
1030
|
+
dst = ctl_info[ :dsts ][ dst_id ]
|
1031
|
+
|
1032
|
+
unless dst then
|
1033
|
+
# puts "debug dst #{ dst_id } not found"
|
1034
|
+
close_btun( btun )
|
1035
|
+
return
|
1036
|
+
end
|
1037
|
+
|
1038
|
+
# puts "debug set btun.dst #{ dst_id }"
|
1039
|
+
btun_info[ :dst ] = dst
|
1040
|
+
dst_info = @dst_infos[ dst ]
|
1041
|
+
btun_info[ :domain_port ] = dst_info[ :domain_port ]
|
1042
|
+
|
1043
|
+
unless dst_info[ :rbuff ].empty? then
|
1044
|
+
data2 = ''
|
1045
|
+
|
1046
|
+
until dst_info[ :rbuff ].empty? do
|
1047
|
+
_data = dst_info[ :rbuff ][ 0, 65535 ]
|
1048
|
+
data_size = _data.bytesize
|
1049
|
+
# puts "debug move dst.rbuff to btun.wbuff"
|
1050
|
+
data2 << pack_a_chunk( _data )
|
1051
|
+
dst_info[ :rbuff ] = dst_info[ :rbuff ][ data_size..-1 ]
|
978
1052
|
end
|
979
1053
|
|
980
|
-
|
1054
|
+
add_btun_wbuff( btun, data2 )
|
981
1055
|
end
|
982
1056
|
|
983
|
-
|
1057
|
+
dst_info[ :btun ] = btun
|
984
1058
|
end
|
985
1059
|
|
986
1060
|
##
|
@@ -993,7 +1067,7 @@ module Girl
|
|
993
1067
|
end
|
994
1068
|
|
995
1069
|
dst_info = @dst_infos[ dst ]
|
996
|
-
|
1070
|
+
atun = dst_info[ :atun ]
|
997
1071
|
data = dst_info[ :wbuff ]
|
998
1072
|
|
999
1073
|
# 写前为空,处理关闭写
|
@@ -1010,41 +1084,45 @@ module Girl
|
|
1010
1084
|
# 写入
|
1011
1085
|
begin
|
1012
1086
|
written = dst.write_nonblock( data )
|
1013
|
-
rescue IO::WaitWritable
|
1087
|
+
rescue IO::WaitWritable
|
1014
1088
|
print 'w'
|
1015
1089
|
return
|
1016
1090
|
rescue Exception => e
|
1017
|
-
# puts "
|
1091
|
+
# puts "debug write dst #{ e.class }"
|
1018
1092
|
close_write_dst( dst )
|
1019
|
-
|
1093
|
+
|
1094
|
+
if atun then
|
1095
|
+
close_atun( atun )
|
1096
|
+
end
|
1097
|
+
|
1020
1098
|
return
|
1021
1099
|
end
|
1022
1100
|
|
1023
|
-
# puts "
|
1101
|
+
# puts "debug write dst #{ written }"
|
1024
1102
|
data = data[ written..-1 ]
|
1025
1103
|
dst_info[ :wbuff ] = data
|
1026
1104
|
@traff_outs[ dst_info[ :im ] ] += written
|
1027
1105
|
end
|
1028
1106
|
|
1029
1107
|
##
|
1030
|
-
# write
|
1108
|
+
# write btun
|
1031
1109
|
#
|
1032
|
-
def
|
1033
|
-
if
|
1034
|
-
puts "p#{ Process.pid } #{ Time.new } write
|
1110
|
+
def write_btun( btun )
|
1111
|
+
if btun.closed? then
|
1112
|
+
puts "p#{ Process.pid } #{ Time.new } write btun but btun closed?"
|
1035
1113
|
return
|
1036
1114
|
end
|
1037
1115
|
|
1038
|
-
|
1039
|
-
dst =
|
1040
|
-
data =
|
1116
|
+
btun_info = @btun_infos[ btun ]
|
1117
|
+
dst = btun_info[ :dst ]
|
1118
|
+
data = btun_info[ :wbuff ]
|
1041
1119
|
|
1042
1120
|
# 写前为空,处理关闭写
|
1043
1121
|
if data.empty? then
|
1044
|
-
if
|
1045
|
-
|
1122
|
+
if btun_info[ :closing ] then
|
1123
|
+
close_btun( btun )
|
1046
1124
|
else
|
1047
|
-
@writes.delete(
|
1125
|
+
@writes.delete( btun )
|
1048
1126
|
end
|
1049
1127
|
|
1050
1128
|
return
|
@@ -1052,21 +1130,21 @@ module Girl
|
|
1052
1130
|
|
1053
1131
|
# 写入
|
1054
1132
|
begin
|
1055
|
-
written =
|
1056
|
-
rescue IO::WaitWritable
|
1133
|
+
written = btun.write_nonblock( data )
|
1134
|
+
rescue IO::WaitWritable
|
1057
1135
|
print 'w'
|
1058
1136
|
return
|
1059
1137
|
rescue Exception => e
|
1060
|
-
# puts "
|
1061
|
-
|
1138
|
+
# puts "debug write btun #{ e.class }"
|
1139
|
+
close_btun( btun )
|
1062
1140
|
close_read_dst( dst ) if dst
|
1063
1141
|
return
|
1064
1142
|
end
|
1065
1143
|
|
1066
|
-
# puts "
|
1144
|
+
# puts "debug write btun #{ written }"
|
1067
1145
|
data = data[ written..-1 ]
|
1068
|
-
|
1069
|
-
@traff_outs[
|
1146
|
+
btun_info[ :wbuff ] = data
|
1147
|
+
@traff_outs[ btun_info[ :im ] ] += written
|
1070
1148
|
|
1071
1149
|
if dst && !dst.closed? then
|
1072
1150
|
dst_info = @dst_infos[ dst ]
|