girl 0.98.0 → 0.99.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: 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: