girl 0.69.0 → 0.70.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/girl.gemspec +0 -5
- data/lib/girl/head.rb +0 -3
- data/lib/girl/proxy.rb +19 -11
- data/lib/girl/proxy_worker.rb +52 -100
- data/lib/girl/proxyd.rb +0 -9
- data/lib/girl/proxyd_worker.rb +35 -63
- data/lib/girl/version.rb +1 -1
- metadata +2 -7
- data/lib/girl/hex.rb +0 -24
- data/lib/girl/resolv.rb +0 -200
- data/lib/girl/resolvd.rb +0 -169
- data/lib/girl/tun.rb +0 -997
- data/lib/girl/tund.rb +0 -897
data/lib/girl/proxyd.rb
CHANGED
@@ -9,15 +9,6 @@ require 'socket'
|
|
9
9
|
##
|
10
10
|
# Girl::Proxyd - 代理服务,远端。
|
11
11
|
#
|
12
|
-
# close logic
|
13
|
-
# ===========
|
14
|
-
#
|
15
|
-
# 1-1. after close dst -> src closed ? no -> send fin1
|
16
|
-
# 1-2. recv fin2 -> del dst ext
|
17
|
-
#
|
18
|
-
# 2-1. recv traffic/fin1/src status -> src closed and all traffic received ? -> close dst after write
|
19
|
-
# 2-2. after close dst -> src closed ? yes -> del dst ext -> send fin2
|
20
|
-
#
|
21
12
|
module Girl
|
22
13
|
class Proxyd
|
23
14
|
|
data/lib/girl/proxyd_worker.rb
CHANGED
@@ -160,7 +160,7 @@ module Girl
|
|
160
160
|
|
161
161
|
tund_info[ :dst_exts ].each do | dst_local_port, dst_ext |
|
162
162
|
if now - dst_ext[ :last_continue_at ] < SEND_STATUS_UNTIL
|
163
|
-
data = [ 0, DEST_STATUS, dst_local_port, dst_ext[ :
|
163
|
+
data = [ 0, DEST_STATUS, dst_local_port, dst_ext[ :relay_pack_id ], dst_ext[ :continue_src_pack_id ] ].pack( 'Q>CnQ>Q>' )
|
164
164
|
add_tund_ctlmsg( tund, data )
|
165
165
|
need_trigger = true
|
166
166
|
end
|
@@ -171,11 +171,6 @@ module Girl
|
|
171
171
|
puts "p#{ Process.pid } #{ Time.new } resume tund"
|
172
172
|
tund_info[ :paused ] = false
|
173
173
|
add_write( tund )
|
174
|
-
|
175
|
-
tund_info[ :dst_exts ].each do | _, dst_ext |
|
176
|
-
add_write( dst_ext[ :dst ] )
|
177
|
-
end
|
178
|
-
|
179
174
|
need_trigger = true
|
180
175
|
end
|
181
176
|
end
|
@@ -253,6 +248,7 @@ module Girl
|
|
253
248
|
@dst_infos[ dst ] = {
|
254
249
|
local_port: local_port, # 本地端口
|
255
250
|
tund: tund, # 对应tund
|
251
|
+
biggest_pack_id: 0, # 最大包号码
|
256
252
|
wbuff: '', # 写前
|
257
253
|
cache: '', # 块读出缓存
|
258
254
|
chunks: [], # 块队列,写前达到块大小时结一个块 filename
|
@@ -270,11 +266,11 @@ module Girl
|
|
270
266
|
src_id: src_id, # 近端src id
|
271
267
|
wmems: {}, # 写后 pack_id => data
|
272
268
|
send_ats: {}, # 上一次发出时间 pack_id => send_at
|
273
|
-
|
269
|
+
relay_pack_id: 0, # 转发到几
|
274
270
|
continue_src_pack_id: 0, # 收到几
|
275
271
|
pieces: {}, # 跳号包 src_pack_id => data
|
276
|
-
is_src_closed: false, #
|
277
|
-
biggest_src_pack_id: 0, #
|
272
|
+
is_src_closed: false, # src是否已关闭
|
273
|
+
biggest_src_pack_id: 0, # src最大包号码
|
278
274
|
completed_pack_id: 0, # 完成到几(对面收到几)
|
279
275
|
last_continue_at: Time.new # 创建,或者上一次收到连续流量,或者发出新包的时间
|
280
276
|
}
|
@@ -320,18 +316,18 @@ module Girl
|
|
320
316
|
##
|
321
317
|
# add tund wbuff
|
322
318
|
#
|
323
|
-
def add_tund_wbuff( tund, dst_local_port, data )
|
319
|
+
def add_tund_wbuff( tund, dst_local_port, pack_id, data )
|
324
320
|
tund_info = @tund_infos[ tund ]
|
325
|
-
tund_info[ :wbuffs ] << [ dst_local_port, data ]
|
321
|
+
tund_info[ :wbuffs ] << [ dst_local_port, pack_id, data ]
|
326
322
|
|
327
323
|
if tund_info[ :wbuffs ].size >= WBUFFS_LIMIT
|
328
324
|
spring = tund_info[ :chunks ].size > 0 ? ( tund_info[ :spring ] + 1 ) : 0
|
329
325
|
filename = "#{ Process.pid }-#{ tund_info[ :port ] }.#{ spring }"
|
330
326
|
chunk_path = File.join( @tund_chunk_dir, filename )
|
331
|
-
|
327
|
+
datas = tund_info[ :wbuffs ].map{ | _dst_local_port, _pack_id, _data | [ [ _dst_local_port, _pack_id, _data.bytesize ].pack( 'nQ>n' ), _data ].join }
|
332
328
|
|
333
329
|
begin
|
334
|
-
IO.binwrite( chunk_path,
|
330
|
+
IO.binwrite( chunk_path, datas.join )
|
335
331
|
rescue Errno::ENOSPC => e
|
336
332
|
puts "p#{ Process.pid } #{ Time.new } #{ e.class }, close tund"
|
337
333
|
set_is_closing( tund )
|
@@ -440,13 +436,13 @@ module Girl
|
|
440
436
|
return unless dst_ext
|
441
437
|
|
442
438
|
if dst_ext[ :is_src_closed ]
|
443
|
-
# puts "debug1
|
439
|
+
# puts "debug1 4-3. after close dst -> src closed ? yes -> del dst ext -> send fin2"
|
444
440
|
del_dst_ext( tund, local_port )
|
445
441
|
data = [ 0, FIN2, local_port ].pack( 'Q>Cn' )
|
446
442
|
add_tund_ctlmsg( tund, data )
|
447
443
|
else
|
448
|
-
# puts "debug1
|
449
|
-
data = [ 0, FIN1, local_port,
|
444
|
+
# puts "debug1 3-1. after close dst -> src closed ? no -> send fin1"
|
445
|
+
data = [ 0, FIN1, local_port, dst_info[ :biggest_pack_id ], dst_ext[ :continue_src_pack_id ] ].pack( 'Q>CnQ>Q>' )
|
450
446
|
add_tund_ctlmsg( tund, data )
|
451
447
|
end
|
452
448
|
end
|
@@ -565,19 +561,7 @@ module Girl
|
|
565
561
|
|
566
562
|
if data.empty?
|
567
563
|
if dst_info[ :is_closing ]
|
568
|
-
|
569
|
-
close_dst( dst )
|
570
|
-
else
|
571
|
-
tund_info = @tund_infos[ dst_info[ :tund ] ]
|
572
|
-
|
573
|
-
if tund_info[ :paused ]
|
574
|
-
@writes.delete( dst )
|
575
|
-
elsif !@writes.include?( dst_info[ :tund ] )
|
576
|
-
# 转发光了,正式关闭
|
577
|
-
# puts "debug2 close dst after tund empty"
|
578
|
-
close_dst( dst )
|
579
|
-
end
|
580
|
-
end
|
564
|
+
close_dst( dst )
|
581
565
|
else
|
582
566
|
@writes.delete( dst )
|
583
567
|
end
|
@@ -658,7 +642,7 @@ module Girl
|
|
658
642
|
|
659
643
|
# 取写前
|
660
644
|
if tund_info[ :caches ].any?
|
661
|
-
dst_local_port, data = tund_info[ :caches ].first
|
645
|
+
dst_local_port, pack_id, data = tund_info[ :caches ].first
|
662
646
|
from = :caches
|
663
647
|
elsif tund_info[ :chunks ].any?
|
664
648
|
path = File.join( @tund_chunk_dir, tund_info[ :chunks ].shift )
|
@@ -675,16 +659,16 @@ module Girl
|
|
675
659
|
caches = []
|
676
660
|
|
677
661
|
until data.empty?
|
678
|
-
_dst_local_port, pack_size = data[ 0,
|
679
|
-
caches << [ _dst_local_port, data[
|
680
|
-
data = data[ (
|
662
|
+
_dst_local_port, _pack_id, pack_size = data[ 0, 12 ].unpack( 'nQ>n' )
|
663
|
+
caches << [ _dst_local_port, _pack_id, data[ 12, pack_size ] ]
|
664
|
+
data = data[ ( 12 + pack_size )..-1 ]
|
681
665
|
end
|
682
666
|
|
683
667
|
tund_info[ :caches ] = caches
|
684
|
-
dst_local_port, data = caches.first
|
668
|
+
dst_local_port, pack_id, data = caches.first
|
685
669
|
from = :caches
|
686
670
|
elsif tund_info[ :wbuffs ].any?
|
687
|
-
dst_local_port, data = tund_info[ :wbuffs ].first
|
671
|
+
dst_local_port, pack_id, data = tund_info[ :wbuffs ].first
|
688
672
|
from = :wbuffs
|
689
673
|
else
|
690
674
|
@writes.delete( tund )
|
@@ -694,8 +678,6 @@ module Girl
|
|
694
678
|
dst_ext = tund_info[ :dst_exts ][ dst_local_port ]
|
695
679
|
|
696
680
|
if dst_ext
|
697
|
-
pack_id = dst_ext[ :biggest_pack_id ] + 1
|
698
|
-
|
699
681
|
if pack_id <= CONFUSE_UNTIL
|
700
682
|
data = @custom.encode( data )
|
701
683
|
# puts "debug1 encoded pack #{ pack_id }"
|
@@ -711,7 +693,7 @@ module Girl
|
|
711
693
|
|
712
694
|
# puts "debug2 written pack #{ pack_id }"
|
713
695
|
now = Time.new
|
714
|
-
dst_ext[ :
|
696
|
+
dst_ext[ :relay_pack_id ] = pack_id
|
715
697
|
dst_ext[ :wmems ][ pack_id ] = data
|
716
698
|
dst_ext[ :send_ats ][ pack_id ] = now
|
717
699
|
dst_ext[ :last_continue_at ] = now
|
@@ -752,15 +734,15 @@ module Girl
|
|
752
734
|
@tund_infos[ tund ] = {
|
753
735
|
port: port, # 端口
|
754
736
|
ctlmsgs: [], # data
|
755
|
-
wbuffs: [], # 写前缓存 [
|
756
|
-
caches: [], # 块读出缓存 [
|
737
|
+
wbuffs: [], # 写前缓存 [ dst_local_port, pack_id, data ]
|
738
|
+
caches: [], # 块读出缓存 [ dst_local_port, pack_id, data ]
|
757
739
|
chunks: [], # 块队列 filename
|
758
740
|
spring: 0, # 块后缀,结块时,如果块队列不为空,则自增,为空,则置为0
|
759
741
|
tun_addr: from_addr, # tun地址
|
760
|
-
dst_exts: {}, # dst额外信息
|
742
|
+
dst_exts: {}, # dst额外信息 dst_local_port => {}
|
761
743
|
dst_local_ports: {}, # src_id => dst_local_port
|
762
744
|
paused: false, # 是否暂停写
|
763
|
-
resendings: [], # 重传队列 [
|
745
|
+
resendings: [], # 重传队列 [ dst_local_port, pack_id ]
|
764
746
|
created_at: Time.new, # 创建时间
|
765
747
|
last_recv_at: nil, # 上一次收到流量的时间,过期关闭
|
766
748
|
is_closing: false # 是否准备关闭
|
@@ -798,7 +780,9 @@ module Girl
|
|
798
780
|
return
|
799
781
|
end
|
800
782
|
|
801
|
-
|
783
|
+
pack_id = dst_info[ :biggest_pack_id ] + 1
|
784
|
+
dst_info[ :biggest_pack_id ] = pack_id
|
785
|
+
add_tund_wbuff( tund, dst_info[ :local_port ], pack_id, data )
|
802
786
|
end
|
803
787
|
|
804
788
|
##
|
@@ -851,7 +835,7 @@ module Girl
|
|
851
835
|
destination_domain_port = @custom.decode( data )
|
852
836
|
resolve_domain( tund, src_id, destination_domain_port )
|
853
837
|
when SOURCE_STATUS
|
854
|
-
src_id,
|
838
|
+
src_id, relay_src_pack_id, continue_dst_pack_id = data[ 9, 24 ].unpack( 'Q>Q>Q>' )
|
855
839
|
|
856
840
|
dst_local_port = tund_info[ :dst_local_ports ][ src_id ]
|
857
841
|
return unless dst_local_port
|
@@ -861,22 +845,10 @@ module Girl
|
|
861
845
|
|
862
846
|
# puts "debug2 got source status"
|
863
847
|
|
864
|
-
# 更新对面发到几
|
865
|
-
if biggest_src_pack_id > dst_ext[ :biggest_src_pack_id ]
|
866
|
-
# puts "debug2 update biggest src pack #{ biggest_src_pack_id }"
|
867
|
-
dst_ext[ :biggest_src_pack_id ] = biggest_src_pack_id
|
868
|
-
|
869
|
-
# 接到对面状态,若对面已关闭,且最后一个包已经进写前,关闭dst
|
870
|
-
if dst_ext[ :is_src_closed ] && ( biggest_src_pack_id == dst_ext[ :continue_src_pack_id ] )
|
871
|
-
# puts "debug1 2-1. recv traffic/fin1/src status -> src closed and all traffic received ? -> close dst after write"
|
872
|
-
set_is_closing( dst_ext[ :dst ] )
|
873
|
-
end
|
874
|
-
end
|
875
|
-
|
876
848
|
release_wmems( dst_ext, continue_dst_pack_id )
|
877
849
|
|
878
850
|
# 发miss
|
879
|
-
if !dst_ext[ :dst ].closed? && ( dst_ext[ :continue_src_pack_id ] <
|
851
|
+
if !dst_ext[ :dst ].closed? && ( dst_ext[ :continue_src_pack_id ] < relay_src_pack_id )
|
880
852
|
ranges = []
|
881
853
|
curr_pack_id = dst_ext[ :continue_src_pack_id ] + 1
|
882
854
|
|
@@ -888,12 +860,12 @@ module Girl
|
|
888
860
|
curr_pack_id = pack_id + 1
|
889
861
|
end
|
890
862
|
|
891
|
-
if curr_pack_id <=
|
892
|
-
ranges << [ curr_pack_id,
|
863
|
+
if curr_pack_id <= relay_src_pack_id
|
864
|
+
ranges << [ curr_pack_id, relay_src_pack_id ]
|
893
865
|
end
|
894
866
|
|
895
867
|
pack_count = 0
|
896
|
-
# puts "debug1 continue/
|
868
|
+
# puts "debug1 continue/relay #{ dst_ext[ :continue_src_pack_id ] }/#{ relay_src_pack_id } send MISS #{ ranges.size }"
|
897
869
|
|
898
870
|
ranges.each do | pack_id_begin, pack_id_end |
|
899
871
|
if pack_count >= BREAK_SEND_MISS
|
@@ -938,7 +910,7 @@ module Girl
|
|
938
910
|
|
939
911
|
# 接到对面已关闭,若最后一个包已经进写前,关闭dst
|
940
912
|
if biggest_src_pack_id == dst_ext[ :continue_src_pack_id ]
|
941
|
-
# puts "debug1
|
913
|
+
# puts "debug1 4-1. tund recv fin1 -> all traffic received ? -> close dst after write"
|
942
914
|
set_is_closing( dst_ext[ :dst ] )
|
943
915
|
end
|
944
916
|
when FIN2
|
@@ -947,7 +919,7 @@ module Girl
|
|
947
919
|
dst_local_port = tund_info[ :dst_local_ports ][ src_id ]
|
948
920
|
return unless dst_local_port
|
949
921
|
|
950
|
-
# puts "debug1
|
922
|
+
# puts "debug1 3-2. tund recv fin2 -> del dst ext"
|
951
923
|
del_dst_ext( tund, dst_local_port )
|
952
924
|
when TUN_FIN
|
953
925
|
puts "p#{ Process.pid } #{ Time.new } recv tun fin"
|
@@ -989,7 +961,7 @@ module Girl
|
|
989
961
|
|
990
962
|
# 接到流量,若对面已关闭,且流量正好收全,关闭dst
|
991
963
|
if dst_ext[ :is_src_closed ] && ( pack_id == dst_ext[ :biggest_src_pack_id ] )
|
992
|
-
# puts "debug1 2
|
964
|
+
# puts "debug1 4-2. tund recv traffic -> src closed and all traffic received ? -> close dst after write"
|
993
965
|
set_is_closing( dst_ext[ :dst ] )
|
994
966
|
return
|
995
967
|
end
|
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.70.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-06-
|
11
|
+
date: 2020-06-30 00:00:00.000000000 Z
|
12
12
|
dependencies: []
|
13
13
|
description: while internet is evil, here's a girl.
|
14
14
|
email:
|
@@ -21,17 +21,12 @@ files:
|
|
21
21
|
- lib/girl.rb
|
22
22
|
- lib/girl/custom.rb
|
23
23
|
- lib/girl/head.rb
|
24
|
-
- lib/girl/hex.rb
|
25
24
|
- lib/girl/proxy.rb
|
26
25
|
- lib/girl/proxy_custom.rb
|
27
26
|
- lib/girl/proxy_worker.rb
|
28
27
|
- lib/girl/proxyd.rb
|
29
28
|
- lib/girl/proxyd_custom.rb
|
30
29
|
- lib/girl/proxyd_worker.rb
|
31
|
-
- lib/girl/resolv.rb
|
32
|
-
- lib/girl/resolvd.rb
|
33
|
-
- lib/girl/tun.rb
|
34
|
-
- lib/girl/tund.rb
|
35
30
|
- lib/girl/udp.rb
|
36
31
|
- lib/girl/udpd.rb
|
37
32
|
- lib/girl/version.rb
|
data/lib/girl/hex.rb
DELETED
@@ -1,24 +0,0 @@
|
|
1
|
-
module Girl
|
2
|
-
class Hex
|
3
|
-
def hello
|
4
|
-
:hello
|
5
|
-
end
|
6
|
-
|
7
|
-
def check( data, addrinfo )
|
8
|
-
:success
|
9
|
-
end
|
10
|
-
|
11
|
-
def gen_random_num
|
12
|
-
rand( ( 2 ** 64 ) - 1 ) + 1
|
13
|
-
end
|
14
|
-
|
15
|
-
def encode( data )
|
16
|
-
# overwrite me, you'll be free
|
17
|
-
data
|
18
|
-
end
|
19
|
-
|
20
|
-
def decode( data )
|
21
|
-
data
|
22
|
-
end
|
23
|
-
end
|
24
|
-
end
|
data/lib/girl/resolv.rb
DELETED
@@ -1,200 +0,0 @@
|
|
1
|
-
require 'girl/hex'
|
2
|
-
require 'girl/version'
|
3
|
-
require 'socket'
|
4
|
-
|
5
|
-
##
|
6
|
-
# Girl::Resolv - dns查询得到正确的ip,近端。
|
7
|
-
#
|
8
|
-
# usage
|
9
|
-
# =====
|
10
|
-
#
|
11
|
-
# Girl::Resolvd.new( 7070 ).looping # 远端
|
12
|
-
#
|
13
|
-
# Girl::Resolv.new( 1717, [ '114.114.114.114' ], 'your.server.ip', 7070, [ 'google.com' ] ).looping # 近端
|
14
|
-
#
|
15
|
-
# dig google.com @127.0.0.1 -p1717
|
16
|
-
#
|
17
|
-
module Girl
|
18
|
-
class Resolv
|
19
|
-
|
20
|
-
def initialize( port = 1717, nameservers = [], resolvd_host = nil, resolvd_port = nil, custom_domains = [] )
|
21
|
-
@hex = Girl::Hex.new
|
22
|
-
@mutex = Mutex.new
|
23
|
-
@reads = []
|
24
|
-
@writes = []
|
25
|
-
@roles = {} # sock => :ctlr / :redir / :resolv / :pub
|
26
|
-
@infos = {} # redir => {}
|
27
|
-
@socks = {} # sock => sock_id
|
28
|
-
@sock_ids = {} # sock_id => sock
|
29
|
-
|
30
|
-
redir = Socket.new( Socket::AF_INET, Socket::SOCK_DGRAM, 0 )
|
31
|
-
redir.setsockopt( Socket::SOL_SOCKET, Socket::SO_REUSEPORT, 1 )
|
32
|
-
redir.bind( Socket.sockaddr_in( port, '0.0.0.0' ) )
|
33
|
-
puts "redir bound on #{ port } #{ Time.new }"
|
34
|
-
|
35
|
-
nameservers = nameservers.select{ | ns | Addrinfo.udp( ns, 53 ).ipv4? }
|
36
|
-
|
37
|
-
if nameservers.empty?
|
38
|
-
nameservers = %w[ 114.114.114.114 114.114.115.115 ]
|
39
|
-
end
|
40
|
-
|
41
|
-
redir_info = {
|
42
|
-
src_addrs: {}, # src_addr => resolv_or_pub
|
43
|
-
socks: {}, # resolv_or_pub => src_addr
|
44
|
-
last_recv_ats: {}, # resolv_or_pub => now
|
45
|
-
pubd_addrs: nameservers.map{ | ns | Socket.sockaddr_in( 53, ns ) },
|
46
|
-
resolvd_addr: ( resolvd_host && resolvd_port ) ? Socket.sockaddr_in( resolvd_port, resolvd_host ) : nil,
|
47
|
-
custom_qnames: custom_domains.map{ | dom | dom.split( '.' ).map{ | sub | [ sub.size ].pack( 'C' ) + sub }.join }
|
48
|
-
}
|
49
|
-
|
50
|
-
@redir = redir
|
51
|
-
@redir_info = redir_info
|
52
|
-
@roles[ redir ] = :redir
|
53
|
-
@infos[ redir ] = redir_info
|
54
|
-
@reads << redir
|
55
|
-
|
56
|
-
ctlr, ctlw = IO.pipe
|
57
|
-
@ctlw = ctlw
|
58
|
-
@roles[ ctlr ] = :ctlr
|
59
|
-
@reads << ctlr
|
60
|
-
end
|
61
|
-
|
62
|
-
def looping
|
63
|
-
loop_expire
|
64
|
-
|
65
|
-
loop do
|
66
|
-
rs, ws = IO.select( @reads, @writes )
|
67
|
-
|
68
|
-
@mutex.synchronize do
|
69
|
-
rs.each do | sock |
|
70
|
-
case @roles[ sock ]
|
71
|
-
when :ctlr
|
72
|
-
read_ctlr( sock )
|
73
|
-
when :redir
|
74
|
-
read_redir( sock )
|
75
|
-
when :resolv, :pub
|
76
|
-
read_sock( sock )
|
77
|
-
end
|
78
|
-
end
|
79
|
-
|
80
|
-
ws.each do | sock |
|
81
|
-
close_sock( sock )
|
82
|
-
end
|
83
|
-
end
|
84
|
-
end
|
85
|
-
end
|
86
|
-
|
87
|
-
def quit!
|
88
|
-
exit
|
89
|
-
end
|
90
|
-
|
91
|
-
private
|
92
|
-
|
93
|
-
def read_ctlr( ctlr )
|
94
|
-
sock_id = ctlr.read( 8 ).unpack( 'Q>' ).first
|
95
|
-
sock = @sock_ids[ sock_id ]
|
96
|
-
|
97
|
-
if sock
|
98
|
-
# puts "debug expire #{ @roles[ sock ] } #{ sock_id } #{ Time.new }"
|
99
|
-
|
100
|
-
unless @writes.include?( sock )
|
101
|
-
@writes << sock
|
102
|
-
end
|
103
|
-
end
|
104
|
-
end
|
105
|
-
|
106
|
-
def read_redir( redir )
|
107
|
-
# https://tools.ietf.org/html/rfc1035#page-26
|
108
|
-
data, addrinfo, rflags, *controls = redir.recvmsg
|
109
|
-
return if data.size <= 12
|
110
|
-
|
111
|
-
id = data[ 0, 2 ]
|
112
|
-
qname_len = data[ 12..-1 ].index( [ 0 ].pack( 'C' ) )
|
113
|
-
return unless qname_len
|
114
|
-
|
115
|
-
now = Time.new
|
116
|
-
info = @infos[ redir ]
|
117
|
-
src_addr = addrinfo.to_sockaddr
|
118
|
-
sock = info[ :src_addrs ][ src_addr ]
|
119
|
-
|
120
|
-
unless sock
|
121
|
-
sock = Socket.new( Socket::AF_INET, Socket::SOCK_DGRAM, 0 )
|
122
|
-
sock.setsockopt( Socket::SOL_SOCKET, Socket::SO_REUSEPORT, 1 )
|
123
|
-
sock.bind( Socket.sockaddr_in( 0, '0.0.0.0' ) )
|
124
|
-
|
125
|
-
sock_id = @hex.gen_random_num
|
126
|
-
@socks[ sock ] = sock_id
|
127
|
-
@sock_ids[ sock_id ] = sock
|
128
|
-
qname = data[ 12, qname_len ]
|
129
|
-
|
130
|
-
if info[ :resolvd_addr ] && ( info[ :custom_qnames ].any? { | custom | qname.include?( custom ) } )
|
131
|
-
@roles[ sock ] = :resolv
|
132
|
-
else
|
133
|
-
@roles[ sock ] = :pub
|
134
|
-
end
|
135
|
-
|
136
|
-
# puts "debug a new #{ @roles[ sock ] } bound on #{ sock.local_address.ip_unpack.last } #{ Time.new }"
|
137
|
-
|
138
|
-
@reads << sock
|
139
|
-
info[ :src_addrs ][ src_addr ] = sock
|
140
|
-
info[ :socks ][ sock ] = src_addr
|
141
|
-
info[ :last_recv_ats ][ sock ] = now
|
142
|
-
end
|
143
|
-
|
144
|
-
if @roles[ sock ] == :resolv
|
145
|
-
data = @hex.encode( data )
|
146
|
-
sock.sendmsg( data, 0, info[ :resolvd_addr ] )
|
147
|
-
else
|
148
|
-
info[ :pubd_addrs ].each { | pubd_addr | sock.sendmsg( data, 0, pubd_addr ) }
|
149
|
-
end
|
150
|
-
end
|
151
|
-
|
152
|
-
def read_sock( sock )
|
153
|
-
data, addrinfo, rflags, *controls = sock.recvmsg
|
154
|
-
return if data.size <= 12
|
155
|
-
|
156
|
-
if @roles[ sock ] == :resolv
|
157
|
-
data = @hex.decode( data )
|
158
|
-
end
|
159
|
-
|
160
|
-
src_addr = @redir_info[ :socks ][ sock ]
|
161
|
-
return unless src_addr
|
162
|
-
|
163
|
-
@redir_info[ :last_recv_ats ][ sock ] = Time.new
|
164
|
-
@redir.sendmsg( data, 0, src_addr )
|
165
|
-
end
|
166
|
-
|
167
|
-
def close_sock( sock )
|
168
|
-
sock.close
|
169
|
-
@reads.delete( sock )
|
170
|
-
@writes.delete( sock )
|
171
|
-
@roles.delete( sock )
|
172
|
-
sock_id = @socks.delete( sock )
|
173
|
-
@sock_ids.delete( sock_id )
|
174
|
-
@redir_info[ :last_recv_ats ].delete( sock )
|
175
|
-
src_addr = @redir_info[ :socks ].delete( sock )
|
176
|
-
@redir_info[ :src_addrs ].delete( src_addr )
|
177
|
-
end
|
178
|
-
|
179
|
-
def loop_expire
|
180
|
-
Thread.new do
|
181
|
-
loop do
|
182
|
-
sleep 60
|
183
|
-
|
184
|
-
@mutex.synchronize do
|
185
|
-
now = Time.new
|
186
|
-
socks = @redir_info[ :socks ].keys
|
187
|
-
|
188
|
-
socks.each do | sock |
|
189
|
-
if now - @redir_info[ :last_recv_ats ][ sock ] > 5
|
190
|
-
sock_id = @socks[ sock ]
|
191
|
-
@ctlw.write( [ sock_id ].pack( 'Q>' ) )
|
192
|
-
end
|
193
|
-
end
|
194
|
-
end
|
195
|
-
end
|
196
|
-
end
|
197
|
-
end
|
198
|
-
|
199
|
-
end
|
200
|
-
end
|