girl 0.92.0 → 0.97.0

This diff has not been reviewed by any users.
Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 3fa3e8cb3a29bc4e4e3c02508fe9277a3efc17d1864459999ec8992c685ed729
4
- data.tar.gz: 88b5969712da8922962166e2b17e355c6c5042051e6b18f29f79e9d3aa15845b
3
+ metadata.gz: 1488058f7502fb83ee815a38ba4b11276a2bd5732bfadf596f5f42fbbb6bae53
4
+ data.tar.gz: 1ac6377572a1ff976f4626127e78f76e7c949683b035c2df7426acac70b3ac86
5
5
  SHA512:
6
- metadata.gz: fcf011065b4049ab8d890abb4e38af6dd2f8001359fb78ae555e667fdc9142d6317c7de6c0ef7cfef8bddc537bef845e665d541734e2350f523aadc4e9e75853
7
- data.tar.gz: 942f594fb209cc3797822b9492ac8ba81eaa8d63b1824cac260e21a472b5589b335b7453d2381f5f839b6d3926b501c33cee079aba9da12dd1d7264e2e68580d
6
+ metadata.gz: 27bc728548949021b2f477ede35b85ff3888ba3371824d32458a390fe9040a10ac0fd11483f25426cda27b95784a2f71b3837fed6b264583ced0378ef6c1b2ee
7
+ data.tar.gz: d07a0a982e4ecbaf4c798163027bbdd68c7cd3510280e5f904a079aa6796aa57f5b0c96067c86ee71630409e92eb923050b132974496bfdbfed71154e61e2a60
@@ -2,8 +2,11 @@ module Girl
2
2
  READ_SIZE = 1024 * 1024 # 一次读多少
3
3
  WBUFF_LIMIT = 100 * 1024 * 1024 # 写前上限,超过上限暂停读
4
4
  RESUME_BELOW = WBUFF_LIMIT / 2 # 降到多少以下恢复读
5
- SEND_HELLO_COUNT = 10 # hello最多发几次
5
+ SEND_HELLO_COUNT = 10 # hello/a new source最多发几次
6
+ SEND_HELLO_INTERVAL = 0.5 # 发送hello/a new source间隔
6
7
  EXPIRE_AFTER = 300 # 多久没有新流量,过期
8
+ RESET_TRAFF_DAY = 1 # 流量计数重置日,0为不重置
9
+ CHECK_TRAFF_INTERVAL = 86400 # 检查今天是否是流量计数重置日间隔
7
10
  CHECK_EXPIRE_INTERVAL = 30 # 检查过期间隔
8
11
  CHECK_RESUME_INTERVAL = 1 # 检查恢复读间隔
9
12
  RESOLV_CACHE_EXPIRE = 300 # dns查询结果缓存多久过期
@@ -26,6 +29,7 @@ module Girl
26
29
  CONTINUE = 17
27
30
  IS_RESEND_READY = 18
28
31
  RESEND_READY = 19
32
+ TRAFF_INFOS = 101
29
33
  HTTP_OK = "HTTP/1.1 200 OK\r\n\r\n"
30
34
  # https://www.iana.org/assignments/iana-ipv4-special-registry/iana-ipv4-special-registry.xhtml
31
35
  RESERVED_ROUTE = <<EOF
@@ -42,6 +46,7 @@ EOF
42
46
  WBUFF_LIMIT
43
47
  RESUME_BELOW
44
48
  SEND_HELLO_COUNT
49
+ SEND_HELLO_INTERVAL
45
50
  EXPIRE_AFTER
46
51
  CHECK_EXPIRE_INTERVAL
47
52
  CHECK_RESUME_INTERVAL
@@ -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 |
@@ -37,7 +37,6 @@ module Girl
37
37
  rs, ws = IO.select( @reads, @writes )
38
38
 
39
39
  @mutex.synchronize do
40
- # 先读,再写,避免打上关闭标记后读到
41
40
  rs.each do | sock |
42
41
  case @roles[ sock ]
43
42
  when :dotr then
@@ -108,7 +107,7 @@ module Girl
108
107
  # add read
109
108
  #
110
109
  def add_read( sock, role = nil )
111
- unless @reads.include?( sock ) then
110
+ if !sock.closed? && !@reads.include?( sock ) then
112
111
  @reads << sock
113
112
 
114
113
  if role then
@@ -188,7 +187,10 @@ module Girl
188
187
  def close_dst( dst )
189
188
  # puts "debug1 close dst"
190
189
  close_sock( dst )
191
- @dst_infos.delete( dst )
190
+ dst_info = @dst_infos.delete( dst )
191
+ src = dst_info[ :src ]
192
+ close_read_src( src )
193
+ set_src_closing_write( src )
192
194
  end
193
195
 
194
196
  ##
@@ -258,7 +260,32 @@ module Girl
258
260
  def close_src( src )
259
261
  # puts "debug1 close src"
260
262
  close_sock( src )
261
- del_src_info( src )
263
+ src_info = del_src_info( src )
264
+ dst = src_info[ :dst ]
265
+
266
+ if dst then
267
+ close_read_dst( dst )
268
+ set_dst_closing_write( dst )
269
+ else
270
+ stream = src_info[ :stream ]
271
+
272
+ if stream then
273
+ close_read_stream( stream )
274
+ set_stream_closing_write( stream )
275
+ end
276
+ end
277
+ end
278
+
279
+ ##
280
+ # close stream
281
+ #
282
+ def close_stream( stream )
283
+ # puts "debug1 close stream"
284
+ close_sock( stream )
285
+ stream_info = @stream_infos.delete( stream )
286
+ src = stream_info[ :src ]
287
+ close_read_src( src )
288
+ set_src_closing_write( src )
262
289
  end
263
290
 
264
291
  ##
@@ -287,6 +314,7 @@ module Girl
287
314
  src_info = @src_infos[ src ]
288
315
  end
289
316
 
317
+ src_info[ :closed_write ] = true
290
318
  src_info
291
319
  end
292
320
 
@@ -307,6 +335,7 @@ module Girl
307
335
  dst_info = @dst_infos[ dst ]
308
336
  end
309
337
 
338
+ dst_info[ :closed_write ] = true
310
339
  dst_info
311
340
  end
312
341
 
@@ -327,6 +356,7 @@ module Girl
327
356
  stream_info = @stream_infos[ stream ]
328
357
  end
329
358
 
359
+ stream_info[ :closed_write ] = true
330
360
  stream_info
331
361
  end
332
362
 
@@ -353,7 +383,7 @@ module Girl
353
383
  def del_src_info( src )
354
384
  src_info = @src_infos.delete( src )
355
385
 
356
- if src_info[ :stream ] && @tun && !@tun.closed? then
386
+ if ( src_info[ :proxy_type ] == :tunnel ) && @tun && !@tun.closed? then
357
387
  @tun_info[ :srcs ].delete( src_info[ :id ] )
358
388
  end
359
389
 
@@ -369,6 +399,7 @@ module Girl
369
399
  sleep CHECK_EXPIRE_INTERVAL
370
400
 
371
401
  @mutex.synchronize do
402
+ trigger = false
372
403
  now = Time.new
373
404
 
374
405
  if @tun && !@tun.closed? then
@@ -382,6 +413,8 @@ module Girl
382
413
  data = [ 0, HEARTBEAT ].pack( 'Q>C' )
383
414
  add_ctlmsg( data )
384
415
  end
416
+
417
+ trigger = true
385
418
  end
386
419
 
387
420
  @src_infos.each do | src, src_info |
@@ -391,10 +424,11 @@ module Girl
391
424
  if ( now - last_recv_at >= EXPIRE_AFTER ) && ( now - last_sent_at >= EXPIRE_AFTER ) then
392
425
  puts "p#{ Process.pid } #{ Time.new } expire src #{ src_info[ :destination_domain ] }"
393
426
  set_src_closing( src )
427
+ trigger = true
394
428
  end
395
429
  end
396
430
 
397
- next_tick
431
+ next_tick if trigger
398
432
  end
399
433
  end
400
434
  end
@@ -492,7 +526,7 @@ module Girl
492
526
  next_tick
493
527
  end
494
528
 
495
- sleep 1
529
+ sleep SEND_HELLO_INTERVAL
496
530
  end
497
531
  end
498
532
  end
@@ -519,15 +553,14 @@ module Girl
519
553
  end
520
554
 
521
555
  # puts "debug1 a new dst #{ dst.local_address.inspect }"
522
- local_port = dst.local_address.ip_port
523
556
  dst_info = {
524
- local_port: local_port, # 本地端口
525
557
  src: src, # 对应src
526
558
  domain: domain, # 目的地
527
559
  wbuff: '', # 写前,从src读到的流量
528
560
  paused: false, # 是否已暂停读
529
561
  closing: false, # 准备关闭
530
- closing_write: false # 准备关闭写
562
+ closing_write: false, # 准备关闭写
563
+ closed_write: false # 已关闭写
531
564
  }
532
565
 
533
566
  @dst_infos[ dst ] = dst_info
@@ -586,10 +619,13 @@ module Girl
586
619
 
587
620
  domain = src_info[ :destination_domain ]
588
621
  @stream_infos[ stream ] = {
589
- src: src, # 对应src
590
- domain: domain, # 目的地
591
- wbuff: data, # 写前,写往远端streamd
592
- paused: false # 是否已暂停读
622
+ src: src, # 对应src
623
+ domain: domain, # 目的地
624
+ wbuff: data, # 写前,写往远端streamd
625
+ paused: false, # 是否已暂停读
626
+ closing: false, # 准备关闭
627
+ closing_write: false, # 准备关闭写
628
+ closed_write: false # 已关闭写
593
629
  }
594
630
 
595
631
  src_info[ :dst_id ] = dst_id
@@ -667,7 +703,7 @@ module Girl
667
703
  next_tick
668
704
  end
669
705
 
670
- sleep 1
706
+ sleep SEND_HELLO_INTERVAL
671
707
  end
672
708
  end
673
709
  end
@@ -721,12 +757,12 @@ module Girl
721
757
  unless src.closed? then
722
758
  puts "p#{ Process.pid } #{ Time.new } resolved #{ domain } #{ ip_info.ip_address }"
723
759
  deal_with_destination_ip( src, ip_info )
760
+ next_tick
724
761
  end
725
762
  else
726
763
  set_src_closing( src )
764
+ next_tick
727
765
  end
728
-
729
- next_tick
730
766
  end
731
767
  end
732
768
  end
@@ -746,9 +782,14 @@ module Girl
746
782
  def set_dst_closing( dst )
747
783
  return if dst.closed?
748
784
  dst_info = @dst_infos[ dst ]
749
- dst_info[ :closing ] = true
750
- @reads.delete( dst )
751
- add_write( dst )
785
+
786
+ if dst_info[ :closed_write ] then
787
+ close_dst( dst )
788
+ else
789
+ dst_info[ :closing ] = true
790
+ @reads.delete( dst )
791
+ add_write( dst )
792
+ end
752
793
  end
753
794
 
754
795
  ##
@@ -756,7 +797,10 @@ module Girl
756
797
  #
757
798
  def set_dst_closing_write( dst )
758
799
  return if dst.closed?
800
+
759
801
  dst_info = @dst_infos[ dst ]
802
+ return if dst_info[ :closed_write ]
803
+
760
804
  dst_info[ :closing_write ] = true
761
805
  add_write( dst )
762
806
  end
@@ -766,10 +810,15 @@ module Girl
766
810
  #
767
811
  def set_src_closing( src )
768
812
  return if src.closed?
769
- @reads.delete( src )
770
813
  src_info = @src_infos[ src ]
771
- src_info[ :closing ] = true
772
- add_write( src )
814
+
815
+ if src_info[ :closed_write ] then
816
+ close_src( src )
817
+ else
818
+ src_info[ :closing ] = true
819
+ @reads.delete( src )
820
+ add_write( src )
821
+ end
773
822
  end
774
823
 
775
824
  ##
@@ -777,7 +826,10 @@ module Girl
777
826
  #
778
827
  def set_src_closing_write( src )
779
828
  return if src.closed?
829
+
780
830
  src_info = @src_infos[ src ]
831
+ return if src_info[ :closed_write ]
832
+
781
833
  src_info[ :closing_write ] = true
782
834
  add_write( src )
783
835
  end
@@ -786,10 +838,6 @@ module Girl
786
838
  # set src proxy type tunnel
787
839
  #
788
840
  def set_src_proxy_type_tunnel( src )
789
- if @tun.nil? || @tun.closed? then
790
- new_a_tun
791
- end
792
-
793
841
  src_info = @src_infos[ src ]
794
842
  src_info[ :proxy_type ] = :tunnel
795
843
  src_id = src_info[ :id ]
@@ -802,23 +850,15 @@ module Girl
802
850
  end
803
851
  end
804
852
 
805
- ##
806
- # set stream closing
807
- #
808
- def set_stream_closing( stream )
809
- return if stream.closed?
810
- stream_info = @stream_infos[ stream ]
811
- stream_info[ :closing ] = true
812
- @reads.delete( stream )
813
- add_write( stream )
814
- end
815
-
816
853
  ##
817
854
  # set stream closing write
818
855
  #
819
856
  def set_stream_closing_write( stream )
820
857
  return if stream.closed?
858
+
821
859
  stream_info = @stream_infos[ stream ]
860
+ return if stream_info[ :closed_write ]
861
+
822
862
  stream_info[ :closing_write ] = true
823
863
  add_write( stream )
824
864
  end
@@ -890,10 +930,15 @@ module Girl
890
930
  last_sent_at: nil, # 上一次发出流量(由dst发出,或者由stream发出)的时间
891
931
  paused: false, # 是否已暂停读
892
932
  closing: false, # 准备关闭
893
- closing_write: false # 准备关闭写
933
+ closing_write: false, # 准备关闭写
934
+ closed_write: false # 已关闭写
894
935
  }
895
936
 
896
937
  add_read( src, :src )
938
+
939
+ if @tun.nil? || @tun.closed? then
940
+ new_a_tun
941
+ end
897
942
  end
898
943
 
899
944
  ##
@@ -957,6 +1002,8 @@ module Girl
957
1002
  # read src
958
1003
  #
959
1004
  def read_src( src )
1005
+ return if src.closed?
1006
+
960
1007
  begin
961
1008
  data = src.read_nonblock( READ_SIZE )
962
1009
  rescue IO::WaitReadable, Errno::EINTR
@@ -1160,6 +1207,8 @@ module Girl
1160
1207
  # read dst
1161
1208
  #
1162
1209
  def read_dst( dst )
1210
+ return if dst.closed?
1211
+
1163
1212
  begin
1164
1213
  data = dst.read_nonblock( READ_SIZE )
1165
1214
  rescue IO::WaitReadable, Errno::EINTR
@@ -1182,6 +1231,8 @@ module Girl
1182
1231
  # read stream
1183
1232
  #
1184
1233
  def read_stream( stream )
1234
+ return if stream.closed?
1235
+
1185
1236
  begin
1186
1237
  data = stream.read_nonblock( READ_SIZE )
1187
1238
  rescue IO::WaitReadable, Errno::EINTR
@@ -1246,19 +1297,6 @@ module Girl
1246
1297
  # 处理关闭
1247
1298
  if src_info[ :closing ] then
1248
1299
  close_src( src )
1249
-
1250
- if dst then
1251
- close_read_dst( dst )
1252
- set_dst_closing_write( dst )
1253
- else
1254
- stream = src_info[ :stream ]
1255
-
1256
- if stream then
1257
- close_read_stream( stream )
1258
- set_stream_closing_write( stream )
1259
- end
1260
- end
1261
-
1262
1300
  return
1263
1301
  end
1264
1302
 
@@ -1312,12 +1350,6 @@ module Girl
1312
1350
  # 处理关闭
1313
1351
  if dst_info[ :closing ] then
1314
1352
  close_dst( dst )
1315
-
1316
- if src then
1317
- close_read_src( src )
1318
- set_src_closing_write( src )
1319
- end
1320
-
1321
1353
  return
1322
1354
  end
1323
1355
 
@@ -1367,8 +1399,6 @@ module Girl
1367
1399
  # 处理关闭
1368
1400
  if stream_info[ :closing ] then
1369
1401
  close_stream( stream )
1370
- close_read_src( src )
1371
- set_src_closing_write( src )
1372
1402
  return
1373
1403
  end
1374
1404
 
@@ -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,26 @@ 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
+ @roles = {} # sock => :dotr / :proxyd / :infod / :dst / :tund / :tcpd / :streamd
13
13
  @tund_infos = {} # tund => {}
14
14
  @tcpd_infos = {} # tcpd => {}
15
15
  @dst_infos = {} # dst => {}
16
16
  @streamd_infos = {} # streamd => {}
17
17
  @tunneling_tunds = {} # tunneling_addr => tund
18
18
  @resolv_caches = {} # domain => [ ip, created_at ]
19
+ @traff_ins = {} # im => 0
20
+ @traff_outs = {} # im => 0
19
21
 
20
22
  dotr, dotw = IO.pipe
21
23
  @dotw = dotw
22
24
  add_read( dotr, :dotr )
23
25
  new_a_proxyd( proxyd_port )
26
+ new_a_infod( infod_port )
24
27
  end
25
28
 
26
29
  ##
@@ -30,18 +33,20 @@ module Girl
30
33
  puts "p#{ Process.pid } #{ Time.new } looping"
31
34
  loop_check_expire
32
35
  loop_check_resume
36
+ loop_check_traff
33
37
 
34
38
  loop do
35
39
  rs, ws = IO.select( @reads, @writes )
36
40
 
37
41
  @mutex.synchronize do
38
- # 先读,再写,避免打上关闭标记后读到
39
42
  rs.each do | sock |
40
43
  case @roles[ sock ]
41
44
  when :dotr then
42
45
  read_dotr( sock )
43
46
  when :proxyd then
44
47
  read_proxyd( sock )
48
+ when :infod then
49
+ read_infod( sock )
45
50
  when :tund then
46
51
  read_tund( sock )
47
52
  when :tcpd then
@@ -113,7 +118,7 @@ module Girl
113
118
  # add read
114
119
  #
115
120
  def add_read( sock, role = nil )
116
- unless @reads.include?( sock ) then
121
+ if !sock.closed? && !@reads.include?( sock ) then
117
122
  @reads << sock
118
123
 
119
124
  if role then
@@ -122,6 +127,27 @@ module Girl
122
127
  end
123
128
  end
124
129
 
130
+ ##
131
+ # add streamd wbuff
132
+ #
133
+ def add_streamd_wbuff( streamd, data )
134
+ return if streamd.closed?
135
+ streamd_info = @streamd_infos[ streamd ]
136
+ streamd_info[ :wbuff ] << data
137
+ add_write( streamd )
138
+
139
+ if streamd_info[ :wbuff ].bytesize >= WBUFF_LIMIT then
140
+ dst = streamd_info[ :dst ]
141
+ dst_info = @dst_infos[ dst ]
142
+
143
+ unless dst_info[ :paused ] then
144
+ puts "p#{ Process.pid } #{ Time.new } pause dst #{ dst_info[ :domain_port ] }"
145
+ dst_info[ :paused ] = true
146
+ @reads.delete( dst )
147
+ end
148
+ end
149
+ end
150
+
125
151
  ##
126
152
  # add write
127
153
  #
@@ -137,7 +163,13 @@ module Girl
137
163
  def close_dst( dst )
138
164
  # puts "debug1 close dst"
139
165
  close_sock( dst )
140
- del_dst_info( dst )
166
+ dst_info = del_dst_info( dst )
167
+ streamd = dst_info[ :streamd ]
168
+
169
+ if streamd then
170
+ close_read_streamd( streamd )
171
+ set_streamd_closing_write( streamd )
172
+ end
141
173
  end
142
174
 
143
175
  ##
@@ -197,7 +229,13 @@ module Girl
197
229
  def close_streamd( streamd )
198
230
  # puts "debug1 close streamd"
199
231
  close_sock( streamd )
200
- @streamd_infos.delete( streamd )
232
+ streamd_info = @streamd_infos.delete( streamd )
233
+ dst = streamd_info[ :dst ]
234
+
235
+ if dst then
236
+ close_read_dst( dst )
237
+ set_dst_closing_write( dst )
238
+ end
201
239
  end
202
240
 
203
241
  ##
@@ -231,6 +269,7 @@ module Girl
231
269
  dst_info = @dst_infos[ dst ]
232
270
  end
233
271
 
272
+ dst_info[ :closed_write ] = true
234
273
  dst_info
235
274
  end
236
275
 
@@ -251,6 +290,7 @@ module Girl
251
290
  streamd_info = @streamd_infos[ streamd ]
252
291
  end
253
292
 
293
+ streamd_info[ :closed_write ] = true
254
294
  streamd_info
255
295
  end
256
296
 
@@ -270,10 +310,12 @@ module Girl
270
310
  end
271
311
 
272
312
  dst_id = dst.local_address.ip_port
313
+ tund_info = @tund_infos[ tund ]
273
314
 
274
315
  @dst_infos[ dst ] = {
275
316
  id: dst_id, # id
276
317
  tund: tund, # 对应tund
318
+ im: tund_info[ :im ], # 标识
277
319
  domain_port: domain_port, # 目的地和端口
278
320
  rbuff: '', # 对应的streamd没准备好,暂存读到的流量
279
321
  streamd: nil, # 对应的streamd
@@ -284,12 +326,12 @@ module Girl
284
326
  last_sent_at: nil, # 上一次发出流量(由streamd发出)的时间
285
327
  paused: false, # 是否已暂停读
286
328
  closing: false, # 准备关闭
287
- closing_write: false # 准备关闭写
329
+ closing_write: false, # 准备关闭写
330
+ closed_write: false # 已关闭写
288
331
  }
289
332
 
290
333
  add_read( dst, :dst )
291
334
 
292
- tund_info = @tund_infos[ tund ]
293
335
  tund_info[ :dst_ids ][ src_id ] = dst_id
294
336
  tund_info[ :dsts ][ dst_id ] = dst
295
337
 
@@ -395,6 +437,27 @@ module Girl
395
437
  end
396
438
  end
397
439
 
440
+ ##
441
+ # loop check traff
442
+ #
443
+ def loop_check_traff
444
+ if RESET_TRAFF_DAY > 0 then
445
+ Thread.new do
446
+ loop do
447
+ sleep CHECK_TRAFF_INTERVAL
448
+
449
+ @mutex.synchronize do
450
+ if Time.new.day == RESET_TRAFF_DAY then
451
+ puts "p#{ Process.pid } #{ Time.new } reset traffs"
452
+ @traff_ins.transform_values!{ | _ | 0 }
453
+ @traff_outs.transform_values!{ | _ | 0 }
454
+ end
455
+ end
456
+ end
457
+ end
458
+ end
459
+ end
460
+
398
461
  ##
399
462
  # new a proxyd
400
463
  #
@@ -412,6 +475,18 @@ module Girl
412
475
  add_read( proxyd, :proxyd )
413
476
  end
414
477
 
478
+ ##
479
+ # new a infod
480
+ #
481
+ def new_a_infod( infod_port )
482
+ infod = Socket.new( Socket::AF_INET, Socket::SOCK_DGRAM, 0 )
483
+ infod.setsockopt( Socket::SOL_SOCKET, Socket::SO_REUSEPORT, 1 )
484
+ infod.bind( Socket.sockaddr_in( infod_port, '127.0.0.1' ) )
485
+
486
+ puts "p#{ Process.pid } #{ Time.new } infod bind on #{ infod_port }"
487
+ add_read( infod, :infod )
488
+ end
489
+
415
490
  ##
416
491
  # next tick
417
492
  #
@@ -489,9 +564,14 @@ module Girl
489
564
  def set_dst_closing( dst )
490
565
  return if dst.closed?
491
566
  dst_info = @dst_infos[ dst ]
492
- dst_info[ :closing ] = true
493
- @reads.delete( dst )
494
- add_write( dst )
567
+
568
+ if dst_info[ :closed_write ] then
569
+ close_dst( dst )
570
+ else
571
+ dst_info[ :closing ] = true
572
+ @reads.delete( dst )
573
+ add_write( dst )
574
+ end
495
575
  end
496
576
 
497
577
  ##
@@ -499,7 +579,10 @@ module Girl
499
579
  #
500
580
  def set_dst_closing_write( dst )
501
581
  return if dst.closed?
582
+
502
583
  dst_info = @dst_infos[ dst ]
584
+ return if dst_info[ :closed_write ]
585
+
503
586
  dst_info[ :closing_write ] = true
504
587
  add_write( dst )
505
588
  end
@@ -510,9 +593,14 @@ module Girl
510
593
  def set_streamd_closing( streamd )
511
594
  return if streamd.closed?
512
595
  streamd_info = @streamd_infos[ streamd ]
513
- streamd_info[ :closing ] = true
514
- @reads.delete( streamd )
515
- add_write( streamd )
596
+
597
+ if streamd_info[ :closed_write ] then
598
+ close_streamd( streamd )
599
+ else
600
+ streamd_info[ :closing ] = true
601
+ @reads.delete( streamd )
602
+ add_write( streamd )
603
+ end
516
604
  end
517
605
 
518
606
  ##
@@ -520,7 +608,10 @@ module Girl
520
608
  #
521
609
  def set_streamd_closing_write( streamd )
522
610
  return if streamd.closed?
611
+
523
612
  streamd_info = @streamd_infos[ streamd ]
613
+ return if streamd_info[ :closed_write ]
614
+
524
615
  streamd_info[ :closing_write ] = true
525
616
  add_write( streamd )
526
617
  end
@@ -565,6 +656,13 @@ module Girl
565
656
  return
566
657
  end
567
658
 
659
+ im = data
660
+
661
+ unless @traff_ins.include?( im ) then
662
+ @traff_ins[ im ] = 0
663
+ @traff_outs[ im ] = 0
664
+ end
665
+
568
666
  tund = Socket.new( Socket::AF_INET, Socket::SOCK_DGRAM, 0 )
569
667
  tund.bind( Socket.sockaddr_in( 0, '0.0.0.0' ) )
570
668
  tund_port = tund.local_address.ip_port
@@ -578,6 +676,7 @@ module Girl
578
676
  add_read( tcpd, :tcpd )
579
677
 
580
678
  tund_info = {
679
+ im: im, # 标识
581
680
  port: tund_port, # 端口
582
681
  tcpd: tcpd, # 对应的tcpd
583
682
  tcpd_port: tcpd_port, # tcpd端口
@@ -601,6 +700,28 @@ module Girl
601
700
  add_proxyd_ctlmsg_tund_port( tund_info )
602
701
  end
603
702
 
703
+ ##
704
+ # read infod
705
+ #
706
+ def read_infod( infod )
707
+ data, addrinfo, rflags, *controls = infod.recvmsg
708
+ ctl_num = data[ 0 ].unpack( 'C' ).first
709
+ # puts "debug1 infod recv #{ ctl_num } #{ addrinfo.inspect }"
710
+
711
+ case ctl_num
712
+ when TRAFF_INFOS then
713
+ data2 = [ TRAFF_INFOS ].pack( 'C' )
714
+
715
+ @traff_ins.keys.sort.each do | im |
716
+ traff_in = @traff_ins[ im ]
717
+ traff_out = @traff_outs[ im ]
718
+ data2 << [ [ im.bytesize ].pack( 'C' ), im, [ traff_in, traff_out ].pack( 'Q>Q>' ) ].join
719
+ end
720
+
721
+ send_data( infod, data2, addrinfo )
722
+ end
723
+ end
724
+
604
725
  ##
605
726
  # read tund
606
727
  #
@@ -672,13 +793,18 @@ module Girl
672
793
  # puts "debug1 accept a streamd"
673
794
  tcpd_info = @tcpd_infos[ tcpd ]
674
795
  tund = tcpd_info[ :tund ]
796
+ tund_info = @tund_infos[ tund ]
675
797
 
676
798
  @streamd_infos[ streamd ] = {
677
- tund: tund, # 对应tund
678
- dst: nil, # 对应dst
679
- domain_port: nil, # dst的目的地和端口
680
- wbuff: '', # 写前,写往近端stream
681
- paused: false # 是否已暂停读
799
+ tund: tund, # 对应tund
800
+ im: tund_info[ :im ], # 标识
801
+ dst: nil, # 对应dst
802
+ domain_port: nil, # dst的目的地和端口
803
+ wbuff: '', # 写前,写往近端stream
804
+ paused: false, # 是否已暂停读
805
+ closing: false, # 准备关闭
806
+ closing_write: false, # 准备关闭写
807
+ closed_write: false # 已关闭写
682
808
  }
683
809
 
684
810
  add_read( streamd, :streamd )
@@ -688,6 +814,8 @@ module Girl
688
814
  # read dst
689
815
  #
690
816
  def read_dst( dst )
817
+ return if dst.closed?
818
+
691
819
  begin
692
820
  data = dst.read_nonblock( READ_SIZE )
693
821
  rescue IO::WaitReadable, Errno::EINTR
@@ -702,6 +830,7 @@ module Girl
702
830
  end
703
831
 
704
832
  dst_info = @dst_infos[ dst ]
833
+ @traff_ins[ dst_info[ :im ] ] += data.bytesize
705
834
  streamd = dst_info[ :streamd ]
706
835
 
707
836
  if streamd then
@@ -709,14 +838,7 @@ module Girl
709
838
  streamd_info = @streamd_infos[ streamd ]
710
839
  data = @custom.encode( data )
711
840
  # 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
841
+ add_streamd_wbuff( streamd, data )
720
842
  end
721
843
  else
722
844
  dst_info[ :rbuff ] << data
@@ -732,6 +854,8 @@ module Girl
732
854
  # read streamd
733
855
  #
734
856
  def read_streamd( streamd )
857
+ return if streamd.closed?
858
+
735
859
  begin
736
860
  data = streamd.read_nonblock( READ_SIZE )
737
861
  rescue IO::WaitReadable, Errno::EINTR
@@ -746,6 +870,7 @@ module Girl
746
870
  end
747
871
 
748
872
  streamd_info = @streamd_infos[ streamd ]
873
+ @traff_ins[ streamd_info[ :im ] ] += data.bytesize
749
874
  dst = streamd_info[ :dst ]
750
875
 
751
876
  unless dst then
@@ -772,7 +897,8 @@ module Girl
772
897
 
773
898
  unless dst_info[ :rbuff ].empty? then
774
899
  # puts "debug1 encode and move dst.rbuff to streamd.wbuff"
775
- streamd_info[ :wbuff ] << @custom.encode( dst_info[ :rbuff ] )
900
+ data2 = @custom.encode( dst_info[ :rbuff ] )
901
+ add_streamd_wbuff( streamd, data2 )
776
902
  end
777
903
 
778
904
  dst_info[ :streamd ] = streamd
@@ -866,12 +992,6 @@ module Girl
866
992
  # 处理关闭
867
993
  if dst_info[ :closing ] then
868
994
  close_dst( dst )
869
-
870
- if streamd then
871
- close_read_streamd( streamd )
872
- set_streamd_closing_write( streamd )
873
- end
874
-
875
995
  return
876
996
  end
877
997
 
@@ -904,6 +1024,7 @@ module Girl
904
1024
  # puts "debug2 written dst #{ written }"
905
1025
  data = data[ written..-1 ]
906
1026
  dst_info[ :wbuff ] = data
1027
+ @traff_outs[ dst_info[ :im ] ] += written
907
1028
  end
908
1029
 
909
1030
  ##
@@ -917,12 +1038,6 @@ module Girl
917
1038
  # 处理关闭
918
1039
  if streamd_info[ :closing ] then
919
1040
  close_streamd( streamd )
920
-
921
- if dst then
922
- close_read_dst( dst )
923
- set_dst_closing_write( dst )
924
- end
925
-
926
1041
  return
927
1042
  end
928
1043
 
@@ -955,6 +1070,7 @@ module Girl
955
1070
  # puts "debug2 written streamd #{ written }"
956
1071
  data = data[ written..-1 ]
957
1072
  streamd_info[ :wbuff ] = data
1073
+ @traff_outs[ streamd_info[ :im ] ] += written
958
1074
 
959
1075
  if dst && !dst.closed? then
960
1076
  dst_info = @dst_infos[ dst ]
@@ -1,3 +1,3 @@
1
1
  module Girl
2
- VERSION = '0.92.0'.freeze
2
+ VERSION = '0.97.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.92.0
4
+ version: 0.97.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-11 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: