girl 4.4.0 → 4.9.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.

@@ -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
- @resolvd_addr = Socket.sockaddr_in( resolvd_port, proxyd_host )
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
- @proxyd_addr = Socket.sockaddr_in( proxyd_port, proxyd_host )
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 ( ( @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
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 >= EXPIRE_AFTER then
524
- puts "p#{ Process.pid } #{ Time.new } expire ctl"
525
- @ctl_info[ :closing ] = true
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 ( now - last_recv_at >= expire_after ) && ( now - last_sent_at >= expire_after ) then
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 ].size < RESUME_BELOW then
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 ].size < RESUME_BELOW then
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 ].size < RESUME_BELOW then
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 ].size < RESUME_BELOW then
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
 
@@ -651,15 +665,22 @@ module Girl
651
665
  src_info = @src_infos[ src ]
652
666
  domain = src_info[ :destination_domain ]
653
667
  destination_addr = Socket.sockaddr_in( src_info[ :destination_port ], ip_info.ip_address )
654
- dst = Socket.new( ip_info.ipv4? ? Socket::AF_INET : Socket::AF_INET6, Socket::SOCK_STREAM, 0 )
655
- dst.setsockopt( Socket::SOL_TCP, Socket::TCP_NODELAY, 1 )
668
+
669
+ begin
670
+ dst = Socket.new( ip_info.ipv4? ? Socket::AF_INET : Socket::AF_INET6, Socket::SOCK_STREAM, 0 )
671
+ rescue Exception => e
672
+ puts "p#{ Process.pid } #{ Time.new } new a dst #{ src_info[ :destination_domain ] } #{ src_info[ :destination_port ] } #{ e.class }"
673
+ add_closing_src( src )
674
+ return
675
+ end
676
+
677
+ dst.setsockopt( Socket::IPPROTO_TCP, Socket::TCP_NODELAY, 1 )
656
678
 
657
679
  begin
658
680
  dst.connect_nonblock( destination_addr )
659
681
  rescue IO::WaitWritable
660
- # connect nonblock 必抛 wait writable
661
682
  rescue Exception => e
662
- puts "p#{ Process.pid } #{ Time.new } dst connect destination #{ domain } #{ src_info[ :destination_port ] } #{ ip_info.ip_address } #{ e.class }, close src"
683
+ puts "p#{ Process.pid } #{ Time.new } dst connect destination #{ domain } #{ src_info[ :destination_port ] } #{ ip_info.ip_address } #{ e.class }"
663
684
  dst.close
664
685
  add_closing_src( src )
665
686
  return
@@ -674,15 +695,17 @@ module Girl
674
695
  }
675
696
 
676
697
  @dst_infos[ dst ] = dst_info
677
- add_read( dst, :dst )
678
698
  src_info[ :proxy_type ] = :direct
679
699
  src_info[ :dst ] = dst
700
+ src_info[ :dst_created_at ] = Time.new
680
701
 
681
702
  if src_info[ :rbuff ] then
682
703
  # puts "debug move src.rbuff to dst.wbuff"
683
704
  dst_info[ :wbuff ] << src_info[ :rbuff ]
684
- add_write( dst )
685
705
  end
706
+
707
+ add_read( dst, :dst )
708
+ add_write( dst )
686
709
  end
687
710
 
688
711
  ##
@@ -698,7 +721,10 @@ module Girl
698
721
  @ctl = ctl
699
722
  add_read( ctl, :ctl )
700
723
 
724
+ ctld_port = @proxyd_port + 10.times.to_a.sample
725
+ ctld_addr = Socket.sockaddr_in( ctld_port, @proxyd_host )
701
726
  @ctl_info = {
727
+ ctld_addr: ctld_addr, # ctld地址
702
728
  resends: ConcurrentHash.new, # key => count
703
729
  atund_addr: nil, # atund地址,src->dst
704
730
  btund_addr: nil, # btund地址,dst->src
@@ -708,7 +734,7 @@ module Girl
708
734
  }
709
735
 
710
736
  hello = @custom.hello
711
- puts "p#{ Process.pid } #{ Time.new } hello i'm #{ hello.inspect }"
737
+ puts "p#{ Process.pid } #{ Time.new } hello i'm #{ hello.inspect } #{ ctld_port }"
712
738
  key = [ HELLO ].pack( 'C' )
713
739
  add_ctlmsg( key, hello )
714
740
  end
@@ -718,6 +744,7 @@ module Girl
718
744
  #
719
745
  def new_a_redir( redir_port )
720
746
  redir = Socket.new( Socket::AF_INET, Socket::SOCK_STREAM, 0 )
747
+ redir.setsockopt( Socket::IPPROTO_TCP, Socket::TCP_NODELAY, 1 )
721
748
  redir.setsockopt( Socket::SOL_SOCKET, Socket::SO_REUSEADDR, 1 )
722
749
  redir.setsockopt( Socket::SOL_SOCKET, Socket::SO_REUSEPORT, 1 )
723
750
  redir.bind( Socket.sockaddr_in( redir_port, '0.0.0.0' ) )
@@ -751,12 +778,12 @@ module Girl
751
778
 
752
779
  if @qnames.any? { | qname | data.include?( qname ) } then
753
780
  data = @custom.encode( data )
754
- to_addr = @resolvd_addr
781
+ to_addr = Socket.sockaddr_in( @resolvd_ports.sample, @proxyd_host )
755
782
  else
756
783
  to_addr = @nameserver_addr
757
784
  end
758
785
 
759
- puts "p#{ Process.pid } #{ Time.new } new a rsv to #{ Addrinfo.new( to_addr ).inspect }"
786
+ # puts "debug new a rsv to #{ Addrinfo.new( to_addr ).inspect }"
760
787
 
761
788
  @rsv_infos[ rsv ] = {
762
789
  src_addr: src_addr,
@@ -778,23 +805,25 @@ module Girl
778
805
 
779
806
  # puts "debug new atun and btun"
780
807
  atun = Socket.new( Socket::AF_INET, Socket::SOCK_STREAM, 0 )
808
+ atun.setsockopt( Socket::IPPROTO_TCP, Socket::TCP_NODELAY, 1 )
781
809
 
782
810
  begin
783
811
  atun.connect_nonblock( @ctl_info[ :atund_addr ] )
784
812
  rescue IO::WaitWritable
785
813
  rescue Exception => e
786
- puts "p#{ Process.pid } #{ Time.new } connect atund #{ e.class }, close atun"
814
+ puts "p#{ Process.pid } #{ Time.new } connect atund #{ e.class }"
787
815
  atun.close
788
816
  return
789
817
  end
790
818
 
791
819
  btun = Socket.new( Socket::AF_INET, Socket::SOCK_STREAM, 0 )
820
+ btun.setsockopt( Socket::IPPROTO_TCP, Socket::TCP_NODELAY, 1 )
792
821
 
793
822
  begin
794
823
  btun.connect_nonblock( @ctl_info[ :btund_addr ] )
795
824
  rescue IO::WaitWritable
796
825
  rescue Exception => e
797
- puts "p#{ Process.pid } #{ Time.new } connect btund #{ e.class }, close btun"
826
+ puts "p#{ Process.pid } #{ Time.new } connect btund #{ e.class }"
798
827
  btun.close
799
828
  return
800
829
  end
@@ -803,7 +832,7 @@ module Girl
803
832
  atun_wbuff = [ dst_id ].pack( 'n' )
804
833
 
805
834
  until src_info[ :rbuff ].empty? do
806
- data = src_info[ :rbuff ][ 0, 65535 ]
835
+ data = src_info[ :rbuff ][ 0, CHUNK_SIZE ]
807
836
  data_size = data.bytesize
808
837
  # puts "debug move src.rbuff #{ data_size } to atun.wbuff"
809
838
  atun_wbuff << pack_a_chunk( data )
@@ -861,7 +890,7 @@ module Girl
861
890
  data = @custom.encode( data )
862
891
 
863
892
  begin
864
- @ctl.sendmsg( data, 0, @proxyd_addr )
893
+ @ctl.sendmsg( data, 0, @ctl_info[ :ctld_addr ] )
865
894
  @ctl_info[ :last_sent_at ] = Time.new
866
895
  rescue Exception => e
867
896
  puts "p#{ Process.pid } #{ Time.new } sendmsg #{ e.class }"
@@ -869,6 +898,17 @@ module Girl
869
898
  end
870
899
  end
871
900
 
901
+ ##
902
+ # send data
903
+ #
904
+ def send_data( sock, to_addr, data )
905
+ begin
906
+ sock.sendmsg( data, 0, to_addr )
907
+ rescue Exception => e
908
+ puts "p#{ Process.pid } #{ Time.new } sendmsg to #{ to_addr.ip_unpack.inspect } #{ e.class }"
909
+ end
910
+ end
911
+
872
912
  ##
873
913
  # set atun closing
874
914
  #
@@ -882,14 +922,12 @@ module Girl
882
922
  end
883
923
 
884
924
  ##
885
- # send data
925
+ # set ctl closing
886
926
  #
887
- def send_data( sock, to_addr, data )
888
- begin
889
- sock.sendmsg( data, 0, to_addr )
890
- rescue Exception => e
891
- puts "p#{ Process.pid } #{ Time.new } sendmsg to #{ to_addr.ip_unpack.inspect } #{ e.class }"
892
- end
927
+ def set_ctl_closing
928
+ return if @ctl.closed?
929
+ @ctl_info[ :closing ] = true
930
+ next_tick
893
931
  end
894
932
 
895
933
  ##
@@ -934,7 +972,7 @@ module Girl
934
972
  # read dotr
935
973
  #
936
974
  def read_dotr( dotr )
937
- dotr.read_nonblock( 65535 )
975
+ dotr.read_nonblock( READ_SIZE )
938
976
 
939
977
  if @ctl_info && @ctl_info[ :closing ] then
940
978
  send_ctlmsg( [ CTL_FIN ].pack( 'C' ) )
@@ -995,7 +1033,7 @@ module Girl
995
1033
  data, addrinfo, rflags, *controls = rsv.recvmsg
996
1034
  # puts "debug rsv recvmsg #{ addrinfo.ip_unpack.inspect } #{ data.inspect }"
997
1035
 
998
- if addrinfo.to_sockaddr == @resolvd_addr then
1036
+ if addrinfo.ip_address == @proxyd_host then
999
1037
  data = @custom.decode( data )
1000
1038
  end
1001
1039
 
@@ -1039,6 +1077,8 @@ module Girl
1039
1077
  destination_port: dest_port, # 目的地端口
1040
1078
  rbuff: '', # 读到的流量
1041
1079
  dst: nil, # :direct的场合,对应的dst
1080
+ dst_created_at: nil, # :direct的场合,对应的dst的创建时间
1081
+ dst_connected: false, # :direct的场合,对应的dst是否已连接
1042
1082
  ctl: nil, # :tunnel的场合,对应的ctl
1043
1083
  atun: nil, # :tunnel的场合,对应的atun
1044
1084
  btun: nil, # :tunnel的场合,对应的btun
@@ -1076,7 +1116,7 @@ module Girl
1076
1116
 
1077
1117
  case ctl_num
1078
1118
  when TUND_PORT then
1079
- return if @ctl_info[ :atund_addr ] || data.size != 5
1119
+ return if @ctl_info[ :atund_addr ] || data.bytesize != 5
1080
1120
  atund_port, btund_port = data[ 1, 4 ].unpack( 'nn' )
1081
1121
  puts "p#{ Process.pid } #{ Time.new } got tund port #{ atund_port } #{ btund_port }"
1082
1122
  @ctl_info[ :resends ].delete( [ HELLO ].pack( 'C' ) )
@@ -1090,14 +1130,14 @@ module Girl
1090
1130
  @pending_srcs.clear
1091
1131
  end
1092
1132
  when PAIRED then
1093
- return if data.size != 11
1133
+ return if data.bytesize != 11
1094
1134
  src_id, dst_id = data[ 1, 10 ].unpack( 'Q>n' )
1095
1135
  # puts "debug got paired #{ src_id } #{ dst_id }"
1096
1136
  @ctl_info[ :resends ].delete( [ A_NEW_SOURCE, src_id ].pack( 'CQ>' ) )
1097
1137
  @ctl_info[ :last_recv_at ] = Time.new
1098
1138
  new_tuns( src_id, dst_id )
1099
1139
  when UNKNOWN_CTL_ADDR then
1100
- puts "p#{ Process.pid } #{ Time.new } got unknown ctl addr, close ctl"
1140
+ puts "p#{ Process.pid } #{ Time.new } got unknown ctl addr"
1101
1141
  close_ctl( ctl )
1102
1142
  end
1103
1143
  end
@@ -1114,7 +1154,7 @@ module Girl
1114
1154
  src_info = @src_infos[ src ]
1115
1155
 
1116
1156
  begin
1117
- data = src.read_nonblock( 65535 )
1157
+ data = src.read_nonblock( CHUNK_SIZE )
1118
1158
  rescue IO::WaitReadable
1119
1159
  print 'r'
1120
1160
  return
@@ -1176,7 +1216,7 @@ module Girl
1176
1216
  src = dst_info[ :src ]
1177
1217
 
1178
1218
  begin
1179
- data = dst.read_nonblock( 65535 )
1219
+ data = dst.read_nonblock( CHUNK_SIZE )
1180
1220
  rescue IO::WaitReadable
1181
1221
  print 'r'
1182
1222
  return
@@ -1341,6 +1381,12 @@ module Girl
1341
1381
 
1342
1382
  dst_info = @dst_infos[ dst ]
1343
1383
  src = dst_info[ :src ]
1384
+ src_info = @src_infos[ src ]
1385
+
1386
+ unless src.closed? then
1387
+ src_info[ :dst_connected ] = true
1388
+ end
1389
+
1344
1390
  data = dst_info[ :wbuff ]
1345
1391
 
1346
1392
  # 写前为空,处理关闭写
@@ -1371,7 +1417,6 @@ module Girl
1371
1417
  dst_info[ :wbuff ] = data
1372
1418
 
1373
1419
  unless src.closed? then
1374
- src_info = @src_infos[ src ]
1375
1420
  src_info[ :last_sent_at ] = Time.new
1376
1421
  end
1377
1422
  end
@@ -16,7 +16,7 @@ module Girl
16
16
  dotr, dotw = IO.pipe
17
17
  @dotw = dotw
18
18
  add_read( dotr, :dotr )
19
- new_a_resolvd( resolvd_port )
19
+ new_resolvds( resolvd_port )
20
20
  end
21
21
 
22
22
  ##
@@ -49,7 +49,7 @@ module Girl
49
49
  # quit!
50
50
  #
51
51
  def quit!
52
- # puts "debug1 exit"
52
+ # puts "debug exit"
53
53
  exit
54
54
  end
55
55
 
@@ -82,7 +82,7 @@ module Girl
82
82
  # close dst
83
83
  #
84
84
  def close_dst( dst )
85
- # puts "debug1 close dst"
85
+ # puts "debug close dst"
86
86
  dst.close
87
87
  @reads.delete( dst )
88
88
  @roles.delete( dst )
@@ -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
- puts "p#{ Process.pid } #{ Time.new } new a dst"
119
+ # puts "debug 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 a resolvd
130
+ # new resolvds
130
131
  #
131
- def new_a_resolvd( resolvd_port )
132
- resolvd = Socket.new( Socket::AF_INET, Socket::SOCK_DGRAM, 0 )
133
- resolvd.setsockopt( Socket::SOL_SOCKET, Socket::SO_REUSEPORT, 1 )
134
- resolvd.bind( Socket.sockaddr_in( resolvd_port, '0.0.0.0' ) )
135
-
136
- puts "p#{ Process.pid } #{ Time.new } resolvd bind on #{ resolvd_port }"
137
- add_read( resolvd, :resolvd )
138
- @resolvd = resolvd
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( 65535 )
168
+ dotr.read_nonblock( READ_SIZE )
166
169
 
167
170
  if @closing_dsts.any? then
168
171
  @closing_dsts.each { | dst | close_dst( dst ) }
@@ -175,9 +178,9 @@ module Girl
175
178
  #
176
179
  def read_resolvd( resolvd )
177
180
  data, addrinfo, rflags, *controls = resolvd.recvmsg
178
- # puts "debug1 resolvd recvmsg #{ addrinfo.ip_unpack.inspect } #{ data.inspect }"
181
+ # puts "debug 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
  ##
@@ -185,10 +188,10 @@ module Girl
185
188
  #
186
189
  def read_dst( dst )
187
190
  data, addrinfo, rflags, *controls = dst.recvmsg
188
- # puts "debug1 dst recvmsg #{ addrinfo.ip_unpack.inspect } #{ data.inspect }"
191
+ # puts "debug dst recvmsg #{ addrinfo.ip_unpack.inspect } #{ data.inspect }"
189
192
  dst_info = @dst_infos[ dst ]
190
193
  data = @custom.encode( data )
191
- send_data( @resolvd, dst_info[ :src_addr ], data )
194
+ send_data( dst_info[ :resolvd ], dst_info[ :src_addr ], data )
192
195
  close_dst( dst )
193
196
  end
194
197