girl 3.7.0 → 4.2.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 +3 -0
- data/lib/girl/proxy_worker.rb +507 -604
- data/lib/girl/proxyd.rb +1 -15
- data/lib/girl/proxyd_custom.rb +3 -0
- data/lib/girl/proxyd_worker.rb +530 -466
- data/lib/girl/relay.rb +0 -2
- data/lib/girl/relay_worker.rb +475 -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 +133 -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
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
301
|
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
|
-
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,18 +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
|
-
puts "p#{ Process.pid } #{ Time.new } proxyd bind on #{ proxyd_port }"
|
525
|
-
ssl_proxyd = OpenSSL::SSL::SSLServer.new proxyd, @context
|
526
|
-
add_read( ssl_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
|
527
492
|
end
|
528
493
|
|
529
494
|
##
|
@@ -533,11 +498,20 @@ module Girl
|
|
533
498
|
infod = Socket.new( Socket::AF_INET, Socket::SOCK_DGRAM, 0 )
|
534
499
|
infod.setsockopt( Socket::SOL_SOCKET, Socket::SO_REUSEPORT, 1 )
|
535
500
|
infod.bind( Socket.sockaddr_in( infod_port, '127.0.0.1' ) )
|
536
|
-
|
537
501
|
puts "p#{ Process.pid } #{ Time.new } infod bind on #{ infod_port }"
|
538
502
|
add_read( infod, :infod )
|
539
503
|
end
|
540
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
|
+
|
541
515
|
##
|
542
516
|
# next tick
|
543
517
|
#
|
@@ -545,22 +519,31 @@ module Girl
|
|
545
519
|
@dotw.write( '.' )
|
546
520
|
end
|
547
521
|
|
522
|
+
##
|
523
|
+
# pack a chunk
|
524
|
+
#
|
525
|
+
def pack_a_chunk( data )
|
526
|
+
# puts "debug pack a chunk"
|
527
|
+
data = @custom.encode( data )
|
528
|
+
"#{ [ data.bytesize ].pack( 'n' ) }#{ data }"
|
529
|
+
end
|
530
|
+
|
548
531
|
##
|
549
532
|
# resolve domain
|
550
533
|
#
|
551
|
-
def resolve_domain(
|
534
|
+
def resolve_domain( ctl_addr, src_id, domain_port )
|
552
535
|
resolv_cache = @resolv_caches[ domain_port ]
|
553
536
|
|
554
537
|
if resolv_cache then
|
555
538
|
destination_addr, created_at = resolv_cache
|
556
539
|
|
557
540
|
if Time.new - created_at < RESOLV_CACHE_EXPIRE then
|
558
|
-
# puts "
|
559
|
-
deal_with_destination_addr(
|
541
|
+
# puts "debug #{ domain_port } hit resolv cache #{ Addrinfo.new( destination_addr ).inspect }"
|
542
|
+
deal_with_destination_addr( ctl_addr, src_id, destination_addr, domain_port )
|
560
543
|
return
|
561
544
|
end
|
562
545
|
|
563
|
-
# puts "
|
546
|
+
# puts "debug expire #{ domain_port } resolv cache"
|
564
547
|
@resolv_caches.delete( domain_port )
|
565
548
|
end
|
566
549
|
|
@@ -579,16 +562,38 @@ module Girl
|
|
579
562
|
end
|
580
563
|
|
581
564
|
if destination_addr then
|
582
|
-
# puts "
|
565
|
+
# puts "debug resolved #{ domain_port } #{ Addrinfo.new( destination_addr ).inspect }"
|
583
566
|
@resolv_caches[ domain_port ] = [ destination_addr, Time.new ]
|
584
|
-
|
585
|
-
unless proxy.closed? then
|
586
|
-
deal_with_destination_addr( proxy, src_id, destination_addr, domain_port )
|
587
|
-
end
|
567
|
+
deal_with_destination_addr( ctl_addr, src_id, destination_addr, domain_port )
|
588
568
|
end
|
589
569
|
end
|
590
570
|
end
|
591
571
|
|
572
|
+
##
|
573
|
+
# send ctlmsg
|
574
|
+
#
|
575
|
+
def send_ctlmsg( data, to_addr )
|
576
|
+
data = @custom.encode( data )
|
577
|
+
|
578
|
+
begin
|
579
|
+
@ctld.sendmsg( data, 0, to_addr )
|
580
|
+
rescue Exception => e
|
581
|
+
puts "p#{ Process.pid } #{ Time.new } sendmsg #{ e.class }"
|
582
|
+
end
|
583
|
+
end
|
584
|
+
|
585
|
+
##
|
586
|
+
# set btun closing
|
587
|
+
#
|
588
|
+
def set_btun_closing( btun )
|
589
|
+
return if btun.closed?
|
590
|
+
btun_info = @btun_infos[ btun ]
|
591
|
+
return if btun_info[ :closing ]
|
592
|
+
# puts "debug set btun closing"
|
593
|
+
btun_info[ :closing ] = true
|
594
|
+
add_write( btun )
|
595
|
+
end
|
596
|
+
|
592
597
|
##
|
593
598
|
# set dst closing write
|
594
599
|
#
|
@@ -596,31 +601,20 @@ module Girl
|
|
596
601
|
return if dst.closed? || @closing_dsts.include?( dst )
|
597
602
|
dst_info = @dst_infos[ dst ]
|
598
603
|
return if dst_info[ :closing_write ]
|
604
|
+
# puts "debug set dst closing write"
|
599
605
|
dst_info[ :closing_write ] = true
|
600
606
|
add_write( dst )
|
601
607
|
end
|
602
608
|
|
603
|
-
##
|
604
|
-
# set tun closing write
|
605
|
-
#
|
606
|
-
def set_tun_closing_write( tun )
|
607
|
-
return if tun.closed? || @closing_tuns.include?( tun )
|
608
|
-
tun_info = @tun_infos[ tun ]
|
609
|
-
return if tun_info[ :closing_write ]
|
610
|
-
tun_info[ :closing_write ] = true
|
611
|
-
add_write( tun )
|
612
|
-
end
|
613
|
-
|
614
609
|
##
|
615
610
|
# read dotr
|
616
611
|
#
|
617
612
|
def read_dotr( dotr )
|
618
|
-
dotr.read_nonblock(
|
613
|
+
dotr.read_nonblock( 65535 )
|
619
614
|
|
620
|
-
|
621
|
-
|
622
|
-
@
|
623
|
-
@closing_proxys.clear
|
615
|
+
if @deleting_ctl_infos.any? then
|
616
|
+
@deleting_ctl_infos.each { | ctl_addr | del_ctl_info( ctl_addr ) }
|
617
|
+
@deleting_ctl_infos.clear
|
624
618
|
end
|
625
619
|
|
626
620
|
if @closing_dsts.any? then
|
@@ -628,11 +622,6 @@ module Girl
|
|
628
622
|
@closing_dsts.clear
|
629
623
|
end
|
630
624
|
|
631
|
-
if @closing_tuns.any? then
|
632
|
-
@closing_tuns.each { | tun | close_tun( tun ) }
|
633
|
-
@closing_tuns.clear
|
634
|
-
end
|
635
|
-
|
636
625
|
if @resume_dsts.any? then
|
637
626
|
@resume_dsts.each do | dst |
|
638
627
|
add_read( dst )
|
@@ -642,78 +631,33 @@ module Girl
|
|
642
631
|
@resume_dsts.clear
|
643
632
|
end
|
644
633
|
|
645
|
-
if @
|
646
|
-
@
|
647
|
-
add_read(
|
648
|
-
@
|
634
|
+
if @resume_atuns.any? then
|
635
|
+
@resume_atuns.each do | atun |
|
636
|
+
add_read( atun )
|
637
|
+
@paused_atuns.delete( atun )
|
649
638
|
end
|
650
639
|
|
651
|
-
@
|
652
|
-
end
|
653
|
-
end
|
654
|
-
|
655
|
-
##
|
656
|
-
# read proxyd
|
657
|
-
#
|
658
|
-
def read_proxyd( proxyd )
|
659
|
-
begin
|
660
|
-
proxy = proxyd.accept
|
661
|
-
rescue Exception => e
|
662
|
-
puts "p#{ Process.pid } #{ Time.new } proxyd accept #{ e.class }"
|
663
|
-
return
|
640
|
+
@resume_atuns.clear
|
664
641
|
end
|
665
|
-
|
666
|
-
@proxy_infos[ proxy ] = {
|
667
|
-
addrinfo: proxy.io.remote_address, # proxy地址
|
668
|
-
im: nil, # 标识
|
669
|
-
tund: nil, # 对应tund
|
670
|
-
tund_port: nil, # tund端口
|
671
|
-
ctlmsgs: [], # ctlmsg
|
672
|
-
dsts: ConcurrentHash.new, # dst_id => dst
|
673
|
-
dst_ids: ConcurrentHash.new, # src_id => dst_id
|
674
|
-
created_at: Time.new, # 创建时间
|
675
|
-
last_recv_at: nil # 上一次收到流量的时间
|
676
|
-
}
|
677
|
-
|
678
|
-
puts "p#{ Process.pid } #{ Time.new } accept a proxy #{ proxy.io.remote_address.inspect } #{ proxy.ssl_version }, #{ @proxy_infos.size } proxys"
|
679
|
-
add_read( proxy, :proxy )
|
680
642
|
end
|
681
643
|
|
682
644
|
##
|
683
|
-
# read
|
645
|
+
# read ctld
|
684
646
|
#
|
685
|
-
def
|
686
|
-
|
687
|
-
|
688
|
-
|
689
|
-
|
690
|
-
|
691
|
-
begin
|
692
|
-
data = proxy.read_nonblock( READ_SIZE )
|
693
|
-
rescue IO::WaitReadable
|
694
|
-
return
|
695
|
-
rescue Errno::EINTR
|
696
|
-
puts e.class
|
697
|
-
return
|
698
|
-
rescue Exception => e
|
699
|
-
# puts "debug1 read proxy #{ e.class }"
|
700
|
-
close_proxy( proxy )
|
701
|
-
return
|
702
|
-
end
|
703
|
-
|
704
|
-
proxy_info = @proxy_infos[ proxy ]
|
705
|
-
proxy_info[ :last_recv_at ] = Time.new
|
706
|
-
|
707
|
-
data.split( SEPARATE ).each do | ctlmsg |
|
708
|
-
next unless ctlmsg[ 0 ]
|
709
|
-
|
710
|
-
ctl_num = ctlmsg[ 0 ].unpack( 'C' ).first
|
647
|
+
def read_ctld( ctld )
|
648
|
+
data, addrinfo, rflags, *controls = ctld.recvmsg
|
649
|
+
data = @custom.decode( data )
|
650
|
+
ctl_num = data[ 0 ].unpack( 'C' ).first
|
651
|
+
ctl_addr = addrinfo.to_sockaddr
|
652
|
+
ctl_info = @ctl_infos[ ctl_addr ]
|
711
653
|
|
712
|
-
|
713
|
-
|
714
|
-
|
715
|
-
|
716
|
-
|
654
|
+
case ctl_num
|
655
|
+
when HELLO then
|
656
|
+
if ctl_info then
|
657
|
+
atund_port, btund_port = ctl_info[ :atund_port ], ctl_info[ :btund_port ]
|
658
|
+
else
|
659
|
+
return if data.size <= 1
|
660
|
+
im = data[ 1..-1 ]
|
717
661
|
result = @custom.check( im, addrinfo )
|
718
662
|
|
719
663
|
if result != :success then
|
@@ -726,62 +670,65 @@ module Girl
|
|
726
670
|
@traff_outs[ im ] = 0
|
727
671
|
end
|
728
672
|
|
729
|
-
|
730
|
-
|
731
|
-
|
732
|
-
|
733
|
-
|
734
|
-
|
735
|
-
|
736
|
-
|
737
|
-
|
738
|
-
|
739
|
-
proxy: proxy,
|
740
|
-
close_read: false,
|
741
|
-
close_write: false
|
673
|
+
atund = new_a_tund
|
674
|
+
atund_port = atund.local_address.ip_port
|
675
|
+
btund = new_a_tund
|
676
|
+
btund_port = btund.local_address.ip_port
|
677
|
+
add_read( atund, :atund )
|
678
|
+
add_read( btund, :btund )
|
679
|
+
|
680
|
+
@atund_infos[ atund ] = {
|
681
|
+
ctl_addr: ctl_addr,
|
682
|
+
im: im
|
742
683
|
}
|
743
684
|
|
744
|
-
|
745
|
-
|
746
|
-
|
747
|
-
|
748
|
-
add_ctlmsg( proxy, data2 )
|
749
|
-
when A_NEW_SOURCE then
|
750
|
-
next if ctlmsg.size <= 9
|
751
|
-
src_id = ctlmsg[ 1, 8 ].unpack( 'Q>' ).first
|
752
|
-
dst_id = proxy_info[ :dst_ids ][ src_id ]
|
753
|
-
next if dst_id
|
754
|
-
domain_port = ctlmsg[ 9..-1 ]
|
755
|
-
# puts "debug1 a new source #{ src_id } #{ domain_port }"
|
756
|
-
resolve_domain( proxy, src_id, domain_port )
|
757
|
-
when RESOLV then
|
758
|
-
next if ctlmsg.size <= 9
|
759
|
-
src_id = ctlmsg[ 1, 8 ].unpack( 'Q>' ).first
|
760
|
-
domain = ctlmsg[ 9..-1 ]
|
761
|
-
|
762
|
-
Thread.new do
|
763
|
-
begin
|
764
|
-
ip_info = Addrinfo.ip( domain )
|
765
|
-
rescue Exception => e
|
766
|
-
puts "p#{ Process.pid } #{ Time.new } resolv #{ domain.inspect } #{ e.class }"
|
767
|
-
end
|
685
|
+
@btund_infos[ btund ] = {
|
686
|
+
ctl_addr: ctl_addr,
|
687
|
+
im: im
|
688
|
+
}
|
768
689
|
|
769
|
-
|
770
|
-
|
771
|
-
|
772
|
-
|
773
|
-
|
774
|
-
|
775
|
-
|
776
|
-
|
777
|
-
|
778
|
-
|
690
|
+
@ctl_infos[ ctl_addr ] = {
|
691
|
+
addrinfo: addrinfo, # 地址
|
692
|
+
im: im, # 标识
|
693
|
+
atund: atund, # 对应atund,src->dst
|
694
|
+
atund_port: atund_port, # atund端口
|
695
|
+
btund: btund, # 对应btund,dst->src
|
696
|
+
btund_port: btund_port, # btund端口
|
697
|
+
dsts: ConcurrentHash.new, # dst_id => dst
|
698
|
+
dst_ids: ConcurrentHash.new, # src_id => dst_id
|
699
|
+
last_recv_at: Time.new # 上一次收到流量的时间
|
700
|
+
}
|
701
|
+
|
702
|
+
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 }"
|
703
|
+
end
|
704
|
+
|
705
|
+
data2 = [ TUND_PORT, atund_port, btund_port ].pack( 'Cnn' )
|
706
|
+
send_ctlmsg( data2, ctl_addr )
|
707
|
+
when A_NEW_SOURCE then
|
708
|
+
unless ctl_info then
|
709
|
+
send_ctlmsg( [ UNKNOWN_CTL_ADDR ].pack( 'C' ), addrinfo )
|
710
|
+
return
|
711
|
+
end
|
712
|
+
|
713
|
+
return if data.size <= 9
|
714
|
+
src_id = data[ 1, 8 ].unpack( 'Q>' ).first
|
715
|
+
dst_id = ctl_info[ :dst_ids ][ src_id ]
|
716
|
+
|
717
|
+
if dst_id then
|
718
|
+
data2 = [ PAIRED, src_id, dst_id ].pack( 'CQ>n' )
|
719
|
+
# puts "debug dst id exist, send ctlmsg paired #{ src_id } #{ dst_id }"
|
720
|
+
send_ctlmsg( data2, ctl_addr )
|
779
721
|
return
|
780
|
-
when HEARTBEAT
|
781
|
-
# puts "debug1 #{ Time.new } got heartbeat"
|
782
|
-
data2 = [ HEARTBEAT ].pack( 'C' )
|
783
|
-
add_ctlmsg( proxy, data2 )
|
784
722
|
end
|
723
|
+
|
724
|
+
domain_port = data[ 9..-1 ]
|
725
|
+
# puts "debug got a new source #{ src_id } #{ domain_port }"
|
726
|
+
resolve_domain( ctl_addr, src_id, domain_port )
|
727
|
+
ctl_info[ :last_recv_at ] = Time.new
|
728
|
+
when CTL_FIN then
|
729
|
+
return unless ctl_info
|
730
|
+
# puts "debug got ctl fin #{ addrinfo.inspect }"
|
731
|
+
del_ctl_info( ctl_addr )
|
785
732
|
end
|
786
733
|
end
|
787
734
|
|
@@ -791,7 +738,7 @@ module Girl
|
|
791
738
|
def read_infod( infod )
|
792
739
|
data, addrinfo, rflags, *controls = infod.recvmsg
|
793
740
|
ctl_num = data[ 0 ].unpack( 'C' ).first
|
794
|
-
# puts "
|
741
|
+
# puts "debug infod got #{ ctl_num } #{ addrinfo.ip_unpack.inspect }"
|
795
742
|
|
796
743
|
case ctl_num
|
797
744
|
when TRAFF_INFOS then
|
@@ -805,9 +752,9 @@ module Girl
|
|
805
752
|
|
806
753
|
begin
|
807
754
|
infod.sendmsg_nonblock( data2, 0, addrinfo )
|
808
|
-
rescue IO::WaitWritable
|
755
|
+
rescue IO::WaitWritable
|
809
756
|
print 'w'
|
810
|
-
rescue
|
757
|
+
rescue Exception => e
|
811
758
|
puts "p#{ Process.pid } #{ Time.new } infod sendmsg to #{ addrinfo.ip_unpack.inspect } #{ e.class }"
|
812
759
|
end
|
813
760
|
end
|
@@ -822,157 +769,270 @@ module Girl
|
|
822
769
|
return
|
823
770
|
end
|
824
771
|
|
772
|
+
dst_info = @dst_infos[ dst ]
|
773
|
+
btun = dst_info[ :btun ]
|
774
|
+
|
825
775
|
begin
|
826
|
-
data = dst.read_nonblock(
|
827
|
-
rescue IO::WaitReadable
|
776
|
+
data = dst.read_nonblock( 65535 )
|
777
|
+
rescue IO::WaitReadable
|
828
778
|
print 'r'
|
829
779
|
return
|
830
780
|
rescue Exception => e
|
831
|
-
# puts "
|
832
|
-
|
833
|
-
|
834
|
-
|
781
|
+
# puts "debug read dst #{ e.class }"
|
782
|
+
close_read_dst( dst )
|
783
|
+
|
784
|
+
if btun then
|
785
|
+
set_btun_closing( btun )
|
786
|
+
end
|
787
|
+
|
835
788
|
return
|
836
789
|
end
|
837
790
|
|
838
|
-
dst_info = @dst_infos[ dst ]
|
839
791
|
@traff_ins[ dst_info[ :im ] ] += data.bytesize
|
840
|
-
|
792
|
+
# puts "debug read dst #{ data.bytesize }"
|
841
793
|
|
842
|
-
if
|
843
|
-
|
844
|
-
tun_info = @tun_infos[ tun ]
|
845
|
-
# puts "debug2 add tun.wbuff #{ data.bytesize }"
|
846
|
-
add_tun_wbuff( tun, data )
|
847
|
-
end
|
794
|
+
if btun then
|
795
|
+
add_btun_wbuff( btun, pack_a_chunk( data ) )
|
848
796
|
else
|
797
|
+
# puts "debug add dst.rbuff #{ data.bytesize }"
|
849
798
|
add_dst_rbuff( dst, data )
|
850
799
|
end
|
851
800
|
end
|
852
801
|
|
853
802
|
##
|
854
|
-
# read
|
803
|
+
# read atund
|
855
804
|
#
|
856
|
-
def
|
857
|
-
if
|
858
|
-
puts "p#{ Process.pid } #{ Time.new } read
|
805
|
+
def read_atund( atund )
|
806
|
+
if atund.closed? then
|
807
|
+
puts "p#{ Process.pid } #{ Time.new } read atund but atund closed?"
|
859
808
|
return
|
860
809
|
end
|
861
810
|
|
811
|
+
atund_info = @atund_infos[ atund ]
|
812
|
+
|
862
813
|
begin
|
863
|
-
|
814
|
+
atun, _ = atund.accept_nonblock
|
864
815
|
rescue Exception => e
|
865
|
-
puts "p#{ Process.pid } #{ Time.new }
|
816
|
+
puts "p#{ Process.pid } #{ Time.new } atund #{ atund_info[ :im ] } accept #{ e.class }"
|
817
|
+
puts e.full_message
|
866
818
|
return
|
867
819
|
end
|
868
820
|
|
869
|
-
# puts "
|
870
|
-
|
871
|
-
|
872
|
-
|
873
|
-
|
874
|
-
|
875
|
-
|
876
|
-
|
877
|
-
|
878
|
-
domain_port: nil, # dst的目的地和端口
|
879
|
-
wbuff: '', # 写前
|
880
|
-
closing_write: false # 准备关闭写
|
821
|
+
# puts "debug accept a atun #{ atund_info[ :im ] }"
|
822
|
+
|
823
|
+
@atun_infos[ atun ] = {
|
824
|
+
ctl_addr: atund_info[ :ctl_addr ], # 对应ctl
|
825
|
+
im: atund_info[ :im ], # 标识
|
826
|
+
dst: nil, # 对应dst
|
827
|
+
domain_port: nil, # dst的目的地和端口
|
828
|
+
rbuff: '', # 暂存当前块没收全的流量
|
829
|
+
wait_bytes: 0 # 还差多少字节收全当前块
|
881
830
|
}
|
882
831
|
|
883
|
-
add_read(
|
832
|
+
add_read( atun, :atun )
|
884
833
|
end
|
885
834
|
|
886
835
|
##
|
887
|
-
# read
|
836
|
+
# read btund
|
888
837
|
#
|
889
|
-
def
|
890
|
-
if
|
891
|
-
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?"
|
892
841
|
return
|
893
842
|
end
|
894
843
|
|
844
|
+
btund_info = @btund_infos[ btund ]
|
845
|
+
|
895
846
|
begin
|
896
|
-
|
897
|
-
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
|
898
851
|
return
|
899
|
-
|
900
|
-
|
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?"
|
901
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 )
|
902
882
|
rescue Exception => e
|
903
|
-
# puts "
|
904
|
-
|
905
|
-
|
906
|
-
|
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
|
+
|
907
890
|
return
|
908
891
|
end
|
909
892
|
|
910
|
-
tun_info = @tun_infos[ tun ]
|
911
|
-
@traff_ins[ tun_info[ :im ] ] += data.bytesize
|
912
|
-
dst = tun_info[ :dst ]
|
913
|
-
|
914
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
|
+
|
915
899
|
dst_id = data[ 0, 2 ].unpack( 'n' ).first
|
916
|
-
|
900
|
+
ctl_addr = atun_info[ :ctl_addr ]
|
901
|
+
ctl_info = @ctl_infos[ ctl_addr ]
|
917
902
|
|
918
|
-
|
919
|
-
|
903
|
+
unless ctl_info then
|
904
|
+
close_atun( atun )
|
920
905
|
return
|
921
906
|
end
|
922
907
|
|
923
|
-
|
924
|
-
dst = proxy_info[ :dsts ][ dst_id ]
|
908
|
+
dst = ctl_info[ :dsts ][ dst_id ]
|
925
909
|
|
926
910
|
unless dst then
|
927
|
-
|
911
|
+
close_atun( atun )
|
928
912
|
return
|
929
913
|
end
|
930
914
|
|
931
|
-
# puts "
|
932
|
-
|
915
|
+
# puts "debug set atun.dst #{ dst_id }"
|
916
|
+
atun_info[ :dst ] = dst
|
933
917
|
dst_info = @dst_infos[ dst ]
|
934
|
-
|
935
|
-
|
936
|
-
unless dst_info[ :rbuff ].empty? then
|
937
|
-
# puts "debug1 move dst.rbuff to tun.wbuff"
|
938
|
-
add_tun_wbuff( tun, dst_info[ :rbuff ] )
|
939
|
-
end
|
918
|
+
atun_info[ :domain_port ] = dst_info[ :domain_port ]
|
919
|
+
dst_info[ :atun ] = atun
|
940
920
|
|
941
|
-
dst_info[ :tun ] = tun
|
942
921
|
data = data[ 2..-1 ]
|
943
|
-
return if data.empty?
|
944
922
|
end
|
945
923
|
|
946
|
-
|
947
|
-
|
924
|
+
until data.empty? do
|
925
|
+
rbuff = atun_info[ :rbuff ]
|
926
|
+
wait_bytes = atun_info[ :wait_bytes ]
|
927
|
+
|
928
|
+
if wait_bytes > 0 then
|
929
|
+
len = wait_bytes
|
930
|
+
# puts "debug wait bytes #{ len }"
|
931
|
+
else
|
932
|
+
if data.bytesize <= 2 then
|
933
|
+
# puts "debug unexpect data length #{ data.bytesize }"
|
934
|
+
close_atun( atun )
|
935
|
+
return
|
936
|
+
end
|
937
|
+
|
938
|
+
len = data[ 0, 2 ].unpack( 'n' ).first
|
939
|
+
# puts "debug read len #{ len }"
|
940
|
+
data = data[ 2..-1 ]
|
941
|
+
end
|
942
|
+
|
943
|
+
chunk = data[ 0, len ]
|
944
|
+
chunk_size = chunk.bytesize
|
945
|
+
|
946
|
+
if chunk_size == len then
|
947
|
+
# 取完整了
|
948
|
+
chunk = @custom.decode( "#{ rbuff }#{ chunk }" )
|
949
|
+
# puts "debug decode and add dst.wbuff #{ chunk.bytesize }"
|
950
|
+
add_dst_wbuff( dst, chunk )
|
951
|
+
atun_info[ :rbuff ].clear
|
952
|
+
atun_info[ :wait_bytes ] = 0
|
953
|
+
else
|
954
|
+
# 暂存
|
955
|
+
# puts "debug add atun.rbuff #{ chunk_size } wait bytes #{ len - chunk_size }"
|
956
|
+
atun_info[ :rbuff ] << chunk
|
957
|
+
atun_info[ :wait_bytes ] = len - chunk_size
|
958
|
+
end
|
959
|
+
|
960
|
+
data = data[ chunk_size..-1 ]
|
961
|
+
end
|
948
962
|
end
|
949
963
|
|
950
964
|
##
|
951
|
-
#
|
965
|
+
# read btun
|
952
966
|
#
|
953
|
-
def
|
954
|
-
|
967
|
+
def read_btun( btun )
|
968
|
+
if btun.closed? then
|
969
|
+
puts "p#{ Process.pid } #{ Time.new } read btun but btun closed?"
|
970
|
+
return
|
971
|
+
end
|
955
972
|
|
956
|
-
|
957
|
-
while proxy_info[ :ctlmsgs ].any? do
|
958
|
-
data = proxy_info[ :ctlmsgs ].map{ | ctlmsg | "#{ ctlmsg }#{ SEPARATE }" }.join
|
973
|
+
btun_info = @btun_infos[ btun ]
|
959
974
|
|
960
|
-
|
961
|
-
|
962
|
-
|
963
|
-
|
964
|
-
|
965
|
-
|
966
|
-
|
967
|
-
|
968
|
-
|
969
|
-
|
975
|
+
begin
|
976
|
+
data = btun.read_nonblock( READ_SIZE )
|
977
|
+
rescue Exception => e
|
978
|
+
# puts "debug read btun #{ btun_info[ :im ] } #{ e.class }"
|
979
|
+
close_btun( btun )
|
980
|
+
return
|
981
|
+
end
|
982
|
+
|
983
|
+
if data.bytesize != 2 then
|
984
|
+
close_btun( btun )
|
985
|
+
return
|
986
|
+
end
|
987
|
+
|
988
|
+
# puts "debug read btun #{ data.inspect }"
|
989
|
+
@traff_ins[ btun_info[ :im ] ] += data.bytesize
|
990
|
+
dst = btun_info[ :dst ]
|
991
|
+
|
992
|
+
if dst then
|
993
|
+
# puts "debug unexpect data"
|
994
|
+
close_btun( btun )
|
995
|
+
return
|
996
|
+
end
|
997
|
+
|
998
|
+
dst_id = data.unpack( 'n' ).first
|
999
|
+
ctl_addr = btun_info[ :ctl_addr ]
|
1000
|
+
ctl_info = @ctl_infos[ ctl_addr ]
|
1001
|
+
|
1002
|
+
unless ctl_info then
|
1003
|
+
# puts "debug ctl info not found"
|
1004
|
+
close_btun( btun )
|
1005
|
+
return
|
1006
|
+
end
|
1007
|
+
|
1008
|
+
dst = ctl_info[ :dsts ][ dst_id ]
|
1009
|
+
|
1010
|
+
unless dst then
|
1011
|
+
# puts "debug dst #{ dst_id } not found"
|
1012
|
+
close_btun( btun )
|
1013
|
+
return
|
1014
|
+
end
|
1015
|
+
|
1016
|
+
# puts "debug set btun.dst #{ dst_id }"
|
1017
|
+
btun_info[ :dst ] = dst
|
1018
|
+
dst_info = @dst_infos[ dst ]
|
1019
|
+
btun_info[ :domain_port ] = dst_info[ :domain_port ]
|
1020
|
+
|
1021
|
+
unless dst_info[ :rbuff ].empty? then
|
1022
|
+
data2 = ''
|
1023
|
+
|
1024
|
+
until dst_info[ :rbuff ].empty? do
|
1025
|
+
_data = dst_info[ :rbuff ][ 0, 65535 ]
|
1026
|
+
data_size = _data.bytesize
|
1027
|
+
# puts "debug move dst.rbuff to btun.wbuff"
|
1028
|
+
data2 << pack_a_chunk( _data )
|
1029
|
+
dst_info[ :rbuff ] = dst_info[ :rbuff ][ data_size..-1 ]
|
970
1030
|
end
|
971
1031
|
|
972
|
-
|
1032
|
+
add_btun_wbuff( btun, data2 )
|
973
1033
|
end
|
974
1034
|
|
975
|
-
|
1035
|
+
dst_info[ :btun ] = btun
|
976
1036
|
end
|
977
1037
|
|
978
1038
|
##
|
@@ -985,7 +1045,7 @@ module Girl
|
|
985
1045
|
end
|
986
1046
|
|
987
1047
|
dst_info = @dst_infos[ dst ]
|
988
|
-
|
1048
|
+
atun = dst_info[ :atun ]
|
989
1049
|
data = dst_info[ :wbuff ]
|
990
1050
|
|
991
1051
|
# 写前为空,处理关闭写
|
@@ -1002,41 +1062,45 @@ module Girl
|
|
1002
1062
|
# 写入
|
1003
1063
|
begin
|
1004
1064
|
written = dst.write_nonblock( data )
|
1005
|
-
rescue IO::WaitWritable
|
1065
|
+
rescue IO::WaitWritable
|
1006
1066
|
print 'w'
|
1007
1067
|
return
|
1008
1068
|
rescue Exception => e
|
1009
|
-
# puts "
|
1069
|
+
# puts "debug write dst #{ e.class }"
|
1010
1070
|
close_write_dst( dst )
|
1011
|
-
|
1071
|
+
|
1072
|
+
if atun then
|
1073
|
+
close_atun( atun )
|
1074
|
+
end
|
1075
|
+
|
1012
1076
|
return
|
1013
1077
|
end
|
1014
1078
|
|
1015
|
-
# puts "
|
1079
|
+
# puts "debug write dst #{ written }"
|
1016
1080
|
data = data[ written..-1 ]
|
1017
1081
|
dst_info[ :wbuff ] = data
|
1018
1082
|
@traff_outs[ dst_info[ :im ] ] += written
|
1019
1083
|
end
|
1020
1084
|
|
1021
1085
|
##
|
1022
|
-
# write
|
1086
|
+
# write btun
|
1023
1087
|
#
|
1024
|
-
def
|
1025
|
-
if
|
1026
|
-
puts "p#{ Process.pid } #{ Time.new } write
|
1088
|
+
def write_btun( btun )
|
1089
|
+
if btun.closed? then
|
1090
|
+
puts "p#{ Process.pid } #{ Time.new } write btun but btun closed?"
|
1027
1091
|
return
|
1028
1092
|
end
|
1029
1093
|
|
1030
|
-
|
1031
|
-
dst =
|
1032
|
-
data =
|
1094
|
+
btun_info = @btun_infos[ btun ]
|
1095
|
+
dst = btun_info[ :dst ]
|
1096
|
+
data = btun_info[ :wbuff ]
|
1033
1097
|
|
1034
1098
|
# 写前为空,处理关闭写
|
1035
1099
|
if data.empty? then
|
1036
|
-
if
|
1037
|
-
|
1100
|
+
if btun_info[ :closing ] then
|
1101
|
+
close_btun( btun )
|
1038
1102
|
else
|
1039
|
-
@writes.delete(
|
1103
|
+
@writes.delete( btun )
|
1040
1104
|
end
|
1041
1105
|
|
1042
1106
|
return
|
@@ -1044,21 +1108,21 @@ module Girl
|
|
1044
1108
|
|
1045
1109
|
# 写入
|
1046
1110
|
begin
|
1047
|
-
written =
|
1048
|
-
rescue IO::WaitWritable
|
1111
|
+
written = btun.write_nonblock( data )
|
1112
|
+
rescue IO::WaitWritable
|
1049
1113
|
print 'w'
|
1050
1114
|
return
|
1051
1115
|
rescue Exception => e
|
1052
|
-
# puts "
|
1053
|
-
|
1116
|
+
# puts "debug write btun #{ e.class }"
|
1117
|
+
close_btun( btun )
|
1054
1118
|
close_read_dst( dst ) if dst
|
1055
1119
|
return
|
1056
1120
|
end
|
1057
1121
|
|
1058
|
-
# puts "
|
1122
|
+
# puts "debug write btun #{ written }"
|
1059
1123
|
data = data[ written..-1 ]
|
1060
|
-
|
1061
|
-
@traff_outs[
|
1124
|
+
btun_info[ :wbuff ] = data
|
1125
|
+
@traff_outs[ btun_info[ :im ] ] += written
|
1062
1126
|
|
1063
1127
|
if dst && !dst.closed? then
|
1064
1128
|
dst_info = @dst_infos[ dst ]
|