girl 4.0.0 → 4.5.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 +0 -1
- data/lib/girl/head.rb +6 -2
- data/lib/girl/proxy.rb +4 -6
- data/lib/girl/proxy_worker.rb +133 -80
- data/lib/girl/proxyd_worker.rb +107 -38
- data/lib/girl/relay.rb +1 -1
- data/lib/girl/relay_worker.rb +125 -75
- data/lib/girl/resolv_custom.rb +2 -2
- data/lib/girl/resolvd_worker.rb +4 -4
- data/lib/girl/ssl_worker.rb +27 -11
- data/lib/girl/version.rb +1 -1
- metadata +3 -4
- data/lib/girl/custom_dns_query.rb +0 -11
data/lib/girl/proxyd_worker.rb
CHANGED
@@ -42,7 +42,6 @@ module Girl
|
|
42
42
|
loop_check_traff
|
43
43
|
|
44
44
|
loop do
|
45
|
-
# puts "debug select"
|
46
45
|
rs, ws = IO.select( @reads, @writes )
|
47
46
|
|
48
47
|
rs.each do | sock |
|
@@ -200,9 +199,7 @@ module Girl
|
|
200
199
|
return if atun.closed?
|
201
200
|
# puts "debug close atun"
|
202
201
|
close_sock( atun )
|
203
|
-
|
204
|
-
@paused_atuns.delete( atun )
|
205
|
-
@resume_atuns.delete( atun )
|
202
|
+
del_atun_info( atun )
|
206
203
|
end
|
207
204
|
|
208
205
|
##
|
@@ -222,7 +219,12 @@ module Girl
|
|
222
219
|
return if btun.closed?
|
223
220
|
# puts "debug close btun"
|
224
221
|
close_sock( btun )
|
225
|
-
@btun_infos.delete( btun )
|
222
|
+
btun_info = @btun_infos.delete( btun )
|
223
|
+
dst = btun_info[ :dst ]
|
224
|
+
|
225
|
+
if dst then
|
226
|
+
@paused_dsts.delete( dst )
|
227
|
+
end
|
226
228
|
end
|
227
229
|
|
228
230
|
##
|
@@ -247,11 +249,13 @@ module Girl
|
|
247
249
|
btun = dst_info[ :btun ]
|
248
250
|
|
249
251
|
if atun then
|
250
|
-
|
252
|
+
close_sock( atun )
|
253
|
+
del_atun_info( atun )
|
251
254
|
end
|
252
255
|
|
253
256
|
if btun then
|
254
|
-
|
257
|
+
close_sock( btun )
|
258
|
+
@btun_infos.delete( btun )
|
255
259
|
end
|
256
260
|
end
|
257
261
|
|
@@ -320,6 +324,7 @@ module Girl
|
|
320
324
|
ctl_addr: ctl_addr, # 对应ctl
|
321
325
|
im: ctl_info[ :im ], # 标识
|
322
326
|
domain_port: domain_port, # 目的地和端口
|
327
|
+
connected: false, # 是否已连接
|
323
328
|
rbuff: '', # 对应的tun没准备好,暂存读到的流量
|
324
329
|
atun: nil, # 对应的atun
|
325
330
|
btun: nil, # 对应的btun
|
@@ -332,6 +337,7 @@ module Girl
|
|
332
337
|
}
|
333
338
|
|
334
339
|
add_read( dst, :dst )
|
340
|
+
add_write( dst )
|
335
341
|
|
336
342
|
ctl_info[ :dst_ids ][ src_id ] = dst_id
|
337
343
|
ctl_info[ :dsts ][ dst_id ] = dst
|
@@ -341,6 +347,15 @@ module Girl
|
|
341
347
|
send_ctlmsg( data, ctl_addr )
|
342
348
|
end
|
343
349
|
|
350
|
+
##
|
351
|
+
# del atun info
|
352
|
+
#
|
353
|
+
def del_atun_info( atun )
|
354
|
+
@atun_infos.delete( atun )
|
355
|
+
@paused_atuns.delete( atun )
|
356
|
+
@resume_atuns.delete( atun )
|
357
|
+
end
|
358
|
+
|
344
359
|
##
|
345
360
|
# del ctl info
|
346
361
|
#
|
@@ -391,11 +406,17 @@ module Girl
|
|
391
406
|
end
|
392
407
|
|
393
408
|
@dst_infos.each do | dst, dst_info |
|
394
|
-
|
395
|
-
|
396
|
-
|
409
|
+
if dst_info[ :connected ] then
|
410
|
+
last_recv_at = dst_info[ :last_recv_at ] || dst_info[ :created_at ]
|
411
|
+
last_sent_at = dst_info[ :last_sent_at ] || dst_info[ :created_at ]
|
412
|
+
expire_after = EXPIRE_AFTER
|
413
|
+
is_expire = ( now - last_recv_at >= expire_after ) && ( now - last_sent_at >= expire_after )
|
414
|
+
else
|
415
|
+
expire_after = EXPIRE_CONNECTING
|
416
|
+
is_expire = ( now - dst_info[ :created_at ] >= expire_after )
|
417
|
+
end
|
397
418
|
|
398
|
-
if
|
419
|
+
if is_expire then
|
399
420
|
puts "p#{ Process.pid } #{ Time.new } expire dst #{ expire_after } #{ dst_info[ :domain_port ] }"
|
400
421
|
|
401
422
|
unless @closing_dsts.include?( dst ) then
|
@@ -419,22 +440,28 @@ module Girl
|
|
419
440
|
@paused_dsts.each do | dst |
|
420
441
|
dst_info = @dst_infos[ dst ]
|
421
442
|
btun = dst_info[ :btun ]
|
422
|
-
btun_info = @btun_infos[ btun ]
|
423
443
|
|
424
|
-
if
|
425
|
-
|
426
|
-
|
444
|
+
if btun && !btun.closed? then
|
445
|
+
btun_info = @btun_infos[ btun ]
|
446
|
+
|
447
|
+
if btun_info[ :wbuff ].size < RESUME_BELOW then
|
448
|
+
puts "p#{ Process.pid } #{ Time.new } resume dst #{ dst_info[ :domain_port ] }"
|
449
|
+
add_resume_dst( dst )
|
450
|
+
end
|
427
451
|
end
|
428
452
|
end
|
429
453
|
|
430
454
|
@paused_atuns.each do | atun |
|
431
455
|
atun_info = @atun_infos[ atun ]
|
432
456
|
dst = atun_info[ :dst ]
|
433
|
-
dst_info = @dst_infos[ dst ]
|
434
457
|
|
435
|
-
if
|
436
|
-
|
437
|
-
|
458
|
+
if dst && !dst.closed? then
|
459
|
+
dst_info = @dst_infos[ dst ]
|
460
|
+
|
461
|
+
if dst_info[ :wbuff ].size < RESUME_BELOW then
|
462
|
+
puts "p#{ Process.pid } #{ Time.new } resume atun #{ atun_info[ :domain_port ] }"
|
463
|
+
add_resume_atun( atun )
|
464
|
+
end
|
438
465
|
end
|
439
466
|
end
|
440
467
|
end
|
@@ -500,6 +527,14 @@ module Girl
|
|
500
527
|
@dotw.write( '.' )
|
501
528
|
end
|
502
529
|
|
530
|
+
##
|
531
|
+
# pack a chunk
|
532
|
+
#
|
533
|
+
def pack_a_chunk( data )
|
534
|
+
data = @custom.encode( data )
|
535
|
+
"#{ [ data.bytesize ].pack( 'n' ) }#{ data }"
|
536
|
+
end
|
537
|
+
|
503
538
|
##
|
504
539
|
# resolve domain
|
505
540
|
#
|
@@ -545,6 +580,8 @@ module Girl
|
|
545
580
|
# send ctlmsg
|
546
581
|
#
|
547
582
|
def send_ctlmsg( data, to_addr )
|
583
|
+
data = @custom.encode( data )
|
584
|
+
|
548
585
|
begin
|
549
586
|
@ctld.sendmsg( data, 0, to_addr )
|
550
587
|
rescue Exception => e
|
@@ -580,7 +617,7 @@ module Girl
|
|
580
617
|
# read dotr
|
581
618
|
#
|
582
619
|
def read_dotr( dotr )
|
583
|
-
dotr.read_nonblock(
|
620
|
+
dotr.read_nonblock( READ_SIZE )
|
584
621
|
|
585
622
|
if @deleting_ctl_infos.any? then
|
586
623
|
@deleting_ctl_infos.each { | ctl_addr | del_ctl_info( ctl_addr ) }
|
@@ -616,6 +653,7 @@ module Girl
|
|
616
653
|
#
|
617
654
|
def read_ctld( ctld )
|
618
655
|
data, addrinfo, rflags, *controls = ctld.recvmsg
|
656
|
+
data = @custom.decode( data )
|
619
657
|
ctl_num = data[ 0 ].unpack( 'C' ).first
|
620
658
|
ctl_addr = addrinfo.to_sockaddr
|
621
659
|
ctl_info = @ctl_infos[ ctl_addr ]
|
@@ -742,7 +780,7 @@ module Girl
|
|
742
780
|
btun = dst_info[ :btun ]
|
743
781
|
|
744
782
|
begin
|
745
|
-
data = dst.read_nonblock(
|
783
|
+
data = dst.read_nonblock( CHUNK_SIZE )
|
746
784
|
rescue IO::WaitReadable
|
747
785
|
print 'r'
|
748
786
|
return
|
@@ -758,12 +796,10 @@ module Girl
|
|
758
796
|
end
|
759
797
|
|
760
798
|
@traff_ins[ dst_info[ :im ] ] += data.bytesize
|
761
|
-
# puts "debug read dst #{ data.bytesize }
|
762
|
-
data = @custom.encode( data )
|
763
|
-
data = "#{ [ data.bytesize ].pack( 'n' ) }#{ data }"
|
799
|
+
# puts "debug read dst #{ data.bytesize }"
|
764
800
|
|
765
801
|
if btun then
|
766
|
-
add_btun_wbuff( btun, data )
|
802
|
+
add_btun_wbuff( btun, pack_a_chunk( data ) )
|
767
803
|
else
|
768
804
|
# puts "debug add dst.rbuff #{ data.bytesize }"
|
769
805
|
add_dst_rbuff( dst, data )
|
@@ -797,7 +833,8 @@ module Girl
|
|
797
833
|
dst: nil, # 对应dst
|
798
834
|
domain_port: nil, # dst的目的地和端口
|
799
835
|
rbuff: '', # 暂存当前块没收全的流量
|
800
|
-
wait_bytes: 0
|
836
|
+
wait_bytes: 0, # 还差多少字节收全当前块
|
837
|
+
lbuff: '' # 流量截断在长度前缀处
|
801
838
|
}
|
802
839
|
|
803
840
|
add_read( atun, :atun )
|
@@ -893,22 +930,44 @@ module Girl
|
|
893
930
|
end
|
894
931
|
|
895
932
|
until data.empty? do
|
896
|
-
rbuff = atun_info[ :rbuff ]
|
897
933
|
wait_bytes = atun_info[ :wait_bytes ]
|
898
934
|
|
899
935
|
if wait_bytes > 0 then
|
900
936
|
len = wait_bytes
|
901
937
|
# puts "debug wait bytes #{ len }"
|
902
938
|
else
|
903
|
-
|
904
|
-
|
905
|
-
|
906
|
-
|
907
|
-
|
939
|
+
lbuff = atun_info[ :lbuff ]
|
940
|
+
|
941
|
+
if lbuff.empty? then
|
942
|
+
# 长度缓存为空,从读到的流量里取长度
|
943
|
+
# 两个字节以下,记进长度缓存
|
944
|
+
if data.bytesize <= 2 then
|
945
|
+
# puts "debug set atun.lbuff #{ data.inspect }"
|
946
|
+
atun_info[ :lbuff ] = data
|
947
|
+
return
|
948
|
+
end
|
949
|
+
|
950
|
+
len = data[ 0, 2 ].unpack( 'n' ).first
|
951
|
+
data = data[ 2..-1 ]
|
952
|
+
elsif lbuff.bytesize == 1 then
|
953
|
+
# 长度缓存记有一个字节,补一个字节
|
954
|
+
lbuff = "#{ lbuff }#{ data[ 0 ] }"
|
908
955
|
|
909
|
-
|
910
|
-
|
911
|
-
|
956
|
+
if data.bytesize == 1 then
|
957
|
+
# puts "debug add atun.lbuff a byte #{ data.inspect }"
|
958
|
+
atun_info[ :lbuff ] = lbuff
|
959
|
+
return
|
960
|
+
end
|
961
|
+
|
962
|
+
# 使用长度缓存
|
963
|
+
len = lbuff.unpack( 'n' ).first
|
964
|
+
atun_info[ :lbuff ].clear
|
965
|
+
data = data[ 1..-1 ]
|
966
|
+
else
|
967
|
+
# 使用长度缓存
|
968
|
+
len = lbuff.unpack( 'n' ).first
|
969
|
+
atun_info[ :lbuff ].clear
|
970
|
+
end
|
912
971
|
end
|
913
972
|
|
914
973
|
chunk = data[ 0, len ]
|
@@ -916,7 +975,7 @@ module Girl
|
|
916
975
|
|
917
976
|
if chunk_size == len then
|
918
977
|
# 取完整了
|
919
|
-
chunk = @custom.decode( "#{ rbuff }#{ chunk }" )
|
978
|
+
chunk = @custom.decode( "#{ atun_info[ :rbuff ] }#{ chunk }" )
|
920
979
|
# puts "debug decode and add dst.wbuff #{ chunk.bytesize }"
|
921
980
|
add_dst_wbuff( dst, chunk )
|
922
981
|
atun_info[ :rbuff ].clear
|
@@ -990,8 +1049,17 @@ module Girl
|
|
990
1049
|
btun_info[ :domain_port ] = dst_info[ :domain_port ]
|
991
1050
|
|
992
1051
|
unless dst_info[ :rbuff ].empty? then
|
993
|
-
|
994
|
-
|
1052
|
+
data2 = ''
|
1053
|
+
|
1054
|
+
until dst_info[ :rbuff ].empty? do
|
1055
|
+
_data = dst_info[ :rbuff ][ 0, CHUNK_SIZE ]
|
1056
|
+
data_size = _data.bytesize
|
1057
|
+
# puts "debug move dst.rbuff to btun.wbuff"
|
1058
|
+
data2 << pack_a_chunk( _data )
|
1059
|
+
dst_info[ :rbuff ] = dst_info[ :rbuff ][ data_size..-1 ]
|
1060
|
+
end
|
1061
|
+
|
1062
|
+
add_btun_wbuff( btun, data2 )
|
995
1063
|
end
|
996
1064
|
|
997
1065
|
dst_info[ :btun ] = btun
|
@@ -1007,6 +1075,7 @@ module Girl
|
|
1007
1075
|
end
|
1008
1076
|
|
1009
1077
|
dst_info = @dst_infos[ dst ]
|
1078
|
+
dst_info[ :connected ] = true
|
1010
1079
|
atun = dst_info[ :atun ]
|
1011
1080
|
data = dst_info[ :wbuff ]
|
1012
1081
|
|
data/lib/girl/relay.rb
CHANGED
data/lib/girl/relay_worker.rb
CHANGED
@@ -13,7 +13,6 @@ module Girl
|
|
13
13
|
@directs = directs
|
14
14
|
@remotes = remotes
|
15
15
|
@custom = Girl::ProxyCustom.new( im )
|
16
|
-
@resolv_custom = Girl::ResolvCustom.new
|
17
16
|
@reads = []
|
18
17
|
@writes = []
|
19
18
|
@closing_rsvs = []
|
@@ -24,7 +23,7 @@ module Girl
|
|
24
23
|
@resume_srcs = []
|
25
24
|
@resume_dsts = []
|
26
25
|
@resume_btuns = []
|
27
|
-
@pending_srcs = [] #
|
26
|
+
@pending_srcs = [] # 还没得到atund和btund地址,暂存的src
|
28
27
|
@roles = ConcurrentHash.new # sock => :dotr / :resolv / :rsv / :redir / :proxy / :src / :dst / :atun / :btun
|
29
28
|
@rsv_infos = ConcurrentHash.new # rsv => {}
|
30
29
|
@src_infos = ConcurrentHash.new # src => {}
|
@@ -298,7 +297,12 @@ module Girl
|
|
298
297
|
return if atun.closed?
|
299
298
|
# puts "debug close atun"
|
300
299
|
close_sock( atun )
|
301
|
-
@atun_infos.delete( atun )
|
300
|
+
atun_info = @atun_infos.delete( atun )
|
301
|
+
src = atun_info[ :src ]
|
302
|
+
|
303
|
+
if src then
|
304
|
+
@paused_srcs.delete( src )
|
305
|
+
end
|
302
306
|
end
|
303
307
|
|
304
308
|
##
|
@@ -308,9 +312,7 @@ module Girl
|
|
308
312
|
return if btun.closed?
|
309
313
|
# puts "debug close btun"
|
310
314
|
close_sock( btun )
|
311
|
-
|
312
|
-
@paused_btuns.delete( btun )
|
313
|
-
@resume_btuns.delete( btun )
|
315
|
+
del_btun_info( btun )
|
314
316
|
end
|
315
317
|
|
316
318
|
##
|
@@ -392,11 +394,13 @@ module Girl
|
|
392
394
|
btun = src_info[ :btun ]
|
393
395
|
|
394
396
|
if atun then
|
395
|
-
|
397
|
+
close_sock( atun )
|
398
|
+
@atun_infos.delete( atun )
|
396
399
|
end
|
397
400
|
|
398
401
|
if btun then
|
399
|
-
|
402
|
+
close_sock( btun )
|
403
|
+
del_btun_info( btun )
|
400
404
|
end
|
401
405
|
end
|
402
406
|
end
|
@@ -440,9 +444,8 @@ module Girl
|
|
440
444
|
return if src.closed?
|
441
445
|
src_info = @src_infos[ src ]
|
442
446
|
|
443
|
-
if
|
444
|
-
|| ip_info.
|
445
|
-
|| ( ( @ip_address_list.any? { | addrinfo | addrinfo.ip_address == ip_info.ip_address } ) && ( src_info[ :destination_port ] == @redir_port ) ) then
|
447
|
+
if ( ( @ip_address_list.any? { | addrinfo | addrinfo.ip_address == ip_info.ip_address } ) && ( src_info[ :destination_port ] == @redir_port ) ) \
|
448
|
+
|| ( ( ip_info.ip_address == @proxyd_host ) && ( src_info[ :destination_port ] == @proxyd_port ) ) then
|
446
449
|
puts "p#{ Process.pid } #{ Time.new } ignore #{ ip_info.ip_address }:#{ src_info[ :destination_port ] }"
|
447
450
|
add_closing_src( src )
|
448
451
|
return
|
@@ -459,7 +462,6 @@ module Girl
|
|
459
462
|
is_direct = @is_direct_caches[ ip_info.ip_address ]
|
460
463
|
else
|
461
464
|
is_direct = @directs.any? { | direct | direct.include?( ip_info.ip_address ) }
|
462
|
-
# 判断直连耗时较长(树莓派 0.27秒),这里可能切去主线程,回来src可能已关闭
|
463
465
|
puts "p#{ Process.pid } #{ Time.new } cache is direct #{ ip_info.ip_address } #{ is_direct }"
|
464
466
|
@is_direct_caches[ ip_info.ip_address ] = is_direct
|
465
467
|
end
|
@@ -468,12 +470,20 @@ module Girl
|
|
468
470
|
# puts "debug #{ ip_info.inspect } hit directs"
|
469
471
|
new_a_dst( src, ip_info )
|
470
472
|
else
|
471
|
-
# 走远端
|
472
473
|
# puts "debug #{ ip_info.inspect } go tunnel"
|
473
474
|
set_proxy_type_tunnel( src )
|
474
475
|
end
|
475
476
|
end
|
476
477
|
|
478
|
+
##
|
479
|
+
# del btun info
|
480
|
+
#
|
481
|
+
def del_btun_info( btun )
|
482
|
+
@btun_infos.delete( btun )
|
483
|
+
@paused_btuns.delete( btun )
|
484
|
+
@resume_btuns.delete( btun )
|
485
|
+
end
|
486
|
+
|
477
487
|
##
|
478
488
|
# del dst info
|
479
489
|
#
|
@@ -527,9 +537,24 @@ module Girl
|
|
527
537
|
@src_infos.each do | src, src_info |
|
528
538
|
last_recv_at = src_info[ :last_recv_at ] || src_info[ :created_at ]
|
529
539
|
last_sent_at = src_info[ :last_sent_at ] || src_info[ :created_at ]
|
530
|
-
expire_after = ( src_info[ :dst ] || src_info[ :tun ] ) ? EXPIRE_AFTER : EXPIRE_NEW
|
531
540
|
|
532
|
-
if
|
541
|
+
if src_info[ :dst ] then
|
542
|
+
if src_info[ :dst_connected ] then
|
543
|
+
expire_after = EXPIRE_AFTER
|
544
|
+
is_expire = ( now - last_recv_at >= expire_after ) && ( now - last_sent_at >= expire_after )
|
545
|
+
else
|
546
|
+
expire_after = EXPIRE_CONNECTING
|
547
|
+
is_expire = ( now - src_info[ :dst_created_at ] >= expire_after )
|
548
|
+
end
|
549
|
+
elsif src_info[ :atun ] then
|
550
|
+
expire_after = EXPIRE_AFTER
|
551
|
+
is_expire = ( now - last_recv_at >= expire_after ) && ( now - last_sent_at >= expire_after )
|
552
|
+
else
|
553
|
+
expire_after = EXPIRE_NEW
|
554
|
+
is_expire = ( now - last_recv_at >= expire_after ) && ( now - last_sent_at >= expire_after )
|
555
|
+
end
|
556
|
+
|
557
|
+
if is_expire then
|
533
558
|
puts "p#{ Process.pid } #{ Time.new } expire src #{ expire_after } #{ src_info[ :id ] } #{ src_info[ :destination_domain ] }"
|
534
559
|
add_closing_src( src )
|
535
560
|
|
@@ -555,19 +580,24 @@ module Girl
|
|
555
580
|
dst = src_info[ :dst ]
|
556
581
|
|
557
582
|
if dst then
|
558
|
-
|
583
|
+
if !dst.closed? then
|
584
|
+
dst_info = @dst_infos[ dst ]
|
559
585
|
|
560
|
-
|
561
|
-
|
562
|
-
|
586
|
+
if dst_info[ :wbuff ].size < RESUME_BELOW then
|
587
|
+
puts "p#{ Process.pid } #{ Time.new } resume direct src #{ src_info[ :destination_domain ] }"
|
588
|
+
add_resume_src( src )
|
589
|
+
end
|
563
590
|
end
|
564
591
|
else
|
565
|
-
|
566
|
-
btun_info = @btun_infos[ btun ]
|
592
|
+
atun = src_info[ :atun ]
|
567
593
|
|
568
|
-
if
|
569
|
-
|
570
|
-
|
594
|
+
if atun && !atun.closed? then
|
595
|
+
atun_info = @atun_infos[ atun ]
|
596
|
+
|
597
|
+
if atun_info[ :wbuff ].size < RESUME_BELOW then
|
598
|
+
puts "p#{ Process.pid } #{ Time.new } resume tunnel src #{ src_info[ :destination_domain ] }"
|
599
|
+
add_resume_src( src )
|
600
|
+
end
|
571
601
|
end
|
572
602
|
end
|
573
603
|
end
|
@@ -575,22 +605,28 @@ module Girl
|
|
575
605
|
@paused_dsts.each do | dst |
|
576
606
|
dst_info = @dst_infos[ dst ]
|
577
607
|
src = dst_info[ :src ]
|
578
|
-
src_info = @src_infos[ src ]
|
579
608
|
|
580
|
-
if
|
581
|
-
|
582
|
-
|
609
|
+
if src && !src.closed? then
|
610
|
+
src_info = @src_infos[ src ]
|
611
|
+
|
612
|
+
if src_info[ :wbuff ].size < RESUME_BELOW then
|
613
|
+
puts "p#{ Process.pid } #{ Time.new } resume dst #{ dst_info[ :domain ] }"
|
614
|
+
add_resume_dst( dst )
|
615
|
+
end
|
583
616
|
end
|
584
617
|
end
|
585
618
|
|
586
619
|
@paused_btuns.each do | btun |
|
587
620
|
btun_info = @btun_infos[ btun ]
|
588
621
|
src = btun_info[ :src ]
|
589
|
-
src_info = @src_infos[ src ]
|
590
622
|
|
591
|
-
if
|
592
|
-
|
593
|
-
|
623
|
+
if src && !src.closed? then
|
624
|
+
src_info = @src_infos[ src ]
|
625
|
+
|
626
|
+
if src_info[ :wbuff ].size < RESUME_BELOW then
|
627
|
+
puts "p#{ Process.pid } #{ Time.new } resume btun #{ btun_info[ :domain ] }"
|
628
|
+
add_resume_btun( btun )
|
629
|
+
end
|
594
630
|
end
|
595
631
|
end
|
596
632
|
end
|
@@ -653,15 +689,17 @@ module Girl
|
|
653
689
|
}
|
654
690
|
|
655
691
|
@dst_infos[ dst ] = dst_info
|
656
|
-
add_read( dst, :dst )
|
657
692
|
src_info[ :proxy_type ] = :direct
|
658
693
|
src_info[ :dst ] = dst
|
694
|
+
src_info[ :dst_created_at ] = Time.new
|
659
695
|
|
660
696
|
if src_info[ :rbuff ] then
|
661
697
|
# puts "debug move src.rbuff to dst.wbuff"
|
662
698
|
dst_info[ :wbuff ] << src_info[ :rbuff ]
|
663
|
-
add_write( dst )
|
664
699
|
end
|
700
|
+
|
701
|
+
add_read( dst, :dst )
|
702
|
+
add_write( dst )
|
665
703
|
end
|
666
704
|
|
667
705
|
##
|
@@ -729,7 +767,7 @@ module Girl
|
|
729
767
|
rsv.bind( Socket.sockaddr_in( 0, '0.0.0.0' ) )
|
730
768
|
|
731
769
|
if @qnames.any? { | qname | data.include?( qname ) } then
|
732
|
-
data = @
|
770
|
+
data = @custom.encode( data )
|
733
771
|
to_addr = @resolvd_addr
|
734
772
|
else
|
735
773
|
to_addr = @nameserver_addr
|
@@ -749,6 +787,7 @@ module Girl
|
|
749
787
|
# new tuns
|
750
788
|
#
|
751
789
|
def new_tuns( src_id, dst_id )
|
790
|
+
return if @ctl_info[ :atund_addr ].nil? || @ctl_info[ :btund_addr ].nil?
|
752
791
|
src = @srcs[ src_id ]
|
753
792
|
return if src.nil? || src.closed?
|
754
793
|
src_info = @src_infos[ src ]
|
@@ -781,7 +820,7 @@ module Girl
|
|
781
820
|
atun_wbuff = [ dst_id ].pack( 'n' )
|
782
821
|
|
783
822
|
until src_info[ :rbuff ].empty? do
|
784
|
-
data = src_info[ :rbuff ][ 0,
|
823
|
+
data = src_info[ :rbuff ][ 0, CHUNK_SIZE ]
|
785
824
|
data_size = data.bytesize
|
786
825
|
# puts "debug move src.rbuff #{ data_size } to atun.wbuff"
|
787
826
|
atun_wbuff << pack_a_chunk( data )
|
@@ -802,7 +841,8 @@ module Girl
|
|
802
841
|
domain: domain, # 目的地
|
803
842
|
wbuff: btun_wbuff, # 写前
|
804
843
|
rbuff: '', # 暂存当前块没收全的流量
|
805
|
-
wait_bytes: 0
|
844
|
+
wait_bytes: 0, # 还差多少字节收全当前块
|
845
|
+
lbuff: '' # 流量截断在长度前缀处
|
806
846
|
}
|
807
847
|
|
808
848
|
src_info[ :dst_id ] = dst_id
|
@@ -835,6 +875,7 @@ module Girl
|
|
835
875
|
#
|
836
876
|
def send_ctlmsg( data )
|
837
877
|
return if @ctl.nil? || @ctl.closed?
|
878
|
+
data = @custom.encode( data )
|
838
879
|
|
839
880
|
begin
|
840
881
|
@ctl.sendmsg( data, 0, @proxyd_addr )
|
@@ -863,9 +904,7 @@ module Girl
|
|
863
904
|
def send_data( sock, to_addr, data )
|
864
905
|
begin
|
865
906
|
sock.sendmsg( data, 0, to_addr )
|
866
|
-
rescue
|
867
|
-
print 'w'
|
868
|
-
rescue Errno::EHOSTUNREACH, Errno::ENETUNREACH, Errno::ENETDOWN => e
|
907
|
+
rescue Exception => e
|
869
908
|
puts "p#{ Process.pid } #{ Time.new } sendmsg to #{ to_addr.ip_unpack.inspect } #{ e.class }"
|
870
909
|
end
|
871
910
|
end
|
@@ -908,30 +947,11 @@ module Girl
|
|
908
947
|
add_write( src )
|
909
948
|
end
|
910
949
|
|
911
|
-
##
|
912
|
-
# sub http request
|
913
|
-
#
|
914
|
-
def sub_http_request( data )
|
915
|
-
lines = data.split( "\r\n" )
|
916
|
-
|
917
|
-
return [ data, nil ] if lines.empty?
|
918
|
-
|
919
|
-
method, url, proto = lines.first.split( ' ' )
|
920
|
-
|
921
|
-
if proto && url && proto[ 0, 4 ] == 'HTTP' && url[ 0, 7 ] == 'http://' then
|
922
|
-
domain_port = url.split( '/' )[ 2 ]
|
923
|
-
data = data.sub( "http://#{ domain_port }", '' )
|
924
|
-
# puts "debug subed #{ data.inspect } #{ domain_port }"
|
925
|
-
end
|
926
|
-
|
927
|
-
[ data, domain_port ]
|
928
|
-
end
|
929
|
-
|
930
950
|
##
|
931
951
|
# read dotr
|
932
952
|
#
|
933
953
|
def read_dotr( dotr )
|
934
|
-
dotr.read_nonblock(
|
954
|
+
dotr.read_nonblock( READ_SIZE )
|
935
955
|
|
936
956
|
if @ctl_info && @ctl_info[ :closing ] then
|
937
957
|
send_ctlmsg( [ CTL_FIN ].pack( 'C' ) )
|
@@ -993,7 +1013,7 @@ module Girl
|
|
993
1013
|
# puts "debug rsv recvmsg #{ addrinfo.ip_unpack.inspect } #{ data.inspect }"
|
994
1014
|
|
995
1015
|
if addrinfo.to_sockaddr == @resolvd_addr then
|
996
|
-
data = @
|
1016
|
+
data = @custom.decode( data )
|
997
1017
|
end
|
998
1018
|
|
999
1019
|
rsv_info = @rsv_infos[ rsv ]
|
@@ -1036,6 +1056,8 @@ module Girl
|
|
1036
1056
|
destination_port: dest_port, # 目的地端口
|
1037
1057
|
rbuff: '', # 读到的流量
|
1038
1058
|
dst: nil, # :direct的场合,对应的dst
|
1059
|
+
dst_created_at: nil, # :direct的场合,对应的dst的创建时间
|
1060
|
+
dst_connected: false, # :direct的场合,对应的dst是否已连接
|
1039
1061
|
ctl: nil, # :tunnel的场合,对应的ctl
|
1040
1062
|
atun: nil, # :tunnel的场合,对应的atun
|
1041
1063
|
btun: nil, # :tunnel的场合,对应的btun
|
@@ -1068,6 +1090,7 @@ module Girl
|
|
1068
1090
|
return
|
1069
1091
|
end
|
1070
1092
|
|
1093
|
+
data = @custom.decode( data )
|
1071
1094
|
ctl_num = data[ 0 ].unpack( 'C' ).first
|
1072
1095
|
|
1073
1096
|
case ctl_num
|
@@ -1086,7 +1109,7 @@ module Girl
|
|
1086
1109
|
@pending_srcs.clear
|
1087
1110
|
end
|
1088
1111
|
when PAIRED then
|
1089
|
-
return if
|
1112
|
+
return if data.size != 11
|
1090
1113
|
src_id, dst_id = data[ 1, 10 ].unpack( 'Q>n' )
|
1091
1114
|
# puts "debug got paired #{ src_id } #{ dst_id }"
|
1092
1115
|
@ctl_info[ :resends ].delete( [ A_NEW_SOURCE, src_id ].pack( 'CQ>' ) )
|
@@ -1110,7 +1133,7 @@ module Girl
|
|
1110
1133
|
src_info = @src_infos[ src ]
|
1111
1134
|
|
1112
1135
|
begin
|
1113
|
-
data = src.read_nonblock(
|
1136
|
+
data = src.read_nonblock( CHUNK_SIZE )
|
1114
1137
|
rescue IO::WaitReadable
|
1115
1138
|
print 'r'
|
1116
1139
|
return
|
@@ -1172,7 +1195,7 @@ module Girl
|
|
1172
1195
|
src = dst_info[ :src ]
|
1173
1196
|
|
1174
1197
|
begin
|
1175
|
-
data = dst.read_nonblock(
|
1198
|
+
data = dst.read_nonblock( CHUNK_SIZE )
|
1176
1199
|
rescue IO::WaitReadable
|
1177
1200
|
print 'r'
|
1178
1201
|
return
|
@@ -1213,22 +1236,44 @@ module Girl
|
|
1213
1236
|
end
|
1214
1237
|
|
1215
1238
|
until data.empty? do
|
1216
|
-
rbuff = btun_info[ :rbuff ]
|
1217
1239
|
wait_bytes = btun_info[ :wait_bytes ]
|
1218
1240
|
|
1219
1241
|
if wait_bytes > 0 then
|
1220
1242
|
len = wait_bytes
|
1221
1243
|
# puts "debug wait bytes #{ len }"
|
1222
1244
|
else
|
1223
|
-
|
1224
|
-
|
1225
|
-
|
1226
|
-
|
1227
|
-
|
1245
|
+
lbuff = btun_info[ :lbuff ]
|
1246
|
+
|
1247
|
+
if lbuff.empty? then
|
1248
|
+
# 长度缓存为空,从读到的流量里取长度
|
1249
|
+
# 两个字节以下,记进长度缓存
|
1250
|
+
if data.bytesize <= 2 then
|
1251
|
+
# puts "debug set btun.lbuff #{ data.inspect }"
|
1252
|
+
btun_info[ :lbuff ] = data
|
1253
|
+
return
|
1254
|
+
end
|
1255
|
+
|
1256
|
+
len = data[ 0, 2 ].unpack( 'n' ).first
|
1257
|
+
data = data[ 2..-1 ]
|
1258
|
+
elsif lbuff.bytesize == 1 then
|
1259
|
+
# 长度缓存记有一个字节,补一个字节
|
1260
|
+
lbuff = "#{ lbuff }#{ data[ 0 ] }"
|
1228
1261
|
|
1229
|
-
|
1230
|
-
|
1231
|
-
|
1262
|
+
if data.bytesize == 1 then
|
1263
|
+
# puts "debug add btun.lbuff a byte #{ data.inspect }"
|
1264
|
+
btun_info[ :lbuff ] = lbuff
|
1265
|
+
return
|
1266
|
+
end
|
1267
|
+
|
1268
|
+
# 使用长度缓存
|
1269
|
+
len = lbuff.unpack( 'n' ).first
|
1270
|
+
btun_info[ :lbuff ].clear
|
1271
|
+
data = data[ 1..-1 ]
|
1272
|
+
else
|
1273
|
+
# 使用长度缓存
|
1274
|
+
len = lbuff.unpack( 'n' ).first
|
1275
|
+
btun_info[ :lbuff ].clear
|
1276
|
+
end
|
1232
1277
|
end
|
1233
1278
|
|
1234
1279
|
chunk = data[ 0, len ]
|
@@ -1236,7 +1281,7 @@ module Girl
|
|
1236
1281
|
|
1237
1282
|
if chunk_size == len then
|
1238
1283
|
# 取完整了
|
1239
|
-
chunk = @custom.decode( "#{ rbuff }#{ chunk }" )
|
1284
|
+
chunk = @custom.decode( "#{ btun_info[ :rbuff ] }#{ chunk }" )
|
1240
1285
|
# puts "debug read btun decoded #{ chunk.bytesize }"
|
1241
1286
|
add_src_wbuff( src, chunk )
|
1242
1287
|
btun_info[ :rbuff ] = ''
|
@@ -1315,6 +1360,12 @@ module Girl
|
|
1315
1360
|
|
1316
1361
|
dst_info = @dst_infos[ dst ]
|
1317
1362
|
src = dst_info[ :src ]
|
1363
|
+
src_info = @src_infos[ src ]
|
1364
|
+
|
1365
|
+
unless src.closed? then
|
1366
|
+
src_info[ :dst_connected ] = true
|
1367
|
+
end
|
1368
|
+
|
1318
1369
|
data = dst_info[ :wbuff ]
|
1319
1370
|
|
1320
1371
|
# 写前为空,处理关闭写
|
@@ -1345,7 +1396,6 @@ module Girl
|
|
1345
1396
|
dst_info[ :wbuff ] = data
|
1346
1397
|
|
1347
1398
|
unless src.closed? then
|
1348
|
-
src_info = @src_infos[ src ]
|
1349
1399
|
src_info[ :last_sent_at ] = Time.new
|
1350
1400
|
end
|
1351
1401
|
end
|