girl 4.3.0 → 4.8.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/lib/girl/head.rb +7 -3
- data/lib/girl/proxy_worker.rb +66 -28
- data/lib/girl/proxyd_worker.rb +44 -30
- data/lib/girl/relay.rb +1 -0
- data/lib/girl/relay_worker.rb +78 -40
- data/lib/girl/resolvd_worker.rb +17 -14
- data/lib/girl/ssl_worker.rb +34 -11
- data/lib/girl/version.rb +1 -1
- metadata +3 -3
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 944b2055e93c9751113af05107dce4dc040bb40a41602388350c292af2286e0b
|
4
|
+
data.tar.gz: 71c9b4cb592f41750a5f21d751afeb4d13be0b2c20da2f10eb0df42a8cfbe2fd
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 8a01d46a18c169d0d4773168379b0aa1106157872554444d166156dbaf7d55966d8f941561754d5e506c91d098383bf419ad42a8cd59432dc0270e7f879dc355
|
7
|
+
data.tar.gz: a9ed3e588404a191c0c7b38abdb1ec3573af2139022258dd9f2ee469ce6ad335b21ab5595002638d73946130535b6f92ac8c7bb429da7cd3c5b005e1dffdb3f8
|
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 # 多久没有建立通道,过期
|
6
|
-
|
7
|
+
EXPIRE_CONNECTING = 2 # 连接中,多久没连上过期
|
8
|
+
EXPIRE_AFTER = 86400 # 多久没有新流量,过期
|
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_worker.rb
CHANGED
@@ -7,7 +7,6 @@ module Girl
|
|
7
7
|
def initialize( redir_port, proxyd_host, proxyd_port, directs, remotes, im )
|
8
8
|
@proxyd_host = proxyd_host
|
9
9
|
@proxyd_port = proxyd_port
|
10
|
-
@proxyd_addr = Socket.sockaddr_in( proxyd_port, proxyd_host )
|
11
10
|
@directs = directs
|
12
11
|
@remotes = remotes
|
13
12
|
@custom = Girl::ProxyCustom.new( im )
|
@@ -431,8 +430,7 @@ module Girl
|
|
431
430
|
return if src.closed?
|
432
431
|
src_info = @src_infos[ src ]
|
433
432
|
|
434
|
-
if (
|
435
|
-
|| ( ( ip_info.ip_address == @proxyd_host ) && ( src_info[ :destination_port ] == @proxyd_port ) ) then
|
433
|
+
if ( @ip_address_list.any? { | addrinfo | addrinfo.ip_address == ip_info.ip_address } ) && ( src_info[ :destination_port ] == @redir_port ) then
|
436
434
|
puts "p#{ Process.pid } #{ Time.new } ignore #{ ip_info.ip_address }:#{ src_info[ :destination_port ] }"
|
437
435
|
add_closing_src( src )
|
438
436
|
return
|
@@ -507,19 +505,33 @@ module Girl
|
|
507
505
|
if @ctl && !@ctl.closed? then
|
508
506
|
last_recv_at = @ctl_info[ :last_recv_at ] || @ctl_info[ :created_at ]
|
509
507
|
|
510
|
-
if now - last_recv_at >=
|
511
|
-
puts "p#{ Process.pid } #{ Time.new } expire ctl"
|
512
|
-
|
513
|
-
next_tick
|
508
|
+
if now - last_recv_at >= EXPIRE_CTL then
|
509
|
+
puts "p#{ Process.pid } #{ Time.new } expire ctl #{ EXPIRE_CTL }"
|
510
|
+
set_ctl_closing
|
514
511
|
end
|
515
512
|
end
|
516
513
|
|
517
514
|
@src_infos.each do | src, src_info |
|
518
515
|
last_recv_at = src_info[ :last_recv_at ] || src_info[ :created_at ]
|
519
516
|
last_sent_at = src_info[ :last_sent_at ] || src_info[ :created_at ]
|
520
|
-
expire_after = ( src_info[ :dst ] || src_info[ :atun ] ) ? EXPIRE_AFTER : EXPIRE_NEW
|
521
517
|
|
522
|
-
if
|
518
|
+
if src_info[ :dst ] then
|
519
|
+
if src_info[ :dst_connected ] then
|
520
|
+
expire_after = EXPIRE_AFTER
|
521
|
+
is_expire = ( now - last_recv_at >= expire_after ) && ( now - last_sent_at >= expire_after )
|
522
|
+
else
|
523
|
+
expire_after = EXPIRE_CONNECTING
|
524
|
+
is_expire = ( now - src_info[ :dst_created_at ] >= expire_after )
|
525
|
+
end
|
526
|
+
elsif src_info[ :atun ] then
|
527
|
+
expire_after = EXPIRE_AFTER
|
528
|
+
is_expire = ( now - last_recv_at >= expire_after ) && ( now - last_sent_at >= expire_after )
|
529
|
+
else
|
530
|
+
expire_after = EXPIRE_NEW
|
531
|
+
is_expire = ( now - last_recv_at >= expire_after ) && ( now - last_sent_at >= expire_after )
|
532
|
+
end
|
533
|
+
|
534
|
+
if is_expire then
|
523
535
|
puts "p#{ Process.pid } #{ Time.new } expire src #{ expire_after } #{ src_info[ :id ] } #{ src_info[ :destination_domain ] }"
|
524
536
|
add_closing_src( src )
|
525
537
|
|
@@ -548,7 +560,7 @@ module Girl
|
|
548
560
|
if !dst.closed? then
|
549
561
|
dst_info = @dst_infos[ dst ]
|
550
562
|
|
551
|
-
if dst_info[ :wbuff ].
|
563
|
+
if dst_info[ :wbuff ].bytesize < RESUME_BELOW then
|
552
564
|
puts "p#{ Process.pid } #{ Time.new } resume direct src #{ src_info[ :destination_domain ] }"
|
553
565
|
add_resume_src( src )
|
554
566
|
end
|
@@ -559,7 +571,7 @@ module Girl
|
|
559
571
|
if atun && !atun.closed? then
|
560
572
|
atun_info = @atun_infos[ atun ]
|
561
573
|
|
562
|
-
if atun_info[ :wbuff ].
|
574
|
+
if atun_info[ :wbuff ].bytesize < RESUME_BELOW then
|
563
575
|
puts "p#{ Process.pid } #{ Time.new } resume tunnel src #{ src_info[ :destination_domain ] }"
|
564
576
|
add_resume_src( src )
|
565
577
|
end
|
@@ -574,7 +586,7 @@ module Girl
|
|
574
586
|
if src && !src.closed? then
|
575
587
|
src_info = @src_infos[ src ]
|
576
588
|
|
577
|
-
if src_info[ :wbuff ].
|
589
|
+
if src_info[ :wbuff ].bytesize < RESUME_BELOW then
|
578
590
|
puts "p#{ Process.pid } #{ Time.new } resume dst #{ dst_info[ :domain ] }"
|
579
591
|
add_resume_dst( dst )
|
580
592
|
end
|
@@ -588,7 +600,7 @@ module Girl
|
|
588
600
|
if src && !src.closed? then
|
589
601
|
src_info = @src_infos[ src ]
|
590
602
|
|
591
|
-
if src_info[ :wbuff ].
|
603
|
+
if src_info[ :wbuff ].bytesize < RESUME_BELOW then
|
592
604
|
puts "p#{ Process.pid } #{ Time.new } resume btun #{ btun_info[ :domain ] }"
|
593
605
|
add_resume_btun( btun )
|
594
606
|
end
|
@@ -615,6 +627,7 @@ module Girl
|
|
615
627
|
|
616
628
|
if resend >= RESEND_LIMIT then
|
617
629
|
@ctl_info[ :resends ].delete( key )
|
630
|
+
set_ctl_closing
|
618
631
|
break
|
619
632
|
end
|
620
633
|
|
@@ -632,13 +645,14 @@ module Girl
|
|
632
645
|
domain = src_info[ :destination_domain ]
|
633
646
|
destination_addr = Socket.sockaddr_in( src_info[ :destination_port ], ip_info.ip_address )
|
634
647
|
dst = Socket.new( ip_info.ipv4? ? Socket::AF_INET : Socket::AF_INET6, Socket::SOCK_STREAM, 0 )
|
648
|
+
dst.setsockopt( Socket::IPPROTO_TCP, Socket::TCP_NODELAY, 1 )
|
635
649
|
|
636
650
|
begin
|
637
651
|
dst.connect_nonblock( destination_addr )
|
638
652
|
rescue IO::WaitWritable
|
639
653
|
# connect nonblock 必抛 wait writable
|
640
654
|
rescue Exception => e
|
641
|
-
puts "p#{ Process.pid } #{ Time.new } dst connect destination #{ domain } #{ src_info[ :destination_port ] } #{ ip_info.ip_address } #{ e.class }
|
655
|
+
puts "p#{ Process.pid } #{ Time.new } dst connect destination #{ domain } #{ src_info[ :destination_port ] } #{ ip_info.ip_address } #{ e.class }"
|
642
656
|
dst.close
|
643
657
|
add_closing_src( src )
|
644
658
|
return
|
@@ -653,9 +667,9 @@ module Girl
|
|
653
667
|
}
|
654
668
|
|
655
669
|
@dst_infos[ dst ] = dst_info
|
656
|
-
add_read( dst, :dst )
|
657
670
|
src_info[ :proxy_type ] = :direct
|
658
671
|
src_info[ :dst ] = dst
|
672
|
+
src_info[ :dst_created_at ] = Time.new
|
659
673
|
|
660
674
|
if src_info[ :proxy_proto ] == :http then
|
661
675
|
if src_info[ :is_connect ] then
|
@@ -664,11 +678,13 @@ module Girl
|
|
664
678
|
elsif src_info[ :rbuff ] then
|
665
679
|
# puts "debug move src.rbuff to dst.wbuff"
|
666
680
|
dst_info[ :wbuff ] << src_info[ :rbuff ]
|
667
|
-
add_write( dst )
|
668
681
|
end
|
669
682
|
elsif src_info[ :proxy_proto ] == :socks5 then
|
670
683
|
add_socks5_conn_reply( src )
|
671
684
|
end
|
685
|
+
|
686
|
+
add_read( dst, :dst )
|
687
|
+
add_write( dst )
|
672
688
|
end
|
673
689
|
|
674
690
|
##
|
@@ -684,7 +700,10 @@ module Girl
|
|
684
700
|
@ctl = ctl
|
685
701
|
add_read( ctl, :ctl )
|
686
702
|
|
703
|
+
ctld_port = @proxyd_port + 10.times.to_a.sample
|
704
|
+
ctld_addr = Socket.sockaddr_in( ctld_port, @proxyd_host )
|
687
705
|
@ctl_info = {
|
706
|
+
ctld_addr: ctld_addr, # ctld地址
|
688
707
|
resends: ConcurrentHash.new, # key => count
|
689
708
|
atund_addr: nil, # atund地址,src->dst
|
690
709
|
btund_addr: nil, # btund地址,dst->src
|
@@ -694,7 +713,7 @@ module Girl
|
|
694
713
|
}
|
695
714
|
|
696
715
|
hello = @custom.hello
|
697
|
-
puts "p#{ Process.pid } #{ Time.new } hello i'm #{ hello.inspect }"
|
716
|
+
puts "p#{ Process.pid } #{ Time.new } hello i'm #{ hello.inspect } #{ ctld_port }"
|
698
717
|
key = [ HELLO ].pack( 'C' )
|
699
718
|
add_ctlmsg( key, hello )
|
700
719
|
end
|
@@ -704,6 +723,7 @@ module Girl
|
|
704
723
|
#
|
705
724
|
def new_a_redir( redir_port )
|
706
725
|
redir = Socket.new( Socket::AF_INET, Socket::SOCK_STREAM, 0 )
|
726
|
+
redir.setsockopt( Socket::IPPROTO_TCP, Socket::TCP_NODELAY, 1 )
|
707
727
|
redir.setsockopt( Socket::SOL_SOCKET, Socket::SO_REUSEADDR, 1 )
|
708
728
|
|
709
729
|
if RUBY_PLATFORM.include?( 'linux' ) then
|
@@ -730,23 +750,25 @@ module Girl
|
|
730
750
|
|
731
751
|
# puts "debug new atun and btun"
|
732
752
|
atun = Socket.new( Socket::AF_INET, Socket::SOCK_STREAM, 0 )
|
753
|
+
atun.setsockopt( Socket::IPPROTO_TCP, Socket::TCP_NODELAY, 1 )
|
733
754
|
|
734
755
|
begin
|
735
756
|
atun.connect_nonblock( @ctl_info[ :atund_addr ] )
|
736
757
|
rescue IO::WaitWritable
|
737
758
|
rescue Exception => e
|
738
|
-
puts "p#{ Process.pid } #{ Time.new } connect atund #{ e.class }
|
759
|
+
puts "p#{ Process.pid } #{ Time.new } connect atund #{ e.class }"
|
739
760
|
atun.close
|
740
761
|
return
|
741
762
|
end
|
742
763
|
|
743
764
|
btun = Socket.new( Socket::AF_INET, Socket::SOCK_STREAM, 0 )
|
765
|
+
btun.setsockopt( Socket::IPPROTO_TCP, Socket::TCP_NODELAY, 1 )
|
744
766
|
|
745
767
|
begin
|
746
768
|
btun.connect_nonblock( @ctl_info[ :btund_addr ] )
|
747
769
|
rescue IO::WaitWritable
|
748
770
|
rescue Exception => e
|
749
|
-
puts "p#{ Process.pid } #{ Time.new } connect btund #{ e.class }
|
771
|
+
puts "p#{ Process.pid } #{ Time.new } connect btund #{ e.class }"
|
750
772
|
btun.close
|
751
773
|
return
|
752
774
|
end
|
@@ -755,7 +777,7 @@ module Girl
|
|
755
777
|
atun_wbuff = [ dst_id ].pack( 'n' )
|
756
778
|
|
757
779
|
until src_info[ :rbuff ].empty? do
|
758
|
-
data = src_info[ :rbuff ][ 0,
|
780
|
+
data = src_info[ :rbuff ][ 0, CHUNK_SIZE ]
|
759
781
|
data_size = data.bytesize
|
760
782
|
# puts "debug move src.rbuff #{ data_size } to atun.wbuff"
|
761
783
|
atun_wbuff << pack_a_chunk( data )
|
@@ -866,7 +888,7 @@ module Girl
|
|
866
888
|
data = @custom.encode( data )
|
867
889
|
|
868
890
|
begin
|
869
|
-
@ctl.sendmsg( data, 0, @
|
891
|
+
@ctl.sendmsg( data, 0, @ctl_info[ :ctld_addr ] )
|
870
892
|
@ctl_info[ :last_sent_at ] = Time.new
|
871
893
|
rescue Exception => e
|
872
894
|
puts "p#{ Process.pid } #{ Time.new } sendmsg #{ e.class }"
|
@@ -886,6 +908,15 @@ module Girl
|
|
886
908
|
add_write( atun )
|
887
909
|
end
|
888
910
|
|
911
|
+
##
|
912
|
+
# set ctl closing
|
913
|
+
#
|
914
|
+
def set_ctl_closing
|
915
|
+
return if @ctl.closed?
|
916
|
+
@ctl_info[ :closing ] = true
|
917
|
+
next_tick
|
918
|
+
end
|
919
|
+
|
889
920
|
##
|
890
921
|
# set dst closing write
|
891
922
|
#
|
@@ -929,7 +960,7 @@ module Girl
|
|
929
960
|
# read dotr
|
930
961
|
#
|
931
962
|
def read_dotr( dotr )
|
932
|
-
dotr.read_nonblock(
|
963
|
+
dotr.read_nonblock( READ_SIZE )
|
933
964
|
|
934
965
|
if @ctl_info && @ctl_info[ :closing ] then
|
935
966
|
send_ctlmsg( [ CTL_FIN ].pack( 'C' ) )
|
@@ -993,6 +1024,8 @@ module Girl
|
|
993
1024
|
is_connect: true, # 代理协议是http的场合,是否是CONNECT
|
994
1025
|
rbuff: '', # 读到的流量
|
995
1026
|
dst: nil, # :direct的场合,对应的dst
|
1027
|
+
dst_created_at: nil, # :direct的场合,对应的dst的创建时间
|
1028
|
+
dst_connected: false, # :direct的场合,对应的dst是否已连接
|
996
1029
|
ctl: nil, # :tunnel的场合,对应的ctl
|
997
1030
|
atun: nil, # :tunnel的场合,对应的atun
|
998
1031
|
btun: nil, # :tunnel的场合,对应的btun
|
@@ -1028,7 +1061,7 @@ module Girl
|
|
1028
1061
|
|
1029
1062
|
case ctl_num
|
1030
1063
|
when TUND_PORT then
|
1031
|
-
return if @ctl_info[ :atund_addr ] || data.
|
1064
|
+
return if @ctl_info[ :atund_addr ] || data.bytesize != 5
|
1032
1065
|
atund_port, btund_port = data[ 1, 4 ].unpack( 'nn' )
|
1033
1066
|
puts "p#{ Process.pid } #{ Time.new } got tund port #{ atund_port } #{ btund_port }"
|
1034
1067
|
@ctl_info[ :resends ].delete( [ HELLO ].pack( 'C' ) )
|
@@ -1042,14 +1075,14 @@ module Girl
|
|
1042
1075
|
@pending_srcs.clear
|
1043
1076
|
end
|
1044
1077
|
when PAIRED then
|
1045
|
-
return if data.
|
1078
|
+
return if data.bytesize != 11
|
1046
1079
|
src_id, dst_id = data[ 1, 10 ].unpack( 'Q>n' )
|
1047
1080
|
# puts "debug got paired #{ src_id } #{ dst_id }"
|
1048
1081
|
@ctl_info[ :resends ].delete( [ A_NEW_SOURCE, src_id ].pack( 'CQ>' ) )
|
1049
1082
|
@ctl_info[ :last_recv_at ] = Time.new
|
1050
1083
|
new_tuns( src_id, dst_id )
|
1051
1084
|
when UNKNOWN_CTL_ADDR then
|
1052
|
-
puts "p#{ Process.pid } #{ Time.new } got unknown ctl addr
|
1085
|
+
puts "p#{ Process.pid } #{ Time.new } got unknown ctl addr"
|
1053
1086
|
close_ctl( ctl )
|
1054
1087
|
end
|
1055
1088
|
end
|
@@ -1066,7 +1099,7 @@ module Girl
|
|
1066
1099
|
src_info = @src_infos[ src ]
|
1067
1100
|
|
1068
1101
|
begin
|
1069
|
-
data = src.read_nonblock(
|
1102
|
+
data = src.read_nonblock( CHUNK_SIZE )
|
1070
1103
|
rescue IO::WaitReadable
|
1071
1104
|
print 'r'
|
1072
1105
|
return
|
@@ -1248,7 +1281,7 @@ module Girl
|
|
1248
1281
|
src = dst_info[ :src ]
|
1249
1282
|
|
1250
1283
|
begin
|
1251
|
-
data = dst.read_nonblock(
|
1284
|
+
data = dst.read_nonblock( CHUNK_SIZE )
|
1252
1285
|
rescue IO::WaitReadable
|
1253
1286
|
print 'r'
|
1254
1287
|
return
|
@@ -1413,6 +1446,12 @@ module Girl
|
|
1413
1446
|
|
1414
1447
|
dst_info = @dst_infos[ dst ]
|
1415
1448
|
src = dst_info[ :src ]
|
1449
|
+
src_info = @src_infos[ src ]
|
1450
|
+
|
1451
|
+
unless src.closed? then
|
1452
|
+
src_info[ :dst_connected ] = true
|
1453
|
+
end
|
1454
|
+
|
1416
1455
|
data = dst_info[ :wbuff ]
|
1417
1456
|
|
1418
1457
|
# 写前为空,处理关闭写
|
@@ -1443,7 +1482,6 @@ module Girl
|
|
1443
1482
|
dst_info[ :wbuff ] = data
|
1444
1483
|
|
1445
1484
|
unless src.closed? then
|
1446
|
-
src_info = @src_infos[ src ]
|
1447
1485
|
src_info[ :last_sent_at ] = Time.new
|
1448
1486
|
end
|
1449
1487
|
end
|
data/lib/girl/proxyd_worker.rb
CHANGED
@@ -28,7 +28,7 @@ module Girl
|
|
28
28
|
dotr, dotw = IO.pipe
|
29
29
|
@dotw = dotw
|
30
30
|
add_read( dotr, :dotr )
|
31
|
-
|
31
|
+
new_ctlds( proxyd_port )
|
32
32
|
new_a_infod( infod_port )
|
33
33
|
end
|
34
34
|
|
@@ -306,6 +306,7 @@ module Girl
|
|
306
306
|
#
|
307
307
|
def deal_with_destination_addr( ctl_addr, src_id, destination_addr, domain_port )
|
308
308
|
dst = Socket.new( Addrinfo.new( destination_addr ).ipv4? ? Socket::AF_INET : Socket::AF_INET6, Socket::SOCK_STREAM, 0 )
|
309
|
+
dst.setsockopt( Socket::IPPROTO_TCP, Socket::TCP_NODELAY, 1 )
|
309
310
|
|
310
311
|
begin
|
311
312
|
dst.connect_nonblock( destination_addr )
|
@@ -324,6 +325,7 @@ module Girl
|
|
324
325
|
ctl_addr: ctl_addr, # 对应ctl
|
325
326
|
im: ctl_info[ :im ], # 标识
|
326
327
|
domain_port: domain_port, # 目的地和端口
|
328
|
+
connected: false, # 是否已连接
|
327
329
|
rbuff: '', # 对应的tun没准备好,暂存读到的流量
|
328
330
|
atun: nil, # 对应的atun
|
329
331
|
btun: nil, # 对应的btun
|
@@ -336,13 +338,14 @@ module Girl
|
|
336
338
|
}
|
337
339
|
|
338
340
|
add_read( dst, :dst )
|
341
|
+
add_write( dst )
|
339
342
|
|
340
343
|
ctl_info[ :dst_ids ][ src_id ] = dst_id
|
341
344
|
ctl_info[ :dsts ][ dst_id ] = dst
|
342
345
|
|
343
346
|
data = [ PAIRED, src_id, dst_id ].pack( 'CQ>n' )
|
344
347
|
# puts "debug add ctlmsg paired #{ src_id } #{ dst_id }"
|
345
|
-
send_ctlmsg( data, ctl_addr )
|
348
|
+
send_ctlmsg( ctl_info[ :ctld ], data, ctl_addr )
|
346
349
|
end
|
347
350
|
|
348
351
|
##
|
@@ -404,11 +407,17 @@ module Girl
|
|
404
407
|
end
|
405
408
|
|
406
409
|
@dst_infos.each do | dst, dst_info |
|
407
|
-
|
408
|
-
|
409
|
-
|
410
|
+
if dst_info[ :connected ] then
|
411
|
+
last_recv_at = dst_info[ :last_recv_at ] || dst_info[ :created_at ]
|
412
|
+
last_sent_at = dst_info[ :last_sent_at ] || dst_info[ :created_at ]
|
413
|
+
expire_after = EXPIRE_AFTER
|
414
|
+
is_expire = ( now - last_recv_at >= expire_after ) && ( now - last_sent_at >= expire_after )
|
415
|
+
else
|
416
|
+
expire_after = EXPIRE_CONNECTING
|
417
|
+
is_expire = ( now - dst_info[ :created_at ] >= expire_after )
|
418
|
+
end
|
410
419
|
|
411
|
-
if
|
420
|
+
if is_expire then
|
412
421
|
puts "p#{ Process.pid } #{ Time.new } expire dst #{ expire_after } #{ dst_info[ :domain_port ] }"
|
413
422
|
|
414
423
|
unless @closing_dsts.include?( dst ) then
|
@@ -436,7 +445,7 @@ module Girl
|
|
436
445
|
if btun && !btun.closed? then
|
437
446
|
btun_info = @btun_infos[ btun ]
|
438
447
|
|
439
|
-
if btun_info[ :wbuff ].
|
448
|
+
if btun_info[ :wbuff ].bytesize < RESUME_BELOW then
|
440
449
|
puts "p#{ Process.pid } #{ Time.new } resume dst #{ dst_info[ :domain_port ] }"
|
441
450
|
add_resume_dst( dst )
|
442
451
|
end
|
@@ -450,7 +459,7 @@ module Girl
|
|
450
459
|
if dst && !dst.closed? then
|
451
460
|
dst_info = @dst_infos[ dst ]
|
452
461
|
|
453
|
-
if dst_info[ :wbuff ].
|
462
|
+
if dst_info[ :wbuff ].bytesize < RESUME_BELOW then
|
454
463
|
puts "p#{ Process.pid } #{ Time.new } resume atun #{ atun_info[ :domain_port ] }"
|
455
464
|
add_resume_atun( atun )
|
456
465
|
end
|
@@ -479,18 +488,6 @@ module Girl
|
|
479
488
|
end
|
480
489
|
end
|
481
490
|
|
482
|
-
##
|
483
|
-
# new a ctld
|
484
|
-
#
|
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
|
492
|
-
end
|
493
|
-
|
494
491
|
##
|
495
492
|
# new a infod
|
496
493
|
#
|
@@ -507,11 +504,26 @@ module Girl
|
|
507
504
|
#
|
508
505
|
def new_a_tund
|
509
506
|
tund = Socket.new( Socket::AF_INET, Socket::SOCK_STREAM, 0 )
|
507
|
+
tund.setsockopt( Socket::IPPROTO_TCP, Socket::TCP_NODELAY, 1 )
|
510
508
|
tund.bind( Socket.sockaddr_in( 0, '0.0.0.0' ) )
|
511
509
|
tund.listen( 127 )
|
512
510
|
tund
|
513
511
|
end
|
514
512
|
|
513
|
+
##
|
514
|
+
# new ctlds
|
515
|
+
#
|
516
|
+
def new_ctlds( proxyd_port )
|
517
|
+
10.times do | i |
|
518
|
+
ctld_port = proxyd_port + i
|
519
|
+
ctld = Socket.new( Socket::AF_INET, Socket::SOCK_DGRAM, 0 )
|
520
|
+
ctld.setsockopt( Socket::SOL_SOCKET, Socket::SO_REUSEPORT, 1 )
|
521
|
+
ctld.bind( Socket.sockaddr_in( ctld_port, '0.0.0.0' ) )
|
522
|
+
puts "p#{ Process.pid } #{ Time.new } ctld bind on #{ ctld_port }"
|
523
|
+
add_read( ctld, :ctld )
|
524
|
+
end
|
525
|
+
end
|
526
|
+
|
515
527
|
##
|
516
528
|
# next tick
|
517
529
|
#
|
@@ -571,11 +583,11 @@ module Girl
|
|
571
583
|
##
|
572
584
|
# send ctlmsg
|
573
585
|
#
|
574
|
-
def send_ctlmsg( data, to_addr )
|
586
|
+
def send_ctlmsg( ctld, data, to_addr )
|
575
587
|
data = @custom.encode( data )
|
576
588
|
|
577
589
|
begin
|
578
|
-
|
590
|
+
ctld.sendmsg( data, 0, to_addr )
|
579
591
|
rescue Exception => e
|
580
592
|
puts "p#{ Process.pid } #{ Time.new } sendmsg #{ e.class }"
|
581
593
|
end
|
@@ -609,7 +621,7 @@ module Girl
|
|
609
621
|
# read dotr
|
610
622
|
#
|
611
623
|
def read_dotr( dotr )
|
612
|
-
dotr.read_nonblock(
|
624
|
+
dotr.read_nonblock( READ_SIZE )
|
613
625
|
|
614
626
|
if @deleting_ctl_infos.any? then
|
615
627
|
@deleting_ctl_infos.each { | ctl_addr | del_ctl_info( ctl_addr ) }
|
@@ -655,7 +667,7 @@ module Girl
|
|
655
667
|
if ctl_info then
|
656
668
|
atund_port, btund_port = ctl_info[ :atund_port ], ctl_info[ :btund_port ]
|
657
669
|
else
|
658
|
-
return if data.
|
670
|
+
return if data.bytesize <= 1
|
659
671
|
im = data[ 1..-1 ]
|
660
672
|
result = @custom.check( im, addrinfo )
|
661
673
|
|
@@ -687,6 +699,7 @@ module Girl
|
|
687
699
|
}
|
688
700
|
|
689
701
|
@ctl_infos[ ctl_addr ] = {
|
702
|
+
ctld: ctld, # 对应的ctld
|
690
703
|
addrinfo: addrinfo, # 地址
|
691
704
|
im: im, # 标识
|
692
705
|
atund: atund, # 对应atund,src->dst
|
@@ -702,21 +715,21 @@ module Girl
|
|
702
715
|
end
|
703
716
|
|
704
717
|
data2 = [ TUND_PORT, atund_port, btund_port ].pack( 'Cnn' )
|
705
|
-
send_ctlmsg( data2, ctl_addr )
|
718
|
+
send_ctlmsg( ctld, data2, ctl_addr )
|
706
719
|
when A_NEW_SOURCE then
|
707
720
|
unless ctl_info then
|
708
|
-
send_ctlmsg( [ UNKNOWN_CTL_ADDR ].pack( 'C' ), addrinfo )
|
721
|
+
send_ctlmsg( ctld, [ UNKNOWN_CTL_ADDR ].pack( 'C' ), addrinfo )
|
709
722
|
return
|
710
723
|
end
|
711
724
|
|
712
|
-
return if data.
|
725
|
+
return if data.bytesize <= 9
|
713
726
|
src_id = data[ 1, 8 ].unpack( 'Q>' ).first
|
714
727
|
dst_id = ctl_info[ :dst_ids ][ src_id ]
|
715
728
|
|
716
729
|
if dst_id then
|
717
730
|
data2 = [ PAIRED, src_id, dst_id ].pack( 'CQ>n' )
|
718
731
|
# puts "debug dst id exist, send ctlmsg paired #{ src_id } #{ dst_id }"
|
719
|
-
send_ctlmsg( data2, ctl_addr )
|
732
|
+
send_ctlmsg( ctld, data2, ctl_addr )
|
720
733
|
return
|
721
734
|
end
|
722
735
|
|
@@ -772,7 +785,7 @@ module Girl
|
|
772
785
|
btun = dst_info[ :btun ]
|
773
786
|
|
774
787
|
begin
|
775
|
-
data = dst.read_nonblock(
|
788
|
+
data = dst.read_nonblock( CHUNK_SIZE )
|
776
789
|
rescue IO::WaitReadable
|
777
790
|
print 'r'
|
778
791
|
return
|
@@ -1044,7 +1057,7 @@ module Girl
|
|
1044
1057
|
data2 = ''
|
1045
1058
|
|
1046
1059
|
until dst_info[ :rbuff ].empty? do
|
1047
|
-
_data = dst_info[ :rbuff ][ 0,
|
1060
|
+
_data = dst_info[ :rbuff ][ 0, CHUNK_SIZE ]
|
1048
1061
|
data_size = _data.bytesize
|
1049
1062
|
# puts "debug move dst.rbuff to btun.wbuff"
|
1050
1063
|
data2 << pack_a_chunk( _data )
|
@@ -1067,6 +1080,7 @@ module Girl
|
|
1067
1080
|
end
|
1068
1081
|
|
1069
1082
|
dst_info = @dst_infos[ dst ]
|
1083
|
+
dst_info[ :connected ] = true
|
1070
1084
|
atun = dst_info[ :atun ]
|
1071
1085
|
data = dst_info[ :wbuff ]
|
1072
1086
|
|
data/lib/girl/relay.rb
CHANGED
data/lib/girl/relay_worker.rb
CHANGED
@@ -6,10 +6,10 @@ module Girl
|
|
6
6
|
#
|
7
7
|
def initialize( resolv_port, nameserver, resolvd_port, redir_port, proxyd_host, proxyd_port, directs, remotes, im )
|
8
8
|
@nameserver_addr = Socket.sockaddr_in( 53, nameserver )
|
9
|
-
@
|
9
|
+
@resolvd_ports = 10.times.map { | i | resolvd_port + i }
|
10
10
|
@qnames = remotes.map { | dom | dom.split( '.' ).map{ | sub | [ sub.size ].pack( 'C' ) + sub }.join }
|
11
11
|
@proxyd_host = proxyd_host
|
12
|
-
@
|
12
|
+
@proxyd_port = proxyd_port
|
13
13
|
@directs = directs
|
14
14
|
@remotes = remotes
|
15
15
|
@custom = Girl::ProxyCustom.new( im )
|
@@ -444,8 +444,7 @@ module Girl
|
|
444
444
|
return if src.closed?
|
445
445
|
src_info = @src_infos[ src ]
|
446
446
|
|
447
|
-
if (
|
448
|
-
|| ( ( ip_info.ip_address == @proxyd_host ) && ( src_info[ :destination_port ] == @proxyd_port ) ) then
|
447
|
+
if ( @ip_address_list.any? { | addrinfo | addrinfo.ip_address == ip_info.ip_address } ) && ( src_info[ :destination_port ] == @redir_port ) then
|
449
448
|
puts "p#{ Process.pid } #{ Time.new } ignore #{ ip_info.ip_address }:#{ src_info[ :destination_port ] }"
|
450
449
|
add_closing_src( src )
|
451
450
|
return
|
@@ -520,10 +519,9 @@ module Girl
|
|
520
519
|
if @ctl && !@ctl.closed? then
|
521
520
|
last_recv_at = @ctl_info[ :last_recv_at ] || @ctl_info[ :created_at ]
|
522
521
|
|
523
|
-
if now - last_recv_at >=
|
524
|
-
puts "p#{ Process.pid } #{ Time.new } expire ctl"
|
525
|
-
|
526
|
-
next_tick
|
522
|
+
if now - last_recv_at >= EXPIRE_CTL then
|
523
|
+
puts "p#{ Process.pid } #{ Time.new } expire ctl #{ EXPIRE_CTL }"
|
524
|
+
set_ctl_closing
|
527
525
|
end
|
528
526
|
end
|
529
527
|
|
@@ -537,9 +535,24 @@ module Girl
|
|
537
535
|
@src_infos.each do | src, src_info |
|
538
536
|
last_recv_at = src_info[ :last_recv_at ] || src_info[ :created_at ]
|
539
537
|
last_sent_at = src_info[ :last_sent_at ] || src_info[ :created_at ]
|
540
|
-
expire_after = ( src_info[ :dst ] || src_info[ :tun ] ) ? EXPIRE_AFTER : EXPIRE_NEW
|
541
538
|
|
542
|
-
if
|
539
|
+
if src_info[ :dst ] then
|
540
|
+
if src_info[ :dst_connected ] then
|
541
|
+
expire_after = EXPIRE_AFTER
|
542
|
+
is_expire = ( now - last_recv_at >= expire_after ) && ( now - last_sent_at >= expire_after )
|
543
|
+
else
|
544
|
+
expire_after = EXPIRE_CONNECTING
|
545
|
+
is_expire = ( now - src_info[ :dst_created_at ] >= expire_after )
|
546
|
+
end
|
547
|
+
elsif src_info[ :atun ] then
|
548
|
+
expire_after = EXPIRE_AFTER
|
549
|
+
is_expire = ( now - last_recv_at >= expire_after ) && ( now - last_sent_at >= expire_after )
|
550
|
+
else
|
551
|
+
expire_after = EXPIRE_NEW
|
552
|
+
is_expire = ( now - last_recv_at >= expire_after ) && ( now - last_sent_at >= expire_after )
|
553
|
+
end
|
554
|
+
|
555
|
+
if is_expire then
|
543
556
|
puts "p#{ Process.pid } #{ Time.new } expire src #{ expire_after } #{ src_info[ :id ] } #{ src_info[ :destination_domain ] }"
|
544
557
|
add_closing_src( src )
|
545
558
|
|
@@ -568,7 +581,7 @@ module Girl
|
|
568
581
|
if !dst.closed? then
|
569
582
|
dst_info = @dst_infos[ dst ]
|
570
583
|
|
571
|
-
if dst_info[ :wbuff ].
|
584
|
+
if dst_info[ :wbuff ].bytesize < RESUME_BELOW then
|
572
585
|
puts "p#{ Process.pid } #{ Time.new } resume direct src #{ src_info[ :destination_domain ] }"
|
573
586
|
add_resume_src( src )
|
574
587
|
end
|
@@ -579,7 +592,7 @@ module Girl
|
|
579
592
|
if atun && !atun.closed? then
|
580
593
|
atun_info = @atun_infos[ atun ]
|
581
594
|
|
582
|
-
if atun_info[ :wbuff ].
|
595
|
+
if atun_info[ :wbuff ].bytesize < RESUME_BELOW then
|
583
596
|
puts "p#{ Process.pid } #{ Time.new } resume tunnel src #{ src_info[ :destination_domain ] }"
|
584
597
|
add_resume_src( src )
|
585
598
|
end
|
@@ -594,7 +607,7 @@ module Girl
|
|
594
607
|
if src && !src.closed? then
|
595
608
|
src_info = @src_infos[ src ]
|
596
609
|
|
597
|
-
if src_info[ :wbuff ].
|
610
|
+
if src_info[ :wbuff ].bytesize < RESUME_BELOW then
|
598
611
|
puts "p#{ Process.pid } #{ Time.new } resume dst #{ dst_info[ :domain ] }"
|
599
612
|
add_resume_dst( dst )
|
600
613
|
end
|
@@ -608,7 +621,7 @@ module Girl
|
|
608
621
|
if src && !src.closed? then
|
609
622
|
src_info = @src_infos[ src ]
|
610
623
|
|
611
|
-
if src_info[ :wbuff ].
|
624
|
+
if src_info[ :wbuff ].bytesize < RESUME_BELOW then
|
612
625
|
puts "p#{ Process.pid } #{ Time.new } resume btun #{ btun_info[ :domain ] }"
|
613
626
|
add_resume_btun( btun )
|
614
627
|
end
|
@@ -635,6 +648,7 @@ module Girl
|
|
635
648
|
|
636
649
|
if resend >= RESEND_LIMIT then
|
637
650
|
@ctl_info[ :resends ].delete( key )
|
651
|
+
set_ctl_closing
|
638
652
|
break
|
639
653
|
end
|
640
654
|
|
@@ -652,14 +666,14 @@ module Girl
|
|
652
666
|
domain = src_info[ :destination_domain ]
|
653
667
|
destination_addr = Socket.sockaddr_in( src_info[ :destination_port ], ip_info.ip_address )
|
654
668
|
dst = Socket.new( ip_info.ipv4? ? Socket::AF_INET : Socket::AF_INET6, Socket::SOCK_STREAM, 0 )
|
655
|
-
dst.setsockopt( Socket::
|
669
|
+
dst.setsockopt( Socket::IPPROTO_TCP, Socket::TCP_NODELAY, 1 )
|
656
670
|
|
657
671
|
begin
|
658
672
|
dst.connect_nonblock( destination_addr )
|
659
673
|
rescue IO::WaitWritable
|
660
674
|
# connect nonblock 必抛 wait writable
|
661
675
|
rescue Exception => e
|
662
|
-
puts "p#{ Process.pid } #{ Time.new } dst connect destination #{ domain } #{ src_info[ :destination_port ] } #{ ip_info.ip_address } #{ e.class }
|
676
|
+
puts "p#{ Process.pid } #{ Time.new } dst connect destination #{ domain } #{ src_info[ :destination_port ] } #{ ip_info.ip_address } #{ e.class }"
|
663
677
|
dst.close
|
664
678
|
add_closing_src( src )
|
665
679
|
return
|
@@ -674,15 +688,17 @@ module Girl
|
|
674
688
|
}
|
675
689
|
|
676
690
|
@dst_infos[ dst ] = dst_info
|
677
|
-
add_read( dst, :dst )
|
678
691
|
src_info[ :proxy_type ] = :direct
|
679
692
|
src_info[ :dst ] = dst
|
693
|
+
src_info[ :dst_created_at ] = Time.new
|
680
694
|
|
681
695
|
if src_info[ :rbuff ] then
|
682
696
|
# puts "debug move src.rbuff to dst.wbuff"
|
683
697
|
dst_info[ :wbuff ] << src_info[ :rbuff ]
|
684
|
-
add_write( dst )
|
685
698
|
end
|
699
|
+
|
700
|
+
add_read( dst, :dst )
|
701
|
+
add_write( dst )
|
686
702
|
end
|
687
703
|
|
688
704
|
##
|
@@ -698,7 +714,10 @@ module Girl
|
|
698
714
|
@ctl = ctl
|
699
715
|
add_read( ctl, :ctl )
|
700
716
|
|
717
|
+
ctld_port = @proxyd_port + 10.times.to_a.sample
|
718
|
+
ctld_addr = Socket.sockaddr_in( ctld_port, @proxyd_host )
|
701
719
|
@ctl_info = {
|
720
|
+
ctld_addr: ctld_addr, # ctld地址
|
702
721
|
resends: ConcurrentHash.new, # key => count
|
703
722
|
atund_addr: nil, # atund地址,src->dst
|
704
723
|
btund_addr: nil, # btund地址,dst->src
|
@@ -708,7 +727,7 @@ module Girl
|
|
708
727
|
}
|
709
728
|
|
710
729
|
hello = @custom.hello
|
711
|
-
puts "p#{ Process.pid } #{ Time.new } hello i'm #{ hello.inspect }"
|
730
|
+
puts "p#{ Process.pid } #{ Time.new } hello i'm #{ hello.inspect } #{ ctld_port }"
|
712
731
|
key = [ HELLO ].pack( 'C' )
|
713
732
|
add_ctlmsg( key, hello )
|
714
733
|
end
|
@@ -718,6 +737,7 @@ module Girl
|
|
718
737
|
#
|
719
738
|
def new_a_redir( redir_port )
|
720
739
|
redir = Socket.new( Socket::AF_INET, Socket::SOCK_STREAM, 0 )
|
740
|
+
redir.setsockopt( Socket::IPPROTO_TCP, Socket::TCP_NODELAY, 1 )
|
721
741
|
redir.setsockopt( Socket::SOL_SOCKET, Socket::SO_REUSEADDR, 1 )
|
722
742
|
redir.setsockopt( Socket::SOL_SOCKET, Socket::SO_REUSEPORT, 1 )
|
723
743
|
redir.bind( Socket.sockaddr_in( redir_port, '0.0.0.0' ) )
|
@@ -751,12 +771,12 @@ module Girl
|
|
751
771
|
|
752
772
|
if @qnames.any? { | qname | data.include?( qname ) } then
|
753
773
|
data = @custom.encode( data )
|
754
|
-
to_addr = @
|
774
|
+
to_addr = Socket.sockaddr_in( @resolvd_ports.sample, @proxyd_host )
|
755
775
|
else
|
756
776
|
to_addr = @nameserver_addr
|
757
777
|
end
|
758
778
|
|
759
|
-
puts "
|
779
|
+
# puts "debug new a rsv to #{ Addrinfo.new( to_addr ).inspect }"
|
760
780
|
|
761
781
|
@rsv_infos[ rsv ] = {
|
762
782
|
src_addr: src_addr,
|
@@ -778,23 +798,25 @@ module Girl
|
|
778
798
|
|
779
799
|
# puts "debug new atun and btun"
|
780
800
|
atun = Socket.new( Socket::AF_INET, Socket::SOCK_STREAM, 0 )
|
801
|
+
atun.setsockopt( Socket::IPPROTO_TCP, Socket::TCP_NODELAY, 1 )
|
781
802
|
|
782
803
|
begin
|
783
804
|
atun.connect_nonblock( @ctl_info[ :atund_addr ] )
|
784
805
|
rescue IO::WaitWritable
|
785
806
|
rescue Exception => e
|
786
|
-
puts "p#{ Process.pid } #{ Time.new } connect atund #{ e.class }
|
807
|
+
puts "p#{ Process.pid } #{ Time.new } connect atund #{ e.class }"
|
787
808
|
atun.close
|
788
809
|
return
|
789
810
|
end
|
790
811
|
|
791
812
|
btun = Socket.new( Socket::AF_INET, Socket::SOCK_STREAM, 0 )
|
813
|
+
btun.setsockopt( Socket::IPPROTO_TCP, Socket::TCP_NODELAY, 1 )
|
792
814
|
|
793
815
|
begin
|
794
816
|
btun.connect_nonblock( @ctl_info[ :btund_addr ] )
|
795
817
|
rescue IO::WaitWritable
|
796
818
|
rescue Exception => e
|
797
|
-
puts "p#{ Process.pid } #{ Time.new } connect btund #{ e.class }
|
819
|
+
puts "p#{ Process.pid } #{ Time.new } connect btund #{ e.class }"
|
798
820
|
btun.close
|
799
821
|
return
|
800
822
|
end
|
@@ -803,7 +825,7 @@ module Girl
|
|
803
825
|
atun_wbuff = [ dst_id ].pack( 'n' )
|
804
826
|
|
805
827
|
until src_info[ :rbuff ].empty? do
|
806
|
-
data = src_info[ :rbuff ][ 0,
|
828
|
+
data = src_info[ :rbuff ][ 0, CHUNK_SIZE ]
|
807
829
|
data_size = data.bytesize
|
808
830
|
# puts "debug move src.rbuff #{ data_size } to atun.wbuff"
|
809
831
|
atun_wbuff << pack_a_chunk( data )
|
@@ -861,7 +883,7 @@ module Girl
|
|
861
883
|
data = @custom.encode( data )
|
862
884
|
|
863
885
|
begin
|
864
|
-
@ctl.sendmsg( data, 0, @
|
886
|
+
@ctl.sendmsg( data, 0, @ctl_info[ :ctld_addr ] )
|
865
887
|
@ctl_info[ :last_sent_at ] = Time.new
|
866
888
|
rescue Exception => e
|
867
889
|
puts "p#{ Process.pid } #{ Time.new } sendmsg #{ e.class }"
|
@@ -869,6 +891,17 @@ module Girl
|
|
869
891
|
end
|
870
892
|
end
|
871
893
|
|
894
|
+
##
|
895
|
+
# send data
|
896
|
+
#
|
897
|
+
def send_data( sock, to_addr, data )
|
898
|
+
begin
|
899
|
+
sock.sendmsg( data, 0, to_addr )
|
900
|
+
rescue Exception => e
|
901
|
+
puts "p#{ Process.pid } #{ Time.new } sendmsg to #{ to_addr.ip_unpack.inspect } #{ e.class }"
|
902
|
+
end
|
903
|
+
end
|
904
|
+
|
872
905
|
##
|
873
906
|
# set atun closing
|
874
907
|
#
|
@@ -882,14 +915,12 @@ module Girl
|
|
882
915
|
end
|
883
916
|
|
884
917
|
##
|
885
|
-
#
|
918
|
+
# set ctl closing
|
886
919
|
#
|
887
|
-
def
|
888
|
-
|
889
|
-
|
890
|
-
|
891
|
-
puts "p#{ Process.pid } #{ Time.new } sendmsg to #{ to_addr.ip_unpack.inspect } #{ e.class }"
|
892
|
-
end
|
920
|
+
def set_ctl_closing
|
921
|
+
return if @ctl.closed?
|
922
|
+
@ctl_info[ :closing ] = true
|
923
|
+
next_tick
|
893
924
|
end
|
894
925
|
|
895
926
|
##
|
@@ -934,7 +965,7 @@ module Girl
|
|
934
965
|
# read dotr
|
935
966
|
#
|
936
967
|
def read_dotr( dotr )
|
937
|
-
dotr.read_nonblock(
|
968
|
+
dotr.read_nonblock( READ_SIZE )
|
938
969
|
|
939
970
|
if @ctl_info && @ctl_info[ :closing ] then
|
940
971
|
send_ctlmsg( [ CTL_FIN ].pack( 'C' ) )
|
@@ -995,7 +1026,7 @@ module Girl
|
|
995
1026
|
data, addrinfo, rflags, *controls = rsv.recvmsg
|
996
1027
|
# puts "debug rsv recvmsg #{ addrinfo.ip_unpack.inspect } #{ data.inspect }"
|
997
1028
|
|
998
|
-
if addrinfo.
|
1029
|
+
if addrinfo.ip_address == @proxyd_host then
|
999
1030
|
data = @custom.decode( data )
|
1000
1031
|
end
|
1001
1032
|
|
@@ -1039,6 +1070,8 @@ module Girl
|
|
1039
1070
|
destination_port: dest_port, # 目的地端口
|
1040
1071
|
rbuff: '', # 读到的流量
|
1041
1072
|
dst: nil, # :direct的场合,对应的dst
|
1073
|
+
dst_created_at: nil, # :direct的场合,对应的dst的创建时间
|
1074
|
+
dst_connected: false, # :direct的场合,对应的dst是否已连接
|
1042
1075
|
ctl: nil, # :tunnel的场合,对应的ctl
|
1043
1076
|
atun: nil, # :tunnel的场合,对应的atun
|
1044
1077
|
btun: nil, # :tunnel的场合,对应的btun
|
@@ -1076,7 +1109,7 @@ module Girl
|
|
1076
1109
|
|
1077
1110
|
case ctl_num
|
1078
1111
|
when TUND_PORT then
|
1079
|
-
return if @ctl_info[ :atund_addr ] || data.
|
1112
|
+
return if @ctl_info[ :atund_addr ] || data.bytesize != 5
|
1080
1113
|
atund_port, btund_port = data[ 1, 4 ].unpack( 'nn' )
|
1081
1114
|
puts "p#{ Process.pid } #{ Time.new } got tund port #{ atund_port } #{ btund_port }"
|
1082
1115
|
@ctl_info[ :resends ].delete( [ HELLO ].pack( 'C' ) )
|
@@ -1090,14 +1123,14 @@ module Girl
|
|
1090
1123
|
@pending_srcs.clear
|
1091
1124
|
end
|
1092
1125
|
when PAIRED then
|
1093
|
-
return if data.
|
1126
|
+
return if data.bytesize != 11
|
1094
1127
|
src_id, dst_id = data[ 1, 10 ].unpack( 'Q>n' )
|
1095
1128
|
# puts "debug got paired #{ src_id } #{ dst_id }"
|
1096
1129
|
@ctl_info[ :resends ].delete( [ A_NEW_SOURCE, src_id ].pack( 'CQ>' ) )
|
1097
1130
|
@ctl_info[ :last_recv_at ] = Time.new
|
1098
1131
|
new_tuns( src_id, dst_id )
|
1099
1132
|
when UNKNOWN_CTL_ADDR then
|
1100
|
-
puts "p#{ Process.pid } #{ Time.new } got unknown ctl addr
|
1133
|
+
puts "p#{ Process.pid } #{ Time.new } got unknown ctl addr"
|
1101
1134
|
close_ctl( ctl )
|
1102
1135
|
end
|
1103
1136
|
end
|
@@ -1114,7 +1147,7 @@ module Girl
|
|
1114
1147
|
src_info = @src_infos[ src ]
|
1115
1148
|
|
1116
1149
|
begin
|
1117
|
-
data = src.read_nonblock(
|
1150
|
+
data = src.read_nonblock( CHUNK_SIZE )
|
1118
1151
|
rescue IO::WaitReadable
|
1119
1152
|
print 'r'
|
1120
1153
|
return
|
@@ -1176,7 +1209,7 @@ module Girl
|
|
1176
1209
|
src = dst_info[ :src ]
|
1177
1210
|
|
1178
1211
|
begin
|
1179
|
-
data = dst.read_nonblock(
|
1212
|
+
data = dst.read_nonblock( CHUNK_SIZE )
|
1180
1213
|
rescue IO::WaitReadable
|
1181
1214
|
print 'r'
|
1182
1215
|
return
|
@@ -1341,6 +1374,12 @@ module Girl
|
|
1341
1374
|
|
1342
1375
|
dst_info = @dst_infos[ dst ]
|
1343
1376
|
src = dst_info[ :src ]
|
1377
|
+
src_info = @src_infos[ src ]
|
1378
|
+
|
1379
|
+
unless src.closed? then
|
1380
|
+
src_info[ :dst_connected ] = true
|
1381
|
+
end
|
1382
|
+
|
1344
1383
|
data = dst_info[ :wbuff ]
|
1345
1384
|
|
1346
1385
|
# 写前为空,处理关闭写
|
@@ -1371,7 +1410,6 @@ module Girl
|
|
1371
1410
|
dst_info[ :wbuff ] = data
|
1372
1411
|
|
1373
1412
|
unless src.closed? then
|
1374
|
-
src_info = @src_infos[ src ]
|
1375
1413
|
src_info[ :last_sent_at ] = Time.new
|
1376
1414
|
end
|
1377
1415
|
end
|
data/lib/girl/resolvd_worker.rb
CHANGED
@@ -16,7 +16,7 @@ module Girl
|
|
16
16
|
dotr, dotw = IO.pipe
|
17
17
|
@dotw = dotw
|
18
18
|
add_read( dotr, :dotr )
|
19
|
-
|
19
|
+
new_resolvds( resolvd_port )
|
20
20
|
end
|
21
21
|
|
22
22
|
##
|
@@ -111,13 +111,14 @@ module Girl
|
|
111
111
|
##
|
112
112
|
# new a dst
|
113
113
|
#
|
114
|
-
def new_a_dst( src_addr, data )
|
114
|
+
def new_a_dst( resolvd, src_addr, data )
|
115
115
|
dst = Socket.new( Socket::AF_INET, Socket::SOCK_DGRAM, 0 )
|
116
116
|
dst.setsockopt( Socket::SOL_SOCKET, Socket::SO_REUSEPORT, 1 )
|
117
117
|
dst.bind( Socket.sockaddr_in( 0, '0.0.0.0' ) )
|
118
118
|
|
119
119
|
puts "p#{ Process.pid } #{ Time.new } new a dst"
|
120
120
|
@dst_infos[ dst ] = {
|
121
|
+
resolvd: resolvd,
|
121
122
|
src_addr: src_addr,
|
122
123
|
created_at: Time.new
|
123
124
|
}
|
@@ -126,16 +127,18 @@ module Girl
|
|
126
127
|
end
|
127
128
|
|
128
129
|
##
|
129
|
-
# new
|
130
|
+
# new resolvds
|
130
131
|
#
|
131
|
-
def
|
132
|
-
|
133
|
-
|
134
|
-
|
135
|
-
|
136
|
-
|
137
|
-
|
138
|
-
|
132
|
+
def new_resolvds( resolvd_port )
|
133
|
+
10.times do
|
134
|
+
resolvd = Socket.new( Socket::AF_INET, Socket::SOCK_DGRAM, 0 )
|
135
|
+
resolvd.setsockopt( Socket::SOL_SOCKET, Socket::SO_REUSEPORT, 1 )
|
136
|
+
resolvd.bind( Socket.sockaddr_in( resolvd_port, '0.0.0.0' ) )
|
137
|
+
|
138
|
+
puts "p#{ Process.pid } #{ Time.new } resolvd bind on #{ resolvd_port }"
|
139
|
+
add_read( resolvd, :resolvd )
|
140
|
+
resolvd_port += 1
|
141
|
+
end
|
139
142
|
end
|
140
143
|
|
141
144
|
##
|
@@ -162,7 +165,7 @@ module Girl
|
|
162
165
|
# read dotr
|
163
166
|
#
|
164
167
|
def read_dotr( dotr )
|
165
|
-
dotr.read_nonblock(
|
168
|
+
dotr.read_nonblock( READ_SIZE )
|
166
169
|
|
167
170
|
if @closing_dsts.any? then
|
168
171
|
@closing_dsts.each { | dst | close_dst( dst ) }
|
@@ -177,7 +180,7 @@ module Girl
|
|
177
180
|
data, addrinfo, rflags, *controls = resolvd.recvmsg
|
178
181
|
# puts "debug1 resolvd recvmsg #{ addrinfo.ip_unpack.inspect } #{ data.inspect }"
|
179
182
|
data = @custom.decode( data )
|
180
|
-
new_a_dst( addrinfo.to_sockaddr, data )
|
183
|
+
new_a_dst( resolvd, addrinfo.to_sockaddr, data )
|
181
184
|
end
|
182
185
|
|
183
186
|
##
|
@@ -188,7 +191,7 @@ module Girl
|
|
188
191
|
# puts "debug1 dst recvmsg #{ addrinfo.ip_unpack.inspect } #{ data.inspect }"
|
189
192
|
dst_info = @dst_infos[ dst ]
|
190
193
|
data = @custom.encode( data )
|
191
|
-
send_data(
|
194
|
+
send_data( dst_info[ :resolvd ], dst_info[ :src_addr ], data )
|
192
195
|
close_dst( dst )
|
193
196
|
end
|
194
197
|
|
data/lib/girl/ssl_worker.rb
CHANGED
@@ -244,7 +244,7 @@ module Girl
|
|
244
244
|
redir.close
|
245
245
|
@roles.delete( redir )
|
246
246
|
@reads.delete( redir )
|
247
|
-
@src_infos.each { | src
|
247
|
+
@src_infos.keys.each { | src | close_src( src ) }
|
248
248
|
end
|
249
249
|
|
250
250
|
##
|
@@ -340,9 +340,21 @@ module Girl
|
|
340
340
|
@src_infos.each do | src, src_info |
|
341
341
|
last_recv_at = src_info[ :last_recv_at ] || src_info[ :created_at ]
|
342
342
|
last_sent_at = src_info[ :last_sent_at ] || src_info[ :created_at ]
|
343
|
-
expire_after = src_info[ :dst ] ? EXPIRE_AFTER : EXPIRE_NEW
|
344
343
|
|
345
|
-
if
|
344
|
+
if src_info[ :dst ] then
|
345
|
+
if src_info[ :dst_connected ] then
|
346
|
+
expire_after = EXPIRE_AFTER
|
347
|
+
is_expire = ( now - last_recv_at >= expire_after ) && ( now - last_sent_at >= expire_after )
|
348
|
+
else
|
349
|
+
expire_after = EXPIRE_CONNECTING
|
350
|
+
is_expire = ( now - src_info[ :dst_created_at ] >= expire_after )
|
351
|
+
end
|
352
|
+
else
|
353
|
+
expire_after = EXPIRE_NEW
|
354
|
+
is_expire = ( now - last_recv_at >= expire_after ) && ( now - last_sent_at >= expire_after )
|
355
|
+
end
|
356
|
+
|
357
|
+
if is_expire then
|
346
358
|
puts "p#{ Process.pid } #{ Time.new } expire src #{ expire_after } #{ src_info[ :id ] } #{ src_info[ :destination_domain ] }"
|
347
359
|
add_closing_src( src )
|
348
360
|
|
@@ -370,7 +382,7 @@ module Girl
|
|
370
382
|
if dst && !dst.closed? then
|
371
383
|
dst_info = @dst_infos[ dst ]
|
372
384
|
|
373
|
-
if dst_info[ :wbuff ].
|
385
|
+
if dst_info[ :wbuff ].bytesize < RESUME_BELOW then
|
374
386
|
puts "p#{ Process.pid } #{ Time.new } resume direct src #{ src_info[ :destination_domain ] }"
|
375
387
|
add_resume_src( src )
|
376
388
|
end
|
@@ -384,7 +396,7 @@ module Girl
|
|
384
396
|
if src && !src.closed? then
|
385
397
|
src_info = @src_infos[ src ]
|
386
398
|
|
387
|
-
if src_info[ :wbuff ].
|
399
|
+
if src_info[ :wbuff ].bytesize < RESUME_BELOW then
|
388
400
|
puts "p#{ Process.pid } #{ Time.new } resume dst #{ dst_info[ :domain ] }"
|
389
401
|
add_resume_dst( dst )
|
390
402
|
end
|
@@ -403,13 +415,14 @@ module Girl
|
|
403
415
|
domain = src_info[ :destination_domain ]
|
404
416
|
destination_addr = Socket.sockaddr_in( src_info[ :destination_port ], ip_info.ip_address )
|
405
417
|
dst = Socket.new( ip_info.ipv4? ? Socket::AF_INET : Socket::AF_INET6, Socket::SOCK_STREAM, 0 )
|
418
|
+
dst.setsockopt( Socket::IPPROTO_TCP, Socket::TCP_NODELAY, 1 )
|
406
419
|
|
407
420
|
begin
|
408
421
|
dst.connect_nonblock( destination_addr )
|
409
422
|
rescue IO::WaitWritable
|
410
423
|
# connect nonblock 必抛 wait writable
|
411
424
|
rescue Exception => e
|
412
|
-
puts "p#{ Process.pid } #{ Time.new } dst connect destination #{ domain } #{ src_info[ :destination_port ] } #{ ip_info.ip_address } #{ e.class }
|
425
|
+
puts "p#{ Process.pid } #{ Time.new } dst connect destination #{ domain } #{ src_info[ :destination_port ] } #{ ip_info.ip_address } #{ e.class }"
|
413
426
|
dst.close
|
414
427
|
add_closing_src( src )
|
415
428
|
return
|
@@ -424,10 +437,12 @@ module Girl
|
|
424
437
|
}
|
425
438
|
|
426
439
|
@dst_infos[ dst ] = dst_info
|
427
|
-
add_read( dst, :dst )
|
428
440
|
src_info[ :proxy_type ] = :direct
|
429
441
|
src_info[ :dst ] = dst
|
442
|
+
src_info[ :dst_created_at ] = Time.new
|
430
443
|
add_socks5_conn_reply( src )
|
444
|
+
add_read( dst, :dst )
|
445
|
+
add_write( dst )
|
431
446
|
end
|
432
447
|
|
433
448
|
##
|
@@ -435,6 +450,7 @@ module Girl
|
|
435
450
|
#
|
436
451
|
def new_a_redir
|
437
452
|
pre = Socket.new( Socket::AF_INET, Socket::SOCK_STREAM, 0 )
|
453
|
+
pre.setsockopt( Socket::IPPROTO_TCP, Socket::TCP_NODELAY, 1 )
|
438
454
|
pre.setsockopt( Socket::SOL_SOCKET, Socket::SO_REUSEADDR, 1 )
|
439
455
|
pre.setsockopt( Socket::SOL_SOCKET, Socket::SO_REUSEPORT, 1 )
|
440
456
|
pre.bind( Socket.sockaddr_in( @redir_port, '0.0.0.0' ) )
|
@@ -534,7 +550,7 @@ module Girl
|
|
534
550
|
# read dotr
|
535
551
|
#
|
536
552
|
def read_dotr( dotr )
|
537
|
-
dotr.read_nonblock(
|
553
|
+
dotr.read_nonblock( READ_SIZE )
|
538
554
|
|
539
555
|
if @closing_srcs.any? then
|
540
556
|
@closing_srcs.each { | src | close_src( src ) }
|
@@ -599,6 +615,8 @@ module Girl
|
|
599
615
|
is_connect: true, # 代理协议是http的场合,是否是CONNECT
|
600
616
|
rbuff: '', # 读到的流量
|
601
617
|
dst: nil, # 对应的dst
|
618
|
+
dst_created_at: nil, # 对应的dst的创建时间
|
619
|
+
dst_connected: false, # 对应的dst是否已连接
|
602
620
|
wbuff: '', # 从dst读到的流量
|
603
621
|
created_at: Time.new, # 创建时间
|
604
622
|
last_recv_at: nil, # 上一次收到新流量(由dst收到)的时间
|
@@ -623,7 +641,7 @@ module Girl
|
|
623
641
|
src_info = @src_infos[ src ]
|
624
642
|
|
625
643
|
begin
|
626
|
-
data = src.read_nonblock(
|
644
|
+
data = src.read_nonblock( READ_SIZE )
|
627
645
|
rescue IO::WaitReadable
|
628
646
|
return
|
629
647
|
rescue Errno::EINTR => e
|
@@ -741,7 +759,7 @@ module Girl
|
|
741
759
|
src = dst_info[ :src ]
|
742
760
|
|
743
761
|
begin
|
744
|
-
data = dst.read_nonblock(
|
762
|
+
data = dst.read_nonblock( READ_SIZE )
|
745
763
|
rescue IO::WaitReadable, Errno::EINTR
|
746
764
|
print 'r'
|
747
765
|
return
|
@@ -812,6 +830,12 @@ module Girl
|
|
812
830
|
|
813
831
|
dst_info = @dst_infos[ dst ]
|
814
832
|
src = dst_info[ :src ]
|
833
|
+
src_info = @src_infos[ src ]
|
834
|
+
|
835
|
+
unless src.closed? then
|
836
|
+
src_info[ :dst_connected ] = true
|
837
|
+
end
|
838
|
+
|
815
839
|
data = dst_info[ :wbuff ]
|
816
840
|
|
817
841
|
# 写前为空,处理关闭写
|
@@ -842,7 +866,6 @@ module Girl
|
|
842
866
|
dst_info[ :wbuff ] = data
|
843
867
|
|
844
868
|
unless src.closed? then
|
845
|
-
src_info = @src_infos[ src ]
|
846
869
|
src_info[ :last_sent_at ] = Time.new
|
847
870
|
end
|
848
871
|
end
|
data/lib/girl/version.rb
CHANGED
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: girl
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 4.
|
4
|
+
version: 4.8.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- takafan
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2021-04-
|
11
|
+
date: 2021-04-22 00:00:00.000000000 Z
|
12
12
|
dependencies: []
|
13
13
|
description: escape evil.
|
14
14
|
email:
|
@@ -55,7 +55,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
55
55
|
- !ruby/object:Gem::Version
|
56
56
|
version: '0'
|
57
57
|
requirements: []
|
58
|
-
rubygems_version: 3.2.
|
58
|
+
rubygems_version: 3.2.3
|
59
59
|
signing_key:
|
60
60
|
specification_version: 4
|
61
61
|
summary: 妹子
|