girl 0.93.0 → 0.98.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: db00d3852751d26d014f0db01a04a8a3c4d7a43681003dc7b5a61b5af3f42db7
4
- data.tar.gz: 1938878b1125a8868aa1415a3c9200cf9003dc4310665ebcd7d51aba5871358a
3
+ metadata.gz: a0201dd1519345fc7a831c89a0a8ab139d2fa96d66da2545fcfd1de9102bbe23
4
+ data.tar.gz: e529faf1d41f6d80074eed26519c0fef85a092058dc74a936e17c067ce3a6f1b
5
5
  SHA512:
6
- metadata.gz: 6764a6e73718d396b02bac36d0d078741a659cfa1a32de13ef41183b4ed67b98be92e60a4d284abbdc3ee7ce929e872860f9aa7eab7caf715c3371c858eb6553
7
- data.tar.gz: 1945f2f6bc976654fe9542df2c8145ab983aa16ebdad0100a8893948a4cf076bf7e4851813fbfd459b78601c66bfd1e5fe120d29808b329e1558375509fe4e9c
6
+ metadata.gz: eec9fbcfa84d537bf1c9a301f2974ac5d2b3b3a0b6a4614d071b39c329faf8800e168afa618851a083a3bfc1df0770bb8da7252457394b6f3a1b02778fdae293
7
+ data.tar.gz: 37dc3789f90c73e6116a15cce0b37b1532f6c2b250996e8db0b0b1ad21ffb8d9a7909b6d06218c20574026f3730b134a0383dc348cad12c5ff56fe5897df420a
@@ -5,6 +5,8 @@ module Girl
5
5
  SEND_HELLO_COUNT = 10 # hello/a new source最多发几次
6
6
  SEND_HELLO_INTERVAL = 0.5 # 发送hello/a new source间隔
7
7
  EXPIRE_AFTER = 300 # 多久没有新流量,过期
8
+ RESET_TRAFF_DAY = 1 # 流量计数重置日,0为不重置
9
+ CHECK_TRAFF_INTERVAL = 86400 # 检查今天是否是流量计数重置日间隔
8
10
  CHECK_EXPIRE_INTERVAL = 30 # 检查过期间隔
9
11
  CHECK_RESUME_INTERVAL = 1 # 检查恢复读间隔
10
12
  RESOLV_CACHE_EXPIRE = 300 # dns查询结果缓存多久过期
@@ -27,6 +29,7 @@ module Girl
27
29
  CONTINUE = 17
28
30
  IS_RESEND_READY = 18
29
31
  RESEND_READY = 19
32
+ TRAFF_INFOS = 101
30
33
  HTTP_OK = "HTTP/1.1 200 OK\r\n\r\n"
31
34
  # https://www.iana.org/assignments/iana-ipv4-special-registry/iana-ipv4-special-registry.xhtml
32
35
  RESERVED_ROUTE = <<EOF
@@ -20,21 +20,34 @@ proxyd-tun:
20
20
 
21
21
  Q>: 0 ctlmsg -> C: 1 tund port -> n: tund port -> n: tcpd port
22
22
 
23
+ local-infod:
24
+
25
+ C: 101 traff infos
26
+
27
+ infod-local:
28
+
29
+ C: 101 traff infos -> [ C: im len -> im -> Q>: traff in -> Q>: traff out ]
30
+
23
31
  tun-tund:
24
32
 
25
33
  Q>: 0 ctlmsg -> C: 2 heartbeat
26
34
  3 a new source -> Q>: src id -> encoded destination address
27
35
  4 paired -> Q>: src id -> n: dst id
28
- 5 dest status [not use]
29
- 6 source status [not use]
30
- 7 miss [not use]
31
- 8 fin1 [not use]
32
- 9 confirm fin1 [not use]
33
- 10 fin2 [not use]
34
- 11 confirm fin2 [not use]
36
+ 5 dest status NOT USE
37
+ 6 source status NOT USE
38
+ 7 miss NOT USE
39
+ 8 fin1 NOT USE
40
+ 9 confirm fin1 NOT USE
41
+ 10 fin2 NOT USE
42
+ 11 confirm fin2 NOT USE
35
43
  12 tund fin
36
44
  13 tun fin
37
45
  14 tun ip changed
46
+ 15 single miss NOT USE
47
+ 16 range miss NOT USE
48
+ 17 continue NOT USE
49
+ 18 is resend ready NOT USE
50
+ 19 resend ready NOT USE
38
51
  =end
39
52
 
40
53
  module Girl
@@ -109,6 +122,10 @@ module Girl
109
122
  puts "im #{ im }"
110
123
  puts "worker count #{ worker_count }"
111
124
 
125
+ Girl::Custom.constants.each do | name |
126
+ puts "#{ name } #{ Girl::Custom.const_get( name ).inspect }"
127
+ end
128
+
112
129
  len = CONSTS.map{ | name | name.size }.max
113
130
 
114
131
  CONSTS.each do | name |
@@ -13,6 +13,7 @@ module Girl
13
13
  @mutex = Mutex.new
14
14
  @reads = []
15
15
  @writes = []
16
+ @closing_srcs = []
16
17
  @roles = {} # sock => :dotr / :proxy / :src / :dst / :tun / :stream
17
18
  @src_infos = {} # src => {}
18
19
  @dst_infos = {} # dst => {}
@@ -37,7 +38,6 @@ module Girl
37
38
  rs, ws = IO.select( @reads, @writes )
38
39
 
39
40
  @mutex.synchronize do
40
- # 先读,再写,避免打上关闭标记后读到
41
41
  rs.each do | sock |
42
42
  case @roles[ sock ]
43
43
  when :dotr then
@@ -108,7 +108,7 @@ module Girl
108
108
  # add read
109
109
  #
110
110
  def add_read( sock, role = nil )
111
- unless @reads.include?( sock ) then
111
+ if !sock.closed? && !@reads.include?( sock ) then
112
112
  @reads << sock
113
113
 
114
114
  if role then
@@ -121,7 +121,7 @@ module Girl
121
121
  # add src wbuff
122
122
  #
123
123
  def add_src_wbuff( src, data )
124
- return if src.closed?
124
+ return if src.closed? || @closing_srcs.include?( src )
125
125
  src_info = @src_infos[ src ]
126
126
  src_info[ :wbuff ] << data
127
127
  src_info[ :last_recv_at ] = Time.new
@@ -167,7 +167,7 @@ module Girl
167
167
  # add write
168
168
  #
169
169
  def add_write( sock )
170
- unless @writes.include?( sock ) then
170
+ if !sock.closed? && !@writes.include?( sock ) then
171
171
  @writes << sock
172
172
  end
173
173
  end
@@ -188,7 +188,10 @@ module Girl
188
188
  def close_dst( dst )
189
189
  # puts "debug1 close dst"
190
190
  close_sock( dst )
191
- @dst_infos.delete( dst )
191
+ dst_info = @dst_infos.delete( dst )
192
+ src = dst_info[ :src ]
193
+ close_read_src( src )
194
+ set_src_closing_write( src )
192
195
  end
193
196
 
194
197
  ##
@@ -258,7 +261,32 @@ module Girl
258
261
  def close_src( src )
259
262
  # puts "debug1 close src"
260
263
  close_sock( src )
261
- del_src_info( src )
264
+ src_info = del_src_info( src )
265
+ dst = src_info[ :dst ]
266
+
267
+ if dst then
268
+ close_read_dst( dst )
269
+ set_dst_closing_write( dst )
270
+ else
271
+ stream = src_info[ :stream ]
272
+
273
+ if stream then
274
+ close_read_stream( stream )
275
+ set_stream_closing_write( stream )
276
+ end
277
+ end
278
+ end
279
+
280
+ ##
281
+ # close stream
282
+ #
283
+ def close_stream( stream )
284
+ # puts "debug1 close stream"
285
+ close_sock( stream )
286
+ stream_info = @stream_infos.delete( stream )
287
+ src = stream_info[ :src ]
288
+ close_read_src( src )
289
+ set_src_closing_write( src )
262
290
  end
263
291
 
264
292
  ##
@@ -267,7 +295,6 @@ module Girl
267
295
  def close_tun( tun )
268
296
  # puts "debug1 close tun"
269
297
  close_sock( tun )
270
- @tun_info[ :srcs ].each{ | _, src | set_src_closing( src ) }
271
298
  end
272
299
 
273
300
  ##
@@ -372,7 +399,7 @@ module Girl
372
399
  trigger = false
373
400
  now = Time.new
374
401
 
375
- if @tun && !@tun.closed? then
402
+ if @tun && !@tun.closed? && !@tun_info[ :closing ] then
376
403
  last_recv_at = @tun_info[ :last_recv_at ] || @tun_info[ :created_at ]
377
404
 
378
405
  if @tun_info[ :srcs ].empty? && ( now - last_recv_at >= EXPIRE_AFTER ) then
@@ -482,7 +509,7 @@ module Girl
482
509
 
483
510
  Thread.new do
484
511
  SEND_HELLO_COUNT.times do | i |
485
- if @tun.nil? || @tun.closed? || src.closed? || src_info[ :stream ] then
512
+ if @tun.nil? || @tun.closed? || @tun_info[ :closing ] || src.closed? || src_info[ :stream ] then
486
513
  # puts "debug1 break loop send a new source #{ src_info[ :dst_port ] }"
487
514
  break
488
515
  end
@@ -523,15 +550,12 @@ module Girl
523
550
  end
524
551
 
525
552
  # puts "debug1 a new dst #{ dst.local_address.inspect }"
526
- local_port = dst.local_address.ip_port
527
553
  dst_info = {
528
- local_port: local_port, # 本地端口
529
- src: src, # 对应src
530
- domain: domain, # 目的地
531
- wbuff: '', # 写前,从src读到的流量
532
- paused: false, # 是否已暂停读
533
- closing: false, # 准备关闭
534
- closing_write: false # 准备关闭写
554
+ src: src, # 对应src
555
+ domain: domain, # 目的地
556
+ wbuff: '', # 写前,从src读到的流量
557
+ paused: false, # 是否已暂停读
558
+ closing_write: false # 准备关闭写
535
559
  }
536
560
 
537
561
  @dst_infos[ dst ] = dst_info
@@ -590,10 +614,11 @@ module Girl
590
614
 
591
615
  domain = src_info[ :destination_domain ]
592
616
  @stream_infos[ stream ] = {
593
- src: src, # 对应src
594
- domain: domain, # 目的地
595
- wbuff: data, # 写前,写往远端streamd
596
- paused: false # 是否已暂停读
617
+ src: src, # 对应src
618
+ domain: domain, # 目的地
619
+ wbuff: data, # 写前,写往远端streamd
620
+ paused: false, # 是否已暂停读
621
+ closing_write: false # 准备关闭写
597
622
  }
598
623
 
599
624
  src_info[ :dst_id ] = dst_id
@@ -657,7 +682,7 @@ module Girl
657
682
 
658
683
  Thread.new do
659
684
  SEND_HELLO_COUNT.times do | i |
660
- if @tun.nil? || @tun.closed? || @tun_info[ :tund_addr ] then
685
+ if @tun.nil? || @tun.closed? || @tun_info[ :closing ] || @tun_info[ :tund_addr ] then
661
686
  # puts "debug1 break loop send hello"
662
687
  break
663
688
  end
@@ -725,12 +750,12 @@ module Girl
725
750
  unless src.closed? then
726
751
  puts "p#{ Process.pid } #{ Time.new } resolved #{ domain } #{ ip_info.ip_address }"
727
752
  deal_with_destination_ip( src, ip_info )
753
+ next_tick
728
754
  end
729
755
  else
730
756
  set_src_closing( src )
757
+ next_tick
731
758
  end
732
-
733
- next_tick
734
759
  end
735
760
  end
736
761
  end
@@ -744,23 +769,15 @@ module Girl
744
769
  add_read( src )
745
770
  end
746
771
 
747
- ##
748
- # set dst closing
749
- #
750
- def set_dst_closing( dst )
751
- return if dst.closed?
752
- dst_info = @dst_infos[ dst ]
753
- dst_info[ :closing ] = true
754
- @reads.delete( dst )
755
- add_write( dst )
756
- end
757
-
758
772
  ##
759
773
  # set dst closing write
760
774
  #
761
775
  def set_dst_closing_write( dst )
762
776
  return if dst.closed?
777
+
763
778
  dst_info = @dst_infos[ dst ]
779
+ return if dst_info[ :closing_write ]
780
+
764
781
  dst_info[ :closing_write ] = true
765
782
  add_write( dst )
766
783
  end
@@ -769,19 +786,22 @@ module Girl
769
786
  # set src is closing
770
787
  #
771
788
  def set_src_closing( src )
772
- return if src.closed?
789
+ return if src.closed? || @closing_srcs.include?( src )
773
790
  @reads.delete( src )
774
- src_info = @src_infos[ src ]
775
- src_info[ :closing ] = true
776
- add_write( src )
791
+ @writes.delete( src )
792
+ @closing_srcs << src
793
+ add_write( @tun ) if @tun
777
794
  end
778
795
 
779
796
  ##
780
797
  # set src closing write
781
798
  #
782
799
  def set_src_closing_write( src )
783
- return if src.closed?
800
+ return if src.closed? || @closing_srcs.include?( src )
801
+
784
802
  src_info = @src_infos[ src ]
803
+ return if src_info[ :closing_write ]
804
+
785
805
  src_info[ :closing_write ] = true
786
806
  add_write( src )
787
807
  end
@@ -790,10 +810,6 @@ module Girl
790
810
  # set src proxy type tunnel
791
811
  #
792
812
  def set_src_proxy_type_tunnel( src )
793
- if @tun.nil? || @tun.closed? then
794
- new_a_tun
795
- end
796
-
797
813
  src_info = @src_infos[ src ]
798
814
  src_info[ :proxy_type ] = :tunnel
799
815
  src_id = src_info[ :id ]
@@ -806,23 +822,15 @@ module Girl
806
822
  end
807
823
  end
808
824
 
809
- ##
810
- # set stream closing
811
- #
812
- def set_stream_closing( stream )
813
- return if stream.closed?
814
- stream_info = @stream_infos[ stream ]
815
- stream_info[ :closing ] = true
816
- @reads.delete( stream )
817
- add_write( stream )
818
- end
819
-
820
825
  ##
821
826
  # set stream closing write
822
827
  #
823
828
  def set_stream_closing_write( stream )
824
829
  return if stream.closed?
830
+
825
831
  stream_info = @stream_infos[ stream ]
832
+ return if stream_info[ :closing_write ]
833
+
826
834
  stream_info[ :closing_write ] = true
827
835
  add_write( stream )
828
836
  end
@@ -831,10 +839,11 @@ module Girl
831
839
  # set tun is closing
832
840
  #
833
841
  def set_tun_closing
834
- return if @tun.closed?
842
+ return if @tun.closed? || @tun_info[ :closing ]
835
843
  @tun_info[ :closing ] = true
836
844
  @reads.delete( @tun )
837
845
  add_write( @tun )
846
+ @tun_info[ :srcs ].each{ | _, src | set_src_closing( src ) }
838
847
  end
839
848
 
840
849
  ##
@@ -893,11 +902,14 @@ module Girl
893
902
  last_recv_at: nil, # 上一次收到新流量(由dst收到,或者由stream收到)的时间
894
903
  last_sent_at: nil, # 上一次发出流量(由dst发出,或者由stream发出)的时间
895
904
  paused: false, # 是否已暂停读
896
- closing: false, # 准备关闭
897
905
  closing_write: false # 准备关闭写
898
906
  }
899
907
 
900
908
  add_read( src, :src )
909
+
910
+ if @tun.nil? || @tun.closed? then
911
+ new_a_tun
912
+ end
901
913
  end
902
914
 
903
915
  ##
@@ -961,6 +973,8 @@ module Girl
961
973
  # read src
962
974
  #
963
975
  def read_src( src )
976
+ return if src.closed?
977
+
964
978
  begin
965
979
  data = src.read_nonblock( READ_SIZE )
966
980
  rescue IO::WaitReadable, Errno::EINTR
@@ -1164,6 +1178,8 @@ module Girl
1164
1178
  # read dst
1165
1179
  #
1166
1180
  def read_dst( dst )
1181
+ return if dst.closed?
1182
+
1167
1183
  begin
1168
1184
  data = dst.read_nonblock( READ_SIZE )
1169
1185
  rescue IO::WaitReadable, Errno::EINTR
@@ -1186,6 +1202,8 @@ module Girl
1186
1202
  # read stream
1187
1203
  #
1188
1204
  def read_stream( stream )
1205
+ return if stream.closed?
1206
+
1189
1207
  begin
1190
1208
  data = stream.read_nonblock( READ_SIZE )
1191
1209
  rescue IO::WaitReadable, Errno::EINTR
@@ -1211,6 +1229,11 @@ module Girl
1211
1229
  #
1212
1230
  def write_tun( tun )
1213
1231
  # 处理关闭
1232
+ if @closing_srcs.any? then
1233
+ @closing_srcs.each{ | src | close_src( src ) }
1234
+ @closing_srcs.clear
1235
+ end
1236
+
1214
1237
  if @tun_info[ :closing ] then
1215
1238
  close_tun( tun )
1216
1239
  return
@@ -1246,27 +1269,6 @@ module Girl
1246
1269
  return if src.closed?
1247
1270
  src_info = @src_infos[ src ]
1248
1271
  dst = src_info[ :dst ]
1249
-
1250
- # 处理关闭
1251
- if src_info[ :closing ] then
1252
- close_src( src )
1253
-
1254
- if dst then
1255
- close_read_dst( dst )
1256
- set_dst_closing_write( dst )
1257
- else
1258
- stream = src_info[ :stream ]
1259
-
1260
- if stream then
1261
- close_read_stream( stream )
1262
- set_stream_closing_write( stream )
1263
- end
1264
- end
1265
-
1266
- return
1267
- end
1268
-
1269
- # 处理wbuff
1270
1272
  data = src_info[ :wbuff ]
1271
1273
 
1272
1274
  # 写前为空,处理关闭写
@@ -1312,19 +1314,6 @@ module Girl
1312
1314
  return if dst.closed?
1313
1315
  dst_info = @dst_infos[ dst ]
1314
1316
  src = dst_info[ :src ]
1315
-
1316
- # 处理关闭
1317
- if dst_info[ :closing ] then
1318
- close_dst( dst )
1319
-
1320
- if src then
1321
- close_read_src( src )
1322
- set_src_closing_write( src )
1323
- end
1324
-
1325
- return
1326
- end
1327
-
1328
1317
  data = dst_info[ :wbuff ]
1329
1318
 
1330
1319
  # 写前为空,处理关闭写
@@ -1367,15 +1356,6 @@ module Girl
1367
1356
  return if stream.closed?
1368
1357
  stream_info = @stream_infos[ stream ]
1369
1358
  src = stream_info[ :src ]
1370
-
1371
- # 处理关闭
1372
- if stream_info[ :closing ] then
1373
- close_stream( stream )
1374
- close_read_src( src )
1375
- set_src_closing_write( src )
1376
- return
1377
- end
1378
-
1379
1359
  data = stream_info[ :wbuff ]
1380
1360
 
1381
1361
  # 写前为空,处理关闭写
@@ -17,6 +17,7 @@ module Girl
17
17
  raise "not found config file #{ config_path }" unless File.exist?( config_path )
18
18
  conf = JSON.parse( IO.binread( config_path ), symbolize_names: true )
19
19
  proxyd_port = conf[ :proxyd_port ]
20
+ infod_port = conf[ :infod_port ]
20
21
  worker_count = conf[ :worker_count ]
21
22
  end
22
23
 
@@ -24,6 +25,10 @@ module Girl
24
25
  proxyd_port = 6060
25
26
  end
26
27
 
28
+ unless infod_port then
29
+ infod_port = 6070
30
+ end
31
+
27
32
  nprocessors = Etc.nprocessors
28
33
 
29
34
  if worker_count.nil? || worker_count <= 0 || worker_count > nprocessors then
@@ -33,8 +38,13 @@ module Girl
33
38
  title = "girl proxyd #{ Girl::VERSION }"
34
39
  puts title
35
40
  puts "proxyd port #{ proxyd_port }"
41
+ puts "infod port #{ infod_port }"
36
42
  puts "worker count #{ worker_count }"
37
43
 
44
+ Girl::Custom.constants.each do | name |
45
+ puts "#{ name } #{ Girl::Custom.const_get( name ).inspect }"
46
+ end
47
+
38
48
  len = CONSTS.map{ | name | name.size }.max
39
49
 
40
50
  CONSTS.each do | name |
@@ -47,7 +57,7 @@ module Girl
47
57
  worker_count.times do | i |
48
58
  workers << fork do
49
59
  $0 = 'girl proxyd worker'
50
- worker = Girl::ProxydWorker.new( proxyd_port )
60
+ worker = Girl::ProxydWorker.new( proxyd_port, infod_port )
51
61
 
52
62
  Signal.trap( :TERM ) do
53
63
  puts "w#{ i } exit"
@@ -4,23 +4,28 @@ module Girl
4
4
  ##
5
5
  # initialize
6
6
  #
7
- def initialize( proxyd_port )
7
+ def initialize( proxyd_port, infod_port )
8
8
  @custom = Girl::ProxydCustom.new
9
9
  @mutex = Mutex.new
10
10
  @reads = []
11
11
  @writes = []
12
- @roles = {} # sock => :dotr / :proxyd / :dst / :tund / :tcpd / :streamd
12
+ @closing_dsts = []
13
+ @closing_streamds = []
14
+ @roles = {} # sock => :dotr / :proxyd / :infod / :dst / :tund / :tcpd / :streamd
13
15
  @tund_infos = {} # tund => {}
14
16
  @tcpd_infos = {} # tcpd => {}
15
17
  @dst_infos = {} # dst => {}
16
18
  @streamd_infos = {} # streamd => {}
17
19
  @tunneling_tunds = {} # tunneling_addr => tund
18
20
  @resolv_caches = {} # domain => [ ip, created_at ]
21
+ @traff_ins = {} # im => 0
22
+ @traff_outs = {} # im => 0
19
23
 
20
24
  dotr, dotw = IO.pipe
21
25
  @dotw = dotw
22
26
  add_read( dotr, :dotr )
23
27
  new_a_proxyd( proxyd_port )
28
+ new_a_infod( infod_port )
24
29
  end
25
30
 
26
31
  ##
@@ -30,18 +35,20 @@ module Girl
30
35
  puts "p#{ Process.pid } #{ Time.new } looping"
31
36
  loop_check_expire
32
37
  loop_check_resume
38
+ loop_check_traff
33
39
 
34
40
  loop do
35
41
  rs, ws = IO.select( @reads, @writes )
36
42
 
37
43
  @mutex.synchronize do
38
- # 先读,再写,避免打上关闭标记后读到
39
44
  rs.each do | sock |
40
45
  case @roles[ sock ]
41
46
  when :dotr then
42
47
  read_dotr( sock )
43
48
  when :proxyd then
44
49
  read_proxyd( sock )
50
+ when :infod then
51
+ read_infod( sock )
45
52
  when :tund then
46
53
  read_tund( sock )
47
54
  when :tcpd then
@@ -113,7 +120,7 @@ module Girl
113
120
  # add read
114
121
  #
115
122
  def add_read( sock, role = nil )
116
- unless @reads.include?( sock ) then
123
+ if !sock.closed? && !@reads.include?( sock ) then
117
124
  @reads << sock
118
125
 
119
126
  if role then
@@ -122,11 +129,32 @@ module Girl
122
129
  end
123
130
  end
124
131
 
132
+ ##
133
+ # add streamd wbuff
134
+ #
135
+ def add_streamd_wbuff( streamd, data )
136
+ return if streamd.closed? || @closing_streamds.include?( streamd )
137
+ streamd_info = @streamd_infos[ streamd ]
138
+ streamd_info[ :wbuff ] << data
139
+ add_write( streamd )
140
+
141
+ if streamd_info[ :wbuff ].bytesize >= WBUFF_LIMIT then
142
+ dst = streamd_info[ :dst ]
143
+ dst_info = @dst_infos[ dst ]
144
+
145
+ unless dst_info[ :paused ] then
146
+ puts "p#{ Process.pid } #{ Time.new } pause dst #{ dst_info[ :domain_port ] }"
147
+ dst_info[ :paused ] = true
148
+ @reads.delete( dst )
149
+ end
150
+ end
151
+ end
152
+
125
153
  ##
126
154
  # add write
127
155
  #
128
156
  def add_write( sock )
129
- unless @writes.include?( sock ) then
157
+ if !sock.closed? && !@writes.include?( sock ) then
130
158
  @writes << sock
131
159
  end
132
160
  end
@@ -137,7 +165,13 @@ module Girl
137
165
  def close_dst( dst )
138
166
  # puts "debug1 close dst"
139
167
  close_sock( dst )
140
- del_dst_info( dst )
168
+ dst_info = del_dst_info( dst )
169
+ streamd = dst_info[ :streamd ]
170
+
171
+ if streamd then
172
+ close_read_streamd( streamd )
173
+ set_streamd_closing_write( streamd )
174
+ end
141
175
  end
142
176
 
143
177
  ##
@@ -197,7 +231,13 @@ module Girl
197
231
  def close_streamd( streamd )
198
232
  # puts "debug1 close streamd"
199
233
  close_sock( streamd )
200
- @streamd_infos.delete( streamd )
234
+ streamd_info = @streamd_infos.delete( streamd )
235
+ dst = streamd_info[ :dst ]
236
+
237
+ if dst then
238
+ close_read_dst( dst )
239
+ set_dst_closing_write( dst )
240
+ end
201
241
  end
202
242
 
203
243
  ##
@@ -210,7 +250,6 @@ module Girl
210
250
  tcpd = tund_info[ :tcpd ]
211
251
  close_sock( tcpd )
212
252
  @tcpd_infos.delete( tcpd )
213
- tund_info[ :dsts ].each{ | _, dst | set_dst_closing( dst ) }
214
253
  @tunneling_tunds.delete( tund_info[ :tun_addr ] )
215
254
  end
216
255
 
@@ -270,10 +309,12 @@ module Girl
270
309
  end
271
310
 
272
311
  dst_id = dst.local_address.ip_port
312
+ tund_info = @tund_infos[ tund ]
273
313
 
274
314
  @dst_infos[ dst ] = {
275
315
  id: dst_id, # id
276
316
  tund: tund, # 对应tund
317
+ im: tund_info[ :im ], # 标识
277
318
  domain_port: domain_port, # 目的地和端口
278
319
  rbuff: '', # 对应的streamd没准备好,暂存读到的流量
279
320
  streamd: nil, # 对应的streamd
@@ -283,13 +324,11 @@ module Girl
283
324
  last_recv_at: nil, # 上一次收到新流量(由streamd收到)的时间
284
325
  last_sent_at: nil, # 上一次发出流量(由streamd发出)的时间
285
326
  paused: false, # 是否已暂停读
286
- closing: false, # 准备关闭
287
327
  closing_write: false # 准备关闭写
288
328
  }
289
329
 
290
330
  add_read( dst, :dst )
291
331
 
292
- tund_info = @tund_infos[ tund ]
293
332
  tund_info[ :dst_ids ][ src_id ] = dst_id
294
333
  tund_info[ :dsts ][ dst_id ] = dst
295
334
 
@@ -328,12 +367,14 @@ module Girl
328
367
  now = Time.new
329
368
 
330
369
  @tund_infos.each do | tund, tund_info |
331
- last_recv_at = tund_info[ :last_recv_at ] || tund_info[ :created_at ]
332
-
333
- if tund_info[ :dsts ].empty? && ( now - last_recv_at >= EXPIRE_AFTER ) then
334
- puts "p#{ Process.pid } #{ Time.new } expire tund #{ tund_info[ :port ] }"
335
- set_tund_closing( tund )
336
- trigger = true
370
+ unless tund_info[ :closing ] then
371
+ last_recv_at = tund_info[ :last_recv_at ] || tund_info[ :created_at ]
372
+
373
+ if tund_info[ :dsts ].empty? && ( now - last_recv_at >= EXPIRE_AFTER ) then
374
+ puts "p#{ Process.pid } #{ Time.new } expire tund #{ tund_info[ :port ] }"
375
+ set_tund_closing( tund )
376
+ trigger = true
377
+ end
337
378
  end
338
379
  end
339
380
 
@@ -395,6 +436,27 @@ module Girl
395
436
  end
396
437
  end
397
438
 
439
+ ##
440
+ # loop check traff
441
+ #
442
+ def loop_check_traff
443
+ if RESET_TRAFF_DAY > 0 then
444
+ Thread.new do
445
+ loop do
446
+ sleep CHECK_TRAFF_INTERVAL
447
+
448
+ @mutex.synchronize do
449
+ if Time.new.day == RESET_TRAFF_DAY then
450
+ puts "p#{ Process.pid } #{ Time.new } reset traffs"
451
+ @traff_ins.transform_values!{ | _ | 0 }
452
+ @traff_outs.transform_values!{ | _ | 0 }
453
+ end
454
+ end
455
+ end
456
+ end
457
+ end
458
+ end
459
+
398
460
  ##
399
461
  # new a proxyd
400
462
  #
@@ -412,6 +474,18 @@ module Girl
412
474
  add_read( proxyd, :proxyd )
413
475
  end
414
476
 
477
+ ##
478
+ # new a infod
479
+ #
480
+ def new_a_infod( infod_port )
481
+ infod = Socket.new( Socket::AF_INET, Socket::SOCK_DGRAM, 0 )
482
+ infod.setsockopt( Socket::SOL_SOCKET, Socket::SO_REUSEPORT, 1 )
483
+ infod.bind( Socket.sockaddr_in( infod_port, '127.0.0.1' ) )
484
+
485
+ puts "p#{ Process.pid } #{ Time.new } infod bind on #{ infod_port }"
486
+ add_read( infod, :infod )
487
+ end
488
+
415
489
  ##
416
490
  # next tick
417
491
  #
@@ -487,19 +561,23 @@ module Girl
487
561
  # set dst closing
488
562
  #
489
563
  def set_dst_closing( dst )
490
- return if dst.closed?
491
- dst_info = @dst_infos[ dst ]
492
- dst_info[ :closing ] = true
564
+ return if dst.closed? || @closing_dsts.include?( dst )
493
565
  @reads.delete( dst )
494
- add_write( dst )
566
+ @writes.delete( dst )
567
+ @closing_dsts << dst
568
+ dst_info = @dst_infos[ dst ]
569
+ add_write( dst_info[ :tund ] )
495
570
  end
496
571
 
497
572
  ##
498
573
  # set dst closing write
499
574
  #
500
575
  def set_dst_closing_write( dst )
501
- return if dst.closed?
576
+ return if dst.closed? || @closing_dsts.include?( dst )
577
+
502
578
  dst_info = @dst_infos[ dst ]
579
+ return if dst_info[ :closing_write ]
580
+
503
581
  dst_info[ :closing_write ] = true
504
582
  add_write( dst )
505
583
  end
@@ -508,19 +586,23 @@ module Girl
508
586
  # set streamd closing
509
587
  #
510
588
  def set_streamd_closing( streamd )
511
- return if streamd.closed?
512
- streamd_info = @streamd_infos[ streamd ]
513
- streamd_info[ :closing ] = true
589
+ return if streamd.closed? || @closing_streamds.include?( streamd )
514
590
  @reads.delete( streamd )
515
- add_write( streamd )
591
+ @writes.delete( streamd )
592
+ @closing_streamds << streamd
593
+ streamd_info = @streamd_infos[ streamd ]
594
+ add_write( streamd_info[ :tund ] )
516
595
  end
517
596
 
518
597
  ##
519
598
  # set streamd closing write
520
599
  #
521
600
  def set_streamd_closing_write( streamd )
522
- return if streamd.closed?
601
+ return if streamd.closed? || @closing_streamds.include?( streamd )
602
+
523
603
  streamd_info = @streamd_infos[ streamd ]
604
+ return if streamd_info[ :closing_write ]
605
+
524
606
  streamd_info[ :closing_write ] = true
525
607
  add_write( streamd )
526
608
  end
@@ -530,10 +612,14 @@ module Girl
530
612
  #
531
613
  def set_tund_closing( tund )
532
614
  return if tund.closed?
615
+
533
616
  tund_info = @tund_infos[ tund ]
617
+ return if tund_info[ :closing ]
618
+
534
619
  tund_info[ :closing ] = true
535
620
  @reads.delete( tund )
536
621
  add_write( tund )
622
+ tund_info[ :dsts ].each{ | _, dst | set_dst_closing( dst ) }
537
623
  end
538
624
 
539
625
  ##
@@ -565,6 +651,13 @@ module Girl
565
651
  return
566
652
  end
567
653
 
654
+ im = data
655
+
656
+ unless @traff_ins.include?( im ) then
657
+ @traff_ins[ im ] = 0
658
+ @traff_outs[ im ] = 0
659
+ end
660
+
568
661
  tund = Socket.new( Socket::AF_INET, Socket::SOCK_DGRAM, 0 )
569
662
  tund.bind( Socket.sockaddr_in( 0, '0.0.0.0' ) )
570
663
  tund_port = tund.local_address.ip_port
@@ -578,6 +671,7 @@ module Girl
578
671
  add_read( tcpd, :tcpd )
579
672
 
580
673
  tund_info = {
674
+ im: im, # 标识
581
675
  port: tund_port, # 端口
582
676
  tcpd: tcpd, # 对应的tcpd
583
677
  tcpd_port: tcpd_port, # tcpd端口
@@ -601,6 +695,28 @@ module Girl
601
695
  add_proxyd_ctlmsg_tund_port( tund_info )
602
696
  end
603
697
 
698
+ ##
699
+ # read infod
700
+ #
701
+ def read_infod( infod )
702
+ data, addrinfo, rflags, *controls = infod.recvmsg
703
+ ctl_num = data[ 0 ].unpack( 'C' ).first
704
+ # puts "debug1 infod recv #{ ctl_num } #{ addrinfo.inspect }"
705
+
706
+ case ctl_num
707
+ when TRAFF_INFOS then
708
+ data2 = [ TRAFF_INFOS ].pack( 'C' )
709
+
710
+ @traff_ins.keys.sort.each do | im |
711
+ traff_in = @traff_ins[ im ]
712
+ traff_out = @traff_outs[ im ]
713
+ data2 << [ [ im.bytesize ].pack( 'C' ), im, [ traff_in, traff_out ].pack( 'Q>Q>' ) ].join
714
+ end
715
+
716
+ send_data( infod, data2, addrinfo )
717
+ end
718
+ end
719
+
604
720
  ##
605
721
  # read tund
606
722
  #
@@ -662,6 +778,8 @@ module Girl
662
778
  # read tcpd
663
779
  #
664
780
  def read_tcpd( tcpd )
781
+ return if tcpd.closed?
782
+
665
783
  begin
666
784
  streamd, addrinfo = tcpd.accept_nonblock
667
785
  rescue IO::WaitReadable, Errno::EINTR
@@ -672,13 +790,16 @@ module Girl
672
790
  # puts "debug1 accept a streamd"
673
791
  tcpd_info = @tcpd_infos[ tcpd ]
674
792
  tund = tcpd_info[ :tund ]
793
+ tund_info = @tund_infos[ tund ]
675
794
 
676
795
  @streamd_infos[ streamd ] = {
677
- tund: tund, # 对应tund
678
- dst: nil, # 对应dst
679
- domain_port: nil, # dst的目的地和端口
680
- wbuff: '', # 写前,写往近端stream
681
- paused: false # 是否已暂停读
796
+ tund: tund, # 对应tund
797
+ im: tund_info[ :im ], # 标识
798
+ dst: nil, # 对应dst
799
+ domain_port: nil, # dst的目的地和端口
800
+ wbuff: '', # 写前,写往近端stream
801
+ paused: false, # 是否已暂停读
802
+ closing_write: false # 准备关闭写
682
803
  }
683
804
 
684
805
  add_read( streamd, :streamd )
@@ -688,6 +809,8 @@ module Girl
688
809
  # read dst
689
810
  #
690
811
  def read_dst( dst )
812
+ return if dst.closed?
813
+
691
814
  begin
692
815
  data = dst.read_nonblock( READ_SIZE )
693
816
  rescue IO::WaitReadable, Errno::EINTR
@@ -702,6 +825,7 @@ module Girl
702
825
  end
703
826
 
704
827
  dst_info = @dst_infos[ dst ]
828
+ @traff_ins[ dst_info[ :im ] ] += data.bytesize
705
829
  streamd = dst_info[ :streamd ]
706
830
 
707
831
  if streamd then
@@ -709,14 +833,7 @@ module Girl
709
833
  streamd_info = @streamd_infos[ streamd ]
710
834
  data = @custom.encode( data )
711
835
  # puts "debug2 add streamd.wbuff encoded #{ data.bytesize }"
712
- streamd_info[ :wbuff ] << data
713
- add_write( streamd )
714
-
715
- if streamd_info[ :wbuff ].bytesize >= WBUFF_LIMIT then
716
- puts "p#{ Process.pid } #{ Time.new } pause dst #{ dst_info[ :domain_port ] }"
717
- dst_info[ :paused ] = true
718
- @reads.delete( dst )
719
- end
836
+ add_streamd_wbuff( streamd, data )
720
837
  end
721
838
  else
722
839
  dst_info[ :rbuff ] << data
@@ -732,6 +849,8 @@ module Girl
732
849
  # read streamd
733
850
  #
734
851
  def read_streamd( streamd )
852
+ return if streamd.closed?
853
+
735
854
  begin
736
855
  data = streamd.read_nonblock( READ_SIZE )
737
856
  rescue IO::WaitReadable, Errno::EINTR
@@ -746,6 +865,7 @@ module Girl
746
865
  end
747
866
 
748
867
  streamd_info = @streamd_infos[ streamd ]
868
+ @traff_ins[ streamd_info[ :im ] ] += data.bytesize
749
869
  dst = streamd_info[ :dst ]
750
870
 
751
871
  unless dst then
@@ -772,7 +892,8 @@ module Girl
772
892
 
773
893
  unless dst_info[ :rbuff ].empty? then
774
894
  # puts "debug1 encode and move dst.rbuff to streamd.wbuff"
775
- streamd_info[ :wbuff ] << @custom.encode( dst_info[ :rbuff ] )
895
+ data2 = @custom.encode( dst_info[ :rbuff ] )
896
+ add_streamd_wbuff( streamd, data2 )
776
897
  end
777
898
 
778
899
  dst_info[ :streamd ] = streamd
@@ -781,7 +902,7 @@ module Girl
781
902
  return if data.empty?
782
903
  end
783
904
 
784
- unless dst.closed? then
905
+ if !dst.closed? && !@closing_dsts.include?( dst ) then
785
906
  dst_info = @dst_infos[ dst ]
786
907
  data = @custom.decode( data )
787
908
  # puts "debug2 add dst.wbuff decoded #{ data.bytesize }"
@@ -824,6 +945,16 @@ module Girl
824
945
  tund_info = @tund_infos[ tund ]
825
946
 
826
947
  # 处理关闭
948
+ if @closing_dsts.any? then
949
+ @closing_dsts.each{ | dst | close_dst( dst ) }
950
+ @closing_dsts.clear
951
+ end
952
+
953
+ if @closing_streamds.any? then
954
+ @closing_streamds.each{ | streamd | close_streamd( streamd ) }
955
+ @closing_streamds.clear
956
+ end
957
+
827
958
  if tund_info[ :closing ] then
828
959
  if tund_info[ :changed_tun_addr ] then
829
960
  data = [ 0, IP_CHANGED ].pack( 'Q>C' )
@@ -862,19 +993,6 @@ module Girl
862
993
  return if dst.closed?
863
994
  dst_info = @dst_infos[ dst ]
864
995
  streamd = dst_info[ :streamd ]
865
-
866
- # 处理关闭
867
- if dst_info[ :closing ] then
868
- close_dst( dst )
869
-
870
- if streamd then
871
- close_read_streamd( streamd )
872
- set_streamd_closing_write( streamd )
873
- end
874
-
875
- return
876
- end
877
-
878
996
  data = dst_info[ :wbuff ]
879
997
 
880
998
  # 写前为空,处理关闭写
@@ -904,6 +1022,7 @@ module Girl
904
1022
  # puts "debug2 written dst #{ written }"
905
1023
  data = data[ written..-1 ]
906
1024
  dst_info[ :wbuff ] = data
1025
+ @traff_outs[ dst_info[ :im ] ] += written
907
1026
  end
908
1027
 
909
1028
  ##
@@ -913,19 +1032,6 @@ module Girl
913
1032
  return if streamd.closed?
914
1033
  streamd_info = @streamd_infos[ streamd ]
915
1034
  dst = streamd_info[ :dst ]
916
-
917
- # 处理关闭
918
- if streamd_info[ :closing ] then
919
- close_streamd( streamd )
920
-
921
- if dst then
922
- close_read_dst( dst )
923
- set_dst_closing_write( dst )
924
- end
925
-
926
- return
927
- end
928
-
929
1035
  data = streamd_info[ :wbuff ]
930
1036
 
931
1037
  # 写前为空,处理关闭写
@@ -955,6 +1061,7 @@ module Girl
955
1061
  # puts "debug2 written streamd #{ written }"
956
1062
  data = data[ written..-1 ]
957
1063
  streamd_info[ :wbuff ] = data
1064
+ @traff_outs[ streamd_info[ :im ] ] += written
958
1065
 
959
1066
  if dst && !dst.closed? then
960
1067
  dst_info = @dst_infos[ dst ]
@@ -1,3 +1,3 @@
1
1
  module Girl
2
- VERSION = '0.93.0'.freeze
2
+ VERSION = '0.98.0'.freeze
3
3
  end
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: 0.93.0
4
+ version: 0.98.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - takafan
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2020-10-12 00:00:00.000000000 Z
11
+ date: 2020-10-19 00:00:00.000000000 Z
12
12
  dependencies: []
13
13
  description: escape evil.
14
14
  email: