girl 0.89.0 → 0.94.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: 8a1e3e17f5d9ca7e92f7c61d52732b78e80b93fcaf9c39c19cb0d4ebc0bb353c
4
- data.tar.gz: 981a168ddcda54ccbddc39acb0dec0af00b018f1fba64ffd04444f584d306671
3
+ metadata.gz: e4fbf6e091f1c0c19865e86a349ed046284ca1f807a171cd8f91b19066de3e28
4
+ data.tar.gz: cb9077f3870ba5cfc2ed17bf66f9c97767d94d882836acf757d5b6addcc4860a
5
5
  SHA512:
6
- metadata.gz: '08f46bb81ff9d4ad4767aad8528e7c7c899f9c305db62f1dcb5079f3ebea28aed0ffc49946ac2b3503303c8dd807e9b27204c0042d3aca73f3c06e42881d294b'
7
- data.tar.gz: 533abffc741dcb060bfc80bf6ac9cdae98a3be4f38d70a7a2e3a0cd3df5eef2b617a961b66d965a306e5adab3d9464fbd3cec7ecd6bddf1b34cbe9cc8acd03c8
6
+ metadata.gz: 4bcb135b88eb5fd4d06f7b7cbeb063553a380efa8c3359c0420b69c2b5481a873ea5632333c8dd56899112d86fb1a11697fa8befc734a168cb2d03ef9eb5b2b2
7
+ data.tar.gz: '07935ef257d9301b18a9e1b4ed943ac0499ca4b502434b27aebebcfb8fcbe3f7a576fc9e5e7a16e9ed37ab9cf75eb490b1802dcad7024dd33f7db1a32ae11d37'
@@ -1,9 +1,12 @@
1
1
  module Girl
2
2
  READ_SIZE = 1024 * 1024 # 一次读多少
3
- WBUFF_LIMIT = 100 * 1024 * 1024 # 写前上限,超过上限暂停读src/dst
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,26 +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
- Q>: 0 ctlmsg -> C: 2 heartbeat not use
26
- 3 a new source -> Q>: src id -> encoded destination address
27
- 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
33
+ Q>: 0 ctlmsg -> C: 2 heartbeat
34
+ 3 a new source -> Q>: src id -> encoded destination address
35
+ 4 paired -> Q>: src id -> n: dst id
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
38
- 15 single miss not use
39
- 16 range miss not use
40
- 17 continue not use
41
- 18 is resend ready not use
42
- 19 resend ready not use
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
43
51
  =end
44
52
 
45
53
  module Girl
@@ -84,14 +92,14 @@ module Girl
84
92
 
85
93
  if direct_path then
86
94
  raise "not found direct file #{ direct_path }" unless File.exist?( direct_path )
87
- directs = ( RESERVED_ROUTE.split( "\n" ) + IO.binread( direct_path ).split( "\n" ) ).map { | line | IPAddr.new( line.strip ) }
95
+ directs = ( RESERVED_ROUTE.split( "\n" ) + IO.binread( direct_path ).split( "\n" ) ).map{ | line | IPAddr.new( line.strip ) }
88
96
  end
89
97
 
90
98
  remotes = []
91
99
 
92
100
  if remote_path then
93
101
  raise "not found remote file #{ remote_path }" unless File.exist?( remote_path )
94
- remotes = IO.binread( remote_path ).split( "\n" ).map { | line | line.strip }
102
+ remotes = IO.binread( remote_path ).split( "\n" ).map{ | line | line.strip }
95
103
  end
96
104
 
97
105
  unless im then
@@ -114,6 +122,10 @@ module Girl
114
122
  puts "im #{ im }"
115
123
  puts "worker count #{ worker_count }"
116
124
 
125
+ Girl::Custom.constants.each do | name |
126
+ puts "#{ name } #{ Girl::Custom.const_get( name ).inspect }"
127
+ end
128
+
117
129
  len = CONSTS.map{ | name | name.size }.max
118
130
 
119
131
  CONSTS.each do | name |
@@ -7,7 +7,6 @@ module Girl
7
7
  def initialize( proxy_port, proxyd_host, proxyd_port, directs, remotes, im )
8
8
  @proxyd_host = proxyd_host
9
9
  @proxyd_addr = Socket.sockaddr_in( proxyd_port, proxyd_host )
10
- @proxyd_ip = Addrinfo.new( @proxyd_addr ).ip_address
11
10
  @directs = directs
12
11
  @remotes = remotes
13
12
  @custom = Girl::ProxyCustom.new( im )
@@ -125,8 +124,28 @@ module Girl
125
124
  return if src.closed?
126
125
  src_info = @src_infos[ src ]
127
126
  src_info[ :wbuff ] << data
128
- add_write( src )
129
127
  src_info[ :last_recv_at ] = Time.new
128
+ add_write( src )
129
+
130
+ if src_info[ :wbuff ].bytesize >= WBUFF_LIMIT then
131
+ dst = src_info[ :dst ]
132
+
133
+ if dst then
134
+ dst_info = @dst_infos[ dst ]
135
+ puts "p#{ Process.pid } #{ Time.new } pause dst #{ dst_info[ :domain ] }"
136
+ dst_info[ :paused ] = true
137
+ @reads.delete( dst )
138
+ else
139
+ stream = src_info[ :stream ]
140
+
141
+ if stream then
142
+ stream_info = @stream_infos[ stream ]
143
+ puts "p#{ Process.pid } #{ Time.new } pause stream #{ stream_info[ :domain ] }"
144
+ stream_info[ :paused ] = true
145
+ @reads.delete( stream )
146
+ end
147
+ end
148
+ end
130
149
  end
131
150
 
132
151
  ##
@@ -169,7 +188,10 @@ module Girl
169
188
  def close_dst( dst )
170
189
  # puts "debug1 close dst"
171
190
  close_sock( dst )
172
- @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 )
173
195
  end
174
196
 
175
197
  ##
@@ -239,7 +261,32 @@ module Girl
239
261
  def close_src( src )
240
262
  # puts "debug1 close src"
241
263
  close_sock( src )
242
- 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 )
243
290
  end
244
291
 
245
292
  ##
@@ -268,6 +315,7 @@ module Girl
268
315
  src_info = @src_infos[ src ]
269
316
  end
270
317
 
318
+ src_info[ :closed_write ] = true
271
319
  src_info
272
320
  end
273
321
 
@@ -288,6 +336,7 @@ module Girl
288
336
  dst_info = @dst_infos[ dst ]
289
337
  end
290
338
 
339
+ dst_info[ :closed_write ] = true
291
340
  dst_info
292
341
  end
293
342
 
@@ -308,6 +357,7 @@ module Girl
308
357
  stream_info = @stream_infos[ stream ]
309
358
  end
310
359
 
360
+ stream_info[ :closed_write ] = true
311
361
  stream_info
312
362
  end
313
363
 
@@ -334,7 +384,7 @@ module Girl
334
384
  def del_src_info( src )
335
385
  src_info = @src_infos.delete( src )
336
386
 
337
- if src_info[ :stream ] && @tun && !@tun.closed? then
387
+ if ( src_info[ :proxy_type ] == :tunnel ) && @tun && !@tun.closed? then
338
388
  @tun_info[ :srcs ].delete( src_info[ :id ] )
339
389
  end
340
390
 
@@ -355,13 +405,17 @@ module Girl
355
405
 
356
406
  if @tun && !@tun.closed? then
357
407
  last_recv_at = @tun_info[ :last_recv_at ] || @tun_info[ :created_at ]
358
- last_sent_at = @tun_info[ :last_sent_at ] || @tun_info[ :created_at ]
359
408
 
360
- if @tun_info[ :srcs ].empty? && ( now - last_recv_at >= EXPIRE_AFTER ) && ( now - last_sent_at >= EXPIRE_AFTER ) then
409
+ if @tun_info[ :srcs ].empty? && ( now - last_recv_at >= EXPIRE_AFTER ) then
361
410
  puts "p#{ Process.pid } #{ Time.new } expire tun"
362
411
  set_tun_closing
363
- trigger = true
412
+ else
413
+ # puts "debug1 #{ Time.new } heartbeat"
414
+ data = [ 0, HEARTBEAT ].pack( 'Q>C' )
415
+ add_ctlmsg( data )
364
416
  end
417
+
418
+ trigger = true
365
419
  end
366
420
 
367
421
  @src_infos.each do | src, src_info |
@@ -415,6 +469,30 @@ module Girl
415
469
  end
416
470
  end
417
471
 
472
+ @dst_infos.select{ | _, dst_info | dst_info[ :paused ] }.each do | dst, dst_info |
473
+ src = dst_info[ :src ]
474
+ src_info = @src_infos[ src ]
475
+
476
+ if src_info[ :wbuff ].size < RESUME_BELOW then
477
+ puts "p#{ Process.pid } #{ Time.new } src.wbuff below #{ RESUME_BELOW }, resume dst #{ dst_info[ :domain ] }"
478
+ dst_info[ :paused ] = false
479
+ add_read( dst )
480
+ trigger = true
481
+ end
482
+ end
483
+
484
+ @stream_infos.select{ | _, stream_info | stream_info[ :paused ] }.each do | stream, stream_info |
485
+ src = stream_info[ :src ]
486
+ src_info = @src_infos[ src ]
487
+
488
+ if src_info[ :wbuff ].size < RESUME_BELOW then
489
+ puts "p#{ Process.pid } #{ Time.new } src.wbuff below #{ RESUME_BELOW }, resume stream #{ stream_info[ :domain ] }"
490
+ stream_info[ :paused ] = false
491
+ add_read( stream )
492
+ trigger = true
493
+ end
494
+ end
495
+
418
496
  next_tick if trigger
419
497
  end
420
498
  end
@@ -449,7 +527,7 @@ module Girl
449
527
  next_tick
450
528
  end
451
529
 
452
- sleep 1
530
+ sleep SEND_HELLO_INTERVAL
453
531
  end
454
532
  end
455
533
  end
@@ -470,7 +548,7 @@ module Girl
470
548
  rescue IO::WaitWritable
471
549
  # connect nonblock 必抛 wait writable
472
550
  rescue Exception => e
473
- puts "p#{ Process.pid } #{ Time.new } dst connect destination #{ e.class }, close src"
551
+ puts "p#{ Process.pid } #{ Time.new } dst connect destination #{ domain } #{ src_info[ :destination_port ] } #{ ip_info.ip_address } #{ e.class }, close src"
474
552
  set_src_closing( src )
475
553
  return
476
554
  end
@@ -480,11 +558,12 @@ module Girl
480
558
  dst_info = {
481
559
  local_port: local_port, # 本地端口
482
560
  src: src, # 对应src
483
- domain: domain, # 域名
561
+ domain: domain, # 目的地
484
562
  wbuff: '', # 写前,从src读到的流量
563
+ paused: false, # 是否已暂停读
485
564
  closing: false, # 准备关闭
486
- closing_read: false, # 准备关闭读
487
- closing_write: false # 准备关闭写
565
+ closing_write: false, # 准备关闭写
566
+ closed_write: false # 已关闭写
488
567
  }
489
568
 
490
569
  @dst_infos[ dst ] = dst_info
@@ -541,9 +620,15 @@ module Girl
541
620
  data << @custom.encode( src_info[ :rbuff ] )
542
621
  end
543
622
 
623
+ domain = src_info[ :destination_domain ]
544
624
  @stream_infos[ stream ] = {
545
- src: src, # 对应src
546
- wbuff: data # 写前,写往远端streamd
625
+ src: src, # 对应src
626
+ domain: domain, # 目的地
627
+ wbuff: data, # 写前,写往远端streamd
628
+ paused: false, # 是否已暂停读
629
+ closing: false, # 准备关闭
630
+ closing_write: false, # 准备关闭写
631
+ closed_write: false # 已关闭写
547
632
  }
548
633
 
549
634
  src_info[ :dst_id ] = dst_id
@@ -588,22 +673,15 @@ module Girl
588
673
  tun.bind( Socket.sockaddr_in( 0, '0.0.0.0' ) )
589
674
  port = tun.local_address.ip_port
590
675
  tun_info = {
591
- port: port, # 端口
592
- pending_sources: [], # 还没配上tund,暂存的src
593
- ctlmsgs: [], # [ ctlmsg, to_addr ]
594
- resend_newers: {}, # 尾巴流量重传队列 src_id => newer_pack_ids
595
- resend_singles: {}, # 单个重传队列 src_id => single_miss_pack_ids
596
- resend_ranges: {}, # 区间重传队列 src_id => range_miss_pack_ids
597
- event_srcs: [], # rbuff不为空,或者准备关闭的src
598
- tund_addr: nil, # tund地址
599
- tcpd_addr: nil, # tcpd地址
600
- srcs: {}, # src_id => src
601
- created_at: Time.new, # 创建时间
602
- last_recv_at: nil, # 上一次收到流量的时间
603
- last_sent_at: nil, # 上一次发出流量的时间
604
- sender_addrs: nil, # 远端发送者地址
605
- last_ping_senders_at: nil, # 上一次ping发送者的时间
606
- closing: false # 是否准备关闭
676
+ port: port, # 端口
677
+ pending_sources: [], # 还没配上tund,暂存的src
678
+ ctlmsgs: [], # [ ctlmsg, to_addr ]
679
+ tund_addr: nil, # tund地址
680
+ tcpd_addr: nil, # tcpd地址
681
+ srcs: {}, # src_id => src
682
+ created_at: Time.new, # 创建时间
683
+ last_recv_at: nil, # 上一次收到流量的时间
684
+ closing: false # 是否准备关闭
607
685
  }
608
686
 
609
687
  @tun = tun
@@ -628,7 +706,7 @@ module Girl
628
706
  next_tick
629
707
  end
630
708
 
631
- sleep 1
709
+ sleep SEND_HELLO_INTERVAL
632
710
  end
633
711
  end
634
712
  end
@@ -701,36 +779,20 @@ module Girl
701
779
  add_read( src )
702
780
  end
703
781
 
704
- ##
705
- # send data
706
- #
707
- def send_data( data, to_addr = nil )
708
- unless to_addr then
709
- to_addr = @tun_info[ :tund_addr ]
710
- end
711
-
712
- begin
713
- written = @tun.sendmsg_nonblock( data, 0, to_addr )
714
- rescue IO::WaitWritable, Errno::EINTR
715
- print '.'
716
- return :wait
717
- rescue Errno::EHOSTUNREACH, Errno::ENETUNREACH, Errno::ENETDOWN => e
718
- puts "#{ Time.new } sendmsg #{ e.class }, close tun"
719
- return :fatal
720
- end
721
-
722
- written
723
- end
724
-
725
782
  ##
726
783
  # set dst closing
727
784
  #
728
785
  def set_dst_closing( dst )
729
786
  return if dst.closed?
730
787
  dst_info = @dst_infos[ dst ]
731
- dst_info[ :closing ] = true
732
- @reads.delete( dst )
733
- add_write( dst )
788
+
789
+ if dst_info[ :closed_write ] then
790
+ close_read_dst( dst )
791
+ else
792
+ dst_info[ :closing ] = true
793
+ @reads.delete( dst )
794
+ add_write( dst )
795
+ end
734
796
  end
735
797
 
736
798
  ##
@@ -738,7 +800,10 @@ module Girl
738
800
  #
739
801
  def set_dst_closing_write( dst )
740
802
  return if dst.closed?
803
+
741
804
  dst_info = @dst_infos[ dst ]
805
+ return if dst_info[ :closed_write ]
806
+
742
807
  dst_info[ :closing_write ] = true
743
808
  add_write( dst )
744
809
  end
@@ -748,10 +813,16 @@ module Girl
748
813
  #
749
814
  def set_src_closing( src )
750
815
  return if src.closed?
751
- @reads.delete( src )
816
+
752
817
  src_info = @src_infos[ src ]
753
- src_info[ :closing ] = true
754
- add_write( src )
818
+
819
+ if src_info[ :closed_write ] then
820
+ close_read_src( src )
821
+ else
822
+ @reads.delete( src )
823
+ src_info[ :closing ] = true
824
+ add_write( src )
825
+ end
755
826
  end
756
827
 
757
828
  ##
@@ -759,7 +830,10 @@ module Girl
759
830
  #
760
831
  def set_src_closing_write( src )
761
832
  return if src.closed?
833
+
762
834
  src_info = @src_infos[ src ]
835
+ return if src_info[ :closed_write ]
836
+
763
837
  src_info[ :closing_write ] = true
764
838
  add_write( src )
765
839
  end
@@ -784,23 +858,15 @@ module Girl
784
858
  end
785
859
  end
786
860
 
787
- ##
788
- # set stream closing
789
- #
790
- def set_stream_closing( stream )
791
- return if stream.closed?
792
- stream_info = @stream_infos[ stream ]
793
- stream_info[ :closing ] = true
794
- @reads.delete( stream )
795
- add_write( stream )
796
- end
797
-
798
861
  ##
799
862
  # set stream closing write
800
863
  #
801
864
  def set_stream_closing_write( stream )
802
865
  return if stream.closed?
866
+
803
867
  stream_info = @stream_infos[ stream ]
868
+ return if stream_info[ :closed_write ]
869
+
804
870
  stream_info[ :closing_write ] = true
805
871
  add_write( stream )
806
872
  end
@@ -856,24 +922,24 @@ module Girl
856
922
  # puts "debug1 accept a src #{ addrinfo.inspect } #{ src_id }"
857
923
 
858
924
  @src_infos[ src ] = {
859
- id: src_id, # id
860
- proxy_proto: :uncheck, # :uncheck / :http / :socks5
861
- proxy_type: :uncheck, # :uncheck / :checking / :direct / :tunnel / :negotiation
862
- destination_domain: nil, # 目的地域名
863
- destination_port: nil, # 目的地端口
864
- is_connect: true, # 代理协议是http的场合,是否是CONNECT
865
- rbuff: '', # 读到的流量
866
- stream: nil, # :tunnel的场合,对应的stream
867
- wbuff: '', # 从dst/stream读到的流量
868
- dst: nil, # :direct的场合,对应的dst
869
- dst_id: nil, # 远端dst id
870
- created_at: Time.new, # 创建时间
871
- last_recv_at: nil, # 上一次收到新流量(由dst收到,或者由stream收到)的时间
872
- last_sent_at: nil, # 上一次发出流量(由dst发出,或者由stream发出)的时间
873
- paused: false, # 是否已暂停
874
- closing: false, # 准备关闭
875
- closing_read: false, # 准备关闭读
876
- closing_write: false # 准备关闭写
925
+ id: src_id, # id
926
+ proxy_proto: :uncheck, # :uncheck / :http / :socks5
927
+ proxy_type: :uncheck, # :uncheck / :checking / :direct / :tunnel / :negotiation
928
+ destination_domain: nil, # 目的地域名
929
+ destination_port: nil, # 目的地端口
930
+ is_connect: true, # 代理协议是http的场合,是否是CONNECT
931
+ rbuff: '', # 读到的流量
932
+ dst: nil, # :direct的场合,对应的dst
933
+ stream: nil, # :tunnel的场合,对应的stream
934
+ dst_id: nil, # 远端dst id
935
+ wbuff: '', # dst/stream读到的流量
936
+ created_at: Time.new, # 创建时间
937
+ last_recv_at: nil, # 上一次收到新流量(由dst收到,或者由stream收到)的时间
938
+ last_sent_at: nil, # 上一次发出流量(由dst发出,或者由stream发出)的时间
939
+ paused: false, # 是否已暂停读
940
+ closing: false, # 准备关闭
941
+ closing_write: false, # 准备关闭写
942
+ closed_write: false # 已关闭写
877
943
  }
878
944
 
879
945
  add_read( src, :src )
@@ -891,10 +957,10 @@ module Girl
891
957
  end
892
958
 
893
959
  from_addr = addrinfo.to_sockaddr
894
- @tun_info[ :last_recv_at ] = Time.new
895
960
  pack_id = data[ 0, 8 ].unpack( 'Q>' ).first
896
961
  return if pack_id != 0
897
962
 
963
+ @tun_info[ :last_recv_at ] = Time.new
898
964
  ctl_num = data[ 8 ].unpack( 'C' ).first
899
965
 
900
966
  case ctl_num
@@ -940,6 +1006,8 @@ module Girl
940
1006
  # read src
941
1007
  #
942
1008
  def read_src( src )
1009
+ return if src.closed?
1010
+
943
1011
  begin
944
1012
  data = src.read_nonblock( READ_SIZE )
945
1013
  rescue IO::WaitReadable, Errno::EINTR
@@ -1093,7 +1161,7 @@ module Girl
1093
1161
  add_write( stream )
1094
1162
 
1095
1163
  if stream_info[ :wbuff ].bytesize >= WBUFF_LIMIT then
1096
- puts "p#{ Process.pid } #{ Time.new } pause tunnel src #{ src_info[ :id ] } #{ src_info[ :destination_domain ] }"
1164
+ puts "p#{ Process.pid } #{ Time.new } pause tunnel src #{ src_info[ :destination_domain ] }"
1097
1165
  src_info[ :paused ] = true
1098
1166
  @reads.delete( src )
1099
1167
  end
@@ -1122,7 +1190,7 @@ module Girl
1122
1190
  add_write( dst )
1123
1191
 
1124
1192
  if dst_info[ :wbuff ].bytesize >= WBUFF_LIMIT then
1125
- puts "p#{ Process.pid } #{ Time.new } pause direct src #{ src_info[ :id ] } #{ src_info[ :destination_domain ] }"
1193
+ puts "p#{ Process.pid } #{ Time.new } pause direct src #{ src_info[ :destination_domain ] }"
1126
1194
  src_info[ :paused ] = true
1127
1195
  @reads.delete( src )
1128
1196
  end
@@ -1143,6 +1211,8 @@ module Girl
1143
1211
  # read dst
1144
1212
  #
1145
1213
  def read_dst( dst )
1214
+ return if dst.closed?
1215
+
1146
1216
  begin
1147
1217
  data = dst.read_nonblock( READ_SIZE )
1148
1218
  rescue IO::WaitReadable, Errno::EINTR
@@ -1165,6 +1235,8 @@ module Girl
1165
1235
  # read stream
1166
1236
  #
1167
1237
  def read_stream( stream )
1238
+ return if stream.closed?
1239
+
1168
1240
  begin
1169
1241
  data = stream.read_nonblock( READ_SIZE )
1170
1242
  rescue IO::WaitReadable, Errno::EINTR
@@ -1200,21 +1272,21 @@ module Girl
1200
1272
  # 发ctlmsg
1201
1273
  while @tun_info[ :ctlmsgs ].any? do
1202
1274
  data, to_addr = @tun_info[ :ctlmsgs ].first
1203
- sent = send_data( data, to_addr )
1204
1275
 
1205
- if sent == :fatal then
1206
- close_tun( tun )
1276
+ begin
1277
+ @tun.sendmsg_nonblock( data, 0, to_addr )
1278
+ rescue IO::WaitWritable, Errno::EINTR
1279
+ puts "p#{ Process.pid } #{ Time.new } wait send ctlmsg, left #{ @tun_info[ :ctlmsgs ].size }"
1207
1280
  return
1208
- elsif sent == :wait then
1209
- # puts "debug1 #{ Time.new } wait send ctlmsg left #{ @tun_info[ :ctlmsgs ].size }"
1210
- @tun_info[ :last_sent_at ] = now
1281
+ rescue Errno::EHOSTUNREACH, Errno::ENETUNREACH, Errno::ENETDOWN => e
1282
+ puts "p#{ Process.pid } #{ Time.new } sendmsg #{ e.class }, close tun"
1283
+ close_tun( tun )
1211
1284
  return
1212
1285
  end
1213
1286
 
1214
1287
  @tun_info[ :ctlmsgs ].shift
1215
1288
  end
1216
1289
 
1217
- @tun_info[ :last_sent_at ] = now
1218
1290
  @writes.delete( tun )
1219
1291
  end
1220
1292
 
@@ -1229,19 +1301,6 @@ module Girl
1229
1301
  # 处理关闭
1230
1302
  if src_info[ :closing ] then
1231
1303
  close_src( src )
1232
-
1233
- if dst then
1234
- close_read_dst( dst )
1235
- set_dst_closing_write( dst )
1236
- else
1237
- stream = src_info[ :stream ]
1238
-
1239
- if stream then
1240
- close_read_stream( stream )
1241
- set_stream_closing_write( stream )
1242
- end
1243
- end
1244
-
1245
1304
  return
1246
1305
  end
1247
1306
 
@@ -1295,12 +1354,6 @@ module Girl
1295
1354
  # 处理关闭
1296
1355
  if dst_info[ :closing ] then
1297
1356
  close_dst( dst )
1298
-
1299
- if src then
1300
- close_read_src( src )
1301
- set_src_closing_write( src )
1302
- end
1303
-
1304
1357
  return
1305
1358
  end
1306
1359
 
@@ -1326,12 +1379,17 @@ module Girl
1326
1379
  rescue Exception => e
1327
1380
  # puts "debug1 write dst #{ e.class }"
1328
1381
  close_write_dst( dst )
1329
- close_read_src( src ) if src
1382
+ close_read_src( src )
1330
1383
  return
1331
1384
  end
1332
1385
 
1333
1386
  data = data[ written..-1 ]
1334
1387
  dst_info[ :wbuff ] = data
1388
+
1389
+ unless src.closed? then
1390
+ src_info = @src_infos[ src ]
1391
+ src_info[ :last_sent_at ] = Time.new
1392
+ end
1335
1393
  end
1336
1394
 
1337
1395
  ##
@@ -1345,8 +1403,6 @@ module Girl
1345
1403
  # 处理关闭
1346
1404
  if stream_info[ :closing ] then
1347
1405
  close_stream( stream )
1348
- close_read_src( src )
1349
- set_src_closing_write( src )
1350
1406
  return
1351
1407
  end
1352
1408
 
@@ -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,6 +33,7 @@ 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 )
@@ -42,6 +46,8 @@ module Girl
42
46
  read_dotr( sock )
43
47
  when :proxyd then
44
48
  read_proxyd( sock )
49
+ when :infod then
50
+ read_infod( sock )
45
51
  when :tund then
46
52
  read_tund( sock )
47
53
  when :tcpd then
@@ -100,15 +106,6 @@ module Girl
100
106
  add_write( @proxyd )
101
107
  end
102
108
 
103
- ##
104
- # add ctlmsg resend ready
105
- #
106
- def add_ctlmsg_resend_ready( tund )
107
- tund_info = @tund_infos[ tund ]
108
- data = [ 0, RESEND_READY ].pack( 'Q>C' )
109
- add_ctlmsg( tund, data )
110
- end
111
-
112
109
  ##
113
110
  # add ctlmsg
114
111
  #
@@ -146,7 +143,13 @@ module Girl
146
143
  def close_dst( dst )
147
144
  # puts "debug1 close dst"
148
145
  close_sock( dst )
149
- del_dst_info( dst )
146
+ dst_info = del_dst_info( dst )
147
+ streamd = dst_info[ :streamd ]
148
+
149
+ if streamd then
150
+ close_read_streamd( streamd )
151
+ set_streamd_closing_write( streamd )
152
+ end
150
153
  end
151
154
 
152
155
  ##
@@ -206,7 +209,13 @@ module Girl
206
209
  def close_streamd( streamd )
207
210
  # puts "debug1 close streamd"
208
211
  close_sock( streamd )
209
- @streamd_infos.delete( streamd )
212
+ streamd_info = @streamd_infos.delete( streamd )
213
+ dst = streamd_info[ :dst ]
214
+
215
+ if dst then
216
+ close_read_dst( dst )
217
+ set_dst_closing_write( dst )
218
+ end
210
219
  end
211
220
 
212
221
  ##
@@ -240,6 +249,7 @@ module Girl
240
249
  dst_info = @dst_infos[ dst ]
241
250
  end
242
251
 
252
+ dst_info[ :closed_write ] = true
243
253
  dst_info
244
254
  end
245
255
 
@@ -260,6 +270,7 @@ module Girl
260
270
  streamd_info = @streamd_infos[ streamd ]
261
271
  end
262
272
 
273
+ streamd_info[ :closed_write ] = true
263
274
  streamd_info
264
275
  end
265
276
 
@@ -274,16 +285,18 @@ module Girl
274
285
  dst.connect_nonblock( destination_addr )
275
286
  rescue IO::WaitWritable
276
287
  rescue Exception => e
277
- puts "p#{ Process.pid } #{ Time.new } connect destination #{ e.class }"
288
+ puts "p#{ Process.pid } #{ Time.new } connect destination #{ domain_port } #{ e.class }"
278
289
  return false
279
290
  end
280
291
 
281
292
  dst_id = dst.local_address.ip_port
293
+ tund_info = @tund_infos[ tund ]
282
294
 
283
295
  @dst_infos[ dst ] = {
284
296
  id: dst_id, # id
285
297
  tund: tund, # 对应tund
286
- domain_port: domain_port, # 域名和端口
298
+ im: tund_info[ :im ], # 标识
299
+ domain_port: domain_port, # 目的地和端口
287
300
  rbuff: '', # 对应的streamd没准备好,暂存读到的流量
288
301
  streamd: nil, # 对应的streamd
289
302
  wbuff: '', # 从streamd读到的流量
@@ -291,15 +304,14 @@ module Girl
291
304
  created_at: Time.new, # 创建时间
292
305
  last_recv_at: nil, # 上一次收到新流量(由streamd收到)的时间
293
306
  last_sent_at: nil, # 上一次发出流量(由streamd发出)的时间
294
- paused: false, # 是否已暂停
307
+ paused: false, # 是否已暂停读
295
308
  closing: false, # 准备关闭
296
- closing_read: false, # 准备关闭读
297
- closing_write: false # 准备关闭写
309
+ closing_write: false, # 准备关闭写
310
+ closed_write: false # 已关闭写
298
311
  }
299
312
 
300
313
  add_read( dst, :dst )
301
314
 
302
- tund_info = @tund_infos[ tund ]
303
315
  tund_info[ :dst_ids ][ src_id ] = dst_id
304
316
  tund_info[ :dsts ][ dst_id ] = dst
305
317
 
@@ -339,9 +351,8 @@ module Girl
339
351
 
340
352
  @tund_infos.each do | tund, tund_info |
341
353
  last_recv_at = tund_info[ :last_recv_at ] || tund_info[ :created_at ]
342
- last_sent_at = tund_info[ :last_sent_at ] || tund_info[ :created_at ]
343
354
 
344
- if tund_info[ :dsts ].empty? && ( now - last_recv_at >= EXPIRE_AFTER ) && ( now - last_sent_at >= EXPIRE_AFTER ) then
355
+ if tund_info[ :dsts ].empty? && ( now - last_recv_at >= EXPIRE_AFTER ) then
345
356
  puts "p#{ Process.pid } #{ Time.new } expire tund #{ tund_info[ :port ] }"
346
357
  set_tund_closing( tund )
347
358
  trigger = true
@@ -388,12 +399,45 @@ module Girl
388
399
  end
389
400
  end
390
401
 
402
+ @streamd_infos.select{ | _, streamd_info | streamd_info[ :paused ] }.each do | streamd, streamd_info |
403
+ dst = streamd_info[ :dst ]
404
+ dst_info = @dst_infos[ dst ]
405
+
406
+ if dst_info[ :wbuff ].size < RESUME_BELOW then
407
+ puts "p#{ Process.pid } #{ Time.new } resume streamd #{ streamd_info[ :domain_port ] }"
408
+ streamd_info[ :paused ] = false
409
+ add_read( streamd )
410
+ trigger = true
411
+ end
412
+ end
413
+
391
414
  next_tick if trigger
392
415
  end
393
416
  end
394
417
  end
395
418
  end
396
419
 
420
+ ##
421
+ # loop check traff
422
+ #
423
+ def loop_check_traff
424
+ if RESET_TRAFF_DAY > 0 then
425
+ Thread.new do
426
+ loop do
427
+ sleep CHECK_TRAFF_INTERVAL
428
+
429
+ @mutex.synchronize do
430
+ if Time.new.day == RESET_TRAFF_DAY then
431
+ puts "p#{ Process.pid } #{ Time.new } reset traffs"
432
+ @traff_ins.transform_values!{ | _ | 0 }
433
+ @traff_outs.transform_values!{ | _ | 0 }
434
+ end
435
+ end
436
+ end
437
+ end
438
+ end
439
+ end
440
+
397
441
  ##
398
442
  # new a proxyd
399
443
  #
@@ -411,6 +455,18 @@ module Girl
411
455
  add_read( proxyd, :proxyd )
412
456
  end
413
457
 
458
+ ##
459
+ # new a infod
460
+ #
461
+ def new_a_infod( infod_port )
462
+ infod = Socket.new( Socket::AF_INET, Socket::SOCK_DGRAM, 0 )
463
+ infod.setsockopt( Socket::SOL_SOCKET, Socket::SO_REUSEPORT, 1 )
464
+ infod.bind( Socket.sockaddr_in( infod_port, '127.0.0.1' ) )
465
+
466
+ puts "p#{ Process.pid } #{ Time.new } infod bind on #{ infod_port }"
467
+ add_read( infod, :infod )
468
+ end
469
+
414
470
  ##
415
471
  # next tick
416
472
  #
@@ -473,9 +529,9 @@ module Girl
473
529
  begin
474
530
  written = sock.sendmsg_nonblock( data, 0, to_addr )
475
531
  rescue IO::WaitWritable, Errno::EINTR
476
- print '.'
477
532
  return :wait
478
533
  rescue Errno::EHOSTUNREACH, Errno::ENETUNREACH, Errno::ENETDOWN => e
534
+ puts "p#{ Process.pid } #{ Time.new } sendmsg #{ e.class }"
479
535
  return :fatal
480
536
  end
481
537
 
@@ -487,10 +543,16 @@ module Girl
487
543
  #
488
544
  def set_dst_closing( dst )
489
545
  return if dst.closed?
546
+
490
547
  dst_info = @dst_infos[ dst ]
491
- dst_info[ :closing ] = true
492
- @reads.delete( dst )
493
- add_write( dst )
548
+
549
+ if dst_info[ :closed_write ] then
550
+ close_read_dst( dst )
551
+ else
552
+ dst_info[ :closing ] = true
553
+ @reads.delete( dst )
554
+ add_write( dst )
555
+ end
494
556
  end
495
557
 
496
558
  ##
@@ -498,7 +560,10 @@ module Girl
498
560
  #
499
561
  def set_dst_closing_write( dst )
500
562
  return if dst.closed?
563
+
501
564
  dst_info = @dst_infos[ dst ]
565
+ return if dst_info[ :closed_write ]
566
+
502
567
  dst_info[ :closing_write ] = true
503
568
  add_write( dst )
504
569
  end
@@ -509,9 +574,14 @@ module Girl
509
574
  def set_streamd_closing( streamd )
510
575
  return if streamd.closed?
511
576
  streamd_info = @streamd_infos[ streamd ]
512
- streamd_info[ :closing ] = true
513
- @reads.delete( streamd )
514
- add_write( streamd )
577
+
578
+ if streamd_info[ :closed_write ] then
579
+ close_read_streamd( streamd )
580
+ else
581
+ streamd_info[ :closing ] = true
582
+ @reads.delete( streamd )
583
+ add_write( streamd )
584
+ end
515
585
  end
516
586
 
517
587
  ##
@@ -519,7 +589,10 @@ module Girl
519
589
  #
520
590
  def set_streamd_closing_write( streamd )
521
591
  return if streamd.closed?
592
+
522
593
  streamd_info = @streamd_infos[ streamd ]
594
+ return if streamd_info[ :closed_write ]
595
+
523
596
  streamd_info[ :closing_write ] = true
524
597
  add_write( streamd )
525
598
  end
@@ -564,6 +637,13 @@ module Girl
564
637
  return
565
638
  end
566
639
 
640
+ im = data
641
+
642
+ unless @traff_ins.include?( im ) then
643
+ @traff_ins[ im ] = 0
644
+ @traff_outs[ im ] = 0
645
+ end
646
+
567
647
  tund = Socket.new( Socket::AF_INET, Socket::SOCK_DGRAM, 0 )
568
648
  tund.bind( Socket.sockaddr_in( 0, '0.0.0.0' ) )
569
649
  tund_port = tund.local_address.ip_port
@@ -577,20 +657,18 @@ module Girl
577
657
  add_read( tcpd, :tcpd )
578
658
 
579
659
  tund_info = {
580
- port: tund_port, # 端口
581
- tcpd: tcpd, # 对应的tcpd
582
- tcpd_port: tcpd_port, # tcpd端口
583
- ctlmsgs: [], # [ ctlmsg, to_addr ]
584
- tun_addr: from_addr, # tun地址
585
- dsts: {}, # dst_id => dst
586
- dst_ids: {}, # src_id => dst_id
587
- created_at: Time.new, # 创建时间
588
- last_recv_at: nil, # 上一次收到流量的时间
589
- last_sent_at: nil, # 上一次发出流量的时间
590
- closing: false, # 准备关闭
591
- closing_read: false, # 准备关闭读
592
- closing_write: false, # 准备关闭写
593
- changed_tun_addr: nil # 记录到和tun addr不符的来源地址
660
+ im: im, # 标识
661
+ port: tund_port, # 端口
662
+ tcpd: tcpd, # 对应的tcpd
663
+ tcpd_port: tcpd_port, # tcpd端口
664
+ ctlmsgs: [], # [ ctlmsg, to_addr ]
665
+ tun_addr: from_addr, # tun地址
666
+ dsts: {}, # dst_id => dst
667
+ dst_ids: {}, # src_id => dst_id
668
+ created_at: Time.new, # 创建时间
669
+ last_recv_at: nil, # 上一次收到流量的时间
670
+ closing: false, # 准备关闭
671
+ changed_tun_addr: nil # 记录到和tun addr不符的来源地址
594
672
  }
595
673
 
596
674
  @tunneling_tunds[ from_addr ] = tund
@@ -603,6 +681,28 @@ module Girl
603
681
  add_proxyd_ctlmsg_tund_port( tund_info )
604
682
  end
605
683
 
684
+ ##
685
+ # read infod
686
+ #
687
+ def read_infod( infod )
688
+ data, addrinfo, rflags, *controls = infod.recvmsg
689
+ ctl_num = data[ 0 ].unpack( 'C' ).first
690
+ # puts "debug1 infod recv #{ ctl_num } #{ addrinfo.inspect }"
691
+
692
+ case ctl_num
693
+ when TRAFF_INFOS then
694
+ data2 = [ TRAFF_INFOS ].pack( 'C' )
695
+
696
+ @traff_ins.keys.sort.each do | im |
697
+ traff_in = @traff_ins[ im ]
698
+ traff_out = @traff_outs[ im ]
699
+ data2 << [ [ im.bytesize ].pack( 'C' ), im, [ traff_in, traff_out ].pack( 'Q>Q>' ) ].join
700
+ end
701
+
702
+ send_data( infod, data2, addrinfo )
703
+ end
704
+ end
705
+
606
706
  ##
607
707
  # read tund
608
708
  #
@@ -625,10 +725,10 @@ module Girl
625
725
  return
626
726
  end
627
727
 
628
- tund_info[ :last_recv_at ] = Time.new
629
728
  pack_id = data[ 0, 8 ].unpack( 'Q>' ).first
630
729
  return if pack_id != 0
631
730
 
731
+ tund_info[ :last_recv_at ] = Time.new
632
732
  ctl_num = data[ 8 ].unpack( 'C' ).first
633
733
 
634
734
  case ctl_num
@@ -674,11 +774,18 @@ module Girl
674
774
  # puts "debug1 accept a streamd"
675
775
  tcpd_info = @tcpd_infos[ tcpd ]
676
776
  tund = tcpd_info[ :tund ]
777
+ tund_info = @tund_infos[ tund ]
677
778
 
678
779
  @streamd_infos[ streamd ] = {
679
- tund: tund, # 对应tund
680
- dst: nil, # 对应dst
681
- wbuff: '' # 写前,写往近端stream
780
+ tund: tund, # 对应tund
781
+ im: tund_info[ :im ], # 标识
782
+ dst: nil, # 对应dst
783
+ domain_port: nil, # dst的目的地和端口
784
+ wbuff: '', # 写前,写往近端stream
785
+ paused: false, # 是否已暂停读
786
+ closing: false, # 准备关闭
787
+ closing_write: false, # 准备关闭写
788
+ closed_write: false # 已关闭写
682
789
  }
683
790
 
684
791
  add_read( streamd, :streamd )
@@ -688,6 +795,8 @@ module Girl
688
795
  # read dst
689
796
  #
690
797
  def read_dst( dst )
798
+ return if dst.closed?
799
+
691
800
  begin
692
801
  data = dst.read_nonblock( READ_SIZE )
693
802
  rescue IO::WaitReadable, Errno::EINTR
@@ -702,6 +811,7 @@ module Girl
702
811
  end
703
812
 
704
813
  dst_info = @dst_infos[ dst ]
814
+ @traff_ins[ dst_info[ :im ] ] += data.bytesize
705
815
  streamd = dst_info[ :streamd ]
706
816
 
707
817
  if streamd then
@@ -713,7 +823,7 @@ module Girl
713
823
  add_write( streamd )
714
824
 
715
825
  if streamd_info[ :wbuff ].bytesize >= WBUFF_LIMIT then
716
- puts "p#{ Process.pid } #{ Time.new } pause dst #{ dst_info[ :id ] } #{ dst_info[ :domain_port ] }"
826
+ puts "p#{ Process.pid } #{ Time.new } pause dst #{ dst_info[ :domain_port ] }"
717
827
  dst_info[ :paused ] = true
718
828
  @reads.delete( dst )
719
829
  end
@@ -722,7 +832,7 @@ module Girl
722
832
  dst_info[ :rbuff ] << data
723
833
 
724
834
  if dst_info[ :rbuff ].bytesize >= WBUFF_LIMIT then
725
- # puts "debug1 dst.rbuff full #{ dst_info[ :rbuff ].bytesize }"
835
+ # puts "debug1 dst.rbuff full"
726
836
  set_dst_closing( dst )
727
837
  end
728
838
  end
@@ -732,6 +842,8 @@ module Girl
732
842
  # read streamd
733
843
  #
734
844
  def read_streamd( streamd )
845
+ return if streamd.closed?
846
+
735
847
  begin
736
848
  data = streamd.read_nonblock( READ_SIZE )
737
849
  rescue IO::WaitReadable, Errno::EINTR
@@ -746,6 +858,7 @@ module Girl
746
858
  end
747
859
 
748
860
  streamd_info = @streamd_infos[ streamd ]
861
+ @traff_ins[ streamd_info[ :im ] ] += data.bytesize
749
862
  dst = streamd_info[ :dst ]
750
863
 
751
864
  unless dst then
@@ -768,6 +881,7 @@ module Girl
768
881
  # puts "debug1 set streamd.dst #{ dst_id }"
769
882
  streamd_info[ :dst ] = dst
770
883
  dst_info = @dst_infos[ dst ]
884
+ streamd_info[ :domain_port ] = dst_info[ :domain_port ]
771
885
 
772
886
  unless dst_info[ :rbuff ].empty? then
773
887
  # puts "debug1 encode and move dst.rbuff to streamd.wbuff"
@@ -787,6 +901,12 @@ module Girl
787
901
  dst_info[ :wbuff ] << data
788
902
  dst_info[ :last_recv_at ] = Time.new
789
903
  add_write( dst )
904
+
905
+ if dst_info[ :wbuff ].bytesize >= WBUFF_LIMIT then
906
+ puts "p#{ Process.pid } #{ Time.new } pause streamd #{ streamd_info[ :domain_port ] }"
907
+ streamd_info[ :paused ] = true
908
+ @reads.delete( streamd )
909
+ end
790
910
  end
791
911
  end
792
912
 
@@ -800,6 +920,7 @@ module Girl
800
920
  sent = send_data( proxyd, data, to_addr )
801
921
 
802
922
  if sent == :wait then
923
+ puts "p#{ Process.pid } #{ Time.new } wait proxyd send ctlmsg, left #{ @proxyd_info[ :ctlmsgs ].size }"
803
924
  return
804
925
  else
805
926
  @proxyd_info[ :ctlmsgs ].shift
@@ -837,15 +958,13 @@ module Girl
837
958
  close_tund( tund )
838
959
  return
839
960
  elsif sent == :wait then
840
- # puts "debug1 #{ Time.new } wait send ctlmsg left #{ tund_info[ :ctlmsgs ].size }"
841
- tund_info[ :last_sent_at ] = now
961
+ puts "p#{ Process.pid } #{ Time.new } wait tund #{ tund_info[ :port ] } send ctlmsg, left #{ tund_info[ :ctlmsgs ].size }"
842
962
  return
843
963
  end
844
964
 
845
965
  tund_info[ :ctlmsgs ].shift
846
966
  end
847
967
 
848
- tund_info[ :last_sent_at ] = now
849
968
  @writes.delete( tund )
850
969
  end
851
970
 
@@ -860,12 +979,6 @@ module Girl
860
979
  # 处理关闭
861
980
  if dst_info[ :closing ] then
862
981
  close_dst( dst )
863
-
864
- if streamd then
865
- close_read_streamd( streamd )
866
- set_streamd_closing_write( streamd )
867
- end
868
-
869
982
  return
870
983
  end
871
984
 
@@ -898,6 +1011,7 @@ module Girl
898
1011
  # puts "debug2 written dst #{ written }"
899
1012
  data = data[ written..-1 ]
900
1013
  dst_info[ :wbuff ] = data
1014
+ @traff_outs[ dst_info[ :im ] ] += written
901
1015
  end
902
1016
 
903
1017
  ##
@@ -911,12 +1025,6 @@ module Girl
911
1025
  # 处理关闭
912
1026
  if streamd_info[ :closing ] then
913
1027
  close_streamd( streamd )
914
-
915
- if dst then
916
- close_read_dst( dst )
917
- set_dst_closing_write( dst )
918
- end
919
-
920
1028
  return
921
1029
  end
922
1030
 
@@ -949,6 +1057,7 @@ module Girl
949
1057
  # puts "debug2 written streamd #{ written }"
950
1058
  data = data[ written..-1 ]
951
1059
  streamd_info[ :wbuff ] = data
1060
+ @traff_outs[ streamd_info[ :im ] ] += written
952
1061
 
953
1062
  if dst && !dst.closed? then
954
1063
  dst_info = @dst_infos[ dst ]
@@ -1,3 +1,3 @@
1
1
  module Girl
2
- VERSION = '0.89.0'.freeze
2
+ VERSION = '0.94.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.89.0
4
+ version: 0.94.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-10 00:00:00.000000000 Z
11
+ date: 2020-10-15 00:00:00.000000000 Z
12
12
  dependencies: []
13
13
  description: escape evil.
14
14
  email: