girl 0.92.0 → 0.97.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 +4 -4
- data/lib/girl/head.rb +6 -1
- data/lib/girl/proxy.rb +24 -7
- data/lib/girl/proxy_worker.rb +90 -60
- data/lib/girl/proxyd.rb +11 -1
- data/lib/girl/proxyd_worker.rb +156 -40
- data/lib/girl/version.rb +1 -1
- metadata +2 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 1488058f7502fb83ee815a38ba4b11276a2bd5732bfadf596f5f42fbbb6bae53
|
4
|
+
data.tar.gz: 1ac6377572a1ff976f4626127e78f76e7c949683b035c2df7426acac70b3ac86
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 27bc728548949021b2f477ede35b85ff3888ba3371824d32458a390fe9040a10ac0fd11483f25426cda27b95784a2f71b3837fed6b264583ced0378ef6c1b2ee
|
7
|
+
data.tar.gz: d07a0a982e4ecbaf4c798163027bbdd68c7cd3510280e5f904a079aa6796aa57f5b0c96067c86ee71630409e92eb923050b132974496bfdbfed71154e61e2a60
|
data/lib/girl/head.rb
CHANGED
@@ -2,8 +2,11 @@ module Girl
|
|
2
2
|
READ_SIZE = 1024 * 1024 # 一次读多少
|
3
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
|
data/lib/girl/proxy.rb
CHANGED
@@ -20,21 +20,34 @@ proxyd-tun:
|
|
20
20
|
|
21
21
|
Q>: 0 ctlmsg -> C: 1 tund port -> n: tund port -> n: tcpd port
|
22
22
|
|
23
|
+
local-infod:
|
24
|
+
|
25
|
+
C: 101 traff infos
|
26
|
+
|
27
|
+
infod-local:
|
28
|
+
|
29
|
+
C: 101 traff infos -> [ C: im len -> im -> Q>: traff in -> Q>: traff out ]
|
30
|
+
|
23
31
|
tun-tund:
|
24
32
|
|
25
33
|
Q>: 0 ctlmsg -> C: 2 heartbeat
|
26
34
|
3 a new source -> Q>: src id -> encoded destination address
|
27
35
|
4 paired -> Q>: src id -> n: dst id
|
28
|
-
5 dest status
|
29
|
-
6 source status
|
30
|
-
7 miss
|
31
|
-
8 fin1
|
32
|
-
9 confirm fin1
|
33
|
-
10 fin2
|
34
|
-
11 confirm fin2
|
36
|
+
5 dest status NOT USE
|
37
|
+
6 source status NOT USE
|
38
|
+
7 miss NOT USE
|
39
|
+
8 fin1 NOT USE
|
40
|
+
9 confirm fin1 NOT USE
|
41
|
+
10 fin2 NOT USE
|
42
|
+
11 confirm fin2 NOT USE
|
35
43
|
12 tund fin
|
36
44
|
13 tun fin
|
37
45
|
14 tun ip changed
|
46
|
+
15 single miss NOT USE
|
47
|
+
16 range miss NOT USE
|
48
|
+
17 continue NOT USE
|
49
|
+
18 is resend ready NOT USE
|
50
|
+
19 resend ready NOT USE
|
38
51
|
=end
|
39
52
|
|
40
53
|
module Girl
|
@@ -109,6 +122,10 @@ module Girl
|
|
109
122
|
puts "im #{ im }"
|
110
123
|
puts "worker count #{ worker_count }"
|
111
124
|
|
125
|
+
Girl::Custom.constants.each do | name |
|
126
|
+
puts "#{ name } #{ Girl::Custom.const_get( name ).inspect }"
|
127
|
+
end
|
128
|
+
|
112
129
|
len = CONSTS.map{ | name | name.size }.max
|
113
130
|
|
114
131
|
CONSTS.each do | name |
|
data/lib/girl/proxy_worker.rb
CHANGED
@@ -37,7 +37,6 @@ module Girl
|
|
37
37
|
rs, ws = IO.select( @reads, @writes )
|
38
38
|
|
39
39
|
@mutex.synchronize do
|
40
|
-
# 先读,再写,避免打上关闭标记后读到
|
41
40
|
rs.each do | sock |
|
42
41
|
case @roles[ sock ]
|
43
42
|
when :dotr then
|
@@ -108,7 +107,7 @@ module Girl
|
|
108
107
|
# add read
|
109
108
|
#
|
110
109
|
def add_read( sock, role = nil )
|
111
|
-
|
110
|
+
if !sock.closed? && !@reads.include?( sock ) then
|
112
111
|
@reads << sock
|
113
112
|
|
114
113
|
if role then
|
@@ -188,7 +187,10 @@ module Girl
|
|
188
187
|
def close_dst( dst )
|
189
188
|
# puts "debug1 close dst"
|
190
189
|
close_sock( dst )
|
191
|
-
@dst_infos.delete( dst )
|
190
|
+
dst_info = @dst_infos.delete( dst )
|
191
|
+
src = dst_info[ :src ]
|
192
|
+
close_read_src( src )
|
193
|
+
set_src_closing_write( src )
|
192
194
|
end
|
193
195
|
|
194
196
|
##
|
@@ -258,7 +260,32 @@ module Girl
|
|
258
260
|
def close_src( src )
|
259
261
|
# puts "debug1 close src"
|
260
262
|
close_sock( src )
|
261
|
-
del_src_info( src )
|
263
|
+
src_info = del_src_info( src )
|
264
|
+
dst = src_info[ :dst ]
|
265
|
+
|
266
|
+
if dst then
|
267
|
+
close_read_dst( dst )
|
268
|
+
set_dst_closing_write( dst )
|
269
|
+
else
|
270
|
+
stream = src_info[ :stream ]
|
271
|
+
|
272
|
+
if stream then
|
273
|
+
close_read_stream( stream )
|
274
|
+
set_stream_closing_write( stream )
|
275
|
+
end
|
276
|
+
end
|
277
|
+
end
|
278
|
+
|
279
|
+
##
|
280
|
+
# close stream
|
281
|
+
#
|
282
|
+
def close_stream( stream )
|
283
|
+
# puts "debug1 close stream"
|
284
|
+
close_sock( stream )
|
285
|
+
stream_info = @stream_infos.delete( stream )
|
286
|
+
src = stream_info[ :src ]
|
287
|
+
close_read_src( src )
|
288
|
+
set_src_closing_write( src )
|
262
289
|
end
|
263
290
|
|
264
291
|
##
|
@@ -287,6 +314,7 @@ module Girl
|
|
287
314
|
src_info = @src_infos[ src ]
|
288
315
|
end
|
289
316
|
|
317
|
+
src_info[ :closed_write ] = true
|
290
318
|
src_info
|
291
319
|
end
|
292
320
|
|
@@ -307,6 +335,7 @@ module Girl
|
|
307
335
|
dst_info = @dst_infos[ dst ]
|
308
336
|
end
|
309
337
|
|
338
|
+
dst_info[ :closed_write ] = true
|
310
339
|
dst_info
|
311
340
|
end
|
312
341
|
|
@@ -327,6 +356,7 @@ module Girl
|
|
327
356
|
stream_info = @stream_infos[ stream ]
|
328
357
|
end
|
329
358
|
|
359
|
+
stream_info[ :closed_write ] = true
|
330
360
|
stream_info
|
331
361
|
end
|
332
362
|
|
@@ -353,7 +383,7 @@ module Girl
|
|
353
383
|
def del_src_info( src )
|
354
384
|
src_info = @src_infos.delete( src )
|
355
385
|
|
356
|
-
if src_info[ :
|
386
|
+
if ( src_info[ :proxy_type ] == :tunnel ) && @tun && !@tun.closed? then
|
357
387
|
@tun_info[ :srcs ].delete( src_info[ :id ] )
|
358
388
|
end
|
359
389
|
|
@@ -369,6 +399,7 @@ module Girl
|
|
369
399
|
sleep CHECK_EXPIRE_INTERVAL
|
370
400
|
|
371
401
|
@mutex.synchronize do
|
402
|
+
trigger = false
|
372
403
|
now = Time.new
|
373
404
|
|
374
405
|
if @tun && !@tun.closed? then
|
@@ -382,6 +413,8 @@ module Girl
|
|
382
413
|
data = [ 0, HEARTBEAT ].pack( 'Q>C' )
|
383
414
|
add_ctlmsg( data )
|
384
415
|
end
|
416
|
+
|
417
|
+
trigger = true
|
385
418
|
end
|
386
419
|
|
387
420
|
@src_infos.each do | src, src_info |
|
@@ -391,10 +424,11 @@ module Girl
|
|
391
424
|
if ( now - last_recv_at >= EXPIRE_AFTER ) && ( now - last_sent_at >= EXPIRE_AFTER ) then
|
392
425
|
puts "p#{ Process.pid } #{ Time.new } expire src #{ src_info[ :destination_domain ] }"
|
393
426
|
set_src_closing( src )
|
427
|
+
trigger = true
|
394
428
|
end
|
395
429
|
end
|
396
430
|
|
397
|
-
next_tick
|
431
|
+
next_tick if trigger
|
398
432
|
end
|
399
433
|
end
|
400
434
|
end
|
@@ -492,7 +526,7 @@ module Girl
|
|
492
526
|
next_tick
|
493
527
|
end
|
494
528
|
|
495
|
-
sleep
|
529
|
+
sleep SEND_HELLO_INTERVAL
|
496
530
|
end
|
497
531
|
end
|
498
532
|
end
|
@@ -519,15 +553,14 @@ module Girl
|
|
519
553
|
end
|
520
554
|
|
521
555
|
# puts "debug1 a new dst #{ dst.local_address.inspect }"
|
522
|
-
local_port = dst.local_address.ip_port
|
523
556
|
dst_info = {
|
524
|
-
local_port: local_port, # 本地端口
|
525
557
|
src: src, # 对应src
|
526
558
|
domain: domain, # 目的地
|
527
559
|
wbuff: '', # 写前,从src读到的流量
|
528
560
|
paused: false, # 是否已暂停读
|
529
561
|
closing: false, # 准备关闭
|
530
|
-
closing_write: false
|
562
|
+
closing_write: false, # 准备关闭写
|
563
|
+
closed_write: false # 已关闭写
|
531
564
|
}
|
532
565
|
|
533
566
|
@dst_infos[ dst ] = dst_info
|
@@ -586,10 +619,13 @@ module Girl
|
|
586
619
|
|
587
620
|
domain = src_info[ :destination_domain ]
|
588
621
|
@stream_infos[ stream ] = {
|
589
|
-
src: src,
|
590
|
-
domain: domain,
|
591
|
-
wbuff: data,
|
592
|
-
paused: false
|
622
|
+
src: src, # 对应src
|
623
|
+
domain: domain, # 目的地
|
624
|
+
wbuff: data, # 写前,写往远端streamd
|
625
|
+
paused: false, # 是否已暂停读
|
626
|
+
closing: false, # 准备关闭
|
627
|
+
closing_write: false, # 准备关闭写
|
628
|
+
closed_write: false # 已关闭写
|
593
629
|
}
|
594
630
|
|
595
631
|
src_info[ :dst_id ] = dst_id
|
@@ -667,7 +703,7 @@ module Girl
|
|
667
703
|
next_tick
|
668
704
|
end
|
669
705
|
|
670
|
-
sleep
|
706
|
+
sleep SEND_HELLO_INTERVAL
|
671
707
|
end
|
672
708
|
end
|
673
709
|
end
|
@@ -721,12 +757,12 @@ module Girl
|
|
721
757
|
unless src.closed? then
|
722
758
|
puts "p#{ Process.pid } #{ Time.new } resolved #{ domain } #{ ip_info.ip_address }"
|
723
759
|
deal_with_destination_ip( src, ip_info )
|
760
|
+
next_tick
|
724
761
|
end
|
725
762
|
else
|
726
763
|
set_src_closing( src )
|
764
|
+
next_tick
|
727
765
|
end
|
728
|
-
|
729
|
-
next_tick
|
730
766
|
end
|
731
767
|
end
|
732
768
|
end
|
@@ -746,9 +782,14 @@ module Girl
|
|
746
782
|
def set_dst_closing( dst )
|
747
783
|
return if dst.closed?
|
748
784
|
dst_info = @dst_infos[ dst ]
|
749
|
-
|
750
|
-
|
751
|
-
|
785
|
+
|
786
|
+
if dst_info[ :closed_write ] then
|
787
|
+
close_dst( dst )
|
788
|
+
else
|
789
|
+
dst_info[ :closing ] = true
|
790
|
+
@reads.delete( dst )
|
791
|
+
add_write( dst )
|
792
|
+
end
|
752
793
|
end
|
753
794
|
|
754
795
|
##
|
@@ -756,7 +797,10 @@ module Girl
|
|
756
797
|
#
|
757
798
|
def set_dst_closing_write( dst )
|
758
799
|
return if dst.closed?
|
800
|
+
|
759
801
|
dst_info = @dst_infos[ dst ]
|
802
|
+
return if dst_info[ :closed_write ]
|
803
|
+
|
760
804
|
dst_info[ :closing_write ] = true
|
761
805
|
add_write( dst )
|
762
806
|
end
|
@@ -766,10 +810,15 @@ module Girl
|
|
766
810
|
#
|
767
811
|
def set_src_closing( src )
|
768
812
|
return if src.closed?
|
769
|
-
@reads.delete( src )
|
770
813
|
src_info = @src_infos[ src ]
|
771
|
-
|
772
|
-
|
814
|
+
|
815
|
+
if src_info[ :closed_write ] then
|
816
|
+
close_src( src )
|
817
|
+
else
|
818
|
+
src_info[ :closing ] = true
|
819
|
+
@reads.delete( src )
|
820
|
+
add_write( src )
|
821
|
+
end
|
773
822
|
end
|
774
823
|
|
775
824
|
##
|
@@ -777,7 +826,10 @@ module Girl
|
|
777
826
|
#
|
778
827
|
def set_src_closing_write( src )
|
779
828
|
return if src.closed?
|
829
|
+
|
780
830
|
src_info = @src_infos[ src ]
|
831
|
+
return if src_info[ :closed_write ]
|
832
|
+
|
781
833
|
src_info[ :closing_write ] = true
|
782
834
|
add_write( src )
|
783
835
|
end
|
@@ -786,10 +838,6 @@ module Girl
|
|
786
838
|
# set src proxy type tunnel
|
787
839
|
#
|
788
840
|
def set_src_proxy_type_tunnel( src )
|
789
|
-
if @tun.nil? || @tun.closed? then
|
790
|
-
new_a_tun
|
791
|
-
end
|
792
|
-
|
793
841
|
src_info = @src_infos[ src ]
|
794
842
|
src_info[ :proxy_type ] = :tunnel
|
795
843
|
src_id = src_info[ :id ]
|
@@ -802,23 +850,15 @@ module Girl
|
|
802
850
|
end
|
803
851
|
end
|
804
852
|
|
805
|
-
##
|
806
|
-
# set stream closing
|
807
|
-
#
|
808
|
-
def set_stream_closing( stream )
|
809
|
-
return if stream.closed?
|
810
|
-
stream_info = @stream_infos[ stream ]
|
811
|
-
stream_info[ :closing ] = true
|
812
|
-
@reads.delete( stream )
|
813
|
-
add_write( stream )
|
814
|
-
end
|
815
|
-
|
816
853
|
##
|
817
854
|
# set stream closing write
|
818
855
|
#
|
819
856
|
def set_stream_closing_write( stream )
|
820
857
|
return if stream.closed?
|
858
|
+
|
821
859
|
stream_info = @stream_infos[ stream ]
|
860
|
+
return if stream_info[ :closed_write ]
|
861
|
+
|
822
862
|
stream_info[ :closing_write ] = true
|
823
863
|
add_write( stream )
|
824
864
|
end
|
@@ -890,10 +930,15 @@ module Girl
|
|
890
930
|
last_sent_at: nil, # 上一次发出流量(由dst发出,或者由stream发出)的时间
|
891
931
|
paused: false, # 是否已暂停读
|
892
932
|
closing: false, # 准备关闭
|
893
|
-
closing_write: false
|
933
|
+
closing_write: false, # 准备关闭写
|
934
|
+
closed_write: false # 已关闭写
|
894
935
|
}
|
895
936
|
|
896
937
|
add_read( src, :src )
|
938
|
+
|
939
|
+
if @tun.nil? || @tun.closed? then
|
940
|
+
new_a_tun
|
941
|
+
end
|
897
942
|
end
|
898
943
|
|
899
944
|
##
|
@@ -957,6 +1002,8 @@ module Girl
|
|
957
1002
|
# read src
|
958
1003
|
#
|
959
1004
|
def read_src( src )
|
1005
|
+
return if src.closed?
|
1006
|
+
|
960
1007
|
begin
|
961
1008
|
data = src.read_nonblock( READ_SIZE )
|
962
1009
|
rescue IO::WaitReadable, Errno::EINTR
|
@@ -1160,6 +1207,8 @@ module Girl
|
|
1160
1207
|
# read dst
|
1161
1208
|
#
|
1162
1209
|
def read_dst( dst )
|
1210
|
+
return if dst.closed?
|
1211
|
+
|
1163
1212
|
begin
|
1164
1213
|
data = dst.read_nonblock( READ_SIZE )
|
1165
1214
|
rescue IO::WaitReadable, Errno::EINTR
|
@@ -1182,6 +1231,8 @@ module Girl
|
|
1182
1231
|
# read stream
|
1183
1232
|
#
|
1184
1233
|
def read_stream( stream )
|
1234
|
+
return if stream.closed?
|
1235
|
+
|
1185
1236
|
begin
|
1186
1237
|
data = stream.read_nonblock( READ_SIZE )
|
1187
1238
|
rescue IO::WaitReadable, Errno::EINTR
|
@@ -1246,19 +1297,6 @@ module Girl
|
|
1246
1297
|
# 处理关闭
|
1247
1298
|
if src_info[ :closing ] then
|
1248
1299
|
close_src( src )
|
1249
|
-
|
1250
|
-
if dst then
|
1251
|
-
close_read_dst( dst )
|
1252
|
-
set_dst_closing_write( dst )
|
1253
|
-
else
|
1254
|
-
stream = src_info[ :stream ]
|
1255
|
-
|
1256
|
-
if stream then
|
1257
|
-
close_read_stream( stream )
|
1258
|
-
set_stream_closing_write( stream )
|
1259
|
-
end
|
1260
|
-
end
|
1261
|
-
|
1262
1300
|
return
|
1263
1301
|
end
|
1264
1302
|
|
@@ -1312,12 +1350,6 @@ module Girl
|
|
1312
1350
|
# 处理关闭
|
1313
1351
|
if dst_info[ :closing ] then
|
1314
1352
|
close_dst( dst )
|
1315
|
-
|
1316
|
-
if src then
|
1317
|
-
close_read_src( src )
|
1318
|
-
set_src_closing_write( src )
|
1319
|
-
end
|
1320
|
-
|
1321
1353
|
return
|
1322
1354
|
end
|
1323
1355
|
|
@@ -1367,8 +1399,6 @@ module Girl
|
|
1367
1399
|
# 处理关闭
|
1368
1400
|
if stream_info[ :closing ] then
|
1369
1401
|
close_stream( stream )
|
1370
|
-
close_read_src( src )
|
1371
|
-
set_src_closing_write( src )
|
1372
1402
|
return
|
1373
1403
|
end
|
1374
1404
|
|
data/lib/girl/proxyd.rb
CHANGED
@@ -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"
|
data/lib/girl/proxyd_worker.rb
CHANGED
@@ -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,18 +33,20 @@ 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 )
|
36
40
|
|
37
41
|
@mutex.synchronize do
|
38
|
-
# 先读,再写,避免打上关闭标记后读到
|
39
42
|
rs.each do | sock |
|
40
43
|
case @roles[ sock ]
|
41
44
|
when :dotr then
|
42
45
|
read_dotr( sock )
|
43
46
|
when :proxyd then
|
44
47
|
read_proxyd( sock )
|
48
|
+
when :infod then
|
49
|
+
read_infod( sock )
|
45
50
|
when :tund then
|
46
51
|
read_tund( sock )
|
47
52
|
when :tcpd then
|
@@ -113,7 +118,7 @@ module Girl
|
|
113
118
|
# add read
|
114
119
|
#
|
115
120
|
def add_read( sock, role = nil )
|
116
|
-
|
121
|
+
if !sock.closed? && !@reads.include?( sock ) then
|
117
122
|
@reads << sock
|
118
123
|
|
119
124
|
if role then
|
@@ -122,6 +127,27 @@ module Girl
|
|
122
127
|
end
|
123
128
|
end
|
124
129
|
|
130
|
+
##
|
131
|
+
# add streamd wbuff
|
132
|
+
#
|
133
|
+
def add_streamd_wbuff( streamd, data )
|
134
|
+
return if streamd.closed?
|
135
|
+
streamd_info = @streamd_infos[ streamd ]
|
136
|
+
streamd_info[ :wbuff ] << data
|
137
|
+
add_write( streamd )
|
138
|
+
|
139
|
+
if streamd_info[ :wbuff ].bytesize >= WBUFF_LIMIT then
|
140
|
+
dst = streamd_info[ :dst ]
|
141
|
+
dst_info = @dst_infos[ dst ]
|
142
|
+
|
143
|
+
unless dst_info[ :paused ] then
|
144
|
+
puts "p#{ Process.pid } #{ Time.new } pause dst #{ dst_info[ :domain_port ] }"
|
145
|
+
dst_info[ :paused ] = true
|
146
|
+
@reads.delete( dst )
|
147
|
+
end
|
148
|
+
end
|
149
|
+
end
|
150
|
+
|
125
151
|
##
|
126
152
|
# add write
|
127
153
|
#
|
@@ -137,7 +163,13 @@ module Girl
|
|
137
163
|
def close_dst( dst )
|
138
164
|
# puts "debug1 close dst"
|
139
165
|
close_sock( dst )
|
140
|
-
del_dst_info( dst )
|
166
|
+
dst_info = del_dst_info( dst )
|
167
|
+
streamd = dst_info[ :streamd ]
|
168
|
+
|
169
|
+
if streamd then
|
170
|
+
close_read_streamd( streamd )
|
171
|
+
set_streamd_closing_write( streamd )
|
172
|
+
end
|
141
173
|
end
|
142
174
|
|
143
175
|
##
|
@@ -197,7 +229,13 @@ module Girl
|
|
197
229
|
def close_streamd( streamd )
|
198
230
|
# puts "debug1 close streamd"
|
199
231
|
close_sock( streamd )
|
200
|
-
@streamd_infos.delete( streamd )
|
232
|
+
streamd_info = @streamd_infos.delete( streamd )
|
233
|
+
dst = streamd_info[ :dst ]
|
234
|
+
|
235
|
+
if dst then
|
236
|
+
close_read_dst( dst )
|
237
|
+
set_dst_closing_write( dst )
|
238
|
+
end
|
201
239
|
end
|
202
240
|
|
203
241
|
##
|
@@ -231,6 +269,7 @@ module Girl
|
|
231
269
|
dst_info = @dst_infos[ dst ]
|
232
270
|
end
|
233
271
|
|
272
|
+
dst_info[ :closed_write ] = true
|
234
273
|
dst_info
|
235
274
|
end
|
236
275
|
|
@@ -251,6 +290,7 @@ module Girl
|
|
251
290
|
streamd_info = @streamd_infos[ streamd ]
|
252
291
|
end
|
253
292
|
|
293
|
+
streamd_info[ :closed_write ] = true
|
254
294
|
streamd_info
|
255
295
|
end
|
256
296
|
|
@@ -270,10 +310,12 @@ module Girl
|
|
270
310
|
end
|
271
311
|
|
272
312
|
dst_id = dst.local_address.ip_port
|
313
|
+
tund_info = @tund_infos[ tund ]
|
273
314
|
|
274
315
|
@dst_infos[ dst ] = {
|
275
316
|
id: dst_id, # id
|
276
317
|
tund: tund, # 对应tund
|
318
|
+
im: tund_info[ :im ], # 标识
|
277
319
|
domain_port: domain_port, # 目的地和端口
|
278
320
|
rbuff: '', # 对应的streamd没准备好,暂存读到的流量
|
279
321
|
streamd: nil, # 对应的streamd
|
@@ -284,12 +326,12 @@ module Girl
|
|
284
326
|
last_sent_at: nil, # 上一次发出流量(由streamd发出)的时间
|
285
327
|
paused: false, # 是否已暂停读
|
286
328
|
closing: false, # 准备关闭
|
287
|
-
closing_write: false
|
329
|
+
closing_write: false, # 准备关闭写
|
330
|
+
closed_write: false # 已关闭写
|
288
331
|
}
|
289
332
|
|
290
333
|
add_read( dst, :dst )
|
291
334
|
|
292
|
-
tund_info = @tund_infos[ tund ]
|
293
335
|
tund_info[ :dst_ids ][ src_id ] = dst_id
|
294
336
|
tund_info[ :dsts ][ dst_id ] = dst
|
295
337
|
|
@@ -395,6 +437,27 @@ module Girl
|
|
395
437
|
end
|
396
438
|
end
|
397
439
|
|
440
|
+
##
|
441
|
+
# loop check traff
|
442
|
+
#
|
443
|
+
def loop_check_traff
|
444
|
+
if RESET_TRAFF_DAY > 0 then
|
445
|
+
Thread.new do
|
446
|
+
loop do
|
447
|
+
sleep CHECK_TRAFF_INTERVAL
|
448
|
+
|
449
|
+
@mutex.synchronize do
|
450
|
+
if Time.new.day == RESET_TRAFF_DAY then
|
451
|
+
puts "p#{ Process.pid } #{ Time.new } reset traffs"
|
452
|
+
@traff_ins.transform_values!{ | _ | 0 }
|
453
|
+
@traff_outs.transform_values!{ | _ | 0 }
|
454
|
+
end
|
455
|
+
end
|
456
|
+
end
|
457
|
+
end
|
458
|
+
end
|
459
|
+
end
|
460
|
+
|
398
461
|
##
|
399
462
|
# new a proxyd
|
400
463
|
#
|
@@ -412,6 +475,18 @@ module Girl
|
|
412
475
|
add_read( proxyd, :proxyd )
|
413
476
|
end
|
414
477
|
|
478
|
+
##
|
479
|
+
# new a infod
|
480
|
+
#
|
481
|
+
def new_a_infod( infod_port )
|
482
|
+
infod = Socket.new( Socket::AF_INET, Socket::SOCK_DGRAM, 0 )
|
483
|
+
infod.setsockopt( Socket::SOL_SOCKET, Socket::SO_REUSEPORT, 1 )
|
484
|
+
infod.bind( Socket.sockaddr_in( infod_port, '127.0.0.1' ) )
|
485
|
+
|
486
|
+
puts "p#{ Process.pid } #{ Time.new } infod bind on #{ infod_port }"
|
487
|
+
add_read( infod, :infod )
|
488
|
+
end
|
489
|
+
|
415
490
|
##
|
416
491
|
# next tick
|
417
492
|
#
|
@@ -489,9 +564,14 @@ module Girl
|
|
489
564
|
def set_dst_closing( dst )
|
490
565
|
return if dst.closed?
|
491
566
|
dst_info = @dst_infos[ dst ]
|
492
|
-
|
493
|
-
|
494
|
-
|
567
|
+
|
568
|
+
if dst_info[ :closed_write ] then
|
569
|
+
close_dst( dst )
|
570
|
+
else
|
571
|
+
dst_info[ :closing ] = true
|
572
|
+
@reads.delete( dst )
|
573
|
+
add_write( dst )
|
574
|
+
end
|
495
575
|
end
|
496
576
|
|
497
577
|
##
|
@@ -499,7 +579,10 @@ module Girl
|
|
499
579
|
#
|
500
580
|
def set_dst_closing_write( dst )
|
501
581
|
return if dst.closed?
|
582
|
+
|
502
583
|
dst_info = @dst_infos[ dst ]
|
584
|
+
return if dst_info[ :closed_write ]
|
585
|
+
|
503
586
|
dst_info[ :closing_write ] = true
|
504
587
|
add_write( dst )
|
505
588
|
end
|
@@ -510,9 +593,14 @@ module Girl
|
|
510
593
|
def set_streamd_closing( streamd )
|
511
594
|
return if streamd.closed?
|
512
595
|
streamd_info = @streamd_infos[ streamd ]
|
513
|
-
|
514
|
-
|
515
|
-
|
596
|
+
|
597
|
+
if streamd_info[ :closed_write ] then
|
598
|
+
close_streamd( streamd )
|
599
|
+
else
|
600
|
+
streamd_info[ :closing ] = true
|
601
|
+
@reads.delete( streamd )
|
602
|
+
add_write( streamd )
|
603
|
+
end
|
516
604
|
end
|
517
605
|
|
518
606
|
##
|
@@ -520,7 +608,10 @@ module Girl
|
|
520
608
|
#
|
521
609
|
def set_streamd_closing_write( streamd )
|
522
610
|
return if streamd.closed?
|
611
|
+
|
523
612
|
streamd_info = @streamd_infos[ streamd ]
|
613
|
+
return if streamd_info[ :closed_write ]
|
614
|
+
|
524
615
|
streamd_info[ :closing_write ] = true
|
525
616
|
add_write( streamd )
|
526
617
|
end
|
@@ -565,6 +656,13 @@ module Girl
|
|
565
656
|
return
|
566
657
|
end
|
567
658
|
|
659
|
+
im = data
|
660
|
+
|
661
|
+
unless @traff_ins.include?( im ) then
|
662
|
+
@traff_ins[ im ] = 0
|
663
|
+
@traff_outs[ im ] = 0
|
664
|
+
end
|
665
|
+
|
568
666
|
tund = Socket.new( Socket::AF_INET, Socket::SOCK_DGRAM, 0 )
|
569
667
|
tund.bind( Socket.sockaddr_in( 0, '0.0.0.0' ) )
|
570
668
|
tund_port = tund.local_address.ip_port
|
@@ -578,6 +676,7 @@ module Girl
|
|
578
676
|
add_read( tcpd, :tcpd )
|
579
677
|
|
580
678
|
tund_info = {
|
679
|
+
im: im, # 标识
|
581
680
|
port: tund_port, # 端口
|
582
681
|
tcpd: tcpd, # 对应的tcpd
|
583
682
|
tcpd_port: tcpd_port, # tcpd端口
|
@@ -601,6 +700,28 @@ module Girl
|
|
601
700
|
add_proxyd_ctlmsg_tund_port( tund_info )
|
602
701
|
end
|
603
702
|
|
703
|
+
##
|
704
|
+
# read infod
|
705
|
+
#
|
706
|
+
def read_infod( infod )
|
707
|
+
data, addrinfo, rflags, *controls = infod.recvmsg
|
708
|
+
ctl_num = data[ 0 ].unpack( 'C' ).first
|
709
|
+
# puts "debug1 infod recv #{ ctl_num } #{ addrinfo.inspect }"
|
710
|
+
|
711
|
+
case ctl_num
|
712
|
+
when TRAFF_INFOS then
|
713
|
+
data2 = [ TRAFF_INFOS ].pack( 'C' )
|
714
|
+
|
715
|
+
@traff_ins.keys.sort.each do | im |
|
716
|
+
traff_in = @traff_ins[ im ]
|
717
|
+
traff_out = @traff_outs[ im ]
|
718
|
+
data2 << [ [ im.bytesize ].pack( 'C' ), im, [ traff_in, traff_out ].pack( 'Q>Q>' ) ].join
|
719
|
+
end
|
720
|
+
|
721
|
+
send_data( infod, data2, addrinfo )
|
722
|
+
end
|
723
|
+
end
|
724
|
+
|
604
725
|
##
|
605
726
|
# read tund
|
606
727
|
#
|
@@ -672,13 +793,18 @@ module Girl
|
|
672
793
|
# puts "debug1 accept a streamd"
|
673
794
|
tcpd_info = @tcpd_infos[ tcpd ]
|
674
795
|
tund = tcpd_info[ :tund ]
|
796
|
+
tund_info = @tund_infos[ tund ]
|
675
797
|
|
676
798
|
@streamd_infos[ streamd ] = {
|
677
|
-
tund: tund,
|
678
|
-
|
679
|
-
|
680
|
-
|
681
|
-
|
799
|
+
tund: tund, # 对应tund
|
800
|
+
im: tund_info[ :im ], # 标识
|
801
|
+
dst: nil, # 对应dst
|
802
|
+
domain_port: nil, # dst的目的地和端口
|
803
|
+
wbuff: '', # 写前,写往近端stream
|
804
|
+
paused: false, # 是否已暂停读
|
805
|
+
closing: false, # 准备关闭
|
806
|
+
closing_write: false, # 准备关闭写
|
807
|
+
closed_write: false # 已关闭写
|
682
808
|
}
|
683
809
|
|
684
810
|
add_read( streamd, :streamd )
|
@@ -688,6 +814,8 @@ module Girl
|
|
688
814
|
# read dst
|
689
815
|
#
|
690
816
|
def read_dst( dst )
|
817
|
+
return if dst.closed?
|
818
|
+
|
691
819
|
begin
|
692
820
|
data = dst.read_nonblock( READ_SIZE )
|
693
821
|
rescue IO::WaitReadable, Errno::EINTR
|
@@ -702,6 +830,7 @@ module Girl
|
|
702
830
|
end
|
703
831
|
|
704
832
|
dst_info = @dst_infos[ dst ]
|
833
|
+
@traff_ins[ dst_info[ :im ] ] += data.bytesize
|
705
834
|
streamd = dst_info[ :streamd ]
|
706
835
|
|
707
836
|
if streamd then
|
@@ -709,14 +838,7 @@ module Girl
|
|
709
838
|
streamd_info = @streamd_infos[ streamd ]
|
710
839
|
data = @custom.encode( data )
|
711
840
|
# puts "debug2 add streamd.wbuff encoded #{ data.bytesize }"
|
712
|
-
|
713
|
-
add_write( streamd )
|
714
|
-
|
715
|
-
if streamd_info[ :wbuff ].bytesize >= WBUFF_LIMIT then
|
716
|
-
puts "p#{ Process.pid } #{ Time.new } pause dst #{ dst_info[ :domain_port ] }"
|
717
|
-
dst_info[ :paused ] = true
|
718
|
-
@reads.delete( dst )
|
719
|
-
end
|
841
|
+
add_streamd_wbuff( streamd, data )
|
720
842
|
end
|
721
843
|
else
|
722
844
|
dst_info[ :rbuff ] << data
|
@@ -732,6 +854,8 @@ module Girl
|
|
732
854
|
# read streamd
|
733
855
|
#
|
734
856
|
def read_streamd( streamd )
|
857
|
+
return if streamd.closed?
|
858
|
+
|
735
859
|
begin
|
736
860
|
data = streamd.read_nonblock( READ_SIZE )
|
737
861
|
rescue IO::WaitReadable, Errno::EINTR
|
@@ -746,6 +870,7 @@ module Girl
|
|
746
870
|
end
|
747
871
|
|
748
872
|
streamd_info = @streamd_infos[ streamd ]
|
873
|
+
@traff_ins[ streamd_info[ :im ] ] += data.bytesize
|
749
874
|
dst = streamd_info[ :dst ]
|
750
875
|
|
751
876
|
unless dst then
|
@@ -772,7 +897,8 @@ module Girl
|
|
772
897
|
|
773
898
|
unless dst_info[ :rbuff ].empty? then
|
774
899
|
# puts "debug1 encode and move dst.rbuff to streamd.wbuff"
|
775
|
-
|
900
|
+
data2 = @custom.encode( dst_info[ :rbuff ] )
|
901
|
+
add_streamd_wbuff( streamd, data2 )
|
776
902
|
end
|
777
903
|
|
778
904
|
dst_info[ :streamd ] = streamd
|
@@ -866,12 +992,6 @@ module Girl
|
|
866
992
|
# 处理关闭
|
867
993
|
if dst_info[ :closing ] then
|
868
994
|
close_dst( dst )
|
869
|
-
|
870
|
-
if streamd then
|
871
|
-
close_read_streamd( streamd )
|
872
|
-
set_streamd_closing_write( streamd )
|
873
|
-
end
|
874
|
-
|
875
995
|
return
|
876
996
|
end
|
877
997
|
|
@@ -904,6 +1024,7 @@ module Girl
|
|
904
1024
|
# puts "debug2 written dst #{ written }"
|
905
1025
|
data = data[ written..-1 ]
|
906
1026
|
dst_info[ :wbuff ] = data
|
1027
|
+
@traff_outs[ dst_info[ :im ] ] += written
|
907
1028
|
end
|
908
1029
|
|
909
1030
|
##
|
@@ -917,12 +1038,6 @@ module Girl
|
|
917
1038
|
# 处理关闭
|
918
1039
|
if streamd_info[ :closing ] then
|
919
1040
|
close_streamd( streamd )
|
920
|
-
|
921
|
-
if dst then
|
922
|
-
close_read_dst( dst )
|
923
|
-
set_dst_closing_write( dst )
|
924
|
-
end
|
925
|
-
|
926
1041
|
return
|
927
1042
|
end
|
928
1043
|
|
@@ -955,6 +1070,7 @@ module Girl
|
|
955
1070
|
# puts "debug2 written streamd #{ written }"
|
956
1071
|
data = data[ written..-1 ]
|
957
1072
|
streamd_info[ :wbuff ] = data
|
1073
|
+
@traff_outs[ streamd_info[ :im ] ] += written
|
958
1074
|
|
959
1075
|
if dst && !dst.closed? then
|
960
1076
|
dst_info = @dst_infos[ dst ]
|
data/lib/girl/version.rb
CHANGED
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.
|
4
|
+
version: 0.97.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-
|
11
|
+
date: 2020-10-19 00:00:00.000000000 Z
|
12
12
|
dependencies: []
|
13
13
|
description: escape evil.
|
14
14
|
email:
|