girl 0.82.0 → 0.87.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 +1 -1
- data/lib/girl/head.rb +29 -28
- data/lib/girl/proxy.rb +26 -35
- data/lib/girl/proxy_worker.rb +368 -474
- data/lib/girl/proxyd.rb +23 -24
- data/lib/girl/proxyd_worker.rb +348 -422
- data/lib/girl/version.rb +1 -1
- metadata +3 -3
data/lib/girl/proxyd.rb
CHANGED
@@ -20,7 +20,6 @@ module Girl
|
|
20
20
|
|
21
21
|
conf = JSON.parse( IO.binread( config_path ), symbolize_names: true )
|
22
22
|
proxyd_port = conf[ :proxyd_port ]
|
23
|
-
proxyd_tmp_dir = conf[ :proxyd_tmp_dir ]
|
24
23
|
worker_count = conf[ :worker_count ]
|
25
24
|
end
|
26
25
|
|
@@ -28,26 +27,6 @@ module Girl
|
|
28
27
|
proxyd_port = 6060
|
29
28
|
end
|
30
29
|
|
31
|
-
unless proxyd_tmp_dir
|
32
|
-
proxyd_tmp_dir = '/tmp/girl.proxyd'
|
33
|
-
end
|
34
|
-
|
35
|
-
unless File.exist?( proxyd_tmp_dir )
|
36
|
-
Dir.mkdir( proxyd_tmp_dir )
|
37
|
-
end
|
38
|
-
|
39
|
-
dst_chunk_dir = File.join( proxyd_tmp_dir, 'dst.chunk' )
|
40
|
-
|
41
|
-
unless Dir.exist?( dst_chunk_dir )
|
42
|
-
Dir.mkdir( dst_chunk_dir )
|
43
|
-
end
|
44
|
-
|
45
|
-
tund_chunk_dir = File.join( proxyd_tmp_dir, 'tund.chunk' )
|
46
|
-
|
47
|
-
unless Dir.exist?( tund_chunk_dir )
|
48
|
-
Dir.mkdir( tund_chunk_dir )
|
49
|
-
end
|
50
|
-
|
51
30
|
nprocessors = Etc.nprocessors
|
52
31
|
|
53
32
|
if worker_count.nil? || worker_count <= 0 || worker_count > nprocessors
|
@@ -57,17 +36,37 @@ module Girl
|
|
57
36
|
title = "girl proxyd #{ Girl::VERSION }"
|
58
37
|
puts title
|
59
38
|
puts "proxyd port #{ proxyd_port }"
|
60
|
-
puts "dst chunk dir #{ dst_chunk_dir }"
|
61
|
-
puts "tund chunk dir #{ tund_chunk_dir }"
|
62
39
|
puts "worker count #{ worker_count }"
|
63
40
|
|
41
|
+
names = %w[
|
42
|
+
PACK_SIZE
|
43
|
+
READ_SIZE
|
44
|
+
WMEMS_LIMIT
|
45
|
+
RESUME_BELOW
|
46
|
+
EXPIRE_NEW
|
47
|
+
EXPIRE_AFTER
|
48
|
+
CHECK_EXPIRE_INTERVAL
|
49
|
+
CHECK_STATUS_INTERVAL
|
50
|
+
SEND_STATUS_UNTIL
|
51
|
+
MULTI_MISS_SIZE
|
52
|
+
MISS_RANGE_LIMIT
|
53
|
+
CONFUSE_UNTIL
|
54
|
+
RESOLV_CACHE_EXPIRE
|
55
|
+
]
|
56
|
+
|
57
|
+
len = names.map{ | name | name.size }.max
|
58
|
+
|
59
|
+
names.each do | name |
|
60
|
+
puts "#{ name.gsub( '_', ' ' ).ljust( len ) } #{ Girl.const_get( name ) }"
|
61
|
+
end
|
62
|
+
|
64
63
|
$0 = title
|
65
64
|
workers = []
|
66
65
|
|
67
66
|
worker_count.times do | i |
|
68
67
|
workers << fork do
|
69
68
|
$0 = 'girl proxyd worker'
|
70
|
-
worker = Girl::ProxydWorker.new( proxyd_port
|
69
|
+
worker = Girl::ProxydWorker.new( proxyd_port )
|
71
70
|
|
72
71
|
Signal.trap( :TERM ) do
|
73
72
|
puts "w#{ i } exit"
|
data/lib/girl/proxyd_worker.rb
CHANGED
@@ -4,13 +4,12 @@ module Girl
|
|
4
4
|
##
|
5
5
|
# initialize
|
6
6
|
#
|
7
|
-
def initialize( proxyd_port
|
8
|
-
@dst_chunk_dir = dst_chunk_dir
|
9
|
-
@tund_chunk_dir = tund_chunk_dir
|
7
|
+
def initialize( proxyd_port )
|
10
8
|
@custom = Girl::ProxydCustom.new
|
11
9
|
@mutex = Mutex.new
|
12
10
|
@reads = []
|
13
11
|
@writes = []
|
12
|
+
@pause_dsts = []
|
14
13
|
@roles = {} # sock => :dotr / :proxyd / :dst / :tund
|
15
14
|
@dst_infos = {} # dst => {}
|
16
15
|
@tunds = {} # port => tund
|
@@ -39,8 +38,6 @@ module Girl
|
|
39
38
|
# 先写,再读
|
40
39
|
ws.each do | sock |
|
41
40
|
case @roles[ sock ]
|
42
|
-
when :proxyd
|
43
|
-
write_proxyd( sock )
|
44
41
|
when :dst
|
45
42
|
write_dst( sock )
|
46
43
|
when :tund
|
@@ -105,20 +102,31 @@ module Girl
|
|
105
102
|
if is_expired
|
106
103
|
puts "p#{ Process.pid } #{ Time.new } expire tund #{ tund_info[ :port ] }"
|
107
104
|
set_is_closing( tund )
|
105
|
+
need_trigger = true
|
108
106
|
else
|
109
107
|
data = [ 0, HEARTBEAT, rand( 128 ) ].pack( 'Q>CC' )
|
110
108
|
# puts "debug1 #{ Time.new } #{ tund_info[ :port ] } heartbeat"
|
111
|
-
|
112
|
-
|
113
|
-
|
114
|
-
|
115
|
-
|
116
|
-
|
109
|
+
send_data( tund, data, tund_info[ :tun_addr ] )
|
110
|
+
del_dst_ids = []
|
111
|
+
|
112
|
+
tund_info[ :dsts ].each do | dst_id, dst |
|
113
|
+
if dst.closed?
|
114
|
+
dst_info = @dst_infos[ dst ]
|
115
|
+
|
116
|
+
if dst_info && ( now - dst_info[ :last_continue_at ] > EXPIRE_AFTER )
|
117
|
+
puts "p#{ Process.pid } #{ Time.new } expire dst ext #{ dst_info[ :domain_port ] }"
|
118
|
+
tund_info[ :wmems ].delete_if { | port_and_pack_id, _ | port_and_pack_id.first == dst_id }
|
119
|
+
tund_info[ :dst_ids ].delete( dst_info[ :src_id ] )
|
120
|
+
@dst_infos.delete( dst )
|
121
|
+
del_dst_ids << dst_id
|
122
|
+
end
|
117
123
|
end
|
118
124
|
end
|
119
|
-
end
|
120
125
|
|
121
|
-
|
126
|
+
if del_dst_ids.any?
|
127
|
+
tund_info[ :dsts ].delete_if { | dst_id, _ | del_dst_ids.include?( dst_id ) }
|
128
|
+
end
|
129
|
+
end
|
122
130
|
end
|
123
131
|
end
|
124
132
|
|
@@ -144,38 +152,71 @@ module Girl
|
|
144
152
|
def loop_check_status
|
145
153
|
Thread.new do
|
146
154
|
loop do
|
147
|
-
sleep
|
155
|
+
sleep CHECK_STATUS_INTERVAL
|
148
156
|
|
149
|
-
|
150
|
-
|
151
|
-
need_trigger = false
|
157
|
+
@mutex.synchronize do
|
158
|
+
need_trigger = false
|
152
159
|
|
160
|
+
if @tunds.any?
|
153
161
|
@tunds.each do | tund_port, tund |
|
154
162
|
tund_info = @tund_infos[ tund ]
|
155
163
|
|
156
|
-
if tund_info[ :
|
164
|
+
if tund_info[ :dsts ].any?
|
157
165
|
now = Time.new
|
158
166
|
|
159
|
-
tund_info[ :
|
160
|
-
|
161
|
-
|
162
|
-
|
163
|
-
|
167
|
+
tund_info[ :dsts ].each do | dst_id, dst |
|
168
|
+
dst_info = @dst_infos[ dst ]
|
169
|
+
|
170
|
+
if dst_info && ( now - dst_info[ :last_continue_at ] < SEND_STATUS_UNTIL )
|
171
|
+
data = [ 0, DEST_STATUS, dst_id, dst_info[ :biggest_pack_id ], dst_info[ :continue_src_pack_id ] ].pack( 'Q>CnQ>Q>' )
|
172
|
+
send_data( tund, data, tund_info[ :tun_addr ] )
|
164
173
|
end
|
165
174
|
end
|
166
175
|
end
|
176
|
+
end
|
177
|
+
end
|
167
178
|
|
168
|
-
|
169
|
-
|
170
|
-
|
171
|
-
|
172
|
-
|
179
|
+
if @pause_dsts.any?
|
180
|
+
resume_dsts = []
|
181
|
+
ignore_dsts = []
|
182
|
+
|
183
|
+
@pause_dsts.each do | dst |
|
184
|
+
dst_info = @dst_infos[ dst ]
|
185
|
+
|
186
|
+
if dst_info
|
187
|
+
tund = dst_info[ :tund ]
|
188
|
+
|
189
|
+
if tund.closed?
|
190
|
+
ignore_dsts << dst
|
191
|
+
else
|
192
|
+
tund_info = @tund_infos[ tund ]
|
193
|
+
|
194
|
+
if tund_info[ :wmems ].size < RESUME_BELOW
|
195
|
+
puts "p#{ Process.pid } #{ Time.new } resume dst #{ dst_info[ :domain_port ] }"
|
196
|
+
resume_dsts << dst
|
197
|
+
end
|
198
|
+
end
|
199
|
+
else
|
200
|
+
ignore_dsts << dst
|
173
201
|
end
|
174
202
|
end
|
175
203
|
|
176
|
-
if
|
177
|
-
|
204
|
+
if resume_dsts.any?
|
205
|
+
resume_dsts.each do | dst |
|
206
|
+
add_read( dst )
|
207
|
+
end
|
208
|
+
|
209
|
+
@pause_dsts -= resume_dsts
|
210
|
+
need_trigger = true
|
178
211
|
end
|
212
|
+
|
213
|
+
if ignore_dsts.any?
|
214
|
+
@pause_dsts -= ignore_dsts
|
215
|
+
end
|
216
|
+
end
|
217
|
+
|
218
|
+
if need_trigger
|
219
|
+
next_tick
|
179
220
|
end
|
180
221
|
end
|
181
222
|
end
|
@@ -185,43 +226,43 @@ module Girl
|
|
185
226
|
##
|
186
227
|
# resolve domain
|
187
228
|
#
|
188
|
-
def resolve_domain( tund, src_id,
|
189
|
-
resolv_cache = @resolv_caches[
|
229
|
+
def resolve_domain( tund, src_id, domain_port )
|
230
|
+
resolv_cache = @resolv_caches[ domain_port ]
|
190
231
|
|
191
232
|
if resolv_cache
|
192
233
|
destination_addr, created_at = resolv_cache
|
193
234
|
|
194
235
|
if Time.new - created_at < RESOLV_CACHE_EXPIRE
|
195
|
-
# puts "debug1 #{
|
196
|
-
deal_with_destination_addr( tund, src_id, destination_addr,
|
236
|
+
# puts "debug1 #{ domain_port } hit resolv cache #{ Addrinfo.new( destination_addr ).inspect }"
|
237
|
+
deal_with_destination_addr( tund, src_id, destination_addr, domain_port )
|
197
238
|
return
|
198
239
|
end
|
199
240
|
|
200
|
-
# puts "debug1 expire #{
|
201
|
-
@resolv_caches.delete(
|
241
|
+
# puts "debug1 expire #{ domain_port } resolv cache"
|
242
|
+
@resolv_caches.delete( domain_port )
|
202
243
|
end
|
203
244
|
|
204
245
|
Thread.new do
|
205
|
-
colon_idx =
|
246
|
+
colon_idx = domain_port.rindex( ':' )
|
206
247
|
|
207
248
|
if colon_idx
|
208
|
-
destination_domain =
|
209
|
-
destination_port =
|
249
|
+
destination_domain = domain_port[ 0...colon_idx ]
|
250
|
+
destination_port = domain_port[ ( colon_idx + 1 )..-1 ].to_i
|
210
251
|
|
211
252
|
begin
|
212
253
|
destination_addr = Socket.sockaddr_in( destination_port, destination_domain )
|
213
254
|
rescue Exception => e
|
214
|
-
puts "p#{ Process.pid } #{ Time.new } sockaddr in #{
|
255
|
+
puts "p#{ Process.pid } #{ Time.new } sockaddr in #{ domain_port } #{ e.class }"
|
215
256
|
end
|
216
257
|
end
|
217
258
|
|
218
259
|
@mutex.synchronize do
|
219
260
|
if destination_addr
|
220
|
-
# puts "debug1 resolved #{
|
221
|
-
@resolv_caches[
|
261
|
+
# puts "debug1 resolved #{ domain_port } #{ Addrinfo.new( destination_addr ).inspect }"
|
262
|
+
@resolv_caches[ domain_port ] = [ destination_addr, Time.new ]
|
222
263
|
|
223
264
|
unless tund.closed?
|
224
|
-
if deal_with_destination_addr( tund, src_id, destination_addr,
|
265
|
+
if deal_with_destination_addr( tund, src_id, destination_addr, domain_port )
|
225
266
|
next_tick
|
226
267
|
end
|
227
268
|
end
|
@@ -233,7 +274,7 @@ module Girl
|
|
233
274
|
##
|
234
275
|
# deal with destination addr
|
235
276
|
#
|
236
|
-
def deal_with_destination_addr( tund, src_id, destination_addr,
|
277
|
+
def deal_with_destination_addr( tund, src_id, destination_addr, domain_port )
|
237
278
|
dst = Socket.new( Addrinfo.new( destination_addr ).ipv4? ? Socket::AF_INET : Socket::AF_INET6, Socket::SOCK_STREAM, 0 )
|
238
279
|
dst.setsockopt( Socket::SOL_TCP, Socket::TCP_NODELAY, 1 )
|
239
280
|
|
@@ -245,42 +286,34 @@ module Girl
|
|
245
286
|
return false
|
246
287
|
end
|
247
288
|
|
248
|
-
|
289
|
+
dst_id = dst.local_address.ip_port
|
249
290
|
|
250
291
|
@dst_infos[ dst ] = {
|
251
|
-
|
252
|
-
tund: tund,
|
253
|
-
domain_port:
|
254
|
-
biggest_pack_id: 0,
|
255
|
-
wbuff: '',
|
256
|
-
|
257
|
-
|
258
|
-
|
259
|
-
|
260
|
-
|
292
|
+
id: dst_id, # id
|
293
|
+
tund: tund, # 对应tund
|
294
|
+
domain_port: domain_port, # 域名和端口
|
295
|
+
biggest_pack_id: 0, # 最大包号码
|
296
|
+
wbuff: '', # 写前
|
297
|
+
src_id: src_id, # 近端src id
|
298
|
+
send_ats: {}, # 上一次发出时间 pack_id => send_at
|
299
|
+
continue_src_pack_id: 0, # 收到几
|
300
|
+
pieces: {}, # 跳号包 src_pack_id => data
|
301
|
+
is_src_closed: false, # src是否已关闭
|
302
|
+
biggest_src_pack_id: 0, # src最大包号码
|
303
|
+
completed_pack_id: 0, # 完成到几(对面收到几)
|
304
|
+
last_continue_at: Time.new, # 上一次发生流量的时间
|
305
|
+
is_closing: false # 是否准备关闭
|
261
306
|
}
|
307
|
+
|
262
308
|
add_read( dst, :dst )
|
263
309
|
|
264
310
|
tund_info = @tund_infos[ tund ]
|
265
|
-
tund_info[ :
|
266
|
-
tund_info[ :
|
267
|
-
dst: dst, # dst
|
268
|
-
src_id: src_id, # 近端src id
|
269
|
-
domain_port: destination_domain_port, # 域名和端口
|
270
|
-
wmems: {}, # 写后 pack_id => data
|
271
|
-
send_ats: {}, # 上一次发出时间 pack_id => send_at
|
272
|
-
relay_pack_id: 0, # 转发到几
|
273
|
-
continue_src_pack_id: 0, # 收到几
|
274
|
-
pieces: {}, # 跳号包 src_pack_id => data
|
275
|
-
is_src_closed: false, # src是否已关闭
|
276
|
-
biggest_src_pack_id: 0, # src最大包号码
|
277
|
-
completed_pack_id: 0, # 完成到几(对面收到几)
|
278
|
-
last_continue_at: Time.new # 上一次发生流量的时间
|
279
|
-
}
|
311
|
+
tund_info[ :dst_ids ][ src_id ] = dst_id
|
312
|
+
tund_info[ :dsts ][ dst_id ] = dst
|
280
313
|
|
281
|
-
data = [ 0, PAIRED, src_id,
|
282
|
-
# puts "debug1
|
283
|
-
|
314
|
+
data = [ 0, PAIRED, src_id, dst_id ].pack( 'Q>CQ>n' )
|
315
|
+
# puts "debug1 send paired #{ data.inspect }"
|
316
|
+
send_data( tund, data, tund_info[ :tun_addr ] )
|
284
317
|
|
285
318
|
true
|
286
319
|
end
|
@@ -295,101 +328,39 @@ module Girl
|
|
295
328
|
|
296
329
|
puts "p#{ Process.pid } #{ Time.new } proxyd bind on #{ proxyd_port }"
|
297
330
|
@proxyd = proxyd
|
298
|
-
@proxyd_ctlmsgs = [] # [ to_addr, data ]
|
299
331
|
add_read( proxyd, :proxyd )
|
300
332
|
end
|
301
333
|
|
302
334
|
##
|
303
|
-
# add
|
304
|
-
#
|
305
|
-
def add_proxyd_ctlmsg( data, to_addr )
|
306
|
-
@proxyd_ctlmsgs << [ to_addr, data ]
|
307
|
-
add_write( @proxyd )
|
308
|
-
end
|
309
|
-
|
310
|
-
##
|
311
|
-
# add tund ctlmsg
|
335
|
+
# add read
|
312
336
|
#
|
313
|
-
def
|
314
|
-
|
315
|
-
|
316
|
-
add_write( tund )
|
317
|
-
end
|
337
|
+
def add_read( sock, role = nil )
|
338
|
+
if sock && !sock.closed? && !@reads.include?( sock )
|
339
|
+
@reads << sock
|
318
340
|
|
319
|
-
|
320
|
-
|
321
|
-
#
|
322
|
-
def add_tund_wbuff( tund, dst_local_port, pack_id, data )
|
323
|
-
tund_info = @tund_infos[ tund ]
|
324
|
-
tund_info[ :wbuffs ] << [ dst_local_port, pack_id, data ]
|
325
|
-
|
326
|
-
if tund_info[ :wbuffs ].size >= WBUFFS_LIMIT
|
327
|
-
spring = tund_info[ :chunks ].size > 0 ? ( tund_info[ :spring ] + 1 ) : 0
|
328
|
-
filename = "#{ Process.pid }-#{ tund_info[ :port ] }.#{ spring }"
|
329
|
-
chunk_path = File.join( @tund_chunk_dir, filename )
|
330
|
-
datas = tund_info[ :wbuffs ].map{ | _dst_local_port, _pack_id, _data | [ [ _dst_local_port, _pack_id, _data.bytesize ].pack( 'nQ>n' ), _data ].join }
|
331
|
-
|
332
|
-
begin
|
333
|
-
IO.binwrite( chunk_path, datas.join )
|
334
|
-
rescue Errno::ENOSPC => e
|
335
|
-
puts "p#{ Process.pid } #{ Time.new } #{ e.class }, close tund"
|
336
|
-
set_is_closing( tund )
|
337
|
-
return
|
341
|
+
if role
|
342
|
+
@roles[ sock ] = role
|
338
343
|
end
|
339
|
-
|
340
|
-
tund_info[ :chunks ] << filename
|
341
|
-
tund_info[ :spring ] = spring
|
342
|
-
tund_info[ :wbuffs ].clear
|
343
344
|
end
|
344
|
-
|
345
|
-
add_write( tund )
|
346
345
|
end
|
347
346
|
|
348
347
|
##
|
349
|
-
# add
|
348
|
+
# add write
|
350
349
|
#
|
351
|
-
def
|
352
|
-
|
353
|
-
|
354
|
-
|
355
|
-
if dst_info[ :wbuff ].bytesize >= CHUNK_SIZE
|
356
|
-
spring = dst_info[ :chunks ].size > 0 ? ( dst_info[ :spring ] + 1 ) : 0
|
357
|
-
filename = "#{ Process.pid }-#{ dst_info[ :local_port ] }.#{ spring }"
|
358
|
-
chunk_path = File.join( @dst_chunk_dir, filename )
|
359
|
-
|
360
|
-
begin
|
361
|
-
IO.binwrite( chunk_path, dst_info[ :wbuff ] )
|
362
|
-
rescue Errno::ENOSPC => e
|
363
|
-
puts "p#{ Process.pid } #{ Time.new } #{ e.class }, close dst"
|
364
|
-
set_is_closing( dst )
|
365
|
-
return
|
366
|
-
end
|
367
|
-
|
368
|
-
dst_info[ :chunks ] << filename
|
369
|
-
dst_info[ :spring ] = spring
|
370
|
-
dst_info[ :wbuff ].clear
|
350
|
+
def add_write( sock )
|
351
|
+
if sock && !sock.closed? && !@writes.include?( sock )
|
352
|
+
@writes << sock
|
371
353
|
end
|
372
|
-
|
373
|
-
add_write( dst )
|
374
354
|
end
|
375
355
|
|
376
356
|
##
|
377
|
-
# add
|
357
|
+
# add pause dst
|
378
358
|
#
|
379
|
-
def
|
380
|
-
|
381
|
-
@reads << sock
|
382
|
-
end
|
383
|
-
|
384
|
-
@roles[ sock ] = role
|
385
|
-
end
|
359
|
+
def add_pause_dst( dst )
|
360
|
+
@reads.delete( dst )
|
386
361
|
|
387
|
-
|
388
|
-
|
389
|
-
#
|
390
|
-
def add_write( sock )
|
391
|
-
if sock && !sock.closed? && !@writes.include?( sock )
|
392
|
-
@writes << sock
|
362
|
+
unless @pause_dsts.include?( dst )
|
363
|
+
@pause_dsts << dst
|
393
364
|
end
|
394
365
|
end
|
395
366
|
|
@@ -415,6 +386,53 @@ module Girl
|
|
415
386
|
end
|
416
387
|
end
|
417
388
|
|
389
|
+
##
|
390
|
+
# tunnel data
|
391
|
+
#
|
392
|
+
def tunnel_data( dst, data )
|
393
|
+
dst_info = @dst_infos[ dst ]
|
394
|
+
tund = dst_info[ :tund ]
|
395
|
+
|
396
|
+
if tund.closed?
|
397
|
+
puts "p#{ Process.pid } #{ Time.new } tund closed, close dst"
|
398
|
+
set_is_closing( dst )
|
399
|
+
return
|
400
|
+
end
|
401
|
+
|
402
|
+
tund_info = @tund_infos[ tund ]
|
403
|
+
dst_id = dst_info[ :id ]
|
404
|
+
now = Time.new
|
405
|
+
pack_id = dst_info[ :biggest_pack_id ]
|
406
|
+
idx = 0
|
407
|
+
len = data.bytesize
|
408
|
+
|
409
|
+
while idx < len
|
410
|
+
chunk = data[ idx, PACK_SIZE ]
|
411
|
+
pack_id += 1
|
412
|
+
|
413
|
+
if pack_id <= CONFUSE_UNTIL
|
414
|
+
chunk = @custom.encode( chunk )
|
415
|
+
# puts "debug1 encoded chunk #{ pack_id }"
|
416
|
+
end
|
417
|
+
|
418
|
+
data2 = [ [ pack_id, dst_id ].pack( 'Q>n' ), chunk ].join
|
419
|
+
sent = send_data( tund, data2, tund_info[ :tun_addr ] )
|
420
|
+
# puts "debug2 written pack #{ pack_id } #{ sent }"
|
421
|
+
tund_info[ :wmems ][ [ dst_id, pack_id ] ] = data2
|
422
|
+
dst_info[ :send_ats ][ pack_id ] = now
|
423
|
+
idx += PACK_SIZE
|
424
|
+
end
|
425
|
+
|
426
|
+
dst_info[ :biggest_pack_id ] = pack_id
|
427
|
+
dst_info[ :last_continue_at ] = now
|
428
|
+
|
429
|
+
# 写后超过上限,暂停读dst
|
430
|
+
if tund_info[ :wmems ].size >= WMEMS_LIMIT
|
431
|
+
puts "p#{ Process.pid } #{ Time.new } pause dst #{ dst_id } #{ dst_info[ :domain_port ] } #{ dst_info[ :biggest_pack_id ] }"
|
432
|
+
add_pause_dst( dst )
|
433
|
+
end
|
434
|
+
end
|
435
|
+
|
418
436
|
##
|
419
437
|
# send data
|
420
438
|
#
|
@@ -440,33 +458,28 @@ module Girl
|
|
440
458
|
def close_dst( dst )
|
441
459
|
# puts "debug1 close dst"
|
442
460
|
close_sock( dst )
|
443
|
-
|
461
|
+
@pause_dsts.delete( dst )
|
462
|
+
dst_info = @dst_infos[ dst ]
|
463
|
+
tund = dst_info[ :tund ]
|
444
464
|
|
445
|
-
|
446
|
-
|
447
|
-
|
448
|
-
rescue Errno::ENOENT
|
449
|
-
end
|
465
|
+
if tund.closed?
|
466
|
+
@dst_infos.delete( dst )
|
467
|
+
return
|
450
468
|
end
|
451
469
|
|
452
|
-
tund = dst_info[ :tund ]
|
453
|
-
return if tund.closed?
|
454
|
-
|
455
470
|
tund_info = @tund_infos[ tund ]
|
456
|
-
|
457
|
-
dst_ext = tund_info[ :dst_exts ][ local_port ]
|
458
|
-
return unless dst_ext
|
471
|
+
dst_id = dst_info[ :id ]
|
459
472
|
|
460
|
-
if
|
473
|
+
if dst_info[ :is_src_closed ]
|
461
474
|
# puts "debug1 4-3. after close dst -> src closed ? yes -> del dst ext -> send fin2"
|
462
|
-
del_dst_ext(
|
463
|
-
data = [ 0, FIN2,
|
464
|
-
add_tund_ctlmsg( tund, data )
|
475
|
+
del_dst_ext( tund_info, dst_id )
|
476
|
+
data = [ 0, FIN2, dst_id ].pack( 'Q>Cn' )
|
465
477
|
else
|
466
478
|
# puts "debug1 3-1. after close dst -> src closed ? no -> send fin1"
|
467
|
-
data = [ 0, FIN1,
|
468
|
-
add_tund_ctlmsg( tund, data )
|
479
|
+
data = [ 0, FIN1, dst_id, dst_info[ :biggest_pack_id ], dst_info[ :continue_src_pack_id ] ].pack( 'Q>CnQ>Q>' )
|
469
480
|
end
|
481
|
+
|
482
|
+
send_data( tund, data, tund_info[ :tun_addr ] )
|
470
483
|
end
|
471
484
|
|
472
485
|
##
|
@@ -475,16 +488,8 @@ module Girl
|
|
475
488
|
def close_tund( tund )
|
476
489
|
# puts "debug1 close tund"
|
477
490
|
close_sock( tund )
|
478
|
-
|
479
491
|
tund_info = @tund_infos.delete( tund )
|
480
|
-
tund_info[ :
|
481
|
-
begin
|
482
|
-
File.delete( File.join( @tund_chunk_dir, filename ) )
|
483
|
-
rescue Errno::ENOENT
|
484
|
-
end
|
485
|
-
end
|
486
|
-
|
487
|
-
tund_info[ :dst_exts ].each{ | _, dst_ext | set_is_closing( dst_ext[ :dst ] ) }
|
492
|
+
tund_info[ :dsts ].each{ | _, dst | set_is_closing( dst ) }
|
488
493
|
@tunneling_tunds.delete( tund_info[ :tun_addr ] )
|
489
494
|
@tunds.delete( tund_info[ :port ] )
|
490
495
|
end
|
@@ -502,30 +507,34 @@ module Girl
|
|
502
507
|
##
|
503
508
|
# del dst ext
|
504
509
|
#
|
505
|
-
def del_dst_ext(
|
506
|
-
tund_info
|
507
|
-
|
510
|
+
def del_dst_ext( tund_info, dst_id )
|
511
|
+
tund_info[ :wmems ].delete_if { | port_and_pack_id, _ | port_and_pack_id.first == dst_id }
|
512
|
+
dst = tund_info[ :dsts ].delete( dst_id )
|
508
513
|
|
509
|
-
if
|
510
|
-
|
514
|
+
if dst
|
515
|
+
dst_info = @dst_infos.delete( dst )
|
516
|
+
|
517
|
+
if dst_info
|
518
|
+
tund_info[ :dst_ids ].delete( dst_info[ :src_id ] )
|
519
|
+
end
|
511
520
|
end
|
512
521
|
end
|
513
522
|
|
514
523
|
##
|
515
524
|
# release wmems
|
516
525
|
#
|
517
|
-
def release_wmems(
|
518
|
-
if completed_pack_id >
|
526
|
+
def release_wmems( tund_info, dst_info, completed_pack_id )
|
527
|
+
if completed_pack_id > dst_info[ :completed_pack_id ]
|
519
528
|
# puts "debug2 update completed pack #{ completed_pack_id }"
|
520
529
|
|
521
|
-
pack_ids =
|
530
|
+
pack_ids = dst_info[ :send_ats ].keys.select { | pack_id | pack_id <= completed_pack_id }
|
522
531
|
|
523
532
|
pack_ids.each do | pack_id |
|
524
|
-
|
525
|
-
|
533
|
+
tund_info[ :wmems ].delete( [ dst_info[ :id ], pack_id ] )
|
534
|
+
dst_info[ :send_ats ].delete( pack_id )
|
526
535
|
end
|
527
536
|
|
528
|
-
|
537
|
+
dst_info[ :completed_pack_id ] = completed_pack_id
|
529
538
|
end
|
530
539
|
end
|
531
540
|
|
@@ -536,54 +545,21 @@ module Girl
|
|
536
545
|
@dotw.write( '.' )
|
537
546
|
end
|
538
547
|
|
539
|
-
##
|
540
|
-
# write proxyd
|
541
|
-
#
|
542
|
-
def write_proxyd( proxyd )
|
543
|
-
while @proxyd_ctlmsgs.any?
|
544
|
-
to_addr, data = @proxyd_ctlmsgs.first
|
545
|
-
|
546
|
-
unless send_data( proxyd, data, to_addr )
|
547
|
-
return
|
548
|
-
end
|
549
|
-
|
550
|
-
@proxyd_ctlmsgs.shift
|
551
|
-
end
|
552
|
-
|
553
|
-
@writes.delete( proxyd )
|
554
|
-
end
|
555
|
-
|
556
548
|
##
|
557
549
|
# write dst
|
558
550
|
#
|
559
551
|
def write_dst( dst )
|
560
552
|
dst_info = @dst_infos[ dst ]
|
561
|
-
from, data = :cache, dst_info[ :cache ]
|
562
|
-
|
563
|
-
if data.empty?
|
564
|
-
if dst_info[ :chunks ].any?
|
565
|
-
path = File.join( @dst_chunk_dir, dst_info[ :chunks ].shift )
|
566
553
|
|
567
|
-
|
568
|
-
|
569
|
-
|
570
|
-
rescue Errno::ENOENT => e
|
571
|
-
puts "p#{ Process.pid } #{ Time.new } read #{ path } #{ e.class }"
|
572
|
-
close_dst( dst )
|
573
|
-
return
|
574
|
-
end
|
575
|
-
else
|
576
|
-
from, data = :wbuff, dst_info[ :wbuff ]
|
577
|
-
end
|
554
|
+
if dst_info[ :is_closing ]
|
555
|
+
close_dst( dst )
|
556
|
+
return
|
578
557
|
end
|
579
558
|
|
580
|
-
|
581
|
-
if dst_info[ :is_closing ]
|
582
|
-
close_dst( dst )
|
583
|
-
else
|
584
|
-
@writes.delete( dst )
|
585
|
-
end
|
559
|
+
data = dst_info[ :wbuff ]
|
586
560
|
|
561
|
+
if data.empty?
|
562
|
+
@writes.delete( dst )
|
587
563
|
return
|
588
564
|
end
|
589
565
|
|
@@ -599,7 +575,7 @@ module Girl
|
|
599
575
|
|
600
576
|
# puts "debug2 write dst #{ written }"
|
601
577
|
data = data[ written..-1 ]
|
602
|
-
dst_info[
|
578
|
+
dst_info[ :wbuff ] = data
|
603
579
|
dst_info[ :last_continue_at ] = Time.new
|
604
580
|
end
|
605
581
|
|
@@ -607,7 +583,6 @@ module Girl
|
|
607
583
|
# write tund
|
608
584
|
#
|
609
585
|
def write_tund( tund )
|
610
|
-
now = Time.new
|
611
586
|
tund_info = @tund_infos[ tund ]
|
612
587
|
|
613
588
|
if tund_info[ :is_closing ]
|
@@ -620,104 +595,7 @@ module Girl
|
|
620
595
|
return
|
621
596
|
end
|
622
597
|
|
623
|
-
|
624
|
-
while tund_info[ :ctlmsgs ].any?
|
625
|
-
data = tund_info[ :ctlmsgs ].first
|
626
|
-
|
627
|
-
unless send_data( tund, data, tund_info[ :tun_addr ] )
|
628
|
-
return
|
629
|
-
end
|
630
|
-
|
631
|
-
tund_info[ :ctlmsgs ].shift
|
632
|
-
end
|
633
|
-
|
634
|
-
# 重传
|
635
|
-
while tund_info[ :resendings ].any?
|
636
|
-
dst_local_port, pack_id = tund_info[ :resendings ].first
|
637
|
-
dst_ext = tund_info[ :dst_exts ][ dst_local_port ]
|
638
|
-
|
639
|
-
if dst_ext
|
640
|
-
data = dst_ext[ :wmems ][ pack_id ]
|
641
|
-
|
642
|
-
if data
|
643
|
-
unless send_data( tund, data, tund_info[ :tun_addr ] )
|
644
|
-
return
|
645
|
-
end
|
646
|
-
|
647
|
-
dst_ext[ :last_continue_at ] = now
|
648
|
-
end
|
649
|
-
end
|
650
|
-
|
651
|
-
tund_info[ :resendings ].shift
|
652
|
-
end
|
653
|
-
|
654
|
-
# 若写后达到上限,暂停取写前
|
655
|
-
if tund_info[ :dst_exts ].map{ | _, dst_ext | dst_ext[ :wmems ].size }.sum >= WMEMS_LIMIT
|
656
|
-
unless tund_info[ :paused ]
|
657
|
-
puts "p#{ Process.pid } #{ Time.new } pause tund #{ tund_info[ :port ] }"
|
658
|
-
tund_info[ :paused ] = true
|
659
|
-
end
|
660
|
-
|
661
|
-
@writes.delete( tund )
|
662
|
-
return
|
663
|
-
end
|
664
|
-
|
665
|
-
# 取写前
|
666
|
-
if tund_info[ :caches ].any?
|
667
|
-
datas = tund_info[ :caches ]
|
668
|
-
elsif tund_info[ :chunks ].any?
|
669
|
-
path = File.join( @tund_chunk_dir, tund_info[ :chunks ].shift )
|
670
|
-
|
671
|
-
begin
|
672
|
-
data = IO.binread( path )
|
673
|
-
File.delete( path )
|
674
|
-
rescue Errno::ENOENT => e
|
675
|
-
puts "p#{ Process.pid } #{ Time.new } read #{ path } #{ e.class }"
|
676
|
-
close_tund( tund )
|
677
|
-
return
|
678
|
-
end
|
679
|
-
|
680
|
-
caches = []
|
681
|
-
|
682
|
-
until data.empty?
|
683
|
-
_dst_local_port, _pack_id, pack_size = data[ 0, 12 ].unpack( 'nQ>n' )
|
684
|
-
caches << [ _dst_local_port, _pack_id, data[ 12, pack_size ] ]
|
685
|
-
data = data[ ( 12 + pack_size )..-1 ]
|
686
|
-
end
|
687
|
-
|
688
|
-
datas = tund_info[ :caches ] = caches
|
689
|
-
elsif tund_info[ :wbuffs ].any?
|
690
|
-
datas = tund_info[ :wbuffs ]
|
691
|
-
else
|
692
|
-
@writes.delete( tund )
|
693
|
-
return
|
694
|
-
end
|
695
|
-
|
696
|
-
while datas.any?
|
697
|
-
dst_local_port, pack_id, data = datas.first
|
698
|
-
dst_ext = tund_info[ :dst_exts ][ dst_local_port ]
|
699
|
-
|
700
|
-
if dst_ext
|
701
|
-
if pack_id <= CONFUSE_UNTIL
|
702
|
-
data = @custom.encode( data )
|
703
|
-
# puts "debug1 encoded pack #{ pack_id }"
|
704
|
-
end
|
705
|
-
|
706
|
-
data = [ [ pack_id, dst_local_port ].pack( 'Q>n' ), data ].join
|
707
|
-
|
708
|
-
unless send_data( tund, data, tund_info[ :tun_addr ] )
|
709
|
-
return
|
710
|
-
end
|
711
|
-
|
712
|
-
# puts "debug2 written pack #{ pack_id }"
|
713
|
-
dst_ext[ :relay_pack_id ] = pack_id
|
714
|
-
dst_ext[ :wmems ][ pack_id ] = data
|
715
|
-
dst_ext[ :send_ats ][ pack_id ] = now
|
716
|
-
dst_ext[ :last_continue_at ] = now
|
717
|
-
end
|
718
|
-
|
719
|
-
datas.shift
|
720
|
-
end
|
598
|
+
@writes.delete( tund )
|
721
599
|
end
|
722
600
|
|
723
601
|
##
|
@@ -734,7 +612,15 @@ module Girl
|
|
734
612
|
data, addrinfo, rflags, *controls = proxyd.recvmsg
|
735
613
|
from_addr = addrinfo.to_sockaddr
|
736
614
|
|
737
|
-
|
615
|
+
if @tunneling_tunds.include?( from_addr )
|
616
|
+
tund = @tunneling_tunds[ from_addr ]
|
617
|
+
tund_info = @tund_infos[ tund ]
|
618
|
+
port = tund_info[ :port ]
|
619
|
+
data = [ 0, TUND_PORT, port ].pack( 'Q>Cn' )
|
620
|
+
puts "p#{ Process.pid } #{ Time.new } resend tund port #{ port }"
|
621
|
+
send_data( proxyd, data, from_addr )
|
622
|
+
return
|
623
|
+
end
|
738
624
|
|
739
625
|
result = @custom.check( data, addrinfo )
|
740
626
|
|
@@ -751,16 +637,11 @@ module Girl
|
|
751
637
|
@tunds[ port ] = tund
|
752
638
|
@tund_infos[ tund ] = {
|
753
639
|
port: port, # 端口
|
754
|
-
|
755
|
-
|
756
|
-
caches: [], # 块读出缓存 [ dst_local_port, pack_id, data ]
|
757
|
-
chunks: [], # 块队列 filename
|
758
|
-
spring: 0, # 块后缀,结块时,如果块队列不为空,则自增,为空,则置为0
|
640
|
+
wbuffs: [], # 写前 [ dst_id, pack_id, data ]
|
641
|
+
wmems: {}, # 写后 [ dst_id, pack_id ] => data
|
759
642
|
tun_addr: from_addr, # tun地址
|
760
|
-
|
761
|
-
|
762
|
-
paused: false, # 是否暂停写
|
763
|
-
resendings: [], # 重传队列 [ dst_local_port, pack_id ]
|
643
|
+
dsts: {}, # dst额外信息 dst_id => dst
|
644
|
+
dst_ids: {}, # src_id => dst_id
|
764
645
|
created_at: Time.new, # 创建时间
|
765
646
|
last_recv_at: nil, # 上一次收到流量的时间,过期关闭
|
766
647
|
is_closing: false, # 是否准备关闭
|
@@ -771,7 +652,7 @@ module Girl
|
|
771
652
|
|
772
653
|
data = [ 0, TUND_PORT, port ].pack( 'Q>Cn' )
|
773
654
|
puts "p#{ Process.pid } #{ Time.new } a new tunnel #{ addrinfo.ip_unpack.inspect } - #{ port }, #{ @tunds.size } tunds"
|
774
|
-
|
655
|
+
send_data( proxyd, data, from_addr )
|
775
656
|
end
|
776
657
|
|
777
658
|
##
|
@@ -779,7 +660,7 @@ module Girl
|
|
779
660
|
#
|
780
661
|
def read_dst( dst )
|
781
662
|
begin
|
782
|
-
data = dst.read_nonblock(
|
663
|
+
data = dst.read_nonblock( READ_SIZE )
|
783
664
|
rescue IO::WaitReadable, Errno::EINTR
|
784
665
|
return
|
785
666
|
rescue Exception => e
|
@@ -788,20 +669,7 @@ module Girl
|
|
788
669
|
return
|
789
670
|
end
|
790
671
|
|
791
|
-
|
792
|
-
dst_info = @dst_infos[ dst ]
|
793
|
-
dst_info[ :last_continue_at ] = Time.new
|
794
|
-
tund = dst_info[ :tund ]
|
795
|
-
|
796
|
-
if tund.closed?
|
797
|
-
puts "p#{ Process.pid } #{ Time.new } tund closed, close dst"
|
798
|
-
set_is_closing( dst )
|
799
|
-
return
|
800
|
-
end
|
801
|
-
|
802
|
-
pack_id = dst_info[ :biggest_pack_id ] + 1
|
803
|
-
dst_info[ :biggest_pack_id ] = pack_id
|
804
|
-
add_tund_wbuff( tund, dst_info[ :local_port ], pack_id, data )
|
672
|
+
tunnel_data( dst, data )
|
805
673
|
end
|
806
674
|
|
807
675
|
##
|
@@ -830,112 +698,165 @@ module Girl
|
|
830
698
|
case ctl_num
|
831
699
|
when A_NEW_SOURCE
|
832
700
|
src_id = data[ 9, 8 ].unpack( 'Q>' ).first
|
833
|
-
|
701
|
+
dst_id = tund_info[ :dst_ids ][ src_id ]
|
834
702
|
|
835
|
-
if
|
836
|
-
|
837
|
-
return unless
|
703
|
+
if dst_id
|
704
|
+
dst = tund_info[ :dsts ][ dst_id ]
|
705
|
+
return unless dst
|
838
706
|
|
839
|
-
if
|
840
|
-
|
707
|
+
if dst.closed?
|
708
|
+
dst_id = 0
|
841
709
|
end
|
842
710
|
|
843
|
-
# puts "debug1
|
844
|
-
data2 = [ 0, PAIRED, src_id,
|
845
|
-
|
711
|
+
# puts "debug1 resend paired #{ dst_id }"
|
712
|
+
data2 = [ 0, PAIRED, src_id, dst_id ].pack( 'Q>CQ>n' )
|
713
|
+
send_data( tund, data2, tund_info[ :tun_addr ] )
|
846
714
|
return
|
847
715
|
end
|
848
716
|
|
849
717
|
data = data[ 17..-1 ]
|
850
|
-
|
851
|
-
puts "p#{ Process.pid } #{ Time.new } a new source #{ src_id } #{
|
852
|
-
resolve_domain( tund, src_id,
|
718
|
+
domain_port = @custom.decode( data )
|
719
|
+
puts "p#{ Process.pid } #{ Time.new } a new source #{ src_id } #{ domain_port }"
|
720
|
+
resolve_domain( tund, src_id, domain_port )
|
853
721
|
when SOURCE_STATUS
|
854
722
|
src_id, relay_src_pack_id, continue_dst_pack_id = data[ 9, 24 ].unpack( 'Q>Q>Q>' )
|
855
723
|
|
856
|
-
|
857
|
-
return unless
|
724
|
+
dst_id = tund_info[ :dst_ids ][ src_id ]
|
725
|
+
return unless dst_id
|
726
|
+
|
727
|
+
dst = tund_info[ :dsts ][ dst_id ]
|
728
|
+
return unless dst
|
858
729
|
|
859
|
-
|
860
|
-
return unless
|
730
|
+
dst_info = @dst_infos[ dst ]
|
731
|
+
return unless dst_info
|
861
732
|
|
862
|
-
# puts "debug2 got source status"
|
733
|
+
# puts "debug2 got source status #{ Time.new }"
|
863
734
|
|
864
|
-
|
735
|
+
# 消写后
|
736
|
+
release_wmems( tund_info, dst_info, continue_dst_pack_id )
|
865
737
|
|
866
738
|
# 发miss
|
867
|
-
if !
|
739
|
+
if !dst.closed? && ( dst_info[ :continue_src_pack_id ] < relay_src_pack_id )
|
868
740
|
ranges = []
|
869
|
-
|
741
|
+
ignored = false
|
742
|
+
curr_pack_id = dst_info[ :continue_src_pack_id ] + 1
|
870
743
|
|
871
|
-
|
744
|
+
dst_info[ :pieces ].keys.sort.each do | pack_id |
|
872
745
|
if pack_id > curr_pack_id
|
873
746
|
ranges << [ curr_pack_id, pack_id - 1 ]
|
747
|
+
|
748
|
+
if ranges.size >= MISS_RANGE_LIMIT
|
749
|
+
puts "p#{ Process.pid } #{ Time.new } break add miss range at #{ pack_id }"
|
750
|
+
ignored = true
|
751
|
+
break
|
752
|
+
end
|
874
753
|
end
|
875
754
|
|
876
755
|
curr_pack_id = pack_id + 1
|
877
756
|
end
|
878
757
|
|
879
|
-
if curr_pack_id <= relay_src_pack_id
|
758
|
+
if !ignored && ( curr_pack_id <= relay_src_pack_id )
|
880
759
|
ranges << [ curr_pack_id, relay_src_pack_id ]
|
881
760
|
end
|
882
761
|
|
883
|
-
|
884
|
-
|
762
|
+
# puts "debug1 continue/relay #{ dst_info[ :continue_src_pack_id ] }/#{ relay_src_pack_id } send MISS #{ ranges.size }"
|
763
|
+
idx = 0
|
764
|
+
ranges = ranges.map{ | pack_id_begin, pack_id_end | [ pack_id_begin, pack_id_end ].pack( 'Q>Q>' ) }
|
885
765
|
|
886
|
-
|
887
|
-
|
888
|
-
|
889
|
-
|
890
|
-
|
766
|
+
while idx < ranges.size
|
767
|
+
chunk = ranges[ idx, MULTI_MISS_SIZE ].join
|
768
|
+
data2 = [ [ 0, MULTI_MISS, src_id ].pack( 'Q>CQ>' ), chunk ].join
|
769
|
+
send_data( tund, data2, tund_info[ :tun_addr ] )
|
770
|
+
idx += MULTI_MISS_SIZE
|
771
|
+
end
|
772
|
+
end
|
773
|
+
when MULTI_MISS
|
774
|
+
dst_id, *ranges = data[ 9..-1 ].unpack( 'nQ>*' )
|
775
|
+
|
776
|
+
dst = tund_info[ :dsts ][ dst_id ]
|
777
|
+
return unless dst
|
778
|
+
|
779
|
+
dst_info = @dst_infos[ dst ]
|
780
|
+
return unless dst_info
|
781
|
+
|
782
|
+
return if ranges.empty? || ( ranges.size % 2 != 0 )
|
783
|
+
|
784
|
+
# puts "debug1 got multi miss #{ dst_id } #{ ranges.size }"
|
785
|
+
|
786
|
+
idx = 0
|
891
787
|
|
892
|
-
|
893
|
-
|
894
|
-
|
788
|
+
while idx < ranges.size
|
789
|
+
pack_id_begin, pack_id_end = ranges[ idx ], ranges[ idx + 1 ]
|
790
|
+
|
791
|
+
( pack_id_begin..pack_id_end ).each do | pack_id |
|
792
|
+
send_at = dst_info[ :send_ats ][ pack_id ]
|
793
|
+
|
794
|
+
if send_at
|
795
|
+
break if now - send_at < CHECK_STATUS_INTERVAL
|
796
|
+
data2 = tund_info[ :wmems ][ [ dst_id, pack_id ] ]
|
797
|
+
|
798
|
+
if data2
|
799
|
+
if send_data( tund, data2, tund_info[ :tun_addr ] )
|
800
|
+
dst_info[ :last_continue_at ] = now
|
801
|
+
end
|
802
|
+
end
|
803
|
+
end
|
895
804
|
end
|
805
|
+
|
806
|
+
idx += 2
|
896
807
|
end
|
897
808
|
when MISS
|
898
|
-
|
809
|
+
dst_id, pack_id_begin, pack_id_end = data[ 9, 18 ].unpack( 'nQ>Q>' )
|
810
|
+
|
811
|
+
dst = tund_info[ :dsts ][ dst_id ]
|
812
|
+
return unless dst
|
899
813
|
|
900
|
-
|
901
|
-
return unless
|
814
|
+
dst_info = @dst_infos[ dst ]
|
815
|
+
return unless dst_info
|
902
816
|
|
903
817
|
( pack_id_begin..pack_id_end ).each do | pack_id |
|
904
|
-
send_at =
|
818
|
+
send_at = dst_info[ :send_ats ][ pack_id ]
|
905
819
|
|
906
820
|
if send_at
|
907
|
-
break if now - send_at <
|
908
|
-
tund_info[ :
|
821
|
+
break if now - send_at < CHECK_STATUS_INTERVAL
|
822
|
+
data2 = tund_info[ :wmems ][ [ dst_id, pack_id ] ]
|
823
|
+
|
824
|
+
if data2
|
825
|
+
if send_data( tund, data2, tund_info[ :tun_addr ] )
|
826
|
+
dst_info[ :last_continue_at ] = now
|
827
|
+
end
|
828
|
+
end
|
909
829
|
end
|
910
830
|
end
|
911
|
-
|
912
|
-
add_write( tund )
|
913
831
|
when FIN1
|
914
832
|
src_id, biggest_src_pack_id, continue_dst_pack_id = data[ 9, 24 ].unpack( 'Q>Q>Q>' )
|
915
833
|
|
916
|
-
|
917
|
-
return unless
|
834
|
+
dst_id = tund_info[ :dst_ids ][ src_id ]
|
835
|
+
return unless dst_id
|
836
|
+
|
837
|
+
dst = tund_info[ :dsts ][ dst_id ]
|
838
|
+
return unless dst
|
918
839
|
|
919
|
-
|
920
|
-
return unless
|
840
|
+
dst_info = @dst_infos[ dst ]
|
841
|
+
return unless dst_info
|
921
842
|
|
922
843
|
# puts "debug1 got fin1 #{ src_id } biggest src pack #{ biggest_src_pack_id } completed dst pack #{ continue_dst_pack_id }"
|
923
|
-
|
924
|
-
|
925
|
-
release_wmems(
|
844
|
+
dst_info[ :is_src_closed ] = true
|
845
|
+
dst_info[ :biggest_src_pack_id ] = biggest_src_pack_id
|
846
|
+
release_wmems( tund_info, dst_info, continue_dst_pack_id )
|
926
847
|
|
927
|
-
if biggest_src_pack_id ==
|
848
|
+
if biggest_src_pack_id == dst_info[ :continue_src_pack_id ]
|
928
849
|
# puts "debug1 4-1. tund recv fin1 -> all traffic received ? -> close dst after write"
|
929
|
-
set_is_closing(
|
850
|
+
set_is_closing( dst )
|
930
851
|
end
|
931
852
|
when FIN2
|
932
853
|
src_id = data[ 9, 8 ].unpack( 'Q>' ).first
|
933
854
|
|
934
|
-
|
935
|
-
return unless
|
855
|
+
dst_id = tund_info[ :dst_ids ][ src_id ]
|
856
|
+
return unless dst_id
|
936
857
|
|
937
858
|
# puts "debug1 3-2. tund recv fin2 -> del dst ext"
|
938
|
-
del_dst_ext(
|
859
|
+
del_dst_ext( tund_info, dst_id )
|
939
860
|
when TUN_FIN
|
940
861
|
puts "p#{ Process.pid } #{ Time.new } recv tun fin"
|
941
862
|
set_is_closing( tund )
|
@@ -946,12 +867,16 @@ module Girl
|
|
946
867
|
|
947
868
|
src_id = data[ 8, 8 ].unpack( 'Q>' ).first
|
948
869
|
|
949
|
-
|
950
|
-
return unless
|
870
|
+
dst_id = tund_info[ :dst_ids ][ src_id ]
|
871
|
+
return unless dst_id
|
951
872
|
|
952
|
-
|
953
|
-
return
|
954
|
-
|
873
|
+
dst = tund_info[ :dsts ][ dst_id ]
|
874
|
+
return unless dst
|
875
|
+
|
876
|
+
dst_info = @dst_infos[ dst ]
|
877
|
+
return unless dst_info
|
878
|
+
|
879
|
+
return if ( pack_id <= dst_info[ :continue_src_pack_id ] ) || dst_info[ :pieces ].include?( pack_id )
|
955
880
|
|
956
881
|
data = data[ 16..-1 ]
|
957
882
|
# puts "debug2 got pack #{ pack_id }"
|
@@ -963,25 +888,26 @@ module Girl
|
|
963
888
|
end
|
964
889
|
|
965
890
|
# 放进写前,跳号放碎片缓存
|
966
|
-
if pack_id -
|
967
|
-
while
|
968
|
-
data <<
|
891
|
+
if pack_id - dst_info[ :continue_src_pack_id ] == 1
|
892
|
+
while dst_info[ :pieces ].include?( pack_id + 1 )
|
893
|
+
data << dst_info[ :pieces ].delete( pack_id + 1 )
|
969
894
|
pack_id += 1
|
970
895
|
end
|
971
896
|
|
972
|
-
|
973
|
-
|
974
|
-
|
897
|
+
dst_info[ :continue_src_pack_id ] = pack_id
|
898
|
+
dst_info[ :last_continue_at ] = now
|
899
|
+
dst_info[ :wbuff ] << data
|
900
|
+
add_write( dst )
|
975
901
|
# puts "debug2 update continue src pack #{ pack_id }"
|
976
902
|
|
977
|
-
#
|
978
|
-
if
|
903
|
+
# 若对面已关闭,且流量正好收全,关闭dst
|
904
|
+
if dst_info[ :is_src_closed ] && ( pack_id == dst_info[ :biggest_src_pack_id ] )
|
979
905
|
# puts "debug1 4-2. tund recv traffic -> src closed and all traffic received ? -> close dst after write"
|
980
|
-
set_is_closing(
|
981
|
-
return
|
906
|
+
set_is_closing( dst )
|
982
907
|
end
|
983
|
-
|
984
|
-
|
908
|
+
elsif !dst_info[ :pieces ].include?( pack_id )
|
909
|
+
dst_info[ :pieces ][ pack_id ] = data
|
910
|
+
dst_info[ :last_continue_at ] = now
|
985
911
|
end
|
986
912
|
end
|
987
913
|
|