girl 0.70.0 → 0.73.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 +13 -13
- data/lib/girl/proxy.rb +12 -14
- data/lib/girl/proxy_worker.rb +49 -30
- data/lib/girl/proxyd.rb +2 -5
- data/lib/girl/proxyd_worker.rb +12 -10
- 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: d975dc92620d5ea2c27493ed0fbbb19a145fc7ecda564c2f5609eb710e06912d
|
4
|
+
data.tar.gz: 5c098f6b8aecc89d246e8e4b1c477eb42e86ce695b27d4329962255d380b4f09
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 326b198254e6508e42b00145e00c56214574510448ba05b852b257b44da2c54b443509d1e2af514a668b1394e27cfff2ae93cf1957526adf9315a73e32a3ebbd
|
7
|
+
data.tar.gz: 21e0cab87ffe323314607d74c3884eb2987208a9375b417c1158d1768e7aafcf536d7370d5fdff58b08d1d7acb95da009eba57ddcc9d9d22702e405078b2c7e5
|
data/lib/girl/head.rb
CHANGED
@@ -1,17 +1,17 @@
|
|
1
1
|
module Girl
|
2
|
-
PACK_SIZE = 1328
|
3
|
-
CHUNK_SIZE = PACK_SIZE * 1000
|
4
|
-
WBUFFS_LIMIT = 1000
|
5
|
-
WMEMS_LIMIT = 100_000
|
6
|
-
RESUME_BELOW = 50_000
|
7
|
-
EXPIRE_NEW = 10
|
8
|
-
EXPIRE_AFTER = 300
|
9
|
-
CHECK_EXPIRE_INTERVAL = 30
|
10
|
-
STATUS_INTERVAL = 0.5
|
11
|
-
SEND_STATUS_UNTIL = 10
|
12
|
-
BREAK_SEND_MISS = 10_000
|
13
|
-
CONFUSE_UNTIL = 5
|
14
|
-
RESOLV_CACHE_EXPIRE = 300
|
2
|
+
PACK_SIZE = 1328 # 包大小 1400(console MTU) - 8(PPPoE header) - 40(IPv6 header) - 8(UDP header) - 8(pack id) - 8(src id) = 1328
|
3
|
+
CHUNK_SIZE = PACK_SIZE * 1000 # 块大小
|
4
|
+
WBUFFS_LIMIT = 1000 # 写前上限,超过上限结一个块
|
5
|
+
WMEMS_LIMIT = 100_000 # 写后上限,达到上限暂停写
|
6
|
+
RESUME_BELOW = 50_000 # 降到多少以下恢复写
|
7
|
+
EXPIRE_NEW = 10 # 创建之后多久没有流量进来,过期
|
8
|
+
EXPIRE_AFTER = 300 # 多久没有新流量,过期
|
9
|
+
CHECK_EXPIRE_INTERVAL = 30 # 检查过期间隔
|
10
|
+
STATUS_INTERVAL = 0.5 # 发送状态间隔
|
11
|
+
SEND_STATUS_UNTIL = 10 # 持续的告之对面状态,直到没有流量往来,持续多少秒
|
12
|
+
BREAK_SEND_MISS = 10_000 # miss包个数上限,达到上限忽略要后面的段,可控碎片缓存
|
13
|
+
CONFUSE_UNTIL = 5 # 混淆前几个包
|
14
|
+
RESOLV_CACHE_EXPIRE = 300 # dns查询结果缓存多久过期
|
15
15
|
TUND_PORT = 1
|
16
16
|
HEARTBEAT = 2
|
17
17
|
A_NEW_SOURCE = 3
|
data/lib/girl/proxy.rb
CHANGED
@@ -23,15 +23,15 @@ require 'socket'
|
|
23
23
|
#
|
24
24
|
# tun-tund:
|
25
25
|
#
|
26
|
-
# Q>: 0 ctlmsg -> C: 2 heartbeat
|
27
|
-
# 3 a new
|
28
|
-
# 4 paired
|
29
|
-
# 5
|
30
|
-
# 6
|
31
|
-
# 7 miss
|
32
|
-
# 8 fin1
|
26
|
+
# Q>: 0 ctlmsg -> C: 2 heartbeat -> C: random char
|
27
|
+
# 3 a new source -> Q>: src id -> encoded destination address
|
28
|
+
# 4 paired -> Q>: src id -> n: dst port
|
29
|
+
# 5 dest status -> n: dst port -> Q>: biggest relayed dst pack id -> Q>: continue src pack id
|
30
|
+
# 6 source status -> Q>: src id -> Q>: biggest relayed src pack id -> Q>: continue dst pack id
|
31
|
+
# 7 miss -> Q>/n: src id / dst port -> Q>: pack id begin -> Q>: pack id end
|
32
|
+
# 8 fin1 -> Q>/n: src id / dst port -> Q>: biggest src pack id / biggest dst pack id -> Q>: continue dst pack id / continue src pack id
|
33
33
|
# 9 not use
|
34
|
-
# 10 fin2
|
34
|
+
# 10 fin2 -> Q>/n: src id / dst port
|
35
35
|
# 11 not use
|
36
36
|
# 12 tund fin
|
37
37
|
# 13 tun fin
|
@@ -129,21 +129,19 @@ module Girl
|
|
129
129
|
end
|
130
130
|
|
131
131
|
src_chunk_dir = File.join( proxy_tmp_dir, 'src.chunk' )
|
132
|
-
dst_chunk_dir = File.join( proxy_tmp_dir, 'dst.chunk' )
|
133
|
-
tun_chunk_dir = File.join( proxy_tmp_dir, 'tun.chunk' )
|
134
|
-
|
135
|
-
unless Dir.exist?( proxy_tmp_dir )
|
136
|
-
Dir.mkdir( proxy_tmp_dir )
|
137
|
-
end
|
138
132
|
|
139
133
|
unless Dir.exist?( src_chunk_dir )
|
140
134
|
Dir.mkdir( src_chunk_dir )
|
141
135
|
end
|
142
136
|
|
137
|
+
dst_chunk_dir = File.join( proxy_tmp_dir, 'dst.chunk' )
|
138
|
+
|
143
139
|
unless Dir.exist?( dst_chunk_dir )
|
144
140
|
Dir.mkdir( dst_chunk_dir )
|
145
141
|
end
|
146
142
|
|
143
|
+
tun_chunk_dir = File.join( proxy_tmp_dir, 'tun.chunk' )
|
144
|
+
|
147
145
|
unless Dir.exist?( tun_chunk_dir )
|
148
146
|
Dir.mkdir( tun_chunk_dir )
|
149
147
|
end
|
data/lib/girl/proxy_worker.rb
CHANGED
@@ -18,7 +18,6 @@ module Girl
|
|
18
18
|
@writes = []
|
19
19
|
@roles = {} # sock => :dotr / :proxy / :src / :dst / :tun
|
20
20
|
@src_infos = {} # src => {}
|
21
|
-
@dsts = {} # local_port => dst
|
22
21
|
@dst_infos = {} # dst => {}
|
23
22
|
@resolv_caches = {} # domain => [ ip, created_at ]
|
24
23
|
|
@@ -192,15 +191,31 @@ module Girl
|
|
192
191
|
end
|
193
192
|
|
194
193
|
##
|
195
|
-
#
|
194
|
+
# loop send a new source
|
196
195
|
#
|
197
|
-
def
|
198
|
-
|
199
|
-
|
200
|
-
|
201
|
-
|
196
|
+
def loop_send_a_new_source( src_ext, data )
|
197
|
+
Thread.new do
|
198
|
+
EXPIRE_NEW.times do
|
199
|
+
if src_ext[ :src ].closed? || src_ext[ :dst_port ]
|
200
|
+
# puts "debug1 break loop send a new source #{ src_ext[ :dst_port ] }"
|
201
|
+
break
|
202
|
+
end
|
203
|
+
|
204
|
+
@mutex.synchronize do
|
205
|
+
# puts "debug1 send a new source #{ data.inspect }"
|
206
|
+
add_tun_ctlmsg( data )
|
207
|
+
next_tick
|
208
|
+
end
|
209
|
+
|
210
|
+
sleep 1
|
211
|
+
end
|
202
212
|
end
|
213
|
+
end
|
203
214
|
|
215
|
+
##
|
216
|
+
# resolve domain
|
217
|
+
#
|
218
|
+
def resolve_domain( src, domain )
|
204
219
|
if @remotes.any? { | remote | ( domain.size >= remote.size ) && ( domain[ ( remote.size * -1 )..-1 ] == remote ) }
|
205
220
|
# puts "debug1 #{ domain } hit remotes"
|
206
221
|
new_a_src_ext( src )
|
@@ -210,11 +225,11 @@ module Girl
|
|
210
225
|
resolv_cache = @resolv_caches[ domain ]
|
211
226
|
|
212
227
|
if resolv_cache
|
213
|
-
|
228
|
+
ip_info, created_at = resolv_cache
|
214
229
|
|
215
230
|
if Time.new - created_at < RESOLV_CACHE_EXPIRE
|
216
|
-
# puts "debug1 #{ domain } hit resolv cache #{
|
217
|
-
deal_with_destination_ip( src,
|
231
|
+
# puts "debug1 #{ domain } hit resolv cache #{ ip_info.inspect }"
|
232
|
+
deal_with_destination_ip( src, ip_info )
|
218
233
|
return
|
219
234
|
end
|
220
235
|
|
@@ -234,12 +249,11 @@ module Girl
|
|
234
249
|
|
235
250
|
@mutex.synchronize do
|
236
251
|
if ip_info
|
237
|
-
|
238
|
-
# puts "debug1 resolved #{ domain } #{ destination_ip }"
|
239
|
-
@resolv_caches[ domain ] = [ destination_ip, Time.new ]
|
252
|
+
@resolv_caches[ domain ] = [ ip_info, Time.new ]
|
240
253
|
|
241
254
|
unless src.closed?
|
242
|
-
|
255
|
+
puts "p#{ Process.pid } #{ Time.new } resolved #{ domain } #{ ip_info.ip_address }"
|
256
|
+
deal_with_destination_ip( src, ip_info )
|
243
257
|
end
|
244
258
|
else
|
245
259
|
set_is_closing( src )
|
@@ -253,11 +267,11 @@ module Girl
|
|
253
267
|
##
|
254
268
|
# deal with destination ip
|
255
269
|
#
|
256
|
-
def deal_with_destination_ip( src,
|
257
|
-
if @directs.any? { | direct | direct.include?(
|
270
|
+
def deal_with_destination_ip( src, ip_info )
|
271
|
+
if @directs.any? { | direct | direct.include?( ip_info.ip_address ) }
|
258
272
|
# ip命中直连列表,直连
|
259
|
-
# puts "debug1 #{
|
260
|
-
new_a_dst( src,
|
273
|
+
# puts "debug1 #{ ip_info.inspect } hit directs"
|
274
|
+
new_a_dst( src, ip_info )
|
261
275
|
else
|
262
276
|
# 走远端
|
263
277
|
new_a_src_ext( src )
|
@@ -321,10 +335,10 @@ module Girl
|
|
321
335
|
##
|
322
336
|
# new a dst
|
323
337
|
#
|
324
|
-
def new_a_dst( src,
|
338
|
+
def new_a_dst( src, ip_info )
|
325
339
|
src_info = @src_infos[ src ]
|
326
|
-
destination_addr = Socket.sockaddr_in( src_info[ :destination_port ],
|
327
|
-
dst = Socket.new( Socket::AF_INET, Socket::SOCK_STREAM, 0 )
|
340
|
+
destination_addr = Socket.sockaddr_in( src_info[ :destination_port ], ip_info.ip_address )
|
341
|
+
dst = Socket.new( ip_info.ipv4? ? Socket::AF_INET : Socket::AF_INET6, Socket::SOCK_STREAM, 0 )
|
328
342
|
|
329
343
|
if RUBY_PLATFORM.include?( 'linux' )
|
330
344
|
dst.setsockopt( Socket::SOL_TCP, Socket::TCP_NODELAY, 1 )
|
@@ -342,7 +356,6 @@ module Girl
|
|
342
356
|
|
343
357
|
# puts "debug1 a new dst #{ dst.local_address.inspect }"
|
344
358
|
local_port = dst.local_address.ip_port
|
345
|
-
@dsts[ local_port ] = dst
|
346
359
|
@dst_infos[ dst ] = {
|
347
360
|
local_port: local_port, # 本地端口
|
348
361
|
src: src, # 对应src
|
@@ -361,11 +374,9 @@ module Girl
|
|
361
374
|
|
362
375
|
if src_info[ :proxy_proto ] == :http
|
363
376
|
if src_info[ :is_connect ]
|
364
|
-
# CONNECT
|
365
377
|
# puts "debug1 add src wbuff http ok"
|
366
378
|
add_src_wbuff( src, HTTP_OK )
|
367
379
|
else
|
368
|
-
# not CONNECT
|
369
380
|
# puts "debug1 add src rbuffs to dst wbuff"
|
370
381
|
|
371
382
|
src_info[ :rbuffs ].each do | _, data |
|
@@ -408,7 +419,7 @@ module Girl
|
|
408
419
|
destination_domain = src_info[ :destination_domain ]
|
409
420
|
destination_domain_port = [ destination_domain, destination_port ].join( ':' )
|
410
421
|
data = [ [ 0, A_NEW_SOURCE, src_id ].pack( 'Q>CQ>' ), @custom.encode( destination_domain_port ) ].join
|
411
|
-
|
422
|
+
loop_send_a_new_source( src_ext, data )
|
412
423
|
end
|
413
424
|
|
414
425
|
##
|
@@ -644,7 +655,6 @@ module Girl
|
|
644
655
|
end
|
645
656
|
end
|
646
657
|
|
647
|
-
@dsts.delete( dst_info[ :local_port ] )
|
648
658
|
set_is_closing( dst_info[ :src ] )
|
649
659
|
end
|
650
660
|
|
@@ -830,6 +840,10 @@ module Girl
|
|
830
840
|
tun.sendmsg( data, 0, to_addr )
|
831
841
|
rescue IO::WaitWritable, Errno::EINTR
|
832
842
|
return
|
843
|
+
rescue Errno::EHOSTUNREACH, Errno::ENETUNREACH => e
|
844
|
+
puts "#{ Time.new } #{ e.class }, close tun"
|
845
|
+
close_tun( tun )
|
846
|
+
return
|
833
847
|
end
|
834
848
|
|
835
849
|
@tun_info[ :ctlmsgs ].shift
|
@@ -848,6 +862,10 @@ module Girl
|
|
848
862
|
tun.sendmsg( data, 0, @tun_info[ :tund_addr ] )
|
849
863
|
rescue IO::WaitWritable, Errno::EINTR
|
850
864
|
return
|
865
|
+
rescue Errno::EHOSTUNREACH, Errno::ENETUNREACH => e
|
866
|
+
puts "#{ Time.new } #{ e.class }, close tun"
|
867
|
+
close_tun( tun )
|
868
|
+
return
|
851
869
|
end
|
852
870
|
end
|
853
871
|
end
|
@@ -916,6 +934,10 @@ module Girl
|
|
916
934
|
tun.sendmsg( data, 0, @tun_info[ :tund_addr ] )
|
917
935
|
rescue IO::WaitWritable, Errno::EINTR
|
918
936
|
return
|
937
|
+
rescue Errno::EHOSTUNREACH, Errno::ENETUNREACH => e
|
938
|
+
puts "#{ Time.new } #{ e.class }, close tun"
|
939
|
+
close_tun( tun )
|
940
|
+
return
|
919
941
|
end
|
920
942
|
|
921
943
|
# puts "debug2 written pack #{ pack_id }"
|
@@ -1093,7 +1115,7 @@ module Girl
|
|
1093
1115
|
src_info[ :destination_domain ] = destination_ip
|
1094
1116
|
src_info[ :destination_port ] = destination_port
|
1095
1117
|
# puts "debug1 IP V4 address #{ destination_addrinfo.inspect }"
|
1096
|
-
deal_with_destination_ip( src,
|
1118
|
+
deal_with_destination_ip( src, destination_addrinfo )
|
1097
1119
|
elsif atyp == 3
|
1098
1120
|
domain_len = data[ 4 ].unpack( 'C' ).first
|
1099
1121
|
|
@@ -1242,11 +1264,9 @@ module Girl
|
|
1242
1264
|
|
1243
1265
|
if src_info[ :proxy_proto ] == :http
|
1244
1266
|
if src_info[ :is_connect ]
|
1245
|
-
# CONNECT
|
1246
1267
|
# puts "debug1 add src wbuff http ok"
|
1247
1268
|
add_src_wbuff( src, HTTP_OK )
|
1248
1269
|
else
|
1249
|
-
# not CONNECT
|
1250
1270
|
# puts "debug1 add src rbuffs to tun wbuffs"
|
1251
1271
|
|
1252
1272
|
src_info[ :rbuffs ].each do | pack_id, _data |
|
@@ -1336,7 +1356,6 @@ module Girl
|
|
1336
1356
|
src_ext[ :biggest_dst_pack_id ] = biggest_dst_pack_id
|
1337
1357
|
release_wmems( src_ext, continue_src_pack_id )
|
1338
1358
|
|
1339
|
-
# 接到对面已关闭,若最后一个包已经进写前,关闭src
|
1340
1359
|
if ( biggest_dst_pack_id == src_ext[ :continue_dst_pack_id ] )
|
1341
1360
|
# puts "debug1 2-1. tun recv fin1 -> all traffic received ? -> close src after write"
|
1342
1361
|
set_is_closing( src_ext[ :src ] )
|
data/lib/girl/proxyd.rb
CHANGED
@@ -37,16 +37,13 @@ module Girl
|
|
37
37
|
end
|
38
38
|
|
39
39
|
dst_chunk_dir = File.join( proxyd_tmp_dir, 'dst.chunk' )
|
40
|
-
tund_chunk_dir = File.join( proxyd_tmp_dir, 'tund.chunk' )
|
41
|
-
|
42
|
-
unless Dir.exist?( proxyd_tmp_dir )
|
43
|
-
Dir.mkdir( proxyd_tmp_dir )
|
44
|
-
end
|
45
40
|
|
46
41
|
unless Dir.exist?( dst_chunk_dir )
|
47
42
|
Dir.mkdir( dst_chunk_dir )
|
48
43
|
end
|
49
44
|
|
45
|
+
tund_chunk_dir = File.join( proxyd_tmp_dir, 'tund.chunk' )
|
46
|
+
|
50
47
|
unless Dir.exist?( tund_chunk_dir )
|
51
48
|
Dir.mkdir( tund_chunk_dir )
|
52
49
|
end
|
data/lib/girl/proxyd_worker.rb
CHANGED
@@ -204,13 +204,17 @@ module Girl
|
|
204
204
|
end
|
205
205
|
|
206
206
|
Thread.new do
|
207
|
-
|
208
|
-
destination_port = destination_port.to_i
|
207
|
+
colon_idx = destination_domain_port.rindex( ':' )
|
209
208
|
|
210
|
-
|
211
|
-
|
212
|
-
|
213
|
-
|
209
|
+
if colon_idx
|
210
|
+
destination_domain = destination_domain_port[ 0...colon_idx ]
|
211
|
+
destination_port = destination_domain_port[ ( colon_idx + 1 )..-1 ].to_i
|
212
|
+
|
213
|
+
begin
|
214
|
+
destination_addr = Socket.sockaddr_in( destination_port, destination_domain )
|
215
|
+
rescue Exception => e
|
216
|
+
puts "p#{ Process.pid } #{ Time.new } sockaddr in #{ destination_domain_port } #{ e.class }"
|
217
|
+
end
|
214
218
|
end
|
215
219
|
|
216
220
|
@mutex.synchronize do
|
@@ -232,7 +236,7 @@ module Girl
|
|
232
236
|
# deal with destination addr
|
233
237
|
#
|
234
238
|
def deal_with_destination_addr( tund, src_id, destination_addr )
|
235
|
-
dst = Socket.new( Socket::AF_INET, Socket::SOCK_STREAM, 0 )
|
239
|
+
dst = Socket.new( Addrinfo.new( destination_addr ).ipv4? ? Socket::AF_INET : Socket::AF_INET6, Socket::SOCK_STREAM, 0 )
|
236
240
|
dst.setsockopt( Socket::SOL_TCP, Socket::TCP_NODELAY, 1 )
|
237
241
|
|
238
242
|
begin
|
@@ -814,7 +818,6 @@ module Girl
|
|
814
818
|
when A_NEW_SOURCE
|
815
819
|
src_id = data[ 9, 8 ].unpack( 'Q>' ).first
|
816
820
|
dst_local_port = tund_info[ :dst_local_ports ][ src_id ]
|
817
|
-
# puts "debug1 got a new source #{ src_id }"
|
818
821
|
|
819
822
|
if dst_local_port
|
820
823
|
dst_ext = tund_info[ :dst_exts ][ dst_local_port ]
|
@@ -831,8 +834,8 @@ module Girl
|
|
831
834
|
end
|
832
835
|
|
833
836
|
data = data[ 17..-1 ]
|
834
|
-
# puts "debug1 #{ data }"
|
835
837
|
destination_domain_port = @custom.decode( data )
|
838
|
+
puts "p#{ Process.pid } #{ Time.new } a new source #{ src_id } #{ destination_domain_port }"
|
836
839
|
resolve_domain( tund, src_id, destination_domain_port )
|
837
840
|
when SOURCE_STATUS
|
838
841
|
src_id, relay_src_pack_id, continue_dst_pack_id = data[ 9, 24 ].unpack( 'Q>Q>Q>' )
|
@@ -908,7 +911,6 @@ module Girl
|
|
908
911
|
dst_ext[ :biggest_src_pack_id ] = biggest_src_pack_id
|
909
912
|
release_wmems( dst_ext, continue_dst_pack_id )
|
910
913
|
|
911
|
-
# 接到对面已关闭,若最后一个包已经进写前,关闭dst
|
912
914
|
if biggest_src_pack_id == dst_ext[ :continue_src_pack_id ]
|
913
915
|
# puts "debug1 4-1. tund recv fin1 -> all traffic received ? -> close dst after write"
|
914
916
|
set_is_closing( dst_ext[ :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.73.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-
|
11
|
+
date: 2020-07-16 00:00:00.000000000 Z
|
12
12
|
dependencies: []
|
13
13
|
description: while internet is evil, here's a girl.
|
14
14
|
email:
|