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