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.

checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: d7b905d2180abe835d892f44038fdf2f96b6710ad942fa2d762a2484430ea48f
4
- data.tar.gz: d0a95baf185ce66219c7ce783c975d5bdd4bd9e00273ae77842f70697301ac40
3
+ metadata.gz: 011aa472a00bf6cb2d5c73af7f5a9f685897bcafa782cb5080c53f830775738a
4
+ data.tar.gz: 05a8c74a0a96a65f77432c2b64fe384283ed0a15178f4e09f820ce1b2d82f706
5
5
  SHA512:
6
- metadata.gz: 6659b516924a9a43be0b7cf9c3d85ae8bda57e22d131089ae295f24ca7247d628e7d8fc795e6625cadac81a785b6390ae1ec3e170a42d5c3403e023879ff11ea
7
- data.tar.gz: 6800db65291e870d6a87c3b22328a9415210c73b8535d5077609f0a957901a05f6832e621321ad9b5f2e78c609c640f1fe18ad8321e44ee195a4af7da2b62239
6
+ metadata.gz: 10e71a4842eb5ab95edb29411607502e073ae0c7f7f371163d42d9ac85dcb5fcda39363c572ddef67565e6eefa17706f836bec0eb48c16f31422d34838691277
7
+ data.tar.gz: facd9596a3518f80d587e436cbbb8fe76da4f7be6657b75d40cf076b11fa4f92c8ea0cb1fde9d8c0a496c3e8667d231a29e47da0ae463cf2a2d06e53ef8f1c07
data/girl.gemspec CHANGED
@@ -31,8 +31,6 @@ lib/girl/relay.rb
31
31
  lib/girl/resolv_custom.rb
32
32
  lib/girl/resolvd_worker.rb
33
33
  lib/girl/resolvd.rb
34
- lib/girl/ssl_worker.rb
35
- lib/girl/ssl.rb
36
34
  lib/girl/version.rb
37
35
  ]
38
36
 
data/lib/girl/head.rb CHANGED
@@ -1,13 +1,15 @@
1
1
  module Girl
2
- READ_SIZE = 1024 * 1024 # atun, btun一次读多少
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
- EXPIRE_AFTER = 300 # 多久没有新流量,过期
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 = 5 # 检查过期间隔
12
+ CHECK_EXPIRE_INTERVAL = 1 # 检查过期间隔
11
13
  CHECK_RESUME_INTERVAL = 1 # 检查恢复读间隔
12
14
  RESOLV_CACHE_EXPIRE = 300 # dns查询结果缓存多久过期
13
15
  RESEND_LIMIT = 5 # ctlmsg重传次数
@@ -47,12 +49,15 @@ module Girl
47
49
  172.16.0.0/12
48
50
  192.168.0.0/16
49
51
  255.255.255.255/32
52
+ ::1
50
53
  EOF
51
54
  CONSTS = %w[
52
55
  READ_SIZE
53
56
  WBUFF_LIMIT
54
57
  RESUME_BELOW
58
+ CHUNK_SIZE
55
59
  EXPIRE_NEW
60
+ EXPIRE_CONNECTING
56
61
  EXPIRE_AFTER
57
62
  EXPIRE_CTL
58
63
  RESET_TRAFF_DAY
@@ -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 ( ( @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
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 >= EXPIRE_AFTER then
511
- puts "p#{ Process.pid } #{ Time.new } expire ctl"
512
- @ctl_info[ :closing ] = true
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 ( now - last_recv_at >= expire_after ) && ( now - last_sent_at >= expire_after ) then
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 ].size < RESUME_BELOW then
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 ].size < RESUME_BELOW then
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 ].size < RESUME_BELOW then
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 ].size < RESUME_BELOW then
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
 
@@ -631,14 +644,22 @@ module Girl
631
644
  src_info = @src_infos[ src ]
632
645
  domain = src_info[ :destination_domain ]
633
646
  destination_addr = Socket.sockaddr_in( src_info[ :destination_port ], ip_info.ip_address )
634
- dst = Socket.new( ip_info.ipv4? ? Socket::AF_INET : Socket::AF_INET6, Socket::SOCK_STREAM, 0 )
647
+
648
+ begin
649
+ dst = Socket.new( ip_info.ipv4? ? Socket::AF_INET : Socket::AF_INET6, Socket::SOCK_STREAM, 0 )
650
+ rescue Exception => e
651
+ puts "p#{ Process.pid } #{ Time.new } new a dst #{ src_info[ :destination_domain ] } #{ src_info[ :destination_port ] } #{ e.class }"
652
+ add_closing_src( src )
653
+ return
654
+ end
655
+
656
+ dst.setsockopt( Socket::IPPROTO_TCP, Socket::TCP_NODELAY, 1 )
635
657
 
636
658
  begin
637
659
  dst.connect_nonblock( destination_addr )
638
660
  rescue IO::WaitWritable
639
- # connect nonblock 必抛 wait writable
640
661
  rescue Exception => e
641
- puts "p#{ Process.pid } #{ Time.new } dst connect destination #{ domain } #{ src_info[ :destination_port ] } #{ ip_info.ip_address } #{ e.class }, close src"
662
+ puts "p#{ Process.pid } #{ Time.new } dst connect destination #{ domain } #{ src_info[ :destination_port ] } #{ ip_info.ip_address } #{ e.class }"
642
663
  dst.close
643
664
  add_closing_src( src )
644
665
  return
@@ -653,9 +674,9 @@ module Girl
653
674
  }
654
675
 
655
676
  @dst_infos[ dst ] = dst_info
656
- add_read( dst, :dst )
657
677
  src_info[ :proxy_type ] = :direct
658
678
  src_info[ :dst ] = dst
679
+ src_info[ :dst_created_at ] = Time.new
659
680
 
660
681
  if src_info[ :proxy_proto ] == :http then
661
682
  if src_info[ :is_connect ] then
@@ -664,11 +685,13 @@ module Girl
664
685
  elsif src_info[ :rbuff ] then
665
686
  # puts "debug move src.rbuff to dst.wbuff"
666
687
  dst_info[ :wbuff ] << src_info[ :rbuff ]
667
- add_write( dst )
668
688
  end
669
689
  elsif src_info[ :proxy_proto ] == :socks5 then
670
690
  add_socks5_conn_reply( src )
671
691
  end
692
+
693
+ add_read( dst, :dst )
694
+ add_write( dst )
672
695
  end
673
696
 
674
697
  ##
@@ -684,7 +707,10 @@ module Girl
684
707
  @ctl = ctl
685
708
  add_read( ctl, :ctl )
686
709
 
710
+ ctld_port = @proxyd_port + 10.times.to_a.sample
711
+ ctld_addr = Socket.sockaddr_in( ctld_port, @proxyd_host )
687
712
  @ctl_info = {
713
+ ctld_addr: ctld_addr, # ctld地址
688
714
  resends: ConcurrentHash.new, # key => count
689
715
  atund_addr: nil, # atund地址,src->dst
690
716
  btund_addr: nil, # btund地址,dst->src
@@ -694,7 +720,7 @@ module Girl
694
720
  }
695
721
 
696
722
  hello = @custom.hello
697
- puts "p#{ Process.pid } #{ Time.new } hello i'm #{ hello.inspect }"
723
+ puts "p#{ Process.pid } #{ Time.new } hello i'm #{ hello.inspect } #{ ctld_port }"
698
724
  key = [ HELLO ].pack( 'C' )
699
725
  add_ctlmsg( key, hello )
700
726
  end
@@ -704,6 +730,7 @@ module Girl
704
730
  #
705
731
  def new_a_redir( redir_port )
706
732
  redir = Socket.new( Socket::AF_INET, Socket::SOCK_STREAM, 0 )
733
+ redir.setsockopt( Socket::IPPROTO_TCP, Socket::TCP_NODELAY, 1 )
707
734
  redir.setsockopt( Socket::SOL_SOCKET, Socket::SO_REUSEADDR, 1 )
708
735
 
709
736
  if RUBY_PLATFORM.include?( 'linux' ) then
@@ -730,23 +757,25 @@ module Girl
730
757
 
731
758
  # puts "debug new atun and btun"
732
759
  atun = Socket.new( Socket::AF_INET, Socket::SOCK_STREAM, 0 )
760
+ atun.setsockopt( Socket::IPPROTO_TCP, Socket::TCP_NODELAY, 1 )
733
761
 
734
762
  begin
735
763
  atun.connect_nonblock( @ctl_info[ :atund_addr ] )
736
764
  rescue IO::WaitWritable
737
765
  rescue Exception => e
738
- puts "p#{ Process.pid } #{ Time.new } connect atund #{ e.class }, close atun"
766
+ puts "p#{ Process.pid } #{ Time.new } connect atund #{ e.class }"
739
767
  atun.close
740
768
  return
741
769
  end
742
770
 
743
771
  btun = Socket.new( Socket::AF_INET, Socket::SOCK_STREAM, 0 )
772
+ btun.setsockopt( Socket::IPPROTO_TCP, Socket::TCP_NODELAY, 1 )
744
773
 
745
774
  begin
746
775
  btun.connect_nonblock( @ctl_info[ :btund_addr ] )
747
776
  rescue IO::WaitWritable
748
777
  rescue Exception => e
749
- puts "p#{ Process.pid } #{ Time.new } connect btund #{ e.class }, close btun"
778
+ puts "p#{ Process.pid } #{ Time.new } connect btund #{ e.class }"
750
779
  btun.close
751
780
  return
752
781
  end
@@ -755,7 +784,7 @@ module Girl
755
784
  atun_wbuff = [ dst_id ].pack( 'n' )
756
785
 
757
786
  until src_info[ :rbuff ].empty? do
758
- data = src_info[ :rbuff ][ 0, 65535 ]
787
+ data = src_info[ :rbuff ][ 0, CHUNK_SIZE ]
759
788
  data_size = data.bytesize
760
789
  # puts "debug move src.rbuff #{ data_size } to atun.wbuff"
761
790
  atun_wbuff << pack_a_chunk( data )
@@ -866,7 +895,7 @@ module Girl
866
895
  data = @custom.encode( data )
867
896
 
868
897
  begin
869
- @ctl.sendmsg( data, 0, @proxyd_addr )
898
+ @ctl.sendmsg( data, 0, @ctl_info[ :ctld_addr ] )
870
899
  @ctl_info[ :last_sent_at ] = Time.new
871
900
  rescue Exception => e
872
901
  puts "p#{ Process.pid } #{ Time.new } sendmsg #{ e.class }"
@@ -886,6 +915,15 @@ module Girl
886
915
  add_write( atun )
887
916
  end
888
917
 
918
+ ##
919
+ # set ctl closing
920
+ #
921
+ def set_ctl_closing
922
+ return if @ctl.closed?
923
+ @ctl_info[ :closing ] = true
924
+ next_tick
925
+ end
926
+
889
927
  ##
890
928
  # set dst closing write
891
929
  #
@@ -929,7 +967,7 @@ module Girl
929
967
  # read dotr
930
968
  #
931
969
  def read_dotr( dotr )
932
- dotr.read_nonblock( 65535 )
970
+ dotr.read_nonblock( READ_SIZE )
933
971
 
934
972
  if @ctl_info && @ctl_info[ :closing ] then
935
973
  send_ctlmsg( [ CTL_FIN ].pack( 'C' ) )
@@ -993,6 +1031,8 @@ module Girl
993
1031
  is_connect: true, # 代理协议是http的场合,是否是CONNECT
994
1032
  rbuff: '', # 读到的流量
995
1033
  dst: nil, # :direct的场合,对应的dst
1034
+ dst_created_at: nil, # :direct的场合,对应的dst的创建时间
1035
+ dst_connected: false, # :direct的场合,对应的dst是否已连接
996
1036
  ctl: nil, # :tunnel的场合,对应的ctl
997
1037
  atun: nil, # :tunnel的场合,对应的atun
998
1038
  btun: nil, # :tunnel的场合,对应的btun
@@ -1028,7 +1068,7 @@ module Girl
1028
1068
 
1029
1069
  case ctl_num
1030
1070
  when TUND_PORT then
1031
- return if @ctl_info[ :atund_addr ] || data.size != 5
1071
+ return if @ctl_info[ :atund_addr ] || data.bytesize != 5
1032
1072
  atund_port, btund_port = data[ 1, 4 ].unpack( 'nn' )
1033
1073
  puts "p#{ Process.pid } #{ Time.new } got tund port #{ atund_port } #{ btund_port }"
1034
1074
  @ctl_info[ :resends ].delete( [ HELLO ].pack( 'C' ) )
@@ -1042,14 +1082,14 @@ module Girl
1042
1082
  @pending_srcs.clear
1043
1083
  end
1044
1084
  when PAIRED then
1045
- return if data.size != 11
1085
+ return if data.bytesize != 11
1046
1086
  src_id, dst_id = data[ 1, 10 ].unpack( 'Q>n' )
1047
1087
  # puts "debug got paired #{ src_id } #{ dst_id }"
1048
1088
  @ctl_info[ :resends ].delete( [ A_NEW_SOURCE, src_id ].pack( 'CQ>' ) )
1049
1089
  @ctl_info[ :last_recv_at ] = Time.new
1050
1090
  new_tuns( src_id, dst_id )
1051
1091
  when UNKNOWN_CTL_ADDR then
1052
- puts "p#{ Process.pid } #{ Time.new } got unknown ctl addr, close ctl"
1092
+ puts "p#{ Process.pid } #{ Time.new } got unknown ctl addr"
1053
1093
  close_ctl( ctl )
1054
1094
  end
1055
1095
  end
@@ -1066,7 +1106,7 @@ module Girl
1066
1106
  src_info = @src_infos[ src ]
1067
1107
 
1068
1108
  begin
1069
- data = src.read_nonblock( 65535 )
1109
+ data = src.read_nonblock( CHUNK_SIZE )
1070
1110
  rescue IO::WaitReadable
1071
1111
  print 'r'
1072
1112
  return
@@ -1167,9 +1207,18 @@ module Girl
1167
1207
  src_info[ :rbuff ] << data
1168
1208
  end
1169
1209
 
1170
- domain, port = domain_port.split( ':' )
1171
- port = port ? port.to_i : 80
1210
+ colon_idx = domain_port.rindex( ':' )
1211
+ close_idx = domain_port.rindex( ']' )
1172
1212
 
1213
+ if colon_idx && ( close_idx.nil? || ( colon_idx > close_idx ) ) then
1214
+ domain = domain_port[ 0...colon_idx ]
1215
+ port = domain_port[ ( colon_idx + 1 )..-1 ].to_i
1216
+ else
1217
+ domain = domain_port
1218
+ port = 80
1219
+ end
1220
+
1221
+ domain = domain.gsub( /\[|\]/, '' )
1173
1222
  src_info[ :proxy_proto ] = :http
1174
1223
  src_info[ :destination_domain ] = domain
1175
1224
  src_info[ :destination_port ] = port
@@ -1210,9 +1259,13 @@ module Girl
1210
1259
  # puts "debug DOMAINNAME #{ domain } #{ port }"
1211
1260
  resolve_domain( src, domain )
1212
1261
  end
1262
+ else
1263
+ puts "p#{ Process.pid } #{ Time.new } socks5 atyp #{ atyp } not implement"
1264
+ add_closing_src( src )
1213
1265
  end
1214
1266
  else
1215
1267
  puts "p#{ Process.pid } #{ Time.new } socks5 cmd #{ cmd } not implement"
1268
+ add_closing_src( src )
1216
1269
  end
1217
1270
  when :tunnel then
1218
1271
  atun = src_info[ :atun ]
@@ -1248,7 +1301,7 @@ module Girl
1248
1301
  src = dst_info[ :src ]
1249
1302
 
1250
1303
  begin
1251
- data = dst.read_nonblock( 65535 )
1304
+ data = dst.read_nonblock( CHUNK_SIZE )
1252
1305
  rescue IO::WaitReadable
1253
1306
  print 'r'
1254
1307
  return
@@ -1413,6 +1466,12 @@ module Girl
1413
1466
 
1414
1467
  dst_info = @dst_infos[ dst ]
1415
1468
  src = dst_info[ :src ]
1469
+ src_info = @src_infos[ src ]
1470
+
1471
+ unless src.closed? then
1472
+ src_info[ :dst_connected ] = true
1473
+ end
1474
+
1416
1475
  data = dst_info[ :wbuff ]
1417
1476
 
1418
1477
  # 写前为空,处理关闭写
@@ -1443,7 +1502,6 @@ module Girl
1443
1502
  dst_info[ :wbuff ] = data
1444
1503
 
1445
1504
  unless src.closed? then
1446
- src_info = @src_infos[ src ]
1447
1505
  src_info[ :last_sent_at ] = Time.new
1448
1506
  end
1449
1507
  end
@@ -28,7 +28,7 @@ module Girl
28
28
  dotr, dotw = IO.pipe
29
29
  @dotw = dotw
30
30
  add_read( dotr, :dotr )
31
- new_a_ctld( proxyd_port )
31
+ new_ctlds( proxyd_port )
32
32
  new_a_infod( infod_port )
33
33
  end
34
34
 
@@ -305,7 +305,14 @@ module Girl
305
305
  # deal with destination addr
306
306
  #
307
307
  def deal_with_destination_addr( ctl_addr, src_id, destination_addr, domain_port )
308
- dst = Socket.new( Addrinfo.new( destination_addr ).ipv4? ? Socket::AF_INET : Socket::AF_INET6, Socket::SOCK_STREAM, 0 )
308
+ begin
309
+ dst = Socket.new( Addrinfo.new( destination_addr ).ipv4? ? Socket::AF_INET : Socket::AF_INET6, Socket::SOCK_STREAM, 0 )
310
+ rescue Exception => e
311
+ puts "p#{ Process.pid } #{ Time.new } new a dst #{ destination_addr.inspect } #{ domain_port } #{ e.class }"
312
+ return
313
+ end
314
+
315
+ dst.setsockopt( Socket::IPPROTO_TCP, Socket::TCP_NODELAY, 1 )
309
316
 
310
317
  begin
311
318
  dst.connect_nonblock( destination_addr )
@@ -324,6 +331,7 @@ module Girl
324
331
  ctl_addr: ctl_addr, # 对应ctl
325
332
  im: ctl_info[ :im ], # 标识
326
333
  domain_port: domain_port, # 目的地和端口
334
+ connected: false, # 是否已连接
327
335
  rbuff: '', # 对应的tun没准备好,暂存读到的流量
328
336
  atun: nil, # 对应的atun
329
337
  btun: nil, # 对应的btun
@@ -336,13 +344,14 @@ module Girl
336
344
  }
337
345
 
338
346
  add_read( dst, :dst )
347
+ add_write( dst )
339
348
 
340
349
  ctl_info[ :dst_ids ][ src_id ] = dst_id
341
350
  ctl_info[ :dsts ][ dst_id ] = dst
342
351
 
343
352
  data = [ PAIRED, src_id, dst_id ].pack( 'CQ>n' )
344
353
  # puts "debug add ctlmsg paired #{ src_id } #{ dst_id }"
345
- send_ctlmsg( data, ctl_addr )
354
+ send_ctlmsg( ctl_info[ :ctld ], data, ctl_addr )
346
355
  end
347
356
 
348
357
  ##
@@ -404,11 +413,17 @@ module Girl
404
413
  end
405
414
 
406
415
  @dst_infos.each do | dst, dst_info |
407
- last_recv_at = dst_info[ :last_recv_at ] || dst_info[ :created_at ]
408
- last_sent_at = dst_info[ :last_sent_at ] || dst_info[ :created_at ]
409
- expire_after = dst_info[ :btun ] ? EXPIRE_AFTER : EXPIRE_NEW
416
+ if dst_info[ :connected ] then
417
+ last_recv_at = dst_info[ :last_recv_at ] || dst_info[ :created_at ]
418
+ last_sent_at = dst_info[ :last_sent_at ] || dst_info[ :created_at ]
419
+ expire_after = EXPIRE_AFTER
420
+ is_expire = ( now - last_recv_at >= expire_after ) && ( now - last_sent_at >= expire_after )
421
+ else
422
+ expire_after = EXPIRE_CONNECTING
423
+ is_expire = ( now - dst_info[ :created_at ] >= expire_after )
424
+ end
410
425
 
411
- if ( now - last_recv_at >= expire_after ) && ( now - last_sent_at >= expire_after ) then
426
+ if is_expire then
412
427
  puts "p#{ Process.pid } #{ Time.new } expire dst #{ expire_after } #{ dst_info[ :domain_port ] }"
413
428
 
414
429
  unless @closing_dsts.include?( dst ) then
@@ -436,7 +451,7 @@ module Girl
436
451
  if btun && !btun.closed? then
437
452
  btun_info = @btun_infos[ btun ]
438
453
 
439
- if btun_info[ :wbuff ].size < RESUME_BELOW then
454
+ if btun_info[ :wbuff ].bytesize < RESUME_BELOW then
440
455
  puts "p#{ Process.pid } #{ Time.new } resume dst #{ dst_info[ :domain_port ] }"
441
456
  add_resume_dst( dst )
442
457
  end
@@ -450,7 +465,7 @@ module Girl
450
465
  if dst && !dst.closed? then
451
466
  dst_info = @dst_infos[ dst ]
452
467
 
453
- if dst_info[ :wbuff ].size < RESUME_BELOW then
468
+ if dst_info[ :wbuff ].bytesize < RESUME_BELOW then
454
469
  puts "p#{ Process.pid } #{ Time.new } resume atun #{ atun_info[ :domain_port ] }"
455
470
  add_resume_atun( atun )
456
471
  end
@@ -479,18 +494,6 @@ module Girl
479
494
  end
480
495
  end
481
496
 
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
497
  ##
495
498
  # new a infod
496
499
  #
@@ -507,11 +510,26 @@ module Girl
507
510
  #
508
511
  def new_a_tund
509
512
  tund = Socket.new( Socket::AF_INET, Socket::SOCK_STREAM, 0 )
513
+ tund.setsockopt( Socket::IPPROTO_TCP, Socket::TCP_NODELAY, 1 )
510
514
  tund.bind( Socket.sockaddr_in( 0, '0.0.0.0' ) )
511
515
  tund.listen( 127 )
512
516
  tund
513
517
  end
514
518
 
519
+ ##
520
+ # new ctlds
521
+ #
522
+ def new_ctlds( proxyd_port )
523
+ 10.times do | i |
524
+ ctld_port = proxyd_port + i
525
+ ctld = Socket.new( Socket::AF_INET, Socket::SOCK_DGRAM, 0 )
526
+ ctld.setsockopt( Socket::SOL_SOCKET, Socket::SO_REUSEPORT, 1 )
527
+ ctld.bind( Socket.sockaddr_in( ctld_port, '0.0.0.0' ) )
528
+ puts "p#{ Process.pid } #{ Time.new } ctld bind on #{ ctld_port }"
529
+ add_read( ctld, :ctld )
530
+ end
531
+ end
532
+
515
533
  ##
516
534
  # next tick
517
535
  #
@@ -571,11 +589,11 @@ module Girl
571
589
  ##
572
590
  # send ctlmsg
573
591
  #
574
- def send_ctlmsg( data, to_addr )
592
+ def send_ctlmsg( ctld, data, to_addr )
575
593
  data = @custom.encode( data )
576
594
 
577
595
  begin
578
- @ctld.sendmsg( data, 0, to_addr )
596
+ ctld.sendmsg( data, 0, to_addr )
579
597
  rescue Exception => e
580
598
  puts "p#{ Process.pid } #{ Time.new } sendmsg #{ e.class }"
581
599
  end
@@ -609,7 +627,7 @@ module Girl
609
627
  # read dotr
610
628
  #
611
629
  def read_dotr( dotr )
612
- dotr.read_nonblock( 65535 )
630
+ dotr.read_nonblock( READ_SIZE )
613
631
 
614
632
  if @deleting_ctl_infos.any? then
615
633
  @deleting_ctl_infos.each { | ctl_addr | del_ctl_info( ctl_addr ) }
@@ -655,7 +673,7 @@ module Girl
655
673
  if ctl_info then
656
674
  atund_port, btund_port = ctl_info[ :atund_port ], ctl_info[ :btund_port ]
657
675
  else
658
- return if data.size <= 1
676
+ return if data.bytesize <= 1
659
677
  im = data[ 1..-1 ]
660
678
  result = @custom.check( im, addrinfo )
661
679
 
@@ -687,6 +705,7 @@ module Girl
687
705
  }
688
706
 
689
707
  @ctl_infos[ ctl_addr ] = {
708
+ ctld: ctld, # 对应的ctld
690
709
  addrinfo: addrinfo, # 地址
691
710
  im: im, # 标识
692
711
  atund: atund, # 对应atund,src->dst
@@ -702,21 +721,21 @@ module Girl
702
721
  end
703
722
 
704
723
  data2 = [ TUND_PORT, atund_port, btund_port ].pack( 'Cnn' )
705
- send_ctlmsg( data2, ctl_addr )
724
+ send_ctlmsg( ctld, data2, ctl_addr )
706
725
  when A_NEW_SOURCE then
707
726
  unless ctl_info then
708
- send_ctlmsg( [ UNKNOWN_CTL_ADDR ].pack( 'C' ), addrinfo )
727
+ send_ctlmsg( ctld, [ UNKNOWN_CTL_ADDR ].pack( 'C' ), addrinfo )
709
728
  return
710
729
  end
711
730
 
712
- return if data.size <= 9
731
+ return if data.bytesize <= 9
713
732
  src_id = data[ 1, 8 ].unpack( 'Q>' ).first
714
733
  dst_id = ctl_info[ :dst_ids ][ src_id ]
715
734
 
716
735
  if dst_id then
717
736
  data2 = [ PAIRED, src_id, dst_id ].pack( 'CQ>n' )
718
737
  # puts "debug dst id exist, send ctlmsg paired #{ src_id } #{ dst_id }"
719
- send_ctlmsg( data2, ctl_addr )
738
+ send_ctlmsg( ctld, data2, ctl_addr )
720
739
  return
721
740
  end
722
741
 
@@ -772,7 +791,7 @@ module Girl
772
791
  btun = dst_info[ :btun ]
773
792
 
774
793
  begin
775
- data = dst.read_nonblock( 65535 )
794
+ data = dst.read_nonblock( CHUNK_SIZE )
776
795
  rescue IO::WaitReadable
777
796
  print 'r'
778
797
  return
@@ -1044,7 +1063,7 @@ module Girl
1044
1063
  data2 = ''
1045
1064
 
1046
1065
  until dst_info[ :rbuff ].empty? do
1047
- _data = dst_info[ :rbuff ][ 0, 65535 ]
1066
+ _data = dst_info[ :rbuff ][ 0, CHUNK_SIZE ]
1048
1067
  data_size = _data.bytesize
1049
1068
  # puts "debug move dst.rbuff to btun.wbuff"
1050
1069
  data2 << pack_a_chunk( _data )
@@ -1067,6 +1086,7 @@ module Girl
1067
1086
  end
1068
1087
 
1069
1088
  dst_info = @dst_infos[ dst ]
1089
+ dst_info[ :connected ] = true
1070
1090
  atun = dst_info[ :atun ]
1071
1091
  data = dst_info[ :wbuff ]
1072
1092