girl 0.86.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/lib/girl/head.rb +29 -29
- data/lib/girl/proxy.rb +5 -37
- data/lib/girl/proxy_worker.rb +355 -463
- data/lib/girl/proxyd.rb +23 -24
- data/lib/girl/proxyd_worker.rb +338 -414
- data/lib/girl/version.rb +1 -1
- metadata +2 -2
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
|
|
@@ -146,37 +154,70 @@ module Girl
|
|
146
154
|
loop do
|
147
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
|
211
|
+
end
|
212
|
+
|
213
|
+
if ignore_dsts.any?
|
214
|
+
@pause_dsts -= ignore_dsts
|
178
215
|
end
|
179
216
|
end
|
217
|
+
|
218
|
+
if need_trigger
|
219
|
+
next_tick
|
220
|
+
end
|
180
221
|
end
|
181
222
|
end
|
182
223
|
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 )
|
513
|
+
|
514
|
+
if dst
|
515
|
+
dst_info = @dst_infos.delete( dst )
|
508
516
|
|
509
|
-
|
510
|
-
|
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
553
|
|
563
|
-
if
|
564
|
-
|
565
|
-
|
566
|
-
|
567
|
-
begin
|
568
|
-
data = dst_info[ :cache ] = IO.binread( path )
|
569
|
-
File.delete( path )
|
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,46 +698,50 @@ 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
|
870
|
-
curr_pack_id =
|
742
|
+
curr_pack_id = dst_info[ :continue_src_pack_id ] + 1
|
871
743
|
|
872
|
-
|
744
|
+
dst_info[ :pieces ].keys.sort.each do | pack_id |
|
873
745
|
if pack_id > curr_pack_id
|
874
746
|
ranges << [ curr_pack_id, pack_id - 1 ]
|
875
747
|
|
@@ -887,57 +759,104 @@ module Girl
|
|
887
759
|
ranges << [ curr_pack_id, relay_src_pack_id ]
|
888
760
|
end
|
889
761
|
|
890
|
-
# puts "debug1 continue/relay #{
|
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>' ) }
|
891
765
|
|
892
|
-
|
893
|
-
|
894
|
-
|
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
|
895
771
|
end
|
896
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
|
787
|
+
|
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
|
804
|
+
end
|
805
|
+
|
806
|
+
idx += 2
|
807
|
+
end
|
897
808
|
when MISS
|
898
|
-
|
809
|
+
dst_id, pack_id_begin, pack_id_end = data[ 9, 18 ].unpack( 'nQ>Q>' )
|
899
810
|
|
900
|
-
|
811
|
+
dst = tund_info[ :dsts ][ dst_id ]
|
812
|
+
return unless dst
|
901
813
|
|
902
|
-
|
903
|
-
return unless
|
814
|
+
dst_info = @dst_infos[ dst ]
|
815
|
+
return unless dst_info
|
904
816
|
|
905
817
|
( pack_id_begin..pack_id_end ).each do | pack_id |
|
906
|
-
send_at =
|
818
|
+
send_at = dst_info[ :send_ats ][ pack_id ]
|
907
819
|
|
908
820
|
if send_at
|
909
821
|
break if now - send_at < CHECK_STATUS_INTERVAL
|
910
|
-
tund_info[ :
|
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
|
911
829
|
end
|
912
830
|
end
|
913
|
-
|
914
|
-
add_write( tund )
|
915
831
|
when FIN1
|
916
832
|
src_id, biggest_src_pack_id, continue_dst_pack_id = data[ 9, 24 ].unpack( 'Q>Q>Q>' )
|
917
833
|
|
918
|
-
|
919
|
-
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
|
920
839
|
|
921
|
-
|
922
|
-
return unless
|
840
|
+
dst_info = @dst_infos[ dst ]
|
841
|
+
return unless dst_info
|
923
842
|
|
924
843
|
# puts "debug1 got fin1 #{ src_id } biggest src pack #{ biggest_src_pack_id } completed dst pack #{ continue_dst_pack_id }"
|
925
|
-
|
926
|
-
|
927
|
-
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 )
|
928
847
|
|
929
|
-
if biggest_src_pack_id ==
|
848
|
+
if biggest_src_pack_id == dst_info[ :continue_src_pack_id ]
|
930
849
|
# puts "debug1 4-1. tund recv fin1 -> all traffic received ? -> close dst after write"
|
931
|
-
set_is_closing(
|
850
|
+
set_is_closing( dst )
|
932
851
|
end
|
933
852
|
when FIN2
|
934
853
|
src_id = data[ 9, 8 ].unpack( 'Q>' ).first
|
935
854
|
|
936
|
-
|
937
|
-
return unless
|
855
|
+
dst_id = tund_info[ :dst_ids ][ src_id ]
|
856
|
+
return unless dst_id
|
938
857
|
|
939
858
|
# puts "debug1 3-2. tund recv fin2 -> del dst ext"
|
940
|
-
del_dst_ext(
|
859
|
+
del_dst_ext( tund_info, dst_id )
|
941
860
|
when TUN_FIN
|
942
861
|
puts "p#{ Process.pid } #{ Time.new } recv tun fin"
|
943
862
|
set_is_closing( tund )
|
@@ -948,12 +867,16 @@ module Girl
|
|
948
867
|
|
949
868
|
src_id = data[ 8, 8 ].unpack( 'Q>' ).first
|
950
869
|
|
951
|
-
|
952
|
-
return unless
|
870
|
+
dst_id = tund_info[ :dst_ids ][ src_id ]
|
871
|
+
return unless dst_id
|
953
872
|
|
954
|
-
|
955
|
-
return
|
956
|
-
|
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 )
|
957
880
|
|
958
881
|
data = data[ 16..-1 ]
|
959
882
|
# puts "debug2 got pack #{ pack_id }"
|
@@ -965,25 +888,26 @@ module Girl
|
|
965
888
|
end
|
966
889
|
|
967
890
|
# 放进写前,跳号放碎片缓存
|
968
|
-
if pack_id -
|
969
|
-
while
|
970
|
-
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 )
|
971
894
|
pack_id += 1
|
972
895
|
end
|
973
896
|
|
974
|
-
|
975
|
-
|
976
|
-
|
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 )
|
977
901
|
# puts "debug2 update continue src pack #{ pack_id }"
|
978
902
|
|
979
|
-
#
|
980
|
-
if
|
903
|
+
# 若对面已关闭,且流量正好收全,关闭dst
|
904
|
+
if dst_info[ :is_src_closed ] && ( pack_id == dst_info[ :biggest_src_pack_id ] )
|
981
905
|
# puts "debug1 4-2. tund recv traffic -> src closed and all traffic received ? -> close dst after write"
|
982
|
-
set_is_closing(
|
983
|
-
return
|
906
|
+
set_is_closing( dst )
|
984
907
|
end
|
985
|
-
|
986
|
-
|
908
|
+
elsif !dst_info[ :pieces ].include?( pack_id )
|
909
|
+
dst_info[ :pieces ][ pack_id ] = data
|
910
|
+
dst_info[ :last_continue_at ] = now
|
987
911
|
end
|
988
912
|
end
|
989
913
|
|