girl 0.91.0 → 0.96.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 +25 -8
- data/lib/girl/proxy_worker.rb +99 -60
- data/lib/girl/proxyd.rb +11 -1
- data/lib/girl/proxyd_worker.rb +146 -38
- 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: 141ddfd9fd89d13f02f9ea69e9880d39620460ae1ff5155276c1b4bcb2b3ed83
|
4
|
+
data.tar.gz: f72985c0577b97927e73c6943f268df9ca92702eb2d84f5f5a4400e4bf93dee3
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 67dc320dc6ef439a146c7396f9a80d6031c5a6cad3d4f36fb23063898fd68c6c6f2a0789cbd51d553a2fcb856d52da826d37f6470f1b5ac83703147809d30341
|
7
|
+
data.tar.gz: 25189cbab69f1d2345a62efb8898f2410c7de3210a06d04547e2cb01decdc31afc3ff56e5ab98356fdb378d1d5afb95f40792fd96e02c05bf8ff0431ea32d18d
|
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
|
-
Q>: 0 ctlmsg -> C: 2 heartbeat
|
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
|
@@ -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
|
|
@@ -374,13 +404,17 @@ module Girl
|
|
374
404
|
|
375
405
|
if @tun && !@tun.closed? then
|
376
406
|
last_recv_at = @tun_info[ :last_recv_at ] || @tun_info[ :created_at ]
|
377
|
-
last_sent_at = @tun_info[ :last_sent_at ] || @tun_info[ :created_at ]
|
378
407
|
|
379
|
-
if @tun_info[ :srcs ].empty? && ( now - last_recv_at >= EXPIRE_AFTER )
|
408
|
+
if @tun_info[ :srcs ].empty? && ( now - last_recv_at >= EXPIRE_AFTER ) then
|
380
409
|
puts "p#{ Process.pid } #{ Time.new } expire tun"
|
381
410
|
set_tun_closing
|
382
|
-
|
411
|
+
else
|
412
|
+
# puts "debug1 #{ Time.new } heartbeat"
|
413
|
+
data = [ 0, HEARTBEAT ].pack( 'Q>C' )
|
414
|
+
add_ctlmsg( data )
|
383
415
|
end
|
416
|
+
|
417
|
+
trigger = true
|
384
418
|
end
|
385
419
|
|
386
420
|
@src_infos.each do | src, src_info |
|
@@ -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,16 +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
|
-
|
531
|
-
|
562
|
+
closing_write: false, # 准备关闭写
|
563
|
+
closed_write: false # 已关闭写
|
532
564
|
}
|
533
565
|
|
534
566
|
@dst_infos[ dst ] = dst_info
|
@@ -587,10 +619,13 @@ module Girl
|
|
587
619
|
|
588
620
|
domain = src_info[ :destination_domain ]
|
589
621
|
@stream_infos[ stream ] = {
|
590
|
-
src: src,
|
591
|
-
domain: domain,
|
592
|
-
wbuff: data,
|
593
|
-
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 # 已关闭写
|
594
629
|
}
|
595
630
|
|
596
631
|
src_info[ :dst_id ] = dst_id
|
@@ -643,7 +678,6 @@ module Girl
|
|
643
678
|
srcs: {}, # src_id => src
|
644
679
|
created_at: Time.new, # 创建时间
|
645
680
|
last_recv_at: nil, # 上一次收到流量的时间
|
646
|
-
last_sent_at: nil, # 上一次发出流量的时间
|
647
681
|
closing: false # 是否准备关闭
|
648
682
|
}
|
649
683
|
|
@@ -669,7 +703,7 @@ module Girl
|
|
669
703
|
next_tick
|
670
704
|
end
|
671
705
|
|
672
|
-
sleep
|
706
|
+
sleep SEND_HELLO_INTERVAL
|
673
707
|
end
|
674
708
|
end
|
675
709
|
end
|
@@ -748,9 +782,14 @@ module Girl
|
|
748
782
|
def set_dst_closing( dst )
|
749
783
|
return if dst.closed?
|
750
784
|
dst_info = @dst_infos[ dst ]
|
751
|
-
|
752
|
-
|
753
|
-
|
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
|
754
793
|
end
|
755
794
|
|
756
795
|
##
|
@@ -758,7 +797,10 @@ module Girl
|
|
758
797
|
#
|
759
798
|
def set_dst_closing_write( dst )
|
760
799
|
return if dst.closed?
|
800
|
+
|
761
801
|
dst_info = @dst_infos[ dst ]
|
802
|
+
return if dst_info[ :closed_write ]
|
803
|
+
|
762
804
|
dst_info[ :closing_write ] = true
|
763
805
|
add_write( dst )
|
764
806
|
end
|
@@ -768,10 +810,15 @@ module Girl
|
|
768
810
|
#
|
769
811
|
def set_src_closing( src )
|
770
812
|
return if src.closed?
|
771
|
-
@reads.delete( src )
|
772
813
|
src_info = @src_infos[ src ]
|
773
|
-
|
774
|
-
|
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
|
775
822
|
end
|
776
823
|
|
777
824
|
##
|
@@ -779,7 +826,10 @@ module Girl
|
|
779
826
|
#
|
780
827
|
def set_src_closing_write( src )
|
781
828
|
return if src.closed?
|
829
|
+
|
782
830
|
src_info = @src_infos[ src ]
|
831
|
+
return if src_info[ :closed_write ]
|
832
|
+
|
783
833
|
src_info[ :closing_write ] = true
|
784
834
|
add_write( src )
|
785
835
|
end
|
@@ -804,23 +854,15 @@ module Girl
|
|
804
854
|
end
|
805
855
|
end
|
806
856
|
|
807
|
-
##
|
808
|
-
# set stream closing
|
809
|
-
#
|
810
|
-
def set_stream_closing( stream )
|
811
|
-
return if stream.closed?
|
812
|
-
stream_info = @stream_infos[ stream ]
|
813
|
-
stream_info[ :closing ] = true
|
814
|
-
@reads.delete( stream )
|
815
|
-
add_write( stream )
|
816
|
-
end
|
817
|
-
|
818
857
|
##
|
819
858
|
# set stream closing write
|
820
859
|
#
|
821
860
|
def set_stream_closing_write( stream )
|
822
861
|
return if stream.closed?
|
862
|
+
|
823
863
|
stream_info = @stream_infos[ stream ]
|
864
|
+
return if stream_info[ :closed_write ]
|
865
|
+
|
824
866
|
stream_info[ :closing_write ] = true
|
825
867
|
add_write( stream )
|
826
868
|
end
|
@@ -892,8 +934,8 @@ module Girl
|
|
892
934
|
last_sent_at: nil, # 上一次发出流量(由dst发出,或者由stream发出)的时间
|
893
935
|
paused: false, # 是否已暂停读
|
894
936
|
closing: false, # 准备关闭
|
895
|
-
|
896
|
-
|
937
|
+
closing_write: false, # 准备关闭写
|
938
|
+
closed_write: false # 已关闭写
|
897
939
|
}
|
898
940
|
|
899
941
|
add_read( src, :src )
|
@@ -960,6 +1002,8 @@ module Girl
|
|
960
1002
|
# read src
|
961
1003
|
#
|
962
1004
|
def read_src( src )
|
1005
|
+
return if src.closed?
|
1006
|
+
|
963
1007
|
begin
|
964
1008
|
data = src.read_nonblock( READ_SIZE )
|
965
1009
|
rescue IO::WaitReadable, Errno::EINTR
|
@@ -981,6 +1025,13 @@ module Girl
|
|
981
1025
|
end
|
982
1026
|
|
983
1027
|
src_info = @src_infos[ src ]
|
1028
|
+
|
1029
|
+
# 处理关闭
|
1030
|
+
if src_info[ :closing ] then
|
1031
|
+
close_src( src )
|
1032
|
+
return
|
1033
|
+
end
|
1034
|
+
|
984
1035
|
proxy_type = src_info[ :proxy_type ]
|
985
1036
|
|
986
1037
|
case proxy_type
|
@@ -1163,6 +1214,8 @@ module Girl
|
|
1163
1214
|
# read dst
|
1164
1215
|
#
|
1165
1216
|
def read_dst( dst )
|
1217
|
+
return if dst.closed?
|
1218
|
+
|
1166
1219
|
begin
|
1167
1220
|
data = dst.read_nonblock( READ_SIZE )
|
1168
1221
|
rescue IO::WaitReadable, Errno::EINTR
|
@@ -1177,6 +1230,13 @@ module Girl
|
|
1177
1230
|
end
|
1178
1231
|
|
1179
1232
|
dst_info = @dst_infos[ dst ]
|
1233
|
+
|
1234
|
+
# 处理关闭
|
1235
|
+
if dst_info[ :closing ] then
|
1236
|
+
close_dst( dst )
|
1237
|
+
return
|
1238
|
+
end
|
1239
|
+
|
1180
1240
|
src = dst_info[ :src ]
|
1181
1241
|
add_src_wbuff( src, data )
|
1182
1242
|
end
|
@@ -1185,6 +1245,8 @@ module Girl
|
|
1185
1245
|
# read stream
|
1186
1246
|
#
|
1187
1247
|
def read_stream( stream )
|
1248
|
+
return if stream.closed?
|
1249
|
+
|
1188
1250
|
begin
|
1189
1251
|
data = stream.read_nonblock( READ_SIZE )
|
1190
1252
|
rescue IO::WaitReadable, Errno::EINTR
|
@@ -1225,7 +1287,6 @@ module Girl
|
|
1225
1287
|
@tun.sendmsg_nonblock( data, 0, to_addr )
|
1226
1288
|
rescue IO::WaitWritable, Errno::EINTR
|
1227
1289
|
puts "p#{ Process.pid } #{ Time.new } wait send ctlmsg, left #{ @tun_info[ :ctlmsgs ].size }"
|
1228
|
-
@tun_info[ :last_sent_at ] = now
|
1229
1290
|
return
|
1230
1291
|
rescue Errno::EHOSTUNREACH, Errno::ENETUNREACH, Errno::ENETDOWN => e
|
1231
1292
|
puts "p#{ Process.pid } #{ Time.new } sendmsg #{ e.class }, close tun"
|
@@ -1236,7 +1297,6 @@ module Girl
|
|
1236
1297
|
@tun_info[ :ctlmsgs ].shift
|
1237
1298
|
end
|
1238
1299
|
|
1239
|
-
@tun_info[ :last_sent_at ] = now
|
1240
1300
|
@writes.delete( tun )
|
1241
1301
|
end
|
1242
1302
|
|
@@ -1251,19 +1311,6 @@ module Girl
|
|
1251
1311
|
# 处理关闭
|
1252
1312
|
if src_info[ :closing ] then
|
1253
1313
|
close_src( src )
|
1254
|
-
|
1255
|
-
if dst then
|
1256
|
-
close_read_dst( dst )
|
1257
|
-
set_dst_closing_write( dst )
|
1258
|
-
else
|
1259
|
-
stream = src_info[ :stream ]
|
1260
|
-
|
1261
|
-
if stream then
|
1262
|
-
close_read_stream( stream )
|
1263
|
-
set_stream_closing_write( stream )
|
1264
|
-
end
|
1265
|
-
end
|
1266
|
-
|
1267
1314
|
return
|
1268
1315
|
end
|
1269
1316
|
|
@@ -1317,12 +1364,6 @@ module Girl
|
|
1317
1364
|
# 处理关闭
|
1318
1365
|
if dst_info[ :closing ] then
|
1319
1366
|
close_dst( dst )
|
1320
|
-
|
1321
|
-
if src then
|
1322
|
-
close_read_src( src )
|
1323
|
-
set_src_closing_write( src )
|
1324
|
-
end
|
1325
|
-
|
1326
1367
|
return
|
1327
1368
|
end
|
1328
1369
|
|
@@ -1372,8 +1413,6 @@ module Girl
|
|
1372
1413
|
# 处理关闭
|
1373
1414
|
if stream_info[ :closing ] then
|
1374
1415
|
close_stream( stream )
|
1375
|
-
close_read_src( src )
|
1376
|
-
set_src_closing_write( src )
|
1377
1416
|
return
|
1378
1417
|
end
|
1379
1418
|
|
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
|
@@ -137,7 +142,13 @@ module Girl
|
|
137
142
|
def close_dst( dst )
|
138
143
|
# puts "debug1 close dst"
|
139
144
|
close_sock( dst )
|
140
|
-
del_dst_info( dst )
|
145
|
+
dst_info = del_dst_info( dst )
|
146
|
+
streamd = dst_info[ :streamd ]
|
147
|
+
|
148
|
+
if streamd then
|
149
|
+
close_read_streamd( streamd )
|
150
|
+
set_streamd_closing_write( streamd )
|
151
|
+
end
|
141
152
|
end
|
142
153
|
|
143
154
|
##
|
@@ -197,7 +208,13 @@ module Girl
|
|
197
208
|
def close_streamd( streamd )
|
198
209
|
# puts "debug1 close streamd"
|
199
210
|
close_sock( streamd )
|
200
|
-
@streamd_infos.delete( streamd )
|
211
|
+
streamd_info = @streamd_infos.delete( streamd )
|
212
|
+
dst = streamd_info[ :dst ]
|
213
|
+
|
214
|
+
if dst then
|
215
|
+
close_read_dst( dst )
|
216
|
+
set_dst_closing_write( dst )
|
217
|
+
end
|
201
218
|
end
|
202
219
|
|
203
220
|
##
|
@@ -231,6 +248,7 @@ module Girl
|
|
231
248
|
dst_info = @dst_infos[ dst ]
|
232
249
|
end
|
233
250
|
|
251
|
+
dst_info[ :closed_write ] = true
|
234
252
|
dst_info
|
235
253
|
end
|
236
254
|
|
@@ -251,6 +269,7 @@ module Girl
|
|
251
269
|
streamd_info = @streamd_infos[ streamd ]
|
252
270
|
end
|
253
271
|
|
272
|
+
streamd_info[ :closed_write ] = true
|
254
273
|
streamd_info
|
255
274
|
end
|
256
275
|
|
@@ -270,10 +289,12 @@ module Girl
|
|
270
289
|
end
|
271
290
|
|
272
291
|
dst_id = dst.local_address.ip_port
|
292
|
+
tund_info = @tund_infos[ tund ]
|
273
293
|
|
274
294
|
@dst_infos[ dst ] = {
|
275
295
|
id: dst_id, # id
|
276
296
|
tund: tund, # 对应tund
|
297
|
+
im: tund_info[ :im ], # 标识
|
277
298
|
domain_port: domain_port, # 目的地和端口
|
278
299
|
rbuff: '', # 对应的streamd没准备好,暂存读到的流量
|
279
300
|
streamd: nil, # 对应的streamd
|
@@ -284,13 +305,12 @@ module Girl
|
|
284
305
|
last_sent_at: nil, # 上一次发出流量(由streamd发出)的时间
|
285
306
|
paused: false, # 是否已暂停读
|
286
307
|
closing: false, # 准备关闭
|
287
|
-
|
288
|
-
|
308
|
+
closing_write: false, # 准备关闭写
|
309
|
+
closed_write: false # 已关闭写
|
289
310
|
}
|
290
311
|
|
291
312
|
add_read( dst, :dst )
|
292
313
|
|
293
|
-
tund_info = @tund_infos[ tund ]
|
294
314
|
tund_info[ :dst_ids ][ src_id ] = dst_id
|
295
315
|
tund_info[ :dsts ][ dst_id ] = dst
|
296
316
|
|
@@ -330,9 +350,8 @@ module Girl
|
|
330
350
|
|
331
351
|
@tund_infos.each do | tund, tund_info |
|
332
352
|
last_recv_at = tund_info[ :last_recv_at ] || tund_info[ :created_at ]
|
333
|
-
last_sent_at = tund_info[ :last_sent_at ] || tund_info[ :created_at ]
|
334
353
|
|
335
|
-
if tund_info[ :dsts ].empty? && ( now - last_recv_at >= EXPIRE_AFTER )
|
354
|
+
if tund_info[ :dsts ].empty? && ( now - last_recv_at >= EXPIRE_AFTER ) then
|
336
355
|
puts "p#{ Process.pid } #{ Time.new } expire tund #{ tund_info[ :port ] }"
|
337
356
|
set_tund_closing( tund )
|
338
357
|
trigger = true
|
@@ -397,6 +416,27 @@ module Girl
|
|
397
416
|
end
|
398
417
|
end
|
399
418
|
|
419
|
+
##
|
420
|
+
# loop check traff
|
421
|
+
#
|
422
|
+
def loop_check_traff
|
423
|
+
if RESET_TRAFF_DAY > 0 then
|
424
|
+
Thread.new do
|
425
|
+
loop do
|
426
|
+
sleep CHECK_TRAFF_INTERVAL
|
427
|
+
|
428
|
+
@mutex.synchronize do
|
429
|
+
if Time.new.day == RESET_TRAFF_DAY then
|
430
|
+
puts "p#{ Process.pid } #{ Time.new } reset traffs"
|
431
|
+
@traff_ins.transform_values!{ | _ | 0 }
|
432
|
+
@traff_outs.transform_values!{ | _ | 0 }
|
433
|
+
end
|
434
|
+
end
|
435
|
+
end
|
436
|
+
end
|
437
|
+
end
|
438
|
+
end
|
439
|
+
|
400
440
|
##
|
401
441
|
# new a proxyd
|
402
442
|
#
|
@@ -414,6 +454,18 @@ module Girl
|
|
414
454
|
add_read( proxyd, :proxyd )
|
415
455
|
end
|
416
456
|
|
457
|
+
##
|
458
|
+
# new a infod
|
459
|
+
#
|
460
|
+
def new_a_infod( infod_port )
|
461
|
+
infod = Socket.new( Socket::AF_INET, Socket::SOCK_DGRAM, 0 )
|
462
|
+
infod.setsockopt( Socket::SOL_SOCKET, Socket::SO_REUSEPORT, 1 )
|
463
|
+
infod.bind( Socket.sockaddr_in( infod_port, '127.0.0.1' ) )
|
464
|
+
|
465
|
+
puts "p#{ Process.pid } #{ Time.new } infod bind on #{ infod_port }"
|
466
|
+
add_read( infod, :infod )
|
467
|
+
end
|
468
|
+
|
417
469
|
##
|
418
470
|
# next tick
|
419
471
|
#
|
@@ -491,9 +543,14 @@ module Girl
|
|
491
543
|
def set_dst_closing( dst )
|
492
544
|
return if dst.closed?
|
493
545
|
dst_info = @dst_infos[ dst ]
|
494
|
-
|
495
|
-
|
496
|
-
|
546
|
+
|
547
|
+
if dst_info[ :closed_write ] then
|
548
|
+
close_dst( dst )
|
549
|
+
else
|
550
|
+
dst_info[ :closing ] = true
|
551
|
+
@reads.delete( dst )
|
552
|
+
add_write( dst )
|
553
|
+
end
|
497
554
|
end
|
498
555
|
|
499
556
|
##
|
@@ -501,7 +558,10 @@ module Girl
|
|
501
558
|
#
|
502
559
|
def set_dst_closing_write( dst )
|
503
560
|
return if dst.closed?
|
561
|
+
|
504
562
|
dst_info = @dst_infos[ dst ]
|
563
|
+
return if dst_info[ :closed_write ]
|
564
|
+
|
505
565
|
dst_info[ :closing_write ] = true
|
506
566
|
add_write( dst )
|
507
567
|
end
|
@@ -512,9 +572,14 @@ module Girl
|
|
512
572
|
def set_streamd_closing( streamd )
|
513
573
|
return if streamd.closed?
|
514
574
|
streamd_info = @streamd_infos[ streamd ]
|
515
|
-
|
516
|
-
|
517
|
-
|
575
|
+
|
576
|
+
if streamd_info[ :closed_write ] then
|
577
|
+
close_streamd( streamd )
|
578
|
+
else
|
579
|
+
streamd_info[ :closing ] = true
|
580
|
+
@reads.delete( streamd )
|
581
|
+
add_write( streamd )
|
582
|
+
end
|
518
583
|
end
|
519
584
|
|
520
585
|
##
|
@@ -522,7 +587,10 @@ module Girl
|
|
522
587
|
#
|
523
588
|
def set_streamd_closing_write( streamd )
|
524
589
|
return if streamd.closed?
|
590
|
+
|
525
591
|
streamd_info = @streamd_infos[ streamd ]
|
592
|
+
return if streamd_info[ :closed_write ]
|
593
|
+
|
526
594
|
streamd_info[ :closing_write ] = true
|
527
595
|
add_write( streamd )
|
528
596
|
end
|
@@ -567,6 +635,13 @@ module Girl
|
|
567
635
|
return
|
568
636
|
end
|
569
637
|
|
638
|
+
im = data
|
639
|
+
|
640
|
+
unless @traff_ins.include?( im ) then
|
641
|
+
@traff_ins[ im ] = 0
|
642
|
+
@traff_outs[ im ] = 0
|
643
|
+
end
|
644
|
+
|
570
645
|
tund = Socket.new( Socket::AF_INET, Socket::SOCK_DGRAM, 0 )
|
571
646
|
tund.bind( Socket.sockaddr_in( 0, '0.0.0.0' ) )
|
572
647
|
tund_port = tund.local_address.ip_port
|
@@ -580,6 +655,7 @@ module Girl
|
|
580
655
|
add_read( tcpd, :tcpd )
|
581
656
|
|
582
657
|
tund_info = {
|
658
|
+
im: im, # 标识
|
583
659
|
port: tund_port, # 端口
|
584
660
|
tcpd: tcpd, # 对应的tcpd
|
585
661
|
tcpd_port: tcpd_port, # tcpd端口
|
@@ -589,10 +665,7 @@ module Girl
|
|
589
665
|
dst_ids: {}, # src_id => dst_id
|
590
666
|
created_at: Time.new, # 创建时间
|
591
667
|
last_recv_at: nil, # 上一次收到流量的时间
|
592
|
-
last_sent_at: nil, # 上一次发出流量的时间
|
593
668
|
closing: false, # 准备关闭
|
594
|
-
closing_read: false, # 准备关闭读
|
595
|
-
closing_write: false, # 准备关闭写
|
596
669
|
changed_tun_addr: nil # 记录到和tun addr不符的来源地址
|
597
670
|
}
|
598
671
|
|
@@ -606,6 +679,28 @@ module Girl
|
|
606
679
|
add_proxyd_ctlmsg_tund_port( tund_info )
|
607
680
|
end
|
608
681
|
|
682
|
+
##
|
683
|
+
# read infod
|
684
|
+
#
|
685
|
+
def read_infod( infod )
|
686
|
+
data, addrinfo, rflags, *controls = infod.recvmsg
|
687
|
+
ctl_num = data[ 0 ].unpack( 'C' ).first
|
688
|
+
# puts "debug1 infod recv #{ ctl_num } #{ addrinfo.inspect }"
|
689
|
+
|
690
|
+
case ctl_num
|
691
|
+
when TRAFF_INFOS then
|
692
|
+
data2 = [ TRAFF_INFOS ].pack( 'C' )
|
693
|
+
|
694
|
+
@traff_ins.keys.sort.each do | im |
|
695
|
+
traff_in = @traff_ins[ im ]
|
696
|
+
traff_out = @traff_outs[ im ]
|
697
|
+
data2 << [ [ im.bytesize ].pack( 'C' ), im, [ traff_in, traff_out ].pack( 'Q>Q>' ) ].join
|
698
|
+
end
|
699
|
+
|
700
|
+
send_data( infod, data2, addrinfo )
|
701
|
+
end
|
702
|
+
end
|
703
|
+
|
609
704
|
##
|
610
705
|
# read tund
|
611
706
|
#
|
@@ -677,13 +772,18 @@ module Girl
|
|
677
772
|
# puts "debug1 accept a streamd"
|
678
773
|
tcpd_info = @tcpd_infos[ tcpd ]
|
679
774
|
tund = tcpd_info[ :tund ]
|
775
|
+
tund_info = @tund_infos[ tund ]
|
680
776
|
|
681
777
|
@streamd_infos[ streamd ] = {
|
682
|
-
tund: tund,
|
683
|
-
|
684
|
-
|
685
|
-
|
686
|
-
|
778
|
+
tund: tund, # 对应tund
|
779
|
+
im: tund_info[ :im ], # 标识
|
780
|
+
dst: nil, # 对应dst
|
781
|
+
domain_port: nil, # dst的目的地和端口
|
782
|
+
wbuff: '', # 写前,写往近端stream
|
783
|
+
paused: false, # 是否已暂停读
|
784
|
+
closing: false, # 准备关闭
|
785
|
+
closing_write: false, # 准备关闭写
|
786
|
+
closed_write: false # 已关闭写
|
687
787
|
}
|
688
788
|
|
689
789
|
add_read( streamd, :streamd )
|
@@ -693,6 +793,8 @@ module Girl
|
|
693
793
|
# read dst
|
694
794
|
#
|
695
795
|
def read_dst( dst )
|
796
|
+
return if dst.closed?
|
797
|
+
|
696
798
|
begin
|
697
799
|
data = dst.read_nonblock( READ_SIZE )
|
698
800
|
rescue IO::WaitReadable, Errno::EINTR
|
@@ -707,6 +809,14 @@ module Girl
|
|
707
809
|
end
|
708
810
|
|
709
811
|
dst_info = @dst_infos[ dst ]
|
812
|
+
|
813
|
+
# 处理关闭
|
814
|
+
if dst_info[ :closing ] then
|
815
|
+
close_dst( dst )
|
816
|
+
return
|
817
|
+
end
|
818
|
+
|
819
|
+
@traff_ins[ dst_info[ :im ] ] += data.bytesize
|
710
820
|
streamd = dst_info[ :streamd ]
|
711
821
|
|
712
822
|
if streamd then
|
@@ -737,6 +847,8 @@ module Girl
|
|
737
847
|
# read streamd
|
738
848
|
#
|
739
849
|
def read_streamd( streamd )
|
850
|
+
return if streamd.closed?
|
851
|
+
|
740
852
|
begin
|
741
853
|
data = streamd.read_nonblock( READ_SIZE )
|
742
854
|
rescue IO::WaitReadable, Errno::EINTR
|
@@ -751,6 +863,14 @@ module Girl
|
|
751
863
|
end
|
752
864
|
|
753
865
|
streamd_info = @streamd_infos[ streamd ]
|
866
|
+
|
867
|
+
# 处理关闭
|
868
|
+
if streamd_info[ :closing ] then
|
869
|
+
close_streamd( streamd )
|
870
|
+
return
|
871
|
+
end
|
872
|
+
|
873
|
+
@traff_ins[ streamd_info[ :im ] ] += data.bytesize
|
754
874
|
dst = streamd_info[ :dst ]
|
755
875
|
|
756
876
|
unless dst then
|
@@ -851,14 +971,12 @@ module Girl
|
|
851
971
|
return
|
852
972
|
elsif sent == :wait then
|
853
973
|
puts "p#{ Process.pid } #{ Time.new } wait tund #{ tund_info[ :port ] } send ctlmsg, left #{ tund_info[ :ctlmsgs ].size }"
|
854
|
-
tund_info[ :last_sent_at ] = now
|
855
974
|
return
|
856
975
|
end
|
857
976
|
|
858
977
|
tund_info[ :ctlmsgs ].shift
|
859
978
|
end
|
860
979
|
|
861
|
-
tund_info[ :last_sent_at ] = now
|
862
980
|
@writes.delete( tund )
|
863
981
|
end
|
864
982
|
|
@@ -873,12 +991,6 @@ module Girl
|
|
873
991
|
# 处理关闭
|
874
992
|
if dst_info[ :closing ] then
|
875
993
|
close_dst( dst )
|
876
|
-
|
877
|
-
if streamd then
|
878
|
-
close_read_streamd( streamd )
|
879
|
-
set_streamd_closing_write( streamd )
|
880
|
-
end
|
881
|
-
|
882
994
|
return
|
883
995
|
end
|
884
996
|
|
@@ -911,6 +1023,7 @@ module Girl
|
|
911
1023
|
# puts "debug2 written dst #{ written }"
|
912
1024
|
data = data[ written..-1 ]
|
913
1025
|
dst_info[ :wbuff ] = data
|
1026
|
+
@traff_outs[ dst_info[ :im ] ] += written
|
914
1027
|
end
|
915
1028
|
|
916
1029
|
##
|
@@ -924,12 +1037,6 @@ module Girl
|
|
924
1037
|
# 处理关闭
|
925
1038
|
if streamd_info[ :closing ] then
|
926
1039
|
close_streamd( streamd )
|
927
|
-
|
928
|
-
if dst then
|
929
|
-
close_read_dst( dst )
|
930
|
-
set_dst_closing_write( dst )
|
931
|
-
end
|
932
|
-
|
933
1040
|
return
|
934
1041
|
end
|
935
1042
|
|
@@ -962,6 +1069,7 @@ module Girl
|
|
962
1069
|
# puts "debug2 written streamd #{ written }"
|
963
1070
|
data = data[ written..-1 ]
|
964
1071
|
streamd_info[ :wbuff ] = data
|
1072
|
+
@traff_outs[ streamd_info[ :im ] ] += written
|
965
1073
|
|
966
1074
|
if dst && !dst.closed? then
|
967
1075
|
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.96.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-18 00:00:00.000000000 Z
|
12
12
|
dependencies: []
|
13
13
|
description: escape evil.
|
14
14
|
email:
|