girl 0.92.0 → 0.97.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: 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: