girl 0.93.0 → 0.98.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: 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: