girl 0.98.0 → 0.99.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: a0201dd1519345fc7a831c89a0a8ab139d2fa96d66da2545fcfd1de9102bbe23
4
- data.tar.gz: e529faf1d41f6d80074eed26519c0fef85a092058dc74a936e17c067ce3a6f1b
3
+ metadata.gz: a9256dd41425122dd6c8f579d7821c70213b042090c2ce3320b20931c6aa9f8e
4
+ data.tar.gz: 7af6d01468ee207a768d52ecaf96b3baadb89bb81130f37850776b4ed6bf0393
5
5
  SHA512:
6
- metadata.gz: eec9fbcfa84d537bf1c9a301f2974ac5d2b3b3a0b6a4614d071b39c329faf8800e168afa618851a083a3bfc1df0770bb8da7252457394b6f3a1b02778fdae293
7
- data.tar.gz: 37dc3789f90c73e6116a15cce0b37b1532f6c2b250996e8db0b0b1ad21ffb8d9a7909b6d06218c20574026f3730b134a0383dc348cad12c5ff56fe5897df420a
6
+ metadata.gz: ff1e09096efc25f66473d85e34652b76841ffa533a538c75f63562c3593afd48089d40398f74abebd40338f4af12bfc2277669ec9550f0b599b30437b681ed51
7
+ data.tar.gz: 95c954a9651bc636c20298a94a39a1ec334867283bd24d0b53423528d0047a82e0a89ea6764015d6d0cfc1598210aba586ef9fdf7e75ceea4a50e3797f85f356
@@ -14,6 +14,12 @@ module Girl
14
14
  @reads = []
15
15
  @writes = []
16
16
  @closing_srcs = []
17
+ @paused_srcs = []
18
+ @paused_dsts = []
19
+ @paused_streams = []
20
+ @resume_srcs = []
21
+ @resume_dsts = []
22
+ @resume_streams = []
17
23
  @roles = {} # sock => :dotr / :proxy / :src / :dst / :tun / :stream
18
24
  @src_infos = {} # src => {}
19
25
  @dst_infos = {} # dst => {}
@@ -90,6 +96,15 @@ module Girl
90
96
 
91
97
  private
92
98
 
99
+ ##
100
+ # add closing src
101
+ #
102
+ def add_closing_src( src )
103
+ return if src.closed? || @closing_srcs.include?( src )
104
+ @closing_srcs << src
105
+ next_tick
106
+ end
107
+
93
108
  ##
94
109
  # add ctlmsg
95
110
  #
@@ -101,9 +116,37 @@ module Girl
101
116
  if to_addr then
102
117
  @tun_info[ :ctlmsgs ] << [ data, to_addr ]
103
118
  add_write( @tun )
119
+ next_tick
104
120
  end
105
121
  end
106
122
 
123
+ ##
124
+ # add paused src
125
+ #
126
+ def add_paused_src( src )
127
+ return if src.closed? || @paused_srcs.include?( src )
128
+ @reads.delete( src )
129
+ @paused_srcs << src
130
+ end
131
+
132
+ ##
133
+ # add paused dst
134
+ #
135
+ def add_paused_dst( dst )
136
+ return if dst.closed? || @paused_dsts.include?( dst )
137
+ @reads.delete( dst )
138
+ @paused_dsts << dst
139
+ end
140
+
141
+ ##
142
+ # add paused stream
143
+ #
144
+ def add_paused_stream( stream )
145
+ return if stream.closed? || @paused_streams.include?( stream )
146
+ @reads.delete( stream )
147
+ @paused_streams << stream
148
+ end
149
+
107
150
  ##
108
151
  # add read
109
152
  #
@@ -117,6 +160,60 @@ module Girl
117
160
  end
118
161
  end
119
162
 
163
+ ##
164
+ # add resume src
165
+ #
166
+ def add_resume_src( src )
167
+ return if @resume_srcs.include?( src )
168
+ @resume_srcs << src
169
+ next_tick
170
+ end
171
+
172
+ ##
173
+ # add resume dst
174
+ #
175
+ def add_resume_dst( dst )
176
+ return if @resume_dsts.include?( dst )
177
+ @resume_dsts << dst
178
+ next_tick
179
+ end
180
+
181
+ ##
182
+ # add resume stream
183
+ #
184
+ def add_resume_stream( stream )
185
+ return if @resume_streams.include?( stream )
186
+ @resume_streams << stream
187
+ next_tick
188
+ end
189
+
190
+ ##
191
+ # add dst wbuff
192
+ #
193
+ def add_dst_wbuff( dst, data )
194
+ dst_info = @dst_infos[ dst ]
195
+ dst_info[ :wbuff ] << data
196
+ add_write( dst )
197
+
198
+ if dst_info[ :wbuff ].bytesize >= WBUFF_LIMIT then
199
+ puts "p#{ Process.pid } #{ Time.new } pause direct src #{ dst_info[ :domain ] }"
200
+ add_paused_src( dst_info[ :src ] )
201
+ end
202
+ end
203
+
204
+ ##
205
+ # add src rbuff
206
+ #
207
+ def add_src_rbuff( src, data )
208
+ src_info = @src_infos[ src ]
209
+ src_info[ :rbuff ] << data
210
+
211
+ if src_info[ :rbuff ].bytesize >= WBUFF_LIMIT then
212
+ # puts "debug1 src.rbuff full"
213
+ add_closing_src( src )
214
+ end
215
+ end
216
+
120
217
  ##
121
218
  # add src wbuff
122
219
  #
@@ -131,23 +228,33 @@ module Girl
131
228
  dst = src_info[ :dst ]
132
229
 
133
230
  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 )
231
+ puts "p#{ Process.pid } #{ Time.new } pause dst #{ src_info[ :destination_domain ] }"
232
+ add_paused_dst( dst )
138
233
  else
139
234
  stream = src_info[ :stream ]
140
235
 
141
236
  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 )
237
+ puts "p#{ Process.pid } #{ Time.new } pause stream #{ src_info[ :destination_domain ] }"
238
+ add_paused_stream( stream )
146
239
  end
147
240
  end
148
241
  end
149
242
  end
150
243
 
244
+ ##
245
+ # add stream wbuff
246
+ #
247
+ def add_stream_wbuff( stream, data )
248
+ stream_info = @stream_infos[ stream ]
249
+ stream_info[ :wbuff ] << data
250
+ add_write( stream )
251
+
252
+ if stream_info[ :wbuff ].bytesize >= WBUFF_LIMIT then
253
+ puts "p#{ Process.pid } #{ Time.new } pause tunnel src #{ stream_info[ :domain ] }"
254
+ add_paused_src( stream_info[ :src ] )
255
+ end
256
+ end
257
+
151
258
  ##
152
259
  # add src wbuff socks5 conn reply
153
260
  #
@@ -182,18 +289,6 @@ module Girl
182
289
  @roles.delete( sock )
183
290
  end
184
291
 
185
- ##
186
- # close dst
187
- #
188
- def close_dst( dst )
189
- # puts "debug1 close dst"
190
- close_sock( dst )
191
- dst_info = @dst_infos.delete( dst )
192
- src = dst_info[ :src ]
193
- close_read_src( src )
194
- set_src_closing_write( src )
195
- end
196
-
197
292
  ##
198
293
  # close read src
199
294
  #
@@ -211,7 +306,6 @@ module Girl
211
306
  src_info = @src_infos[ src ]
212
307
  end
213
308
 
214
- src_info[ :paused ] = false
215
309
  src_info
216
310
  end
217
311
 
@@ -259,6 +353,7 @@ module Girl
259
353
  # close src
260
354
  #
261
355
  def close_src( src )
356
+ return if src.closed?
262
357
  # puts "debug1 close src"
263
358
  close_sock( src )
264
359
  src_info = del_src_info( src )
@@ -277,24 +372,14 @@ module Girl
277
372
  end
278
373
  end
279
374
 
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 )
290
- end
291
-
292
375
  ##
293
376
  # close tun
294
377
  #
295
378
  def close_tun( tun )
296
379
  # puts "debug1 close tun"
297
380
  close_sock( tun )
381
+ @tun_info[ :ctlmsgs ].clear
382
+ @tun_info[ :srcs ].each{ | _, src | close_src( src ) }
298
383
  end
299
384
 
300
385
  ##
@@ -380,7 +465,7 @@ module Girl
380
465
  def del_src_info( src )
381
466
  src_info = @src_infos.delete( src )
382
467
 
383
- if ( src_info[ :proxy_type ] == :tunnel ) && @tun && !@tun.closed? then
468
+ if ( src_info[ :proxy_type ] == :tunnel ) && @tun then
384
469
  @tun_info[ :srcs ].delete( src_info[ :id ] )
385
470
  end
386
471
 
@@ -396,10 +481,9 @@ module Girl
396
481
  sleep CHECK_EXPIRE_INTERVAL
397
482
 
398
483
  @mutex.synchronize do
399
- trigger = false
400
484
  now = Time.new
401
485
 
402
- if @tun && !@tun.closed? && !@tun_info[ :closing ] then
486
+ if @tun && !@tun.closed? then
403
487
  last_recv_at = @tun_info[ :last_recv_at ] || @tun_info[ :created_at ]
404
488
 
405
489
  if @tun_info[ :srcs ].empty? && ( now - last_recv_at >= EXPIRE_AFTER ) then
@@ -410,8 +494,6 @@ module Girl
410
494
  data = [ 0, HEARTBEAT ].pack( 'Q>C' )
411
495
  add_ctlmsg( data )
412
496
  end
413
-
414
- trigger = true
415
497
  end
416
498
 
417
499
  @src_infos.each do | src, src_info |
@@ -420,12 +502,9 @@ module Girl
420
502
 
421
503
  if ( now - last_recv_at >= EXPIRE_AFTER ) && ( now - last_sent_at >= EXPIRE_AFTER ) then
422
504
  puts "p#{ Process.pid } #{ Time.new } expire src #{ src_info[ :destination_domain ] }"
423
- set_src_closing( src )
424
- trigger = true
505
+ add_closing_src( src )
425
506
  end
426
507
  end
427
-
428
- next_tick if trigger
429
508
  end
430
509
  end
431
510
  end
@@ -440,56 +519,61 @@ module Girl
440
519
  sleep CHECK_RESUME_INTERVAL
441
520
 
442
521
  @mutex.synchronize do
443
- trigger = false
444
-
445
- @src_infos.select{ | _, src_info | src_info[ :paused ] }.each do | src, src_info |
446
- dst = src_info[ :dst ]
447
-
448
- if dst then
449
- dst_info = @dst_infos[ dst ]
450
-
451
- if dst_info[ :wbuff ].size < RESUME_BELOW then
452
- puts "p#{ Process.pid } #{ Time.new } dst.wbuff below #{ RESUME_BELOW }, resume src #{ src_info[ :destination_domain ] }"
453
- resume_src( src )
454
- trigger = true
455
- end
522
+ @paused_srcs.each do | src |
523
+ if src.closed? then
524
+ add_resume_src( src )
456
525
  else
457
- stream = src_info[ :stream ]
458
- stream_info = @stream_infos[ stream ]
459
-
460
- if stream_info[ :wbuff ].size < RESUME_BELOW then
461
- puts "p#{ Process.pid } #{ Time.new } stream.wbuff below #{ RESUME_BELOW }, resume src #{ src_info[ :destination_domain ] }"
462
- resume_src( src )
463
- trigger = true
526
+ src_info = @src_infos[ src ]
527
+ dst = src_info[ :dst ]
528
+
529
+ if dst then
530
+ dst_info = @dst_infos[ dst ]
531
+
532
+ if dst_info[ :wbuff ].size < RESUME_BELOW then
533
+ puts "p#{ Process.pid } #{ Time.new } resume direct src #{ src_info[ :destination_domain ] }"
534
+ add_resume_src( src )
535
+ end
536
+ else
537
+ stream = src_info[ :stream ]
538
+ stream_info = @stream_infos[ stream ]
539
+
540
+ if stream_info[ :wbuff ].size < RESUME_BELOW then
541
+ puts "p#{ Process.pid } #{ Time.new } resume tunnel src #{ src_info[ :destination_domain ] }"
542
+ add_resume_src( src )
543
+ end
464
544
  end
465
545
  end
466
546
  end
467
547
 
468
- @dst_infos.select{ | _, dst_info | dst_info[ :paused ] }.each do | dst, dst_info |
469
- src = dst_info[ :src ]
470
- src_info = @src_infos[ src ]
548
+ @paused_dsts.each do | dst |
549
+ if dst.closed? then
550
+ add_resume_dst( dst )
551
+ else
552
+ dst_info = @dst_infos[ dst ]
553
+ src = dst_info[ :src ]
554
+ src_info = @src_infos[ src ]
471
555
 
472
- if src_info[ :wbuff ].size < RESUME_BELOW then
473
- puts "p#{ Process.pid } #{ Time.new } src.wbuff below #{ RESUME_BELOW }, resume dst #{ dst_info[ :domain ] }"
474
- dst_info[ :paused ] = false
475
- add_read( dst )
476
- trigger = true
556
+ if src_info[ :wbuff ].size < RESUME_BELOW then
557
+ puts "p#{ Process.pid } #{ Time.new } resume dst #{ dst_info[ :domain ] }"
558
+ add_resume_dst( dst )
559
+ end
477
560
  end
478
561
  end
479
562
 
480
- @stream_infos.select{ | _, stream_info | stream_info[ :paused ] }.each do | stream, stream_info |
481
- src = stream_info[ :src ]
482
- src_info = @src_infos[ src ]
563
+ @paused_streams.each do | stream |
564
+ if stream.closed? then
565
+ add_resume_stream( stream )
566
+ else
567
+ stream_info = @stream_infos[ stream ]
568
+ src = stream_info[ :src ]
569
+ src_info = @src_infos[ src ]
483
570
 
484
- if src_info[ :wbuff ].size < RESUME_BELOW then
485
- puts "p#{ Process.pid } #{ Time.new } src.wbuff below #{ RESUME_BELOW }, resume stream #{ stream_info[ :domain ] }"
486
- stream_info[ :paused ] = false
487
- add_read( stream )
488
- trigger = true
571
+ if src_info[ :wbuff ].size < RESUME_BELOW then
572
+ puts "p#{ Process.pid } #{ Time.new } resume stream #{ stream_info[ :domain ] }"
573
+ add_resume_stream( stream )
574
+ end
489
575
  end
490
576
  end
491
-
492
- next_tick if trigger
493
577
  end
494
578
  end
495
579
  end
@@ -520,7 +604,6 @@ module Girl
520
604
  end
521
605
 
522
606
  add_ctlmsg( data )
523
- next_tick
524
607
  end
525
608
 
526
609
  sleep SEND_HELLO_INTERVAL
@@ -545,7 +628,7 @@ module Girl
545
628
  # connect nonblock 必抛 wait writable
546
629
  rescue Exception => e
547
630
  puts "p#{ Process.pid } #{ Time.new } dst connect destination #{ domain } #{ src_info[ :destination_port ] } #{ ip_info.ip_address } #{ e.class }, close src"
548
- set_src_closing( src )
631
+ add_closing_src( src )
549
632
  return
550
633
  end
551
634
 
@@ -554,7 +637,6 @@ module Girl
554
637
  src: src, # 对应src
555
638
  domain: domain, # 目的地
556
639
  wbuff: '', # 写前,从src读到的流量
557
- paused: false, # 是否已暂停读
558
640
  closing_write: false # 准备关闭写
559
641
  }
560
642
 
@@ -589,7 +671,7 @@ module Girl
589
671
 
590
672
  if dst_id == 0 then
591
673
  puts "p#{ Process.pid } #{ Time.new } remote dst already closed"
592
- set_src_closing( src )
674
+ add_closing_src( src )
593
675
  return
594
676
  end
595
677
 
@@ -617,7 +699,6 @@ module Girl
617
699
  src: src, # 对应src
618
700
  domain: domain, # 目的地
619
701
  wbuff: data, # 写前,写往远端streamd
620
- paused: false, # 是否已暂停读
621
702
  closing_write: false # 准备关闭写
622
703
  }
623
704
 
@@ -693,7 +774,6 @@ module Girl
693
774
  # puts "debug1 #{ data.inspect }"
694
775
 
695
776
  add_ctlmsg( data, @proxyd_addr )
696
- next_tick
697
777
  end
698
778
 
699
779
  sleep SEND_HELLO_INTERVAL
@@ -753,22 +833,12 @@ module Girl
753
833
  next_tick
754
834
  end
755
835
  else
756
- set_src_closing( src )
757
- next_tick
836
+ add_closing_src( src )
758
837
  end
759
838
  end
760
839
  end
761
840
  end
762
841
 
763
- ##
764
- # resume src
765
- #
766
- def resume_src( src )
767
- src_info = @src_infos[ src ]
768
- src_info[ :paused ] = false
769
- add_read( src )
770
- end
771
-
772
842
  ##
773
843
  # set dst closing write
774
844
  #
@@ -782,17 +852,6 @@ module Girl
782
852
  add_write( dst )
783
853
  end
784
854
 
785
- ##
786
- # set src is closing
787
- #
788
- def set_src_closing( src )
789
- return if src.closed? || @closing_srcs.include?( src )
790
- @reads.delete( src )
791
- @writes.delete( src )
792
- @closing_srcs << src
793
- add_write( @tun ) if @tun
794
- end
795
-
796
855
  ##
797
856
  # set src closing write
798
857
  #
@@ -842,8 +901,8 @@ module Girl
842
901
  return if @tun.closed? || @tun_info[ :closing ]
843
902
  @tun_info[ :closing ] = true
844
903
  @reads.delete( @tun )
845
- add_write( @tun )
846
- @tun_info[ :srcs ].each{ | _, src | set_src_closing( src ) }
904
+ @writes.delete( @tun )
905
+ next_tick
847
906
  end
848
907
 
849
908
  ##
@@ -869,7 +928,43 @@ module Girl
869
928
  # read dotr
870
929
  #
871
930
  def read_dotr( dotr )
872
- dotr.read( 1 )
931
+ dotr.read_nonblock( READ_SIZE )
932
+
933
+ if @tun && !@tun.closed? && @tun_info[ :closing ] then
934
+ close_tun( @tun )
935
+ end
936
+
937
+ if @closing_srcs.any? then
938
+ @closing_srcs.each{ | src | close_src( src ) }
939
+ @closing_srcs.clear
940
+ end
941
+
942
+ if @resume_srcs.any? then
943
+ @resume_srcs.each do | src |
944
+ add_read( src )
945
+ @paused_srcs.delete( src )
946
+ end
947
+
948
+ @resume_srcs.clear
949
+ end
950
+
951
+ if @resume_dsts.any? then
952
+ @resume_dsts.each do | dst |
953
+ add_read( dst )
954
+ @paused_dsts.delete( dst )
955
+ end
956
+
957
+ @resume_dsts.clear
958
+ end
959
+
960
+ if @resume_streams.any? then
961
+ @resume_streams.each do | stream |
962
+ add_read( stream )
963
+ @paused_streams.delete( stream )
964
+ end
965
+
966
+ @resume_streams.clear
967
+ end
873
968
  end
874
969
 
875
970
  ##
@@ -901,12 +996,12 @@ module Girl
901
996
  created_at: Time.new, # 创建时间
902
997
  last_recv_at: nil, # 上一次收到新流量(由dst收到,或者由stream收到)的时间
903
998
  last_sent_at: nil, # 上一次发出流量(由dst发出,或者由stream发出)的时间
904
- paused: false, # 是否已暂停读
905
999
  closing_write: false # 准备关闭写
906
1000
  }
907
1001
 
908
1002
  add_read( src, :src )
909
1003
 
1004
+ # 用到tun,是在解析目的地域名得出是国外ip之后。但解析域名是额外的线程,为避免多线程重复建tun,在accept到src时就建。
910
1005
  if @tun.nil? || @tun.closed? then
911
1006
  new_a_tun
912
1007
  end
@@ -916,6 +1011,8 @@ module Girl
916
1011
  # read tun
917
1012
  #
918
1013
  def read_tun( tun )
1014
+ return if tun.closed?
1015
+
919
1016
  begin
920
1017
  data, addrinfo, rflags, *controls = tun.recvmsg_nonblock
921
1018
  rescue IO::WaitReadable, Errno::EINTR
@@ -1006,7 +1103,7 @@ module Girl
1006
1103
 
1007
1104
  unless domain_port then
1008
1105
  puts "p#{ Process.pid } #{ Time.new } CONNECT miss domain"
1009
- set_src_closing( src )
1106
+ add_closing_src( src )
1010
1107
  return
1011
1108
  end
1012
1109
  elsif data[ 0 ].unpack( 'C' ).first == 5 then
@@ -1024,7 +1121,7 @@ module Girl
1024
1121
 
1025
1122
  unless methods.include?( 0 ) then
1026
1123
  puts "p#{ Process.pid } #{ Time.new } miss method 00"
1027
- set_src_closing( src )
1124
+ add_closing_src( src )
1028
1125
  return
1029
1126
  end
1030
1127
 
@@ -1044,7 +1141,7 @@ module Girl
1044
1141
 
1045
1142
  unless host_line then
1046
1143
  # puts "debug1 not found host line"
1047
- set_src_closing( src )
1144
+ add_closing_src( src )
1048
1145
  return
1049
1146
  end
1050
1147
 
@@ -1056,7 +1153,7 @@ module Girl
1056
1153
 
1057
1154
  unless domain_port then
1058
1155
  puts "p#{ Process.pid } #{ Time.new } Host line miss domain"
1059
- set_src_closing( src )
1156
+ add_closing_src( src )
1060
1157
  return
1061
1158
  end
1062
1159
  end
@@ -1121,26 +1218,13 @@ module Girl
1121
1218
  data, _ = sub_http_request( data )
1122
1219
  end
1123
1220
 
1124
- stream_info = @stream_infos[ stream ]
1125
1221
  data = @custom.encode( data )
1126
1222
  # puts "debug2 add stream.wbuff encoded #{ data.bytesize }"
1127
- stream_info[ :wbuff ] << data
1128
- add_write( stream )
1129
-
1130
- if stream_info[ :wbuff ].bytesize >= WBUFF_LIMIT then
1131
- puts "p#{ Process.pid } #{ Time.new } pause tunnel src #{ src_info[ :destination_domain ] }"
1132
- src_info[ :paused ] = true
1133
- @reads.delete( src )
1134
- end
1223
+ add_stream_wbuff( stream, data )
1135
1224
  end
1136
1225
  else
1137
1226
  # puts "debug1 stream not ready, save data to src.rbuff"
1138
- src_info[ :rbuff ] << data
1139
-
1140
- if src_info[ :rbuff ].bytesize >= WBUFF_LIMIT then
1141
- # puts "debug1 tunnel src.rbuff full"
1142
- set_src_closing( src )
1143
- end
1227
+ add_src_rbuff( src, data )
1144
1228
  end
1145
1229
  when :direct then
1146
1230
  dst = src_info[ :dst ]
@@ -1151,25 +1235,12 @@ module Girl
1151
1235
  data, _ = sub_http_request( data )
1152
1236
  end
1153
1237
 
1154
- dst_info = @dst_infos[ dst ]
1155
1238
  # puts "debug2 add dst.wbuff #{ data.bytesize }"
1156
- dst_info[ :wbuff ] << data
1157
- add_write( dst )
1158
-
1159
- if dst_info[ :wbuff ].bytesize >= WBUFF_LIMIT then
1160
- puts "p#{ Process.pid } #{ Time.new } pause direct src #{ src_info[ :destination_domain ] }"
1161
- src_info[ :paused ] = true
1162
- @reads.delete( src )
1163
- end
1239
+ add_dst_wbuff( dst, data )
1164
1240
  end
1165
1241
  else
1166
1242
  # puts "debug1 dst not ready, save data to src.rbuff"
1167
- src_info[ :rbuff ] << data
1168
-
1169
- if src_info[ :rbuff ].bytesize >= WBUFF_LIMIT then
1170
- # puts "debug1 direct src.rbuff full"
1171
- set_src_closing( src )
1172
- end
1243
+ add_src_rbuff( src, data )
1173
1244
  end
1174
1245
  end
1175
1246
  end
@@ -1228,18 +1299,7 @@ module Girl
1228
1299
  # write tun
1229
1300
  #
1230
1301
  def write_tun( tun )
1231
- # 处理关闭
1232
- if @closing_srcs.any? then
1233
- @closing_srcs.each{ | src | close_src( src ) }
1234
- @closing_srcs.clear
1235
- end
1236
-
1237
- if @tun_info[ :closing ] then
1238
- close_tun( tun )
1239
- return
1240
- end
1241
-
1242
- now = Time.new
1302
+ return if tun.closed?
1243
1303
 
1244
1304
  # 发ctlmsg
1245
1305
  while @tun_info[ :ctlmsgs ].any? do
@@ -1251,8 +1311,8 @@ module Girl
1251
1311
  puts "p#{ Process.pid } #{ Time.new } wait send ctlmsg, left #{ @tun_info[ :ctlmsgs ].size }"
1252
1312
  return
1253
1313
  rescue Errno::EHOSTUNREACH, Errno::ENETUNREACH, Errno::ENETDOWN => e
1254
- puts "p#{ Process.pid } #{ Time.new } sendmsg #{ e.class }, close tun"
1255
- close_tun( tun )
1314
+ puts "p#{ Process.pid } #{ Time.new } sendmsg #{ e.class }, set tun closing"
1315
+ set_tun_closing
1256
1316
  return
1257
1317
  end
1258
1318
 
@@ -9,8 +9,13 @@ module Girl
9
9
  @mutex = Mutex.new
10
10
  @reads = []
11
11
  @writes = []
12
+ @closing_tunds = []
12
13
  @closing_dsts = []
13
14
  @closing_streamds = []
15
+ @paused_dsts = []
16
+ @paused_streamds = []
17
+ @resume_dsts = []
18
+ @resume_streamds = []
14
19
  @roles = {} # sock => :dotr / :proxyd / :infod / :dst / :tund / :tcpd / :streamd
15
20
  @tund_infos = {} # tund => {}
16
21
  @tcpd_infos = {} # tcpd => {}
@@ -99,12 +104,30 @@ module Girl
99
104
  private
100
105
 
101
106
  ##
102
- # add proxyd ctlmsg
107
+ # add closing dst
103
108
  #
104
- def add_proxyd_ctlmsg_tund_port( tund_info )
105
- data = [ 0, TUND_PORT, tund_info[ :port ], tund_info[ :tcpd_port ] ].pack( 'Q>Cnn' )
106
- @proxyd_info[ :ctlmsgs ] << [ data, tund_info[ :tun_addr ] ]
107
- add_write( @proxyd )
109
+ def add_closing_dst( dst )
110
+ return if dst.closed? || @closing_dsts.include?( dst )
111
+ @closing_dsts << dst
112
+ next_tick
113
+ end
114
+
115
+ ##
116
+ # add closing streamd
117
+ #
118
+ def add_closing_streamd( streamd )
119
+ return if streamd.closed? || @closing_streamds.include?( streamd )
120
+ @closing_streamds << streamd
121
+ next_tick
122
+ end
123
+
124
+ ##
125
+ # add closing tund
126
+ #
127
+ def add_closing_tund( tund )
128
+ return if tund.closed? || @closing_tunds.include?( tund )
129
+ @closing_tunds << tund
130
+ next_tick
108
131
  end
109
132
 
110
133
  ##
@@ -116,6 +139,63 @@ module Girl
116
139
  add_write( tund )
117
140
  end
118
141
 
142
+ ##
143
+ # add dst rbuff
144
+ #
145
+ def add_dst_rbuff( dst, data )
146
+ dst_info = @dst_infos[ dst ]
147
+ dst_info[ :rbuff ] << data
148
+
149
+ if dst_info[ :rbuff ].bytesize >= WBUFF_LIMIT then
150
+ # puts "debug1 dst.rbuff full"
151
+ add_closing_dst( dst )
152
+ end
153
+ end
154
+
155
+ ##
156
+ # add dst wbuff
157
+ #
158
+ def add_dst_wbuff( dst, data )
159
+ return if dst.closed? || @closing_dsts.include?( dst )
160
+
161
+ dst_info = @dst_infos[ dst ]
162
+ dst_info[ :wbuff ] << data
163
+ dst_info[ :last_recv_at ] = Time.new
164
+ add_write( dst )
165
+
166
+ if dst_info[ :wbuff ].bytesize >= WBUFF_LIMIT then
167
+ puts "p#{ Process.pid } #{ Time.new } pause streamd #{ dst_info[ :domain_port ] }"
168
+ add_paused_streamd( dst_info[ :streamd ] )
169
+ end
170
+ end
171
+
172
+ ##
173
+ # add paused dst
174
+ #
175
+ def add_paused_dst( dst )
176
+ return if dst.closed? || @paused_dsts.include?( dst )
177
+ @reads.delete( dst )
178
+ @paused_dsts << dst
179
+ end
180
+
181
+ ##
182
+ # add paused streamd
183
+ #
184
+ def add_paused_streamd( streamd )
185
+ return if streamd.closed? || @paused_streamds.include?( streamd )
186
+ @reads.delete( streamd )
187
+ @paused_streamds << streamd
188
+ end
189
+
190
+ ##
191
+ # add proxyd ctlmsg
192
+ #
193
+ def add_proxyd_ctlmsg_tund_port( tund_info )
194
+ data = [ 0, TUND_PORT, tund_info[ :port ], tund_info[ :tcpd_port ] ].pack( 'Q>Cnn' )
195
+ @proxyd_info[ :ctlmsgs ] << [ data, tund_info[ :tun_addr ] ]
196
+ add_write( @proxyd )
197
+ end
198
+
119
199
  ##
120
200
  # add read
121
201
  #
@@ -129,6 +209,24 @@ module Girl
129
209
  end
130
210
  end
131
211
 
212
+ ##
213
+ # add resume dst
214
+ #
215
+ def add_resume_dst( dst )
216
+ return if @resume_dsts.include?( dst )
217
+ @resume_dsts << dst
218
+ next_tick
219
+ end
220
+
221
+ ##
222
+ # add resume streamd
223
+ #
224
+ def add_resume_streamd( streamd )
225
+ return if @resume_streamds.include?( streamd )
226
+ @resume_streamds << streamd
227
+ next_tick
228
+ end
229
+
132
230
  ##
133
231
  # add streamd wbuff
134
232
  #
@@ -139,14 +237,8 @@ module Girl
139
237
  add_write( streamd )
140
238
 
141
239
  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
240
+ puts "p#{ Process.pid } #{ Time.new } pause dst #{ streamd_info[ :domain_port ] }"
241
+ add_paused_dst( streamd_info[ :dst ] )
150
242
  end
151
243
  end
152
244
 
@@ -163,6 +255,7 @@ module Girl
163
255
  # close dst
164
256
  #
165
257
  def close_dst( dst )
258
+ return if dst.closed?
166
259
  # puts "debug1 close dst"
167
260
  close_sock( dst )
168
261
  dst_info = del_dst_info( dst )
@@ -191,7 +284,6 @@ module Girl
191
284
  dst_info = @dst_infos[ dst ]
192
285
  end
193
286
 
194
- dst_info[ :paused ] = false
195
287
  dst_info
196
288
  end
197
289
 
@@ -229,6 +321,7 @@ module Girl
229
321
  # close streamd
230
322
  #
231
323
  def close_streamd( streamd )
324
+ return if streamd.closed?
232
325
  # puts "debug1 close streamd"
233
326
  close_sock( streamd )
234
327
  streamd_info = @streamd_infos.delete( streamd )
@@ -251,6 +344,7 @@ module Girl
251
344
  close_sock( tcpd )
252
345
  @tcpd_infos.delete( tcpd )
253
346
  @tunneling_tunds.delete( tund_info[ :tun_addr ] )
347
+ tund_info[ :dsts ].each{ | _, dst | close_dst( dst ) }
254
348
  end
255
349
 
256
350
  ##
@@ -323,7 +417,6 @@ module Girl
323
417
  created_at: Time.new, # 创建时间
324
418
  last_recv_at: nil, # 上一次收到新流量(由streamd收到)的时间
325
419
  last_sent_at: nil, # 上一次发出流量(由streamd发出)的时间
326
- paused: false, # 是否已暂停读
327
420
  closing_write: false # 准备关闭写
328
421
  }
329
422
 
@@ -344,13 +437,13 @@ module Girl
344
437
  def del_dst_info( dst )
345
438
  dst_info = @dst_infos.delete( dst )
346
439
  tund = dst_info[ :tund ]
440
+ tund_info = @tund_infos[ tund ]
347
441
 
348
- unless tund.closed? then
349
- tund_info = @tund_infos[ tund ]
442
+ if tund_info then
350
443
  tund_info[ :dsts ].delete( dst_info[ :id ] )
351
444
  tund_info[ :dst_ids ].delete( dst_info[ :src_id ] )
352
445
  end
353
-
446
+
354
447
  dst_info
355
448
  end
356
449
 
@@ -363,18 +456,14 @@ module Girl
363
456
  sleep CHECK_EXPIRE_INTERVAL
364
457
 
365
458
  @mutex.synchronize do
366
- trigger = false
367
459
  now = Time.new
368
460
 
369
461
  @tund_infos.each do | tund, tund_info |
370
- unless tund_info[ :closing ] then
371
- last_recv_at = tund_info[ :last_recv_at ] || tund_info[ :created_at ]
462
+ last_recv_at = tund_info[ :last_recv_at ] || tund_info[ :created_at ]
372
463
 
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
464
+ if tund_info[ :dsts ].empty? && ( now - last_recv_at >= EXPIRE_AFTER ) then
465
+ puts "p#{ Process.pid } #{ Time.new } expire tund #{ tund_info[ :port ] }"
466
+ add_closing_tund( tund )
378
467
  end
379
468
  end
380
469
 
@@ -384,12 +473,9 @@ module Girl
384
473
 
385
474
  if ( now - last_recv_at >= EXPIRE_AFTER ) && ( now - last_sent_at >= EXPIRE_AFTER ) then
386
475
  puts "p#{ Process.pid } #{ Time.new } expire dst #{ dst_info[ :domain_port ] }"
387
- set_dst_closing( dst )
388
- trigger = true
476
+ add_closing_dst( dst )
389
477
  end
390
478
  end
391
-
392
- next_tick if trigger
393
479
  end
394
480
  end
395
481
  end
@@ -404,33 +490,35 @@ module Girl
404
490
  sleep CHECK_RESUME_INTERVAL
405
491
 
406
492
  @mutex.synchronize do
407
- trigger = false
408
-
409
- @dst_infos.select{ | _, dst_info | dst_info[ :paused ] }.each do | dst, dst_info |
410
- streamd = dst_info[ :streamd ]
411
- streamd_info = @streamd_infos[ streamd ]
412
-
413
- if streamd_info[ :wbuff ].size < RESUME_BELOW then
414
- puts "p#{ Process.pid } #{ Time.new } resume dst #{ dst_info[ :domain_port ] }"
415
- dst_info[ :paused ] = false
416
- add_read( dst )
417
- trigger = true
493
+ @paused_dsts.each do | dst |
494
+ if dst.closed? then
495
+ add_resume_dst( dst )
496
+ else
497
+ dst_info = @dst_infos[ dst ]
498
+ streamd = dst_info[ :streamd ]
499
+ streamd_info = @streamd_infos[ streamd ]
500
+
501
+ if streamd_info[ :wbuff ].size < RESUME_BELOW then
502
+ puts "p#{ Process.pid } #{ Time.new } resume dst #{ dst_info[ :domain_port ] }"
503
+ add_resume_dst( dst )
504
+ end
418
505
  end
419
506
  end
420
507
 
421
- @streamd_infos.select{ | _, streamd_info | streamd_info[ :paused ] }.each do | streamd, streamd_info |
422
- dst = streamd_info[ :dst ]
423
- dst_info = @dst_infos[ dst ]
424
-
425
- if dst_info[ :wbuff ].size < RESUME_BELOW then
426
- puts "p#{ Process.pid } #{ Time.new } resume streamd #{ streamd_info[ :domain_port ] }"
427
- streamd_info[ :paused ] = false
428
- add_read( streamd )
429
- trigger = true
508
+ @paused_streamds.each do | streamd |
509
+ if streamd.closed? then
510
+ add_resume_streamd( streamd )
511
+ else
512
+ streamd_info = @streamd_infos[ streamd ]
513
+ dst = streamd_info[ :dst ]
514
+ dst_info = @dst_infos[ dst ]
515
+
516
+ if dst_info[ :wbuff ].size < RESUME_BELOW then
517
+ puts "p#{ Process.pid } #{ Time.new } resume streamd #{ streamd_info[ :domain_port ] }"
518
+ add_resume_streamd( streamd )
519
+ end
430
520
  end
431
521
  end
432
-
433
- next_tick if trigger
434
522
  end
435
523
  end
436
524
  end
@@ -557,18 +645,6 @@ module Girl
557
645
  written
558
646
  end
559
647
 
560
- ##
561
- # set dst closing
562
- #
563
- def set_dst_closing( dst )
564
- return if dst.closed? || @closing_dsts.include?( dst )
565
- @reads.delete( dst )
566
- @writes.delete( dst )
567
- @closing_dsts << dst
568
- dst_info = @dst_infos[ dst ]
569
- add_write( dst_info[ :tund ] )
570
- end
571
-
572
648
  ##
573
649
  # set dst closing write
574
650
  #
@@ -582,18 +658,6 @@ module Girl
582
658
  add_write( dst )
583
659
  end
584
660
 
585
- ##
586
- # set streamd closing
587
- #
588
- def set_streamd_closing( streamd )
589
- return if streamd.closed? || @closing_streamds.include?( streamd )
590
- @reads.delete( streamd )
591
- @writes.delete( streamd )
592
- @closing_streamds << streamd
593
- streamd_info = @streamd_infos[ streamd ]
594
- add_write( streamd_info[ :tund ] )
595
- end
596
-
597
661
  ##
598
662
  # set streamd closing write
599
663
  #
@@ -608,25 +672,56 @@ module Girl
608
672
  end
609
673
 
610
674
  ##
611
- # set tund is closing
675
+ # read dotr
612
676
  #
613
- def set_tund_closing( tund )
614
- return if tund.closed?
677
+ def read_dotr( dotr )
678
+ dotr.read_nonblock( READ_SIZE )
615
679
 
616
- tund_info = @tund_infos[ tund ]
617
- return if tund_info[ :closing ]
680
+ # 处理关闭
681
+ if @closing_tunds.any? then
682
+ @closing_tunds.each do | tund |
683
+ unless tund.closed? then
684
+ tund_info = @tund_infos[ tund ]
685
+
686
+ if tund_info[ :changed_tun_addr ] then
687
+ data = [ 0, IP_CHANGED ].pack( 'Q>C' )
688
+ send_data( tund, data, tund_info[ :changed_tun_addr ] )
689
+ end
618
690
 
619
- tund_info[ :closing ] = true
620
- @reads.delete( tund )
621
- add_write( tund )
622
- tund_info[ :dsts ].each{ | _, dst | set_dst_closing( dst ) }
623
- end
691
+ close_tund( tund )
692
+ end
693
+ end
624
694
 
625
- ##
626
- # read dotr
627
- #
628
- def read_dotr( dotr )
629
- dotr.read( 1 )
695
+ @closing_tunds.clear
696
+ end
697
+
698
+ if @closing_dsts.any? then
699
+ @closing_dsts.each{ | dst | close_dst( dst ) }
700
+ @closing_dsts.clear
701
+ end
702
+
703
+ if @closing_streamds.any? then
704
+ @closing_streamds.each{ | streamd | close_streamd( streamd ) }
705
+ @closing_streamds.clear
706
+ end
707
+
708
+ if @resume_dsts.any? then
709
+ @resume_dsts.each do | dst |
710
+ add_read( dst )
711
+ @paused_dsts.delete( dst )
712
+ end
713
+
714
+ @resume_dsts.clear
715
+ end
716
+
717
+ if @resume_streamds.any? then
718
+ @resume_streamds.each do | streamd |
719
+ add_read( streamd )
720
+ @paused_streamds.delete( streamd )
721
+ end
722
+
723
+ @resume_streamds.clear
724
+ end
630
725
  end
631
726
 
632
727
  ##
@@ -681,7 +776,6 @@ module Girl
681
776
  dst_ids: {}, # src_id => dst_id
682
777
  created_at: Time.new, # 创建时间
683
778
  last_recv_at: nil, # 上一次收到流量的时间
684
- closing: false, # 准备关闭
685
779
  changed_tun_addr: nil # 记录到和tun addr不符的来源地址
686
780
  }
687
781
 
@@ -721,6 +815,8 @@ module Girl
721
815
  # read tund
722
816
  #
723
817
  def read_tund( tund )
818
+ return if tund.closed?
819
+
724
820
  begin
725
821
  data, addrinfo, rflags, *controls = tund.recvmsg_nonblock
726
822
  rescue IO::WaitReadable, Errno::EINTR
@@ -735,7 +831,7 @@ module Girl
735
831
  # 通常是光猫刷新ip和端口,但万一不是,为了避免脏数据注入,关闭tund
736
832
  puts "p#{ Process.pid } #{ Time.new } from #{ addrinfo.inspect } not match tun addr #{ Addrinfo.new( tund_info[ :tun_addr ] ).inspect }"
737
833
  tund_info[ :changed_tun_addr ] = from_addr
738
- set_tund_closing( tund )
834
+ add_closing_tund( tund )
739
835
  return
740
836
  end
741
837
 
@@ -770,7 +866,7 @@ module Girl
770
866
  resolve_domain( tund, src_id, domain_port )
771
867
  when TUN_FIN then
772
868
  puts "p#{ Process.pid } #{ Time.new } recv tun fin"
773
- set_tund_closing( tund )
869
+ add_closing_tund( tund )
774
870
  end
775
871
  end
776
872
 
@@ -798,7 +894,6 @@ module Girl
798
894
  dst: nil, # 对应dst
799
895
  domain_port: nil, # dst的目的地和端口
800
896
  wbuff: '', # 写前,写往近端stream
801
- paused: false, # 是否已暂停读
802
897
  closing_write: false # 准备关闭写
803
898
  }
804
899
 
@@ -836,12 +931,7 @@ module Girl
836
931
  add_streamd_wbuff( streamd, data )
837
932
  end
838
933
  else
839
- dst_info[ :rbuff ] << data
840
-
841
- if dst_info[ :rbuff ].bytesize >= WBUFF_LIMIT then
842
- # puts "debug1 dst.rbuff full"
843
- set_dst_closing( dst )
844
- end
934
+ add_dst_rbuff( dst, data )
845
935
  end
846
936
  end
847
937
 
@@ -873,7 +963,7 @@ module Girl
873
963
  tund = streamd_info[ :tund ]
874
964
 
875
965
  if tund.closed? then
876
- set_streamd_closing( streamd )
966
+ add_closing_streamd( streamd )
877
967
  return
878
968
  end
879
969
 
@@ -881,7 +971,7 @@ module Girl
881
971
  dst = tund_info[ :dsts ][ dst_id ]
882
972
 
883
973
  unless dst then
884
- set_streamd_closing( streamd )
974
+ add_closing_streamd( streamd )
885
975
  return
886
976
  end
887
977
 
@@ -902,20 +992,9 @@ module Girl
902
992
  return if data.empty?
903
993
  end
904
994
 
905
- if !dst.closed? && !@closing_dsts.include?( dst ) then
906
- dst_info = @dst_infos[ dst ]
907
- data = @custom.decode( data )
908
- # puts "debug2 add dst.wbuff decoded #{ data.bytesize }"
909
- dst_info[ :wbuff ] << data
910
- dst_info[ :last_recv_at ] = Time.new
911
- add_write( dst )
912
-
913
- if dst_info[ :wbuff ].bytesize >= WBUFF_LIMIT then
914
- puts "p#{ Process.pid } #{ Time.new } pause streamd #{ streamd_info[ :domain_port ] }"
915
- streamd_info[ :paused ] = true
916
- @reads.delete( streamd )
917
- end
918
- end
995
+ data = @custom.decode( data )
996
+ # puts "debug2 add dst.wbuff decoded #{ data.bytesize }"
997
+ add_dst_wbuff( dst, data )
919
998
  end
920
999
 
921
1000
  ##
@@ -942,31 +1021,9 @@ module Girl
942
1021
  # write tund
943
1022
  #
944
1023
  def write_tund( tund )
1024
+ return if tund.closed?
945
1025
  tund_info = @tund_infos[ tund ]
946
1026
 
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
-
958
- if tund_info[ :closing ] then
959
- if tund_info[ :changed_tun_addr ] then
960
- data = [ 0, IP_CHANGED ].pack( 'Q>C' )
961
- send_data( tund, data, tund_info[ :changed_tun_addr ] )
962
- end
963
-
964
- close_tund( tund )
965
- return
966
- end
967
-
968
- now = Time.new
969
-
970
1027
  # 发ctlmsg
971
1028
  while tund_info[ :ctlmsgs ].any? do
972
1029
  data = tund_info[ :ctlmsgs ].first
@@ -1,3 +1,3 @@
1
1
  module Girl
2
- VERSION = '0.98.0'.freeze
2
+ VERSION = '0.99.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.98.0
4
+ version: 0.99.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-19 00:00:00.000000000 Z
11
+ date: 2020-10-20 00:00:00.000000000 Z
12
12
  dependencies: []
13
13
  description: escape evil.
14
14
  email: