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
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 2631d53d8c27dfb593364dc65b8d84cfbcad3e27f231c906f1b5ae6ceeea44fd
|
4
|
+
data.tar.gz: 6bef34c3cf545b9851038dcd630f62afd5117402ac4955ecadf6bdda3f633e68
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 221343c8278bea0f825adee69c7bc392005c637a787e6561004607ce5529105e9ecb5cdfd88d9b6523caff23b05cd0dcf4085d523e873f44c80e37a6360b3947
|
7
|
+
data.tar.gz: c1efea95b6fb2d91111abd3d97d36b557a40b6261361209abf39f9a645452afdadf85014ae338229a2b8333efb32c773456c169cc9fc9c015614b9decf8f7cd4
|
data/girl.gemspec
CHANGED
data/lib/girl/head.rb
CHANGED
@@ -1,13 +1,15 @@
|
|
1
1
|
module Girl
|
2
|
-
READ_SIZE = 1024 * 1024 #
|
2
|
+
READ_SIZE = 1024 * 1024 # 一次读多少
|
3
3
|
WBUFF_LIMIT = 50 * 1024 * 1024 # 写前上限,超过上限暂停读
|
4
4
|
RESUME_BELOW = WBUFF_LIMIT / 2 # 降到多少以下恢复读
|
5
|
+
CHUNK_SIZE = 65535 # 按块加解密,块尺寸上限,不超过65535
|
5
6
|
EXPIRE_NEW = 5 # 多久没有建立通道,过期
|
7
|
+
EXPIRE_CONNECTING = 2 # 连接中,多久没连上过期
|
6
8
|
EXPIRE_AFTER = 300 # 多久没有新流量,过期
|
7
9
|
EXPIRE_CTL = 86400 # 多久没有ctlmsg来,过期
|
8
10
|
RESET_TRAFF_DAY = 1 # 流量计数重置日,0为不重置
|
9
11
|
CHECK_TRAFF_INTERVAL = 86400 # 检查今天是否是流量计数重置日间隔
|
10
|
-
CHECK_EXPIRE_INTERVAL =
|
12
|
+
CHECK_EXPIRE_INTERVAL = 1 # 检查过期间隔
|
11
13
|
CHECK_RESUME_INTERVAL = 1 # 检查恢复读间隔
|
12
14
|
RESOLV_CACHE_EXPIRE = 300 # dns查询结果缓存多久过期
|
13
15
|
RESEND_LIMIT = 5 # ctlmsg重传次数
|
@@ -52,7 +54,9 @@ EOF
|
|
52
54
|
READ_SIZE
|
53
55
|
WBUFF_LIMIT
|
54
56
|
RESUME_BELOW
|
57
|
+
CHUNK_SIZE
|
55
58
|
EXPIRE_NEW
|
59
|
+
EXPIRE_CONNECTING
|
56
60
|
EXPIRE_AFTER
|
57
61
|
EXPIRE_CTL
|
58
62
|
RESET_TRAFF_DAY
|
data/lib/girl/proxy.rb
CHANGED
@@ -14,8 +14,8 @@ require 'socket'
|
|
14
14
|
#
|
15
15
|
=begin
|
16
16
|
C: 1 hello -> hello
|
17
|
-
2 tund port -> n:
|
18
|
-
3 a new source -> Q>: src id ->
|
17
|
+
2 tund port -> n: atund port -> n: btund port
|
18
|
+
3 a new source -> Q>: src id -> destination
|
19
19
|
4 paired -> Q>: src id -> n: dst id
|
20
20
|
5 dest status NOT USE
|
21
21
|
6 source status NOT USE
|
@@ -32,13 +32,11 @@ C: 1 hello -> hello
|
|
32
32
|
17 continue NOT USE
|
33
33
|
18 is resend ready NOT USE
|
34
34
|
19 resend ready NOT USE
|
35
|
-
20 resolv
|
36
|
-
21 resolved
|
35
|
+
20 resolv NOT USE
|
36
|
+
21 resolved NOT USE
|
37
37
|
22 heartbeat NOT USE
|
38
38
|
23 unknown ctl addr
|
39
39
|
24 ctl fin
|
40
|
-
25 source eof -> Q>: dst id
|
41
|
-
26 dest eof -> Q>: src id
|
42
40
|
101 traff infos
|
43
41
|
101 traff infos -> [ C: im len -> im -> Q>: traff in -> Q>: traff out ]
|
44
42
|
=end
|
data/lib/girl/proxy_worker.rb
CHANGED
@@ -6,6 +6,7 @@ module Girl
|
|
6
6
|
#
|
7
7
|
def initialize( redir_port, proxyd_host, proxyd_port, directs, remotes, im )
|
8
8
|
@proxyd_host = proxyd_host
|
9
|
+
@proxyd_port = proxyd_port
|
9
10
|
@proxyd_addr = Socket.sockaddr_in( proxyd_port, proxyd_host )
|
10
11
|
@directs = directs
|
11
12
|
@remotes = remotes
|
@@ -19,7 +20,7 @@ module Girl
|
|
19
20
|
@resume_srcs = []
|
20
21
|
@resume_dsts = []
|
21
22
|
@resume_btuns = []
|
22
|
-
@pending_srcs = [] #
|
23
|
+
@pending_srcs = [] # 还没得到atund和btund地址,暂存的src
|
23
24
|
@roles = ConcurrentHash.new # sock => :dotr / :redir / :ctl / :src / :dst / :atun / :btun
|
24
25
|
@src_infos = ConcurrentHash.new # src => {}
|
25
26
|
@dst_infos = ConcurrentHash.new # dst => {}
|
@@ -45,7 +46,6 @@ module Girl
|
|
45
46
|
loop_check_resume
|
46
47
|
|
47
48
|
loop do
|
48
|
-
# puts "debug select"
|
49
49
|
rs, ws = IO.select( @reads, @writes )
|
50
50
|
|
51
51
|
rs.each do | sock |
|
@@ -295,7 +295,12 @@ module Girl
|
|
295
295
|
return if atun.closed?
|
296
296
|
# puts "debug close atun"
|
297
297
|
close_sock( atun )
|
298
|
-
@atun_infos.delete( atun )
|
298
|
+
atun_info = @atun_infos.delete( atun )
|
299
|
+
src = atun_info[ :src ]
|
300
|
+
|
301
|
+
if src then
|
302
|
+
@paused_srcs.delete( src )
|
303
|
+
end
|
299
304
|
end
|
300
305
|
|
301
306
|
##
|
@@ -305,9 +310,7 @@ module Girl
|
|
305
310
|
return if btun.closed?
|
306
311
|
# puts "debug close btun"
|
307
312
|
close_sock( btun )
|
308
|
-
|
309
|
-
@paused_btuns.delete( btun )
|
310
|
-
@resume_btuns.delete( btun )
|
313
|
+
del_btun_info( btun )
|
311
314
|
end
|
312
315
|
|
313
316
|
##
|
@@ -378,11 +381,13 @@ module Girl
|
|
378
381
|
btun = src_info[ :btun ]
|
379
382
|
|
380
383
|
if atun then
|
381
|
-
|
384
|
+
close_sock( atun )
|
385
|
+
@atun_infos.delete( atun )
|
382
386
|
end
|
383
387
|
|
384
388
|
if btun then
|
385
|
-
|
389
|
+
close_sock( btun )
|
390
|
+
del_btun_info( btun )
|
386
391
|
end
|
387
392
|
end
|
388
393
|
end
|
@@ -426,9 +431,8 @@ module Girl
|
|
426
431
|
return if src.closed?
|
427
432
|
src_info = @src_infos[ src ]
|
428
433
|
|
429
|
-
if
|
430
|
-
|| ip_info.
|
431
|
-
|| ( ( @ip_address_list.any? { | addrinfo | addrinfo.ip_address == ip_info.ip_address } ) && ( src_info[ :destination_port ] == @redir_port ) ) then
|
434
|
+
if ( ( @ip_address_list.any? { | addrinfo | addrinfo.ip_address == ip_info.ip_address } ) && ( src_info[ :destination_port ] == @redir_port ) ) \
|
435
|
+
|| ( ( ip_info.ip_address == @proxyd_host ) && ( src_info[ :destination_port ] == @proxyd_port ) ) then
|
432
436
|
puts "p#{ Process.pid } #{ Time.new } ignore #{ ip_info.ip_address }:#{ src_info[ :destination_port ] }"
|
433
437
|
add_closing_src( src )
|
434
438
|
return
|
@@ -445,7 +449,6 @@ module Girl
|
|
445
449
|
is_direct = @is_direct_caches[ ip_info.ip_address ]
|
446
450
|
else
|
447
451
|
is_direct = @directs.any? { | direct | direct.include?( ip_info.ip_address ) }
|
448
|
-
# 判断直连耗时较长(树莓派 0.27秒),这里可能切去主线程,回来src可能已关闭
|
449
452
|
puts "p#{ Process.pid } #{ Time.new } cache is direct #{ ip_info.ip_address } #{ is_direct }"
|
450
453
|
@is_direct_caches[ ip_info.ip_address ] = is_direct
|
451
454
|
end
|
@@ -454,12 +457,20 @@ module Girl
|
|
454
457
|
# puts "debug #{ ip_info.inspect } hit directs"
|
455
458
|
new_a_dst( src, ip_info )
|
456
459
|
else
|
457
|
-
# 走远端
|
458
460
|
# puts "debug #{ ip_info.inspect } go tunnel"
|
459
461
|
set_proxy_type_tunnel( src )
|
460
462
|
end
|
461
463
|
end
|
462
464
|
|
465
|
+
##
|
466
|
+
# del btun info
|
467
|
+
#
|
468
|
+
def del_btun_info( btun )
|
469
|
+
@btun_infos.delete( btun )
|
470
|
+
@paused_btuns.delete( btun )
|
471
|
+
@resume_btuns.delete( btun )
|
472
|
+
end
|
473
|
+
|
463
474
|
##
|
464
475
|
# del dst info
|
465
476
|
#
|
@@ -506,9 +517,24 @@ module Girl
|
|
506
517
|
@src_infos.each do | src, src_info |
|
507
518
|
last_recv_at = src_info[ :last_recv_at ] || src_info[ :created_at ]
|
508
519
|
last_sent_at = src_info[ :last_sent_at ] || src_info[ :created_at ]
|
509
|
-
expire_after = ( src_info[ :dst ] || src_info[ :atun ] ) ? EXPIRE_AFTER : EXPIRE_NEW
|
510
520
|
|
511
|
-
if
|
521
|
+
if src_info[ :dst ] then
|
522
|
+
if src_info[ :dst_connected ] then
|
523
|
+
expire_after = EXPIRE_AFTER
|
524
|
+
is_expire = ( now - last_recv_at >= expire_after ) && ( now - last_sent_at >= expire_after )
|
525
|
+
else
|
526
|
+
expire_after = EXPIRE_CONNECTING
|
527
|
+
is_expire = ( now - src_info[ :dst_created_at ] >= expire_after )
|
528
|
+
end
|
529
|
+
elsif src_info[ :atun ] then
|
530
|
+
expire_after = EXPIRE_AFTER
|
531
|
+
is_expire = ( now - last_recv_at >= expire_after ) && ( now - last_sent_at >= expire_after )
|
532
|
+
else
|
533
|
+
expire_after = EXPIRE_NEW
|
534
|
+
is_expire = ( now - last_recv_at >= expire_after ) && ( now - last_sent_at >= expire_after )
|
535
|
+
end
|
536
|
+
|
537
|
+
if is_expire then
|
512
538
|
puts "p#{ Process.pid } #{ Time.new } expire src #{ expire_after } #{ src_info[ :id ] } #{ src_info[ :destination_domain ] }"
|
513
539
|
add_closing_src( src )
|
514
540
|
|
@@ -534,19 +560,24 @@ module Girl
|
|
534
560
|
dst = src_info[ :dst ]
|
535
561
|
|
536
562
|
if dst then
|
537
|
-
|
563
|
+
if !dst.closed? then
|
564
|
+
dst_info = @dst_infos[ dst ]
|
538
565
|
|
539
|
-
|
540
|
-
|
541
|
-
|
566
|
+
if dst_info[ :wbuff ].size < RESUME_BELOW then
|
567
|
+
puts "p#{ Process.pid } #{ Time.new } resume direct src #{ src_info[ :destination_domain ] }"
|
568
|
+
add_resume_src( src )
|
569
|
+
end
|
542
570
|
end
|
543
571
|
else
|
544
|
-
|
545
|
-
btun_info = @btun_infos[ btun ]
|
572
|
+
atun = src_info[ :atun ]
|
546
573
|
|
547
|
-
if
|
548
|
-
|
549
|
-
|
574
|
+
if atun && !atun.closed? then
|
575
|
+
atun_info = @atun_infos[ atun ]
|
576
|
+
|
577
|
+
if atun_info[ :wbuff ].size < RESUME_BELOW then
|
578
|
+
puts "p#{ Process.pid } #{ Time.new } resume tunnel src #{ src_info[ :destination_domain ] }"
|
579
|
+
add_resume_src( src )
|
580
|
+
end
|
550
581
|
end
|
551
582
|
end
|
552
583
|
end
|
@@ -554,22 +585,28 @@ module Girl
|
|
554
585
|
@paused_dsts.each do | dst |
|
555
586
|
dst_info = @dst_infos[ dst ]
|
556
587
|
src = dst_info[ :src ]
|
557
|
-
src_info = @src_infos[ src ]
|
558
588
|
|
559
|
-
if
|
560
|
-
|
561
|
-
|
589
|
+
if src && !src.closed? then
|
590
|
+
src_info = @src_infos[ src ]
|
591
|
+
|
592
|
+
if src_info[ :wbuff ].size < RESUME_BELOW then
|
593
|
+
puts "p#{ Process.pid } #{ Time.new } resume dst #{ dst_info[ :domain ] }"
|
594
|
+
add_resume_dst( dst )
|
595
|
+
end
|
562
596
|
end
|
563
597
|
end
|
564
598
|
|
565
599
|
@paused_btuns.each do | btun |
|
566
600
|
btun_info = @btun_infos[ btun ]
|
567
601
|
src = btun_info[ :src ]
|
568
|
-
src_info = @src_infos[ src ]
|
569
602
|
|
570
|
-
if
|
571
|
-
|
572
|
-
|
603
|
+
if src && !src.closed? then
|
604
|
+
src_info = @src_infos[ src ]
|
605
|
+
|
606
|
+
if src_info[ :wbuff ].size < RESUME_BELOW then
|
607
|
+
puts "p#{ Process.pid } #{ Time.new } resume btun #{ btun_info[ :domain ] }"
|
608
|
+
add_resume_btun( btun )
|
609
|
+
end
|
573
610
|
end
|
574
611
|
end
|
575
612
|
end
|
@@ -631,9 +668,9 @@ module Girl
|
|
631
668
|
}
|
632
669
|
|
633
670
|
@dst_infos[ dst ] = dst_info
|
634
|
-
add_read( dst, :dst )
|
635
671
|
src_info[ :proxy_type ] = :direct
|
636
672
|
src_info[ :dst ] = dst
|
673
|
+
src_info[ :dst_created_at ] = Time.new
|
637
674
|
|
638
675
|
if src_info[ :proxy_proto ] == :http then
|
639
676
|
if src_info[ :is_connect ] then
|
@@ -642,11 +679,13 @@ module Girl
|
|
642
679
|
elsif src_info[ :rbuff ] then
|
643
680
|
# puts "debug move src.rbuff to dst.wbuff"
|
644
681
|
dst_info[ :wbuff ] << src_info[ :rbuff ]
|
645
|
-
add_write( dst )
|
646
682
|
end
|
647
683
|
elsif src_info[ :proxy_proto ] == :socks5 then
|
648
684
|
add_socks5_conn_reply( src )
|
649
685
|
end
|
686
|
+
|
687
|
+
add_read( dst, :dst )
|
688
|
+
add_write( dst )
|
650
689
|
end
|
651
690
|
|
652
691
|
##
|
@@ -700,6 +739,7 @@ module Girl
|
|
700
739
|
# new tuns
|
701
740
|
#
|
702
741
|
def new_tuns( src_id, dst_id )
|
742
|
+
return if @ctl_info[ :atund_addr ].nil? || @ctl_info[ :btund_addr ].nil?
|
703
743
|
src = @srcs[ src_id ]
|
704
744
|
return if src.nil? || src.closed?
|
705
745
|
src_info = @src_infos[ src ]
|
@@ -732,7 +772,7 @@ module Girl
|
|
732
772
|
atun_wbuff = [ dst_id ].pack( 'n' )
|
733
773
|
|
734
774
|
until src_info[ :rbuff ].empty? do
|
735
|
-
data = src_info[ :rbuff ][ 0,
|
775
|
+
data = src_info[ :rbuff ][ 0, CHUNK_SIZE ]
|
736
776
|
data_size = data.bytesize
|
737
777
|
# puts "debug move src.rbuff #{ data_size } to atun.wbuff"
|
738
778
|
atun_wbuff << pack_a_chunk( data )
|
@@ -753,7 +793,8 @@ module Girl
|
|
753
793
|
domain: domain, # 目的地
|
754
794
|
wbuff: btun_wbuff, # 写前
|
755
795
|
rbuff: '', # 暂存当前块没收全的流量
|
756
|
-
wait_bytes: 0
|
796
|
+
wait_bytes: 0, # 还差多少字节收全当前块
|
797
|
+
lbuff: '' # 流量截断在长度前缀处
|
757
798
|
}
|
758
799
|
|
759
800
|
src_info[ :dst_id ] = dst_id
|
@@ -785,7 +826,6 @@ module Girl
|
|
785
826
|
# pack a chunk
|
786
827
|
#
|
787
828
|
def pack_a_chunk( data )
|
788
|
-
# puts "debug pack a chunk"
|
789
829
|
data = @custom.encode( data )
|
790
830
|
"#{ [ data.bytesize ].pack( 'n' ) }#{ data }"
|
791
831
|
end
|
@@ -840,6 +880,7 @@ module Girl
|
|
840
880
|
#
|
841
881
|
def send_ctlmsg( data )
|
842
882
|
return if @ctl.nil? || @ctl.closed?
|
883
|
+
data = @custom.encode( data )
|
843
884
|
|
844
885
|
begin
|
845
886
|
@ctl.sendmsg( data, 0, @proxyd_addr )
|
@@ -901,30 +942,11 @@ module Girl
|
|
901
942
|
add_write( src )
|
902
943
|
end
|
903
944
|
|
904
|
-
##
|
905
|
-
# sub http request
|
906
|
-
#
|
907
|
-
def sub_http_request( data )
|
908
|
-
lines = data.split( "\r\n" )
|
909
|
-
|
910
|
-
return [ data, nil ] if lines.empty?
|
911
|
-
|
912
|
-
method, url, proto = lines.first.split( ' ' )
|
913
|
-
|
914
|
-
if proto && url && proto[ 0, 4 ] == 'HTTP' && url[ 0, 7 ] == 'http://' then
|
915
|
-
domain_port = url.split( '/' )[ 2 ]
|
916
|
-
data = data.sub( "http://#{ domain_port }", '' )
|
917
|
-
# puts "debug subed #{ data.inspect } #{ domain_port }"
|
918
|
-
end
|
919
|
-
|
920
|
-
[ data, domain_port ]
|
921
|
-
end
|
922
|
-
|
923
945
|
##
|
924
946
|
# read dotr
|
925
947
|
#
|
926
948
|
def read_dotr( dotr )
|
927
|
-
dotr.read_nonblock(
|
949
|
+
dotr.read_nonblock( READ_SIZE )
|
928
950
|
|
929
951
|
if @ctl_info && @ctl_info[ :closing ] then
|
930
952
|
send_ctlmsg( [ CTL_FIN ].pack( 'C' ) )
|
@@ -988,6 +1010,8 @@ module Girl
|
|
988
1010
|
is_connect: true, # 代理协议是http的场合,是否是CONNECT
|
989
1011
|
rbuff: '', # 读到的流量
|
990
1012
|
dst: nil, # :direct的场合,对应的dst
|
1013
|
+
dst_created_at: nil, # :direct的场合,对应的dst的创建时间
|
1014
|
+
dst_connected: false, # :direct的场合,对应的dst是否已连接
|
991
1015
|
ctl: nil, # :tunnel的场合,对应的ctl
|
992
1016
|
atun: nil, # :tunnel的场合,对应的atun
|
993
1017
|
btun: nil, # :tunnel的场合,对应的btun
|
@@ -1018,6 +1042,7 @@ module Girl
|
|
1018
1042
|
return
|
1019
1043
|
end
|
1020
1044
|
|
1045
|
+
data = @custom.decode( data )
|
1021
1046
|
ctl_num = data[ 0 ].unpack( 'C' ).first
|
1022
1047
|
|
1023
1048
|
case ctl_num
|
@@ -1036,7 +1061,7 @@ module Girl
|
|
1036
1061
|
@pending_srcs.clear
|
1037
1062
|
end
|
1038
1063
|
when PAIRED then
|
1039
|
-
return if
|
1064
|
+
return if data.size != 11
|
1040
1065
|
src_id, dst_id = data[ 1, 10 ].unpack( 'Q>n' )
|
1041
1066
|
# puts "debug got paired #{ src_id } #{ dst_id }"
|
1042
1067
|
@ctl_info[ :resends ].delete( [ A_NEW_SOURCE, src_id ].pack( 'CQ>' ) )
|
@@ -1060,7 +1085,7 @@ module Girl
|
|
1060
1085
|
src_info = @src_infos[ src ]
|
1061
1086
|
|
1062
1087
|
begin
|
1063
|
-
data = src.read_nonblock(
|
1088
|
+
data = src.read_nonblock( CHUNK_SIZE )
|
1064
1089
|
rescue IO::WaitReadable
|
1065
1090
|
print 'r'
|
1066
1091
|
return
|
@@ -1135,7 +1160,16 @@ module Girl
|
|
1135
1160
|
return
|
1136
1161
|
end
|
1137
1162
|
|
1138
|
-
|
1163
|
+
lines = data.split( "\r\n" )
|
1164
|
+
|
1165
|
+
unless lines.empty? then
|
1166
|
+
method, url, proto = lines.first.split( ' ' )
|
1167
|
+
|
1168
|
+
if proto && url && proto[ 0, 4 ] == 'HTTP' && url[ 0, 7 ] == 'http://' then
|
1169
|
+
domain_port = url.split( '/' )[ 2 ]
|
1170
|
+
# puts "debug domain port #{ domain_port }"
|
1171
|
+
end
|
1172
|
+
end
|
1139
1173
|
|
1140
1174
|
unless domain_port then
|
1141
1175
|
# puts "debug not HTTP"
|
@@ -1202,10 +1236,6 @@ module Girl
|
|
1202
1236
|
when :tunnel then
|
1203
1237
|
atun = src_info[ :atun ]
|
1204
1238
|
|
1205
|
-
if atun && !src_info[ :is_connect ] then
|
1206
|
-
data, _ = sub_http_request( data )
|
1207
|
-
end
|
1208
|
-
|
1209
1239
|
if atun then
|
1210
1240
|
add_atun_wbuff( atun, pack_a_chunk( data ) )
|
1211
1241
|
else
|
@@ -1216,10 +1246,6 @@ module Girl
|
|
1216
1246
|
dst = src_info[ :dst ]
|
1217
1247
|
|
1218
1248
|
if dst then
|
1219
|
-
unless src_info[ :is_connect ] then
|
1220
|
-
data, _ = sub_http_request( data )
|
1221
|
-
end
|
1222
|
-
|
1223
1249
|
add_dst_wbuff( dst, data )
|
1224
1250
|
else
|
1225
1251
|
# puts "debug add src.rbuff #{ data.bytesize }"
|
@@ -1241,7 +1267,7 @@ module Girl
|
|
1241
1267
|
src = dst_info[ :src ]
|
1242
1268
|
|
1243
1269
|
begin
|
1244
|
-
data = dst.read_nonblock(
|
1270
|
+
data = dst.read_nonblock( CHUNK_SIZE )
|
1245
1271
|
rescue IO::WaitReadable
|
1246
1272
|
print 'r'
|
1247
1273
|
return
|
@@ -1282,22 +1308,44 @@ module Girl
|
|
1282
1308
|
end
|
1283
1309
|
|
1284
1310
|
until data.empty? do
|
1285
|
-
rbuff = btun_info[ :rbuff ]
|
1286
1311
|
wait_bytes = btun_info[ :wait_bytes ]
|
1287
1312
|
|
1288
1313
|
if wait_bytes > 0 then
|
1289
1314
|
len = wait_bytes
|
1290
1315
|
# puts "debug wait bytes #{ len }"
|
1291
1316
|
else
|
1292
|
-
|
1293
|
-
|
1294
|
-
|
1295
|
-
|
1296
|
-
|
1317
|
+
lbuff = btun_info[ :lbuff ]
|
1318
|
+
|
1319
|
+
if lbuff.empty? then
|
1320
|
+
# 长度缓存为空,从读到的流量里取长度
|
1321
|
+
# 两个字节以下,记进长度缓存
|
1322
|
+
if data.bytesize <= 2 then
|
1323
|
+
# puts "debug set btun.lbuff #{ data.inspect }"
|
1324
|
+
btun_info[ :lbuff ] = data
|
1325
|
+
return
|
1326
|
+
end
|
1327
|
+
|
1328
|
+
len = data[ 0, 2 ].unpack( 'n' ).first
|
1329
|
+
data = data[ 2..-1 ]
|
1330
|
+
elsif lbuff.bytesize == 1 then
|
1331
|
+
# 长度缓存记有一个字节,补一个字节
|
1332
|
+
lbuff = "#{ lbuff }#{ data[ 0 ] }"
|
1333
|
+
|
1334
|
+
if data.bytesize == 1 then
|
1335
|
+
# puts "debug add btun.lbuff a byte #{ data.inspect }"
|
1336
|
+
btun_info[ :lbuff ] = lbuff
|
1337
|
+
return
|
1338
|
+
end
|
1297
1339
|
|
1298
|
-
|
1299
|
-
|
1300
|
-
|
1340
|
+
# 使用长度缓存
|
1341
|
+
len = lbuff.unpack( 'n' ).first
|
1342
|
+
btun_info[ :lbuff ].clear
|
1343
|
+
data = data[ 1..-1 ]
|
1344
|
+
else
|
1345
|
+
# 使用长度缓存
|
1346
|
+
len = lbuff.unpack( 'n' ).first
|
1347
|
+
btun_info[ :lbuff ].clear
|
1348
|
+
end
|
1301
1349
|
end
|
1302
1350
|
|
1303
1351
|
chunk = data[ 0, len ]
|
@@ -1305,7 +1353,7 @@ module Girl
|
|
1305
1353
|
|
1306
1354
|
if chunk_size == len then
|
1307
1355
|
# 取完整了
|
1308
|
-
chunk = @custom.decode( "#{ rbuff }#{ chunk }" )
|
1356
|
+
chunk = @custom.decode( "#{ btun_info[ :rbuff ] }#{ chunk }" )
|
1309
1357
|
# puts "debug decode and add src.wbuff #{ chunk.bytesize }"
|
1310
1358
|
add_src_wbuff( src, chunk )
|
1311
1359
|
btun_info[ :rbuff ].clear
|
@@ -1384,6 +1432,12 @@ module Girl
|
|
1384
1432
|
|
1385
1433
|
dst_info = @dst_infos[ dst ]
|
1386
1434
|
src = dst_info[ :src ]
|
1435
|
+
src_info = @src_infos[ src ]
|
1436
|
+
|
1437
|
+
unless src.closed? then
|
1438
|
+
src_info[ :dst_connected ] = true
|
1439
|
+
end
|
1440
|
+
|
1387
1441
|
data = dst_info[ :wbuff ]
|
1388
1442
|
|
1389
1443
|
# 写前为空,处理关闭写
|
@@ -1414,7 +1468,6 @@ module Girl
|
|
1414
1468
|
dst_info[ :wbuff ] = data
|
1415
1469
|
|
1416
1470
|
unless src.closed? then
|
1417
|
-
src_info = @src_infos[ src ]
|
1418
1471
|
src_info[ :last_sent_at ] = Time.new
|
1419
1472
|
end
|
1420
1473
|
end
|