girl 0.89.0 → 0.94.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: 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: