girl 0.89.0 → 0.94.0
Sign up to get free protection for your applications and to get access to all the features.
Potentially problematic release.
This version of girl might be problematic. Click here for more details.
- checksums.yaml +4 -4
- data/lib/girl/head.rb +7 -2
- data/lib/girl/proxy.rb +29 -17
- data/lib/girl/proxy_worker.rb +176 -120
- data/lib/girl/proxyd.rb +11 -1
- data/lib/girl/proxyd_worker.rb +172 -63
- 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: e4fbf6e091f1c0c19865e86a349ed046284ca1f807a171cd8f91b19066de3e28
|
4
|
+
data.tar.gz: cb9077f3870ba5cfc2ed17bf66f9c97767d94d882836acf757d5b6addcc4860a
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 4bcb135b88eb5fd4d06f7b7cbeb063553a380efa8c3359c0420b69c2b5481a873ea5632333c8dd56899112d86fb1a11697fa8befc734a168cb2d03ef9eb5b2b2
|
7
|
+
data.tar.gz: '07935ef257d9301b18a9e1b4ed943ac0499ca4b502434b27aebebcfb8fcbe3f7a576fc9e5e7a16e9ed37ab9cf75eb490b1802dcad7024dd33f7db1a32ae11d37'
|
data/lib/girl/head.rb
CHANGED
@@ -1,9 +1,12 @@
|
|
1
1
|
module Girl
|
2
2
|
READ_SIZE = 1024 * 1024 # 一次读多少
|
3
|
-
WBUFF_LIMIT = 100 * 1024 * 1024 # 写前上限,超过上限暂停读
|
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,26 +20,34 @@ proxyd-tun:
|
|
20
20
|
|
21
21
|
Q>: 0 ctlmsg -> C: 1 tund port -> n: tund port -> n: tcpd port
|
22
22
|
|
23
|
+
local-infod:
|
24
|
+
|
25
|
+
C: 101 traff infos
|
26
|
+
|
27
|
+
infod-local:
|
28
|
+
|
29
|
+
C: 101 traff infos -> [ C: im len -> im -> Q>: traff in -> Q>: traff out ]
|
30
|
+
|
23
31
|
tun-tund:
|
24
32
|
|
25
|
-
Q>: 0 ctlmsg -> C: 2 heartbeat
|
26
|
-
3 a new source
|
27
|
-
4 paired
|
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
|
33
|
+
Q>: 0 ctlmsg -> C: 2 heartbeat
|
34
|
+
3 a new source -> Q>: src id -> encoded destination address
|
35
|
+
4 paired -> Q>: src id -> n: dst id
|
36
|
+
5 dest status NOT USE
|
37
|
+
6 source status NOT USE
|
38
|
+
7 miss NOT USE
|
39
|
+
8 fin1 NOT USE
|
40
|
+
9 confirm fin1 NOT USE
|
41
|
+
10 fin2 NOT USE
|
42
|
+
11 confirm fin2 NOT USE
|
35
43
|
12 tund fin
|
36
44
|
13 tun fin
|
37
45
|
14 tun ip changed
|
38
|
-
15 single miss
|
39
|
-
16 range miss
|
40
|
-
17 continue
|
41
|
-
18 is resend ready
|
42
|
-
19 resend ready
|
46
|
+
15 single miss NOT USE
|
47
|
+
16 range miss NOT USE
|
48
|
+
17 continue NOT USE
|
49
|
+
18 is resend ready NOT USE
|
50
|
+
19 resend ready NOT USE
|
43
51
|
=end
|
44
52
|
|
45
53
|
module Girl
|
@@ -84,14 +92,14 @@ module Girl
|
|
84
92
|
|
85
93
|
if direct_path then
|
86
94
|
raise "not found direct file #{ direct_path }" unless File.exist?( direct_path )
|
87
|
-
directs = ( RESERVED_ROUTE.split( "\n" ) + IO.binread( direct_path ).split( "\n" ) ).map
|
95
|
+
directs = ( RESERVED_ROUTE.split( "\n" ) + IO.binread( direct_path ).split( "\n" ) ).map{ | line | IPAddr.new( line.strip ) }
|
88
96
|
end
|
89
97
|
|
90
98
|
remotes = []
|
91
99
|
|
92
100
|
if remote_path then
|
93
101
|
raise "not found remote file #{ remote_path }" unless File.exist?( remote_path )
|
94
|
-
remotes = IO.binread( remote_path ).split( "\n" ).map
|
102
|
+
remotes = IO.binread( remote_path ).split( "\n" ).map{ | line | line.strip }
|
95
103
|
end
|
96
104
|
|
97
105
|
unless im then
|
@@ -114,6 +122,10 @@ module Girl
|
|
114
122
|
puts "im #{ im }"
|
115
123
|
puts "worker count #{ worker_count }"
|
116
124
|
|
125
|
+
Girl::Custom.constants.each do | name |
|
126
|
+
puts "#{ name } #{ Girl::Custom.const_get( name ).inspect }"
|
127
|
+
end
|
128
|
+
|
117
129
|
len = CONSTS.map{ | name | name.size }.max
|
118
130
|
|
119
131
|
CONSTS.each do | name |
|
data/lib/girl/proxy_worker.rb
CHANGED
@@ -7,7 +7,6 @@ module Girl
|
|
7
7
|
def initialize( proxy_port, proxyd_host, proxyd_port, directs, remotes, im )
|
8
8
|
@proxyd_host = proxyd_host
|
9
9
|
@proxyd_addr = Socket.sockaddr_in( proxyd_port, proxyd_host )
|
10
|
-
@proxyd_ip = Addrinfo.new( @proxyd_addr ).ip_address
|
11
10
|
@directs = directs
|
12
11
|
@remotes = remotes
|
13
12
|
@custom = Girl::ProxyCustom.new( im )
|
@@ -125,8 +124,28 @@ module Girl
|
|
125
124
|
return if src.closed?
|
126
125
|
src_info = @src_infos[ src ]
|
127
126
|
src_info[ :wbuff ] << data
|
128
|
-
add_write( src )
|
129
127
|
src_info[ :last_recv_at ] = Time.new
|
128
|
+
add_write( src )
|
129
|
+
|
130
|
+
if src_info[ :wbuff ].bytesize >= WBUFF_LIMIT then
|
131
|
+
dst = src_info[ :dst ]
|
132
|
+
|
133
|
+
if dst then
|
134
|
+
dst_info = @dst_infos[ dst ]
|
135
|
+
puts "p#{ Process.pid } #{ Time.new } pause dst #{ dst_info[ :domain ] }"
|
136
|
+
dst_info[ :paused ] = true
|
137
|
+
@reads.delete( dst )
|
138
|
+
else
|
139
|
+
stream = src_info[ :stream ]
|
140
|
+
|
141
|
+
if stream then
|
142
|
+
stream_info = @stream_infos[ stream ]
|
143
|
+
puts "p#{ Process.pid } #{ Time.new } pause stream #{ stream_info[ :domain ] }"
|
144
|
+
stream_info[ :paused ] = true
|
145
|
+
@reads.delete( stream )
|
146
|
+
end
|
147
|
+
end
|
148
|
+
end
|
130
149
|
end
|
131
150
|
|
132
151
|
##
|
@@ -169,7 +188,10 @@ module Girl
|
|
169
188
|
def close_dst( dst )
|
170
189
|
# puts "debug1 close dst"
|
171
190
|
close_sock( dst )
|
172
|
-
@dst_infos.delete( dst )
|
191
|
+
dst_info = @dst_infos.delete( dst )
|
192
|
+
src = dst_info[ :src ]
|
193
|
+
close_read_src( src )
|
194
|
+
set_src_closing_write( src )
|
173
195
|
end
|
174
196
|
|
175
197
|
##
|
@@ -239,7 +261,32 @@ module Girl
|
|
239
261
|
def close_src( src )
|
240
262
|
# puts "debug1 close src"
|
241
263
|
close_sock( src )
|
242
|
-
del_src_info( src )
|
264
|
+
src_info = del_src_info( src )
|
265
|
+
dst = src_info[ :dst ]
|
266
|
+
|
267
|
+
if dst then
|
268
|
+
close_read_dst( dst )
|
269
|
+
set_dst_closing_write( dst )
|
270
|
+
else
|
271
|
+
stream = src_info[ :stream ]
|
272
|
+
|
273
|
+
if stream then
|
274
|
+
close_read_stream( stream )
|
275
|
+
set_stream_closing_write( stream )
|
276
|
+
end
|
277
|
+
end
|
278
|
+
end
|
279
|
+
|
280
|
+
##
|
281
|
+
# close stream
|
282
|
+
#
|
283
|
+
def close_stream( stream )
|
284
|
+
# puts "debug1 close stream"
|
285
|
+
close_sock( stream )
|
286
|
+
stream_info = @stream_infos.delete( stream )
|
287
|
+
src = stream_info[ :src ]
|
288
|
+
close_read_src( src )
|
289
|
+
set_src_closing_write( src )
|
243
290
|
end
|
244
291
|
|
245
292
|
##
|
@@ -268,6 +315,7 @@ module Girl
|
|
268
315
|
src_info = @src_infos[ src ]
|
269
316
|
end
|
270
317
|
|
318
|
+
src_info[ :closed_write ] = true
|
271
319
|
src_info
|
272
320
|
end
|
273
321
|
|
@@ -288,6 +336,7 @@ module Girl
|
|
288
336
|
dst_info = @dst_infos[ dst ]
|
289
337
|
end
|
290
338
|
|
339
|
+
dst_info[ :closed_write ] = true
|
291
340
|
dst_info
|
292
341
|
end
|
293
342
|
|
@@ -308,6 +357,7 @@ module Girl
|
|
308
357
|
stream_info = @stream_infos[ stream ]
|
309
358
|
end
|
310
359
|
|
360
|
+
stream_info[ :closed_write ] = true
|
311
361
|
stream_info
|
312
362
|
end
|
313
363
|
|
@@ -334,7 +384,7 @@ module Girl
|
|
334
384
|
def del_src_info( src )
|
335
385
|
src_info = @src_infos.delete( src )
|
336
386
|
|
337
|
-
if src_info[ :
|
387
|
+
if ( src_info[ :proxy_type ] == :tunnel ) && @tun && !@tun.closed? then
|
338
388
|
@tun_info[ :srcs ].delete( src_info[ :id ] )
|
339
389
|
end
|
340
390
|
|
@@ -355,13 +405,17 @@ module Girl
|
|
355
405
|
|
356
406
|
if @tun && !@tun.closed? then
|
357
407
|
last_recv_at = @tun_info[ :last_recv_at ] || @tun_info[ :created_at ]
|
358
|
-
last_sent_at = @tun_info[ :last_sent_at ] || @tun_info[ :created_at ]
|
359
408
|
|
360
|
-
if @tun_info[ :srcs ].empty? && ( now - last_recv_at >= EXPIRE_AFTER )
|
409
|
+
if @tun_info[ :srcs ].empty? && ( now - last_recv_at >= EXPIRE_AFTER ) then
|
361
410
|
puts "p#{ Process.pid } #{ Time.new } expire tun"
|
362
411
|
set_tun_closing
|
363
|
-
|
412
|
+
else
|
413
|
+
# puts "debug1 #{ Time.new } heartbeat"
|
414
|
+
data = [ 0, HEARTBEAT ].pack( 'Q>C' )
|
415
|
+
add_ctlmsg( data )
|
364
416
|
end
|
417
|
+
|
418
|
+
trigger = true
|
365
419
|
end
|
366
420
|
|
367
421
|
@src_infos.each do | src, src_info |
|
@@ -415,6 +469,30 @@ module Girl
|
|
415
469
|
end
|
416
470
|
end
|
417
471
|
|
472
|
+
@dst_infos.select{ | _, dst_info | dst_info[ :paused ] }.each do | dst, dst_info |
|
473
|
+
src = dst_info[ :src ]
|
474
|
+
src_info = @src_infos[ src ]
|
475
|
+
|
476
|
+
if src_info[ :wbuff ].size < RESUME_BELOW then
|
477
|
+
puts "p#{ Process.pid } #{ Time.new } src.wbuff below #{ RESUME_BELOW }, resume dst #{ dst_info[ :domain ] }"
|
478
|
+
dst_info[ :paused ] = false
|
479
|
+
add_read( dst )
|
480
|
+
trigger = true
|
481
|
+
end
|
482
|
+
end
|
483
|
+
|
484
|
+
@stream_infos.select{ | _, stream_info | stream_info[ :paused ] }.each do | stream, stream_info |
|
485
|
+
src = stream_info[ :src ]
|
486
|
+
src_info = @src_infos[ src ]
|
487
|
+
|
488
|
+
if src_info[ :wbuff ].size < RESUME_BELOW then
|
489
|
+
puts "p#{ Process.pid } #{ Time.new } src.wbuff below #{ RESUME_BELOW }, resume stream #{ stream_info[ :domain ] }"
|
490
|
+
stream_info[ :paused ] = false
|
491
|
+
add_read( stream )
|
492
|
+
trigger = true
|
493
|
+
end
|
494
|
+
end
|
495
|
+
|
418
496
|
next_tick if trigger
|
419
497
|
end
|
420
498
|
end
|
@@ -449,7 +527,7 @@ module Girl
|
|
449
527
|
next_tick
|
450
528
|
end
|
451
529
|
|
452
|
-
sleep
|
530
|
+
sleep SEND_HELLO_INTERVAL
|
453
531
|
end
|
454
532
|
end
|
455
533
|
end
|
@@ -470,7 +548,7 @@ module Girl
|
|
470
548
|
rescue IO::WaitWritable
|
471
549
|
# connect nonblock 必抛 wait writable
|
472
550
|
rescue Exception => e
|
473
|
-
puts "p#{ Process.pid } #{ Time.new } dst connect destination #{ e.class }, close src"
|
551
|
+
puts "p#{ Process.pid } #{ Time.new } dst connect destination #{ domain } #{ src_info[ :destination_port ] } #{ ip_info.ip_address } #{ e.class }, close src"
|
474
552
|
set_src_closing( src )
|
475
553
|
return
|
476
554
|
end
|
@@ -480,11 +558,12 @@ module Girl
|
|
480
558
|
dst_info = {
|
481
559
|
local_port: local_port, # 本地端口
|
482
560
|
src: src, # 对应src
|
483
|
-
domain: domain, #
|
561
|
+
domain: domain, # 目的地
|
484
562
|
wbuff: '', # 写前,从src读到的流量
|
563
|
+
paused: false, # 是否已暂停读
|
485
564
|
closing: false, # 准备关闭
|
486
|
-
|
487
|
-
|
565
|
+
closing_write: false, # 准备关闭写
|
566
|
+
closed_write: false # 已关闭写
|
488
567
|
}
|
489
568
|
|
490
569
|
@dst_infos[ dst ] = dst_info
|
@@ -541,9 +620,15 @@ module Girl
|
|
541
620
|
data << @custom.encode( src_info[ :rbuff ] )
|
542
621
|
end
|
543
622
|
|
623
|
+
domain = src_info[ :destination_domain ]
|
544
624
|
@stream_infos[ stream ] = {
|
545
|
-
src: src,
|
546
|
-
|
625
|
+
src: src, # 对应src
|
626
|
+
domain: domain, # 目的地
|
627
|
+
wbuff: data, # 写前,写往远端streamd
|
628
|
+
paused: false, # 是否已暂停读
|
629
|
+
closing: false, # 准备关闭
|
630
|
+
closing_write: false, # 准备关闭写
|
631
|
+
closed_write: false # 已关闭写
|
547
632
|
}
|
548
633
|
|
549
634
|
src_info[ :dst_id ] = dst_id
|
@@ -588,22 +673,15 @@ module Girl
|
|
588
673
|
tun.bind( Socket.sockaddr_in( 0, '0.0.0.0' ) )
|
589
674
|
port = tun.local_address.ip_port
|
590
675
|
tun_info = {
|
591
|
-
port: port,
|
592
|
-
pending_sources: [],
|
593
|
-
ctlmsgs: [],
|
594
|
-
|
595
|
-
|
596
|
-
|
597
|
-
|
598
|
-
|
599
|
-
|
600
|
-
srcs: {}, # src_id => src
|
601
|
-
created_at: Time.new, # 创建时间
|
602
|
-
last_recv_at: nil, # 上一次收到流量的时间
|
603
|
-
last_sent_at: nil, # 上一次发出流量的时间
|
604
|
-
sender_addrs: nil, # 远端发送者地址
|
605
|
-
last_ping_senders_at: nil, # 上一次ping发送者的时间
|
606
|
-
closing: false # 是否准备关闭
|
676
|
+
port: port, # 端口
|
677
|
+
pending_sources: [], # 还没配上tund,暂存的src
|
678
|
+
ctlmsgs: [], # [ ctlmsg, to_addr ]
|
679
|
+
tund_addr: nil, # tund地址
|
680
|
+
tcpd_addr: nil, # tcpd地址
|
681
|
+
srcs: {}, # src_id => src
|
682
|
+
created_at: Time.new, # 创建时间
|
683
|
+
last_recv_at: nil, # 上一次收到流量的时间
|
684
|
+
closing: false # 是否准备关闭
|
607
685
|
}
|
608
686
|
|
609
687
|
@tun = tun
|
@@ -628,7 +706,7 @@ module Girl
|
|
628
706
|
next_tick
|
629
707
|
end
|
630
708
|
|
631
|
-
sleep
|
709
|
+
sleep SEND_HELLO_INTERVAL
|
632
710
|
end
|
633
711
|
end
|
634
712
|
end
|
@@ -701,36 +779,20 @@ module Girl
|
|
701
779
|
add_read( src )
|
702
780
|
end
|
703
781
|
|
704
|
-
##
|
705
|
-
# send data
|
706
|
-
#
|
707
|
-
def send_data( data, to_addr = nil )
|
708
|
-
unless to_addr then
|
709
|
-
to_addr = @tun_info[ :tund_addr ]
|
710
|
-
end
|
711
|
-
|
712
|
-
begin
|
713
|
-
written = @tun.sendmsg_nonblock( data, 0, to_addr )
|
714
|
-
rescue IO::WaitWritable, Errno::EINTR
|
715
|
-
print '.'
|
716
|
-
return :wait
|
717
|
-
rescue Errno::EHOSTUNREACH, Errno::ENETUNREACH, Errno::ENETDOWN => e
|
718
|
-
puts "#{ Time.new } sendmsg #{ e.class }, close tun"
|
719
|
-
return :fatal
|
720
|
-
end
|
721
|
-
|
722
|
-
written
|
723
|
-
end
|
724
|
-
|
725
782
|
##
|
726
783
|
# set dst closing
|
727
784
|
#
|
728
785
|
def set_dst_closing( dst )
|
729
786
|
return if dst.closed?
|
730
787
|
dst_info = @dst_infos[ dst ]
|
731
|
-
|
732
|
-
|
733
|
-
|
788
|
+
|
789
|
+
if dst_info[ :closed_write ] then
|
790
|
+
close_read_dst( dst )
|
791
|
+
else
|
792
|
+
dst_info[ :closing ] = true
|
793
|
+
@reads.delete( dst )
|
794
|
+
add_write( dst )
|
795
|
+
end
|
734
796
|
end
|
735
797
|
|
736
798
|
##
|
@@ -738,7 +800,10 @@ module Girl
|
|
738
800
|
#
|
739
801
|
def set_dst_closing_write( dst )
|
740
802
|
return if dst.closed?
|
803
|
+
|
741
804
|
dst_info = @dst_infos[ dst ]
|
805
|
+
return if dst_info[ :closed_write ]
|
806
|
+
|
742
807
|
dst_info[ :closing_write ] = true
|
743
808
|
add_write( dst )
|
744
809
|
end
|
@@ -748,10 +813,16 @@ module Girl
|
|
748
813
|
#
|
749
814
|
def set_src_closing( src )
|
750
815
|
return if src.closed?
|
751
|
-
|
816
|
+
|
752
817
|
src_info = @src_infos[ src ]
|
753
|
-
|
754
|
-
|
818
|
+
|
819
|
+
if src_info[ :closed_write ] then
|
820
|
+
close_read_src( src )
|
821
|
+
else
|
822
|
+
@reads.delete( src )
|
823
|
+
src_info[ :closing ] = true
|
824
|
+
add_write( src )
|
825
|
+
end
|
755
826
|
end
|
756
827
|
|
757
828
|
##
|
@@ -759,7 +830,10 @@ module Girl
|
|
759
830
|
#
|
760
831
|
def set_src_closing_write( src )
|
761
832
|
return if src.closed?
|
833
|
+
|
762
834
|
src_info = @src_infos[ src ]
|
835
|
+
return if src_info[ :closed_write ]
|
836
|
+
|
763
837
|
src_info[ :closing_write ] = true
|
764
838
|
add_write( src )
|
765
839
|
end
|
@@ -784,23 +858,15 @@ module Girl
|
|
784
858
|
end
|
785
859
|
end
|
786
860
|
|
787
|
-
##
|
788
|
-
# set stream closing
|
789
|
-
#
|
790
|
-
def set_stream_closing( stream )
|
791
|
-
return if stream.closed?
|
792
|
-
stream_info = @stream_infos[ stream ]
|
793
|
-
stream_info[ :closing ] = true
|
794
|
-
@reads.delete( stream )
|
795
|
-
add_write( stream )
|
796
|
-
end
|
797
|
-
|
798
861
|
##
|
799
862
|
# set stream closing write
|
800
863
|
#
|
801
864
|
def set_stream_closing_write( stream )
|
802
865
|
return if stream.closed?
|
866
|
+
|
803
867
|
stream_info = @stream_infos[ stream ]
|
868
|
+
return if stream_info[ :closed_write ]
|
869
|
+
|
804
870
|
stream_info[ :closing_write ] = true
|
805
871
|
add_write( stream )
|
806
872
|
end
|
@@ -856,24 +922,24 @@ module Girl
|
|
856
922
|
# puts "debug1 accept a src #{ addrinfo.inspect } #{ src_id }"
|
857
923
|
|
858
924
|
@src_infos[ src ] = {
|
859
|
-
id: src_id,
|
860
|
-
proxy_proto: :uncheck,
|
861
|
-
proxy_type: :uncheck,
|
862
|
-
destination_domain: nil,
|
863
|
-
destination_port: nil,
|
864
|
-
is_connect: true,
|
865
|
-
rbuff: '',
|
866
|
-
|
867
|
-
|
868
|
-
|
869
|
-
|
870
|
-
created_at: Time.new,
|
871
|
-
last_recv_at: nil,
|
872
|
-
last_sent_at: nil,
|
873
|
-
paused: false,
|
874
|
-
closing: false,
|
875
|
-
|
876
|
-
|
925
|
+
id: src_id, # id
|
926
|
+
proxy_proto: :uncheck, # :uncheck / :http / :socks5
|
927
|
+
proxy_type: :uncheck, # :uncheck / :checking / :direct / :tunnel / :negotiation
|
928
|
+
destination_domain: nil, # 目的地域名
|
929
|
+
destination_port: nil, # 目的地端口
|
930
|
+
is_connect: true, # 代理协议是http的场合,是否是CONNECT
|
931
|
+
rbuff: '', # 读到的流量
|
932
|
+
dst: nil, # :direct的场合,对应的dst
|
933
|
+
stream: nil, # :tunnel的场合,对应的stream
|
934
|
+
dst_id: nil, # 远端dst id
|
935
|
+
wbuff: '', # 从dst/stream读到的流量
|
936
|
+
created_at: Time.new, # 创建时间
|
937
|
+
last_recv_at: nil, # 上一次收到新流量(由dst收到,或者由stream收到)的时间
|
938
|
+
last_sent_at: nil, # 上一次发出流量(由dst发出,或者由stream发出)的时间
|
939
|
+
paused: false, # 是否已暂停读
|
940
|
+
closing: false, # 准备关闭
|
941
|
+
closing_write: false, # 准备关闭写
|
942
|
+
closed_write: false # 已关闭写
|
877
943
|
}
|
878
944
|
|
879
945
|
add_read( src, :src )
|
@@ -891,10 +957,10 @@ module Girl
|
|
891
957
|
end
|
892
958
|
|
893
959
|
from_addr = addrinfo.to_sockaddr
|
894
|
-
@tun_info[ :last_recv_at ] = Time.new
|
895
960
|
pack_id = data[ 0, 8 ].unpack( 'Q>' ).first
|
896
961
|
return if pack_id != 0
|
897
962
|
|
963
|
+
@tun_info[ :last_recv_at ] = Time.new
|
898
964
|
ctl_num = data[ 8 ].unpack( 'C' ).first
|
899
965
|
|
900
966
|
case ctl_num
|
@@ -940,6 +1006,8 @@ module Girl
|
|
940
1006
|
# read src
|
941
1007
|
#
|
942
1008
|
def read_src( src )
|
1009
|
+
return if src.closed?
|
1010
|
+
|
943
1011
|
begin
|
944
1012
|
data = src.read_nonblock( READ_SIZE )
|
945
1013
|
rescue IO::WaitReadable, Errno::EINTR
|
@@ -1093,7 +1161,7 @@ module Girl
|
|
1093
1161
|
add_write( stream )
|
1094
1162
|
|
1095
1163
|
if stream_info[ :wbuff ].bytesize >= WBUFF_LIMIT then
|
1096
|
-
puts "p#{ Process.pid } #{ Time.new } pause tunnel src #{ src_info[ :
|
1164
|
+
puts "p#{ Process.pid } #{ Time.new } pause tunnel src #{ src_info[ :destination_domain ] }"
|
1097
1165
|
src_info[ :paused ] = true
|
1098
1166
|
@reads.delete( src )
|
1099
1167
|
end
|
@@ -1122,7 +1190,7 @@ module Girl
|
|
1122
1190
|
add_write( dst )
|
1123
1191
|
|
1124
1192
|
if dst_info[ :wbuff ].bytesize >= WBUFF_LIMIT then
|
1125
|
-
puts "p#{ Process.pid } #{ Time.new } pause direct src #{ src_info[ :
|
1193
|
+
puts "p#{ Process.pid } #{ Time.new } pause direct src #{ src_info[ :destination_domain ] }"
|
1126
1194
|
src_info[ :paused ] = true
|
1127
1195
|
@reads.delete( src )
|
1128
1196
|
end
|
@@ -1143,6 +1211,8 @@ module Girl
|
|
1143
1211
|
# read dst
|
1144
1212
|
#
|
1145
1213
|
def read_dst( dst )
|
1214
|
+
return if dst.closed?
|
1215
|
+
|
1146
1216
|
begin
|
1147
1217
|
data = dst.read_nonblock( READ_SIZE )
|
1148
1218
|
rescue IO::WaitReadable, Errno::EINTR
|
@@ -1165,6 +1235,8 @@ module Girl
|
|
1165
1235
|
# read stream
|
1166
1236
|
#
|
1167
1237
|
def read_stream( stream )
|
1238
|
+
return if stream.closed?
|
1239
|
+
|
1168
1240
|
begin
|
1169
1241
|
data = stream.read_nonblock( READ_SIZE )
|
1170
1242
|
rescue IO::WaitReadable, Errno::EINTR
|
@@ -1200,21 +1272,21 @@ module Girl
|
|
1200
1272
|
# 发ctlmsg
|
1201
1273
|
while @tun_info[ :ctlmsgs ].any? do
|
1202
1274
|
data, to_addr = @tun_info[ :ctlmsgs ].first
|
1203
|
-
sent = send_data( data, to_addr )
|
1204
1275
|
|
1205
|
-
|
1206
|
-
|
1276
|
+
begin
|
1277
|
+
@tun.sendmsg_nonblock( data, 0, to_addr )
|
1278
|
+
rescue IO::WaitWritable, Errno::EINTR
|
1279
|
+
puts "p#{ Process.pid } #{ Time.new } wait send ctlmsg, left #{ @tun_info[ :ctlmsgs ].size }"
|
1207
1280
|
return
|
1208
|
-
|
1209
|
-
|
1210
|
-
|
1281
|
+
rescue Errno::EHOSTUNREACH, Errno::ENETUNREACH, Errno::ENETDOWN => e
|
1282
|
+
puts "p#{ Process.pid } #{ Time.new } sendmsg #{ e.class }, close tun"
|
1283
|
+
close_tun( tun )
|
1211
1284
|
return
|
1212
1285
|
end
|
1213
1286
|
|
1214
1287
|
@tun_info[ :ctlmsgs ].shift
|
1215
1288
|
end
|
1216
1289
|
|
1217
|
-
@tun_info[ :last_sent_at ] = now
|
1218
1290
|
@writes.delete( tun )
|
1219
1291
|
end
|
1220
1292
|
|
@@ -1229,19 +1301,6 @@ module Girl
|
|
1229
1301
|
# 处理关闭
|
1230
1302
|
if src_info[ :closing ] then
|
1231
1303
|
close_src( src )
|
1232
|
-
|
1233
|
-
if dst then
|
1234
|
-
close_read_dst( dst )
|
1235
|
-
set_dst_closing_write( dst )
|
1236
|
-
else
|
1237
|
-
stream = src_info[ :stream ]
|
1238
|
-
|
1239
|
-
if stream then
|
1240
|
-
close_read_stream( stream )
|
1241
|
-
set_stream_closing_write( stream )
|
1242
|
-
end
|
1243
|
-
end
|
1244
|
-
|
1245
1304
|
return
|
1246
1305
|
end
|
1247
1306
|
|
@@ -1295,12 +1354,6 @@ module Girl
|
|
1295
1354
|
# 处理关闭
|
1296
1355
|
if dst_info[ :closing ] then
|
1297
1356
|
close_dst( dst )
|
1298
|
-
|
1299
|
-
if src then
|
1300
|
-
close_read_src( src )
|
1301
|
-
set_src_closing_write( src )
|
1302
|
-
end
|
1303
|
-
|
1304
1357
|
return
|
1305
1358
|
end
|
1306
1359
|
|
@@ -1326,12 +1379,17 @@ module Girl
|
|
1326
1379
|
rescue Exception => e
|
1327
1380
|
# puts "debug1 write dst #{ e.class }"
|
1328
1381
|
close_write_dst( dst )
|
1329
|
-
close_read_src( src )
|
1382
|
+
close_read_src( src )
|
1330
1383
|
return
|
1331
1384
|
end
|
1332
1385
|
|
1333
1386
|
data = data[ written..-1 ]
|
1334
1387
|
dst_info[ :wbuff ] = data
|
1388
|
+
|
1389
|
+
unless src.closed? then
|
1390
|
+
src_info = @src_infos[ src ]
|
1391
|
+
src_info[ :last_sent_at ] = Time.new
|
1392
|
+
end
|
1335
1393
|
end
|
1336
1394
|
|
1337
1395
|
##
|
@@ -1345,8 +1403,6 @@ module Girl
|
|
1345
1403
|
# 处理关闭
|
1346
1404
|
if stream_info[ :closing ] then
|
1347
1405
|
close_stream( stream )
|
1348
|
-
close_read_src( src )
|
1349
|
-
set_src_closing_write( src )
|
1350
1406
|
return
|
1351
1407
|
end
|
1352
1408
|
|
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,6 +33,7 @@ module Girl
|
|
30
33
|
puts "p#{ Process.pid } #{ Time.new } looping"
|
31
34
|
loop_check_expire
|
32
35
|
loop_check_resume
|
36
|
+
loop_check_traff
|
33
37
|
|
34
38
|
loop do
|
35
39
|
rs, ws = IO.select( @reads, @writes )
|
@@ -42,6 +46,8 @@ module Girl
|
|
42
46
|
read_dotr( sock )
|
43
47
|
when :proxyd then
|
44
48
|
read_proxyd( sock )
|
49
|
+
when :infod then
|
50
|
+
read_infod( sock )
|
45
51
|
when :tund then
|
46
52
|
read_tund( sock )
|
47
53
|
when :tcpd then
|
@@ -100,15 +106,6 @@ module Girl
|
|
100
106
|
add_write( @proxyd )
|
101
107
|
end
|
102
108
|
|
103
|
-
##
|
104
|
-
# add ctlmsg resend ready
|
105
|
-
#
|
106
|
-
def add_ctlmsg_resend_ready( tund )
|
107
|
-
tund_info = @tund_infos[ tund ]
|
108
|
-
data = [ 0, RESEND_READY ].pack( 'Q>C' )
|
109
|
-
add_ctlmsg( tund, data )
|
110
|
-
end
|
111
|
-
|
112
109
|
##
|
113
110
|
# add ctlmsg
|
114
111
|
#
|
@@ -146,7 +143,13 @@ module Girl
|
|
146
143
|
def close_dst( dst )
|
147
144
|
# puts "debug1 close dst"
|
148
145
|
close_sock( dst )
|
149
|
-
del_dst_info( dst )
|
146
|
+
dst_info = del_dst_info( dst )
|
147
|
+
streamd = dst_info[ :streamd ]
|
148
|
+
|
149
|
+
if streamd then
|
150
|
+
close_read_streamd( streamd )
|
151
|
+
set_streamd_closing_write( streamd )
|
152
|
+
end
|
150
153
|
end
|
151
154
|
|
152
155
|
##
|
@@ -206,7 +209,13 @@ module Girl
|
|
206
209
|
def close_streamd( streamd )
|
207
210
|
# puts "debug1 close streamd"
|
208
211
|
close_sock( streamd )
|
209
|
-
@streamd_infos.delete( streamd )
|
212
|
+
streamd_info = @streamd_infos.delete( streamd )
|
213
|
+
dst = streamd_info[ :dst ]
|
214
|
+
|
215
|
+
if dst then
|
216
|
+
close_read_dst( dst )
|
217
|
+
set_dst_closing_write( dst )
|
218
|
+
end
|
210
219
|
end
|
211
220
|
|
212
221
|
##
|
@@ -240,6 +249,7 @@ module Girl
|
|
240
249
|
dst_info = @dst_infos[ dst ]
|
241
250
|
end
|
242
251
|
|
252
|
+
dst_info[ :closed_write ] = true
|
243
253
|
dst_info
|
244
254
|
end
|
245
255
|
|
@@ -260,6 +270,7 @@ module Girl
|
|
260
270
|
streamd_info = @streamd_infos[ streamd ]
|
261
271
|
end
|
262
272
|
|
273
|
+
streamd_info[ :closed_write ] = true
|
263
274
|
streamd_info
|
264
275
|
end
|
265
276
|
|
@@ -274,16 +285,18 @@ module Girl
|
|
274
285
|
dst.connect_nonblock( destination_addr )
|
275
286
|
rescue IO::WaitWritable
|
276
287
|
rescue Exception => e
|
277
|
-
puts "p#{ Process.pid } #{ Time.new } connect destination #{ e.class }"
|
288
|
+
puts "p#{ Process.pid } #{ Time.new } connect destination #{ domain_port } #{ e.class }"
|
278
289
|
return false
|
279
290
|
end
|
280
291
|
|
281
292
|
dst_id = dst.local_address.ip_port
|
293
|
+
tund_info = @tund_infos[ tund ]
|
282
294
|
|
283
295
|
@dst_infos[ dst ] = {
|
284
296
|
id: dst_id, # id
|
285
297
|
tund: tund, # 对应tund
|
286
|
-
|
298
|
+
im: tund_info[ :im ], # 标识
|
299
|
+
domain_port: domain_port, # 目的地和端口
|
287
300
|
rbuff: '', # 对应的streamd没准备好,暂存读到的流量
|
288
301
|
streamd: nil, # 对应的streamd
|
289
302
|
wbuff: '', # 从streamd读到的流量
|
@@ -291,15 +304,14 @@ module Girl
|
|
291
304
|
created_at: Time.new, # 创建时间
|
292
305
|
last_recv_at: nil, # 上一次收到新流量(由streamd收到)的时间
|
293
306
|
last_sent_at: nil, # 上一次发出流量(由streamd发出)的时间
|
294
|
-
paused: false, #
|
307
|
+
paused: false, # 是否已暂停读
|
295
308
|
closing: false, # 准备关闭
|
296
|
-
|
297
|
-
|
309
|
+
closing_write: false, # 准备关闭写
|
310
|
+
closed_write: false # 已关闭写
|
298
311
|
}
|
299
312
|
|
300
313
|
add_read( dst, :dst )
|
301
314
|
|
302
|
-
tund_info = @tund_infos[ tund ]
|
303
315
|
tund_info[ :dst_ids ][ src_id ] = dst_id
|
304
316
|
tund_info[ :dsts ][ dst_id ] = dst
|
305
317
|
|
@@ -339,9 +351,8 @@ module Girl
|
|
339
351
|
|
340
352
|
@tund_infos.each do | tund, tund_info |
|
341
353
|
last_recv_at = tund_info[ :last_recv_at ] || tund_info[ :created_at ]
|
342
|
-
last_sent_at = tund_info[ :last_sent_at ] || tund_info[ :created_at ]
|
343
354
|
|
344
|
-
if tund_info[ :dsts ].empty? && ( now - last_recv_at >= EXPIRE_AFTER )
|
355
|
+
if tund_info[ :dsts ].empty? && ( now - last_recv_at >= EXPIRE_AFTER ) then
|
345
356
|
puts "p#{ Process.pid } #{ Time.new } expire tund #{ tund_info[ :port ] }"
|
346
357
|
set_tund_closing( tund )
|
347
358
|
trigger = true
|
@@ -388,12 +399,45 @@ module Girl
|
|
388
399
|
end
|
389
400
|
end
|
390
401
|
|
402
|
+
@streamd_infos.select{ | _, streamd_info | streamd_info[ :paused ] }.each do | streamd, streamd_info |
|
403
|
+
dst = streamd_info[ :dst ]
|
404
|
+
dst_info = @dst_infos[ dst ]
|
405
|
+
|
406
|
+
if dst_info[ :wbuff ].size < RESUME_BELOW then
|
407
|
+
puts "p#{ Process.pid } #{ Time.new } resume streamd #{ streamd_info[ :domain_port ] }"
|
408
|
+
streamd_info[ :paused ] = false
|
409
|
+
add_read( streamd )
|
410
|
+
trigger = true
|
411
|
+
end
|
412
|
+
end
|
413
|
+
|
391
414
|
next_tick if trigger
|
392
415
|
end
|
393
416
|
end
|
394
417
|
end
|
395
418
|
end
|
396
419
|
|
420
|
+
##
|
421
|
+
# loop check traff
|
422
|
+
#
|
423
|
+
def loop_check_traff
|
424
|
+
if RESET_TRAFF_DAY > 0 then
|
425
|
+
Thread.new do
|
426
|
+
loop do
|
427
|
+
sleep CHECK_TRAFF_INTERVAL
|
428
|
+
|
429
|
+
@mutex.synchronize do
|
430
|
+
if Time.new.day == RESET_TRAFF_DAY then
|
431
|
+
puts "p#{ Process.pid } #{ Time.new } reset traffs"
|
432
|
+
@traff_ins.transform_values!{ | _ | 0 }
|
433
|
+
@traff_outs.transform_values!{ | _ | 0 }
|
434
|
+
end
|
435
|
+
end
|
436
|
+
end
|
437
|
+
end
|
438
|
+
end
|
439
|
+
end
|
440
|
+
|
397
441
|
##
|
398
442
|
# new a proxyd
|
399
443
|
#
|
@@ -411,6 +455,18 @@ module Girl
|
|
411
455
|
add_read( proxyd, :proxyd )
|
412
456
|
end
|
413
457
|
|
458
|
+
##
|
459
|
+
# new a infod
|
460
|
+
#
|
461
|
+
def new_a_infod( infod_port )
|
462
|
+
infod = Socket.new( Socket::AF_INET, Socket::SOCK_DGRAM, 0 )
|
463
|
+
infod.setsockopt( Socket::SOL_SOCKET, Socket::SO_REUSEPORT, 1 )
|
464
|
+
infod.bind( Socket.sockaddr_in( infod_port, '127.0.0.1' ) )
|
465
|
+
|
466
|
+
puts "p#{ Process.pid } #{ Time.new } infod bind on #{ infod_port }"
|
467
|
+
add_read( infod, :infod )
|
468
|
+
end
|
469
|
+
|
414
470
|
##
|
415
471
|
# next tick
|
416
472
|
#
|
@@ -473,9 +529,9 @@ module Girl
|
|
473
529
|
begin
|
474
530
|
written = sock.sendmsg_nonblock( data, 0, to_addr )
|
475
531
|
rescue IO::WaitWritable, Errno::EINTR
|
476
|
-
print '.'
|
477
532
|
return :wait
|
478
533
|
rescue Errno::EHOSTUNREACH, Errno::ENETUNREACH, Errno::ENETDOWN => e
|
534
|
+
puts "p#{ Process.pid } #{ Time.new } sendmsg #{ e.class }"
|
479
535
|
return :fatal
|
480
536
|
end
|
481
537
|
|
@@ -487,10 +543,16 @@ module Girl
|
|
487
543
|
#
|
488
544
|
def set_dst_closing( dst )
|
489
545
|
return if dst.closed?
|
546
|
+
|
490
547
|
dst_info = @dst_infos[ dst ]
|
491
|
-
|
492
|
-
|
493
|
-
|
548
|
+
|
549
|
+
if dst_info[ :closed_write ] then
|
550
|
+
close_read_dst( dst )
|
551
|
+
else
|
552
|
+
dst_info[ :closing ] = true
|
553
|
+
@reads.delete( dst )
|
554
|
+
add_write( dst )
|
555
|
+
end
|
494
556
|
end
|
495
557
|
|
496
558
|
##
|
@@ -498,7 +560,10 @@ module Girl
|
|
498
560
|
#
|
499
561
|
def set_dst_closing_write( dst )
|
500
562
|
return if dst.closed?
|
563
|
+
|
501
564
|
dst_info = @dst_infos[ dst ]
|
565
|
+
return if dst_info[ :closed_write ]
|
566
|
+
|
502
567
|
dst_info[ :closing_write ] = true
|
503
568
|
add_write( dst )
|
504
569
|
end
|
@@ -509,9 +574,14 @@ module Girl
|
|
509
574
|
def set_streamd_closing( streamd )
|
510
575
|
return if streamd.closed?
|
511
576
|
streamd_info = @streamd_infos[ streamd ]
|
512
|
-
|
513
|
-
|
514
|
-
|
577
|
+
|
578
|
+
if streamd_info[ :closed_write ] then
|
579
|
+
close_read_streamd( streamd )
|
580
|
+
else
|
581
|
+
streamd_info[ :closing ] = true
|
582
|
+
@reads.delete( streamd )
|
583
|
+
add_write( streamd )
|
584
|
+
end
|
515
585
|
end
|
516
586
|
|
517
587
|
##
|
@@ -519,7 +589,10 @@ module Girl
|
|
519
589
|
#
|
520
590
|
def set_streamd_closing_write( streamd )
|
521
591
|
return if streamd.closed?
|
592
|
+
|
522
593
|
streamd_info = @streamd_infos[ streamd ]
|
594
|
+
return if streamd_info[ :closed_write ]
|
595
|
+
|
523
596
|
streamd_info[ :closing_write ] = true
|
524
597
|
add_write( streamd )
|
525
598
|
end
|
@@ -564,6 +637,13 @@ module Girl
|
|
564
637
|
return
|
565
638
|
end
|
566
639
|
|
640
|
+
im = data
|
641
|
+
|
642
|
+
unless @traff_ins.include?( im ) then
|
643
|
+
@traff_ins[ im ] = 0
|
644
|
+
@traff_outs[ im ] = 0
|
645
|
+
end
|
646
|
+
|
567
647
|
tund = Socket.new( Socket::AF_INET, Socket::SOCK_DGRAM, 0 )
|
568
648
|
tund.bind( Socket.sockaddr_in( 0, '0.0.0.0' ) )
|
569
649
|
tund_port = tund.local_address.ip_port
|
@@ -577,20 +657,18 @@ module Girl
|
|
577
657
|
add_read( tcpd, :tcpd )
|
578
658
|
|
579
659
|
tund_info = {
|
580
|
-
|
581
|
-
|
582
|
-
|
583
|
-
|
584
|
-
|
585
|
-
|
586
|
-
|
587
|
-
|
588
|
-
|
589
|
-
|
590
|
-
closing: false,
|
591
|
-
|
592
|
-
closing_write: false, # 准备关闭写
|
593
|
-
changed_tun_addr: nil # 记录到和tun addr不符的来源地址
|
660
|
+
im: im, # 标识
|
661
|
+
port: tund_port, # 端口
|
662
|
+
tcpd: tcpd, # 对应的tcpd
|
663
|
+
tcpd_port: tcpd_port, # tcpd端口
|
664
|
+
ctlmsgs: [], # [ ctlmsg, to_addr ]
|
665
|
+
tun_addr: from_addr, # tun地址
|
666
|
+
dsts: {}, # dst_id => dst
|
667
|
+
dst_ids: {}, # src_id => dst_id
|
668
|
+
created_at: Time.new, # 创建时间
|
669
|
+
last_recv_at: nil, # 上一次收到流量的时间
|
670
|
+
closing: false, # 准备关闭
|
671
|
+
changed_tun_addr: nil # 记录到和tun addr不符的来源地址
|
594
672
|
}
|
595
673
|
|
596
674
|
@tunneling_tunds[ from_addr ] = tund
|
@@ -603,6 +681,28 @@ module Girl
|
|
603
681
|
add_proxyd_ctlmsg_tund_port( tund_info )
|
604
682
|
end
|
605
683
|
|
684
|
+
##
|
685
|
+
# read infod
|
686
|
+
#
|
687
|
+
def read_infod( infod )
|
688
|
+
data, addrinfo, rflags, *controls = infod.recvmsg
|
689
|
+
ctl_num = data[ 0 ].unpack( 'C' ).first
|
690
|
+
# puts "debug1 infod recv #{ ctl_num } #{ addrinfo.inspect }"
|
691
|
+
|
692
|
+
case ctl_num
|
693
|
+
when TRAFF_INFOS then
|
694
|
+
data2 = [ TRAFF_INFOS ].pack( 'C' )
|
695
|
+
|
696
|
+
@traff_ins.keys.sort.each do | im |
|
697
|
+
traff_in = @traff_ins[ im ]
|
698
|
+
traff_out = @traff_outs[ im ]
|
699
|
+
data2 << [ [ im.bytesize ].pack( 'C' ), im, [ traff_in, traff_out ].pack( 'Q>Q>' ) ].join
|
700
|
+
end
|
701
|
+
|
702
|
+
send_data( infod, data2, addrinfo )
|
703
|
+
end
|
704
|
+
end
|
705
|
+
|
606
706
|
##
|
607
707
|
# read tund
|
608
708
|
#
|
@@ -625,10 +725,10 @@ module Girl
|
|
625
725
|
return
|
626
726
|
end
|
627
727
|
|
628
|
-
tund_info[ :last_recv_at ] = Time.new
|
629
728
|
pack_id = data[ 0, 8 ].unpack( 'Q>' ).first
|
630
729
|
return if pack_id != 0
|
631
730
|
|
731
|
+
tund_info[ :last_recv_at ] = Time.new
|
632
732
|
ctl_num = data[ 8 ].unpack( 'C' ).first
|
633
733
|
|
634
734
|
case ctl_num
|
@@ -674,11 +774,18 @@ module Girl
|
|
674
774
|
# puts "debug1 accept a streamd"
|
675
775
|
tcpd_info = @tcpd_infos[ tcpd ]
|
676
776
|
tund = tcpd_info[ :tund ]
|
777
|
+
tund_info = @tund_infos[ tund ]
|
677
778
|
|
678
779
|
@streamd_infos[ streamd ] = {
|
679
|
-
tund: tund,
|
680
|
-
|
681
|
-
|
780
|
+
tund: tund, # 对应tund
|
781
|
+
im: tund_info[ :im ], # 标识
|
782
|
+
dst: nil, # 对应dst
|
783
|
+
domain_port: nil, # dst的目的地和端口
|
784
|
+
wbuff: '', # 写前,写往近端stream
|
785
|
+
paused: false, # 是否已暂停读
|
786
|
+
closing: false, # 准备关闭
|
787
|
+
closing_write: false, # 准备关闭写
|
788
|
+
closed_write: false # 已关闭写
|
682
789
|
}
|
683
790
|
|
684
791
|
add_read( streamd, :streamd )
|
@@ -688,6 +795,8 @@ module Girl
|
|
688
795
|
# read dst
|
689
796
|
#
|
690
797
|
def read_dst( dst )
|
798
|
+
return if dst.closed?
|
799
|
+
|
691
800
|
begin
|
692
801
|
data = dst.read_nonblock( READ_SIZE )
|
693
802
|
rescue IO::WaitReadable, Errno::EINTR
|
@@ -702,6 +811,7 @@ module Girl
|
|
702
811
|
end
|
703
812
|
|
704
813
|
dst_info = @dst_infos[ dst ]
|
814
|
+
@traff_ins[ dst_info[ :im ] ] += data.bytesize
|
705
815
|
streamd = dst_info[ :streamd ]
|
706
816
|
|
707
817
|
if streamd then
|
@@ -713,7 +823,7 @@ module Girl
|
|
713
823
|
add_write( streamd )
|
714
824
|
|
715
825
|
if streamd_info[ :wbuff ].bytesize >= WBUFF_LIMIT then
|
716
|
-
puts "p#{ Process.pid } #{ Time.new } pause dst #{ dst_info[ :
|
826
|
+
puts "p#{ Process.pid } #{ Time.new } pause dst #{ dst_info[ :domain_port ] }"
|
717
827
|
dst_info[ :paused ] = true
|
718
828
|
@reads.delete( dst )
|
719
829
|
end
|
@@ -722,7 +832,7 @@ module Girl
|
|
722
832
|
dst_info[ :rbuff ] << data
|
723
833
|
|
724
834
|
if dst_info[ :rbuff ].bytesize >= WBUFF_LIMIT then
|
725
|
-
# puts "debug1 dst.rbuff full
|
835
|
+
# puts "debug1 dst.rbuff full"
|
726
836
|
set_dst_closing( dst )
|
727
837
|
end
|
728
838
|
end
|
@@ -732,6 +842,8 @@ module Girl
|
|
732
842
|
# read streamd
|
733
843
|
#
|
734
844
|
def read_streamd( streamd )
|
845
|
+
return if streamd.closed?
|
846
|
+
|
735
847
|
begin
|
736
848
|
data = streamd.read_nonblock( READ_SIZE )
|
737
849
|
rescue IO::WaitReadable, Errno::EINTR
|
@@ -746,6 +858,7 @@ module Girl
|
|
746
858
|
end
|
747
859
|
|
748
860
|
streamd_info = @streamd_infos[ streamd ]
|
861
|
+
@traff_ins[ streamd_info[ :im ] ] += data.bytesize
|
749
862
|
dst = streamd_info[ :dst ]
|
750
863
|
|
751
864
|
unless dst then
|
@@ -768,6 +881,7 @@ module Girl
|
|
768
881
|
# puts "debug1 set streamd.dst #{ dst_id }"
|
769
882
|
streamd_info[ :dst ] = dst
|
770
883
|
dst_info = @dst_infos[ dst ]
|
884
|
+
streamd_info[ :domain_port ] = dst_info[ :domain_port ]
|
771
885
|
|
772
886
|
unless dst_info[ :rbuff ].empty? then
|
773
887
|
# puts "debug1 encode and move dst.rbuff to streamd.wbuff"
|
@@ -787,6 +901,12 @@ module Girl
|
|
787
901
|
dst_info[ :wbuff ] << data
|
788
902
|
dst_info[ :last_recv_at ] = Time.new
|
789
903
|
add_write( dst )
|
904
|
+
|
905
|
+
if dst_info[ :wbuff ].bytesize >= WBUFF_LIMIT then
|
906
|
+
puts "p#{ Process.pid } #{ Time.new } pause streamd #{ streamd_info[ :domain_port ] }"
|
907
|
+
streamd_info[ :paused ] = true
|
908
|
+
@reads.delete( streamd )
|
909
|
+
end
|
790
910
|
end
|
791
911
|
end
|
792
912
|
|
@@ -800,6 +920,7 @@ module Girl
|
|
800
920
|
sent = send_data( proxyd, data, to_addr )
|
801
921
|
|
802
922
|
if sent == :wait then
|
923
|
+
puts "p#{ Process.pid } #{ Time.new } wait proxyd send ctlmsg, left #{ @proxyd_info[ :ctlmsgs ].size }"
|
803
924
|
return
|
804
925
|
else
|
805
926
|
@proxyd_info[ :ctlmsgs ].shift
|
@@ -837,15 +958,13 @@ module Girl
|
|
837
958
|
close_tund( tund )
|
838
959
|
return
|
839
960
|
elsif sent == :wait then
|
840
|
-
|
841
|
-
tund_info[ :last_sent_at ] = now
|
961
|
+
puts "p#{ Process.pid } #{ Time.new } wait tund #{ tund_info[ :port ] } send ctlmsg, left #{ tund_info[ :ctlmsgs ].size }"
|
842
962
|
return
|
843
963
|
end
|
844
964
|
|
845
965
|
tund_info[ :ctlmsgs ].shift
|
846
966
|
end
|
847
967
|
|
848
|
-
tund_info[ :last_sent_at ] = now
|
849
968
|
@writes.delete( tund )
|
850
969
|
end
|
851
970
|
|
@@ -860,12 +979,6 @@ module Girl
|
|
860
979
|
# 处理关闭
|
861
980
|
if dst_info[ :closing ] then
|
862
981
|
close_dst( dst )
|
863
|
-
|
864
|
-
if streamd then
|
865
|
-
close_read_streamd( streamd )
|
866
|
-
set_streamd_closing_write( streamd )
|
867
|
-
end
|
868
|
-
|
869
982
|
return
|
870
983
|
end
|
871
984
|
|
@@ -898,6 +1011,7 @@ module Girl
|
|
898
1011
|
# puts "debug2 written dst #{ written }"
|
899
1012
|
data = data[ written..-1 ]
|
900
1013
|
dst_info[ :wbuff ] = data
|
1014
|
+
@traff_outs[ dst_info[ :im ] ] += written
|
901
1015
|
end
|
902
1016
|
|
903
1017
|
##
|
@@ -911,12 +1025,6 @@ module Girl
|
|
911
1025
|
# 处理关闭
|
912
1026
|
if streamd_info[ :closing ] then
|
913
1027
|
close_streamd( streamd )
|
914
|
-
|
915
|
-
if dst then
|
916
|
-
close_read_dst( dst )
|
917
|
-
set_dst_closing_write( dst )
|
918
|
-
end
|
919
|
-
|
920
1028
|
return
|
921
1029
|
end
|
922
1030
|
|
@@ -949,6 +1057,7 @@ module Girl
|
|
949
1057
|
# puts "debug2 written streamd #{ written }"
|
950
1058
|
data = data[ written..-1 ]
|
951
1059
|
streamd_info[ :wbuff ] = data
|
1060
|
+
@traff_outs[ streamd_info[ :im ] ] += written
|
952
1061
|
|
953
1062
|
if dst && !dst.closed? then
|
954
1063
|
dst_info = @dst_infos[ dst ]
|
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.94.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- takafan
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2020-10-
|
11
|
+
date: 2020-10-15 00:00:00.000000000 Z
|
12
12
|
dependencies: []
|
13
13
|
description: escape evil.
|
14
14
|
email:
|