p2p2 0.15.1 → 0.16.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/lib/p2p2/custom.rb +12 -0
- data/lib/p2p2/head.rb +12 -11
- data/lib/p2p2/p1.rb +62 -900
- data/lib/p2p2/p1_custom.rb +7 -0
- data/lib/p2p2/p1_worker.rb +915 -0
- data/lib/p2p2/p2.rb +62 -968
- data/lib/p2p2/p2_custom.rb +7 -0
- data/lib/p2p2/p2_worker.rb +963 -0
- data/lib/p2p2/p2pd.rb +79 -94
- data/lib/p2p2/p2pd_worker.rb +78 -0
- data/lib/p2p2/version.rb +1 -1
- data/p2p2.gemspec +6 -1
- metadata +8 -3
- data/lib/p2p2/hex.rb +0 -15
data/lib/p2p2/p2.rb
CHANGED
@@ -1,1018 +1,112 @@
|
|
1
|
+
require 'json'
|
1
2
|
require 'p2p2/head'
|
2
|
-
require 'p2p2/
|
3
|
+
require 'p2p2/p2_custom'
|
4
|
+
require 'p2p2/p2_worker'
|
3
5
|
require 'p2p2/version'
|
4
6
|
require 'socket'
|
5
7
|
|
6
8
|
##
|
7
9
|
# P2p2::P2 - 内网里的任意应用,访问另一个内网里的应用服务端。p2端。
|
8
10
|
#
|
9
|
-
# 两套关闭
|
10
|
-
# ========
|
11
|
-
#
|
12
|
-
# 1-1. app.close -> ext.is_shadow_closed ? no -> send fin1 loop
|
13
|
-
# 1-2. recv got_fin1 -> break loop
|
14
|
-
# 1-3. recv fin2 -> send got_fin2 -> del ext
|
15
|
-
#
|
16
|
-
# 2-1. recv fin1 -> send got_fin1 -> ext.is_shadow_closed = true
|
17
|
-
# 2-2. all sent && ext.biggest_shadow_pack_id == ext.continue_shadow_pack_id -> add closing app
|
18
|
-
# 2-3. app.close -> ext.is_shadow_closed ? yes -> del ext -> loop send fin2
|
19
|
-
# 2-4. recv got_fin2 -> break loop
|
20
|
-
#
|
21
11
|
module P2p2
|
22
12
|
class P2
|
23
13
|
|
24
|
-
|
25
|
-
|
26
|
-
|
27
|
-
# appd_host 代理地址 不限制访问:'0.0.0.0',或者只允许本地访问:'127.0.0.1'
|
28
|
-
# appd_port 代理端口
|
29
|
-
# title 约定的房间名
|
30
|
-
# app_chunk_dir 文件缓存目录,缓存app来不及写的流量
|
31
|
-
# p2_chunk_dir 文件缓存目录,缓存p2来不及写的流量
|
32
|
-
#
|
33
|
-
def initialize( p2pd_host, p2pd_port, appd_host, appd_port, title, app_chunk_dir = '/tmp', p2_chunk_dir = '/tmp' )
|
34
|
-
@p2pd_sockaddr = Socket.sockaddr_in( p2pd_port, p2pd_host )
|
35
|
-
@appd_sockaddr = Socket.sockaddr_in( appd_port, appd_host )
|
36
|
-
@title = title
|
37
|
-
@app_chunk_dir = app_chunk_dir
|
38
|
-
@p2_chunk_dir = p2_chunk_dir
|
39
|
-
@hex = P2p2::Hex.new
|
40
|
-
@mutex = Mutex.new
|
41
|
-
@reads = []
|
42
|
-
@writes = []
|
43
|
-
@closings = []
|
44
|
-
@roles = {} # sock => :ctlr / :appd / :app / :p2
|
45
|
-
@infos = {} # sock => {}
|
46
|
-
@socks = {} # sock => sock_id
|
47
|
-
@sock_ids = {} # sock_id => sock
|
48
|
-
|
49
|
-
ctlr, ctlw = IO.pipe
|
50
|
-
@ctlw = ctlw
|
51
|
-
@roles[ ctlr ] = :ctlr
|
52
|
-
@reads << ctlr
|
53
|
-
end
|
54
|
-
|
55
|
-
def looping
|
56
|
-
puts 'looping'
|
57
|
-
|
58
|
-
new_appd
|
59
|
-
|
60
|
-
loop do
|
61
|
-
rs, ws = IO.select( @reads, @writes )
|
62
|
-
|
63
|
-
@mutex.synchronize do
|
64
|
-
rs.each do | sock |
|
65
|
-
case @roles[ sock ]
|
66
|
-
when :ctlr
|
67
|
-
read_ctlr( sock )
|
68
|
-
when :appd
|
69
|
-
read_appd( sock )
|
70
|
-
when :app
|
71
|
-
read_app( sock )
|
72
|
-
when :p2
|
73
|
-
read_p2( sock )
|
74
|
-
end
|
75
|
-
end
|
76
|
-
|
77
|
-
ws.each do | sock |
|
78
|
-
case @roles[ sock ]
|
79
|
-
when :app
|
80
|
-
write_app( sock )
|
81
|
-
when :p2
|
82
|
-
write_p2( sock )
|
83
|
-
end
|
84
|
-
end
|
85
|
-
end
|
86
|
-
end
|
87
|
-
rescue Interrupt => e
|
88
|
-
puts e.class
|
89
|
-
quit!
|
90
|
-
end
|
91
|
-
|
92
|
-
def quit!
|
93
|
-
if @p2 && !@p2.closed? && @p2_info[ :p1_addr ]
|
94
|
-
ctlmsg = [ 0, P2_FIN ].pack( 'Q>C' )
|
95
|
-
send_pack( @p2, ctlmsg, @p2_info[ :p1_addr ] )
|
96
|
-
end
|
97
|
-
|
98
|
-
exit
|
99
|
-
end
|
100
|
-
|
101
|
-
private
|
102
|
-
|
103
|
-
##
|
104
|
-
# read ctlr
|
105
|
-
#
|
106
|
-
def read_ctlr( ctlr )
|
107
|
-
case ctlr.read( 1 ).unpack( 'C' ).first
|
108
|
-
when CTL_CLOSE
|
109
|
-
sock_id = ctlr.read( 8 ).unpack( 'Q>' ).first
|
110
|
-
sock = @sock_ids[ sock_id ]
|
111
|
-
|
112
|
-
if sock
|
113
|
-
add_closing( sock )
|
114
|
-
end
|
115
|
-
when CTL_RESUME
|
116
|
-
sock_id = ctlr.read( 8 ).unpack( 'Q>' ).first
|
117
|
-
sock = @sock_ids[ sock_id ]
|
118
|
-
|
119
|
-
if sock
|
120
|
-
add_write( sock )
|
121
|
-
end
|
122
|
-
end
|
123
|
-
end
|
124
|
-
|
125
|
-
##
|
126
|
-
# read appd
|
127
|
-
#
|
128
|
-
def read_appd( appd )
|
129
|
-
begin
|
130
|
-
app, _ = appd.accept_nonblock
|
131
|
-
rescue IO::WaitReadable, Errno::EINTR
|
132
|
-
return
|
133
|
-
end
|
134
|
-
|
135
|
-
if @p2.nil? || @p2.closed?
|
136
|
-
new_p2
|
137
|
-
end
|
138
|
-
|
139
|
-
app_id = @hex.gen_random_num
|
140
|
-
@roles[ app ] = :app
|
141
|
-
@infos[ app ] = {
|
142
|
-
id: app_id,
|
143
|
-
p2: @p2
|
144
|
-
}
|
145
|
-
@socks[ app ] = app_id
|
146
|
-
@sock_ids[ app_id ] = app
|
147
|
-
|
148
|
-
@p2_info[ :waitings ][ app_id ] = []
|
149
|
-
@p2_info[ :app_exts ][ app_id ] = {
|
150
|
-
app: app,
|
151
|
-
created_at: Time.new,
|
152
|
-
last_recv_at: nil, # 上一次收到流量的时间
|
153
|
-
wbuff: '', # 写前缓存
|
154
|
-
cache: '', # 块读出缓存
|
155
|
-
chunks: [], # 块队列,写前达到块大小时结一个块 filename
|
156
|
-
spring: 0, # 块后缀,结块时,如果块队列不为空,则自增,为空,则置为0
|
157
|
-
wmems: {}, # 写后缓存 pack_id => data
|
158
|
-
send_ats: {}, # 上一次发出时间 pack_id => send_at
|
159
|
-
biggest_pack_id: 0, # 发到几
|
160
|
-
continue_shadow_pack_id: 0, # 收到几
|
161
|
-
pieces: {}, # 跳号包 shadow_pack_id => data
|
162
|
-
is_shadow_closed: false, # 对面是否已关闭
|
163
|
-
biggest_shadow_pack_id: 0, # 对面发到几
|
164
|
-
completed_pack_id: 0, # 完成到几(对面收到几)
|
165
|
-
last_traffic_at: nil # 收到有效流量,或者发出流量的时间戳
|
166
|
-
}
|
167
|
-
|
168
|
-
add_read( app )
|
169
|
-
loop_send_a_new_app( app )
|
170
|
-
end
|
171
|
-
|
172
|
-
##
|
173
|
-
# read app
|
174
|
-
#
|
175
|
-
def read_app( app )
|
176
|
-
begin
|
177
|
-
data = app.read_nonblock( PACK_SIZE )
|
178
|
-
rescue IO::WaitReadable, Errno::EINTR
|
179
|
-
return
|
180
|
-
rescue Exception => e
|
181
|
-
add_closing( app )
|
182
|
-
return
|
183
|
-
end
|
184
|
-
|
185
|
-
info = @infos[ app ]
|
186
|
-
p2 = info[ :p2 ]
|
187
|
-
|
188
|
-
if p2.closed?
|
189
|
-
add_closing( app )
|
190
|
-
return
|
191
|
-
end
|
192
|
-
|
193
|
-
app_id = @socks[ app ]
|
194
|
-
p2_info = @infos[ p2 ]
|
195
|
-
shadow_id = p2_info[ :app_ids ][ app_id ]
|
196
|
-
|
197
|
-
if p2_info[ :p1_addr ].nil? || shadow_id.nil?
|
198
|
-
p2_info[ :waitings ][ app_id ] << data
|
199
|
-
return
|
200
|
-
end
|
201
|
-
|
202
|
-
p2_info[ :wbuffs ] << [ app_id, data ]
|
203
|
-
|
204
|
-
if p2_info[ :wbuffs ].size >= WBUFFS_LIMIT
|
205
|
-
p2_id = @socks[ p2 ]
|
206
|
-
spring = p2_info[ :chunks ].size > 0 ? ( p2_info[ :spring ] + 1 ) : 0
|
207
|
-
filename = "#{ p2_id }.#{ spring }"
|
208
|
-
chunk_path = File.join( @p2_chunk_dir, filename )
|
209
|
-
IO.binwrite( chunk_path, p2_info[ :wbuffs ].map{ | app_id, data | "#{ [ app_id, data.bytesize ].pack( 'Q>n' ) }#{ data }" }.join )
|
210
|
-
p2_info[ :chunks ] << filename
|
211
|
-
p2_info[ :spring ] = spring
|
212
|
-
p2_info[ :wbuffs ].clear
|
213
|
-
end
|
214
|
-
|
215
|
-
unless p2_info[ :paused ]
|
216
|
-
add_write( p2 )
|
217
|
-
end
|
218
|
-
end
|
219
|
-
|
220
|
-
##
|
221
|
-
# read p2
|
222
|
-
#
|
223
|
-
def read_p2( p2 )
|
224
|
-
data, addrinfo, rflags, *controls = p2.recvmsg
|
225
|
-
sockaddr = addrinfo.to_sockaddr
|
226
|
-
now = Time.new
|
227
|
-
info = @infos[ p2 ]
|
228
|
-
shadow_id = data[ 0, 8 ].unpack( 'Q>' ).first
|
229
|
-
|
230
|
-
if shadow_id == 0
|
231
|
-
case data[ 8 ].unpack( 'C' ).first
|
232
|
-
when PEER_ADDR
|
233
|
-
return if info[ :peer_addr ] || ( sockaddr != @p2pd_sockaddr )
|
234
|
-
|
235
|
-
info[ :peer_addr ] = data[ 9..-1 ]
|
236
|
-
# puts "debug peer addr #{ Addrinfo.new( info[ :peer_addr ] ).ip_unpack.inspect } #{ Time.new }"
|
237
|
-
loop_punch_peer( p2 )
|
238
|
-
when HEARTBEAT
|
239
|
-
return if info[ :p1_addr ] || ( sockaddr != info[ :peer_addr ] )
|
240
|
-
|
241
|
-
info[ :p1_addr ] = sockaddr
|
242
|
-
# puts "debug p1 addr #{ Addrinfo.new( info[ :p1_addr ] ).ip_unpack.inspect } #{ Time.new }"
|
243
|
-
info[ :last_traffic_at ] = now
|
244
|
-
loop_send_heartbeat( p2 )
|
245
|
-
loop_check_expire( p2 )
|
246
|
-
loop_send_status( p2 )
|
247
|
-
when PAIRED
|
248
|
-
return if sockaddr != info[ :p1_addr ]
|
249
|
-
|
250
|
-
app_id, shadow_id = data[ 9, 16 ].unpack( 'Q>Q>' )
|
251
|
-
return if info[ :app_ids ].include?( app_id )
|
252
|
-
|
253
|
-
# puts "debug got PAIRED #{ app_id } #{ shadow_id } #{ Time.new }"
|
254
|
-
info[ :app_ids ][ app_id ] = shadow_id
|
255
|
-
info[ :shadow_ids ][ shadow_id ] = app_id
|
256
|
-
buffs = info[ :waitings ][ app_id ]
|
257
|
-
|
258
|
-
if buffs.any?
|
259
|
-
# puts "debug move #{ buffs.size } waiting buffs to wbuffs #{ Time.new } p#{ Process.pid }"
|
260
|
-
|
261
|
-
buffs.each do | buff |
|
262
|
-
info[ :wbuffs ] << [ app_id, buff ]
|
263
|
-
end
|
264
|
-
|
265
|
-
buffs.clear
|
266
|
-
add_write( p2 )
|
267
|
-
end
|
268
|
-
when SHADOW_STATUS
|
269
|
-
return if sockaddr != info[ :p1_addr ]
|
270
|
-
|
271
|
-
shadow_id, biggest_shadow_pack_id, continue_app_pack_id = data[ 9, 24 ].unpack( 'Q>Q>Q>' )
|
272
|
-
app_id = info[ :shadow_ids ][ shadow_id ]
|
273
|
-
return unless app_id
|
274
|
-
|
275
|
-
ext = info[ :app_exts ][ app_id ]
|
276
|
-
return unless ext
|
277
|
-
|
278
|
-
# 更新对面发到几
|
279
|
-
if biggest_shadow_pack_id > ext[ :biggest_shadow_pack_id ]
|
280
|
-
ext[ :biggest_shadow_pack_id ] = biggest_shadow_pack_id
|
281
|
-
end
|
282
|
-
|
283
|
-
# 更新对面收到几,释放写后
|
284
|
-
if continue_app_pack_id > ext[ :completed_pack_id ]
|
285
|
-
pack_ids = ext[ :wmems ].keys.select { | pack_id | pack_id <= continue_app_pack_id }
|
286
|
-
|
287
|
-
pack_ids.each do | pack_id |
|
288
|
-
ext[ :wmems ].delete( pack_id )
|
289
|
-
ext[ :send_ats ].delete( pack_id )
|
290
|
-
end
|
291
|
-
|
292
|
-
ext[ :completed_pack_id ] = continue_app_pack_id
|
293
|
-
end
|
294
|
-
|
295
|
-
if ext[ :is_shadow_closed ] && ( ext[ :biggest_shadow_pack_id ] == ext[ :continue_shadow_pack_id ] )
|
296
|
-
add_write( ext[ :app ] )
|
297
|
-
return
|
298
|
-
end
|
299
|
-
|
300
|
-
# 发miss
|
301
|
-
if !ext[ :app ].closed? && ( ext[ :continue_shadow_pack_id ] < ext[ :biggest_shadow_pack_id ] )
|
302
|
-
ranges = []
|
303
|
-
curr_pack_id = ext[ :continue_shadow_pack_id ] + 1
|
304
|
-
|
305
|
-
ext[ :pieces ].keys.sort.each do | pack_id |
|
306
|
-
if pack_id > curr_pack_id
|
307
|
-
ranges << [ curr_pack_id, pack_id - 1 ]
|
308
|
-
end
|
309
|
-
|
310
|
-
curr_pack_id = pack_id + 1
|
311
|
-
end
|
312
|
-
|
313
|
-
if curr_pack_id <= ext[ :biggest_shadow_pack_id ]
|
314
|
-
ranges << [ curr_pack_id, ext[ :biggest_shadow_pack_id ] ]
|
315
|
-
end
|
316
|
-
|
317
|
-
pack_count = 0
|
318
|
-
# puts "debug #{ ext[ :continue_shadow_pack_id ] }/#{ ext[ :biggest_shadow_pack_id ] } send MISS #{ ranges.size }"
|
319
|
-
ranges.each do | pack_id_begin, pack_id_end |
|
320
|
-
if pack_count >= BREAK_SEND_MISS
|
321
|
-
puts "break send miss at #{ pack_id_begin } #{ Time.new }"
|
322
|
-
break
|
323
|
-
end
|
324
|
-
|
325
|
-
ctlmsg = [
|
326
|
-
0,
|
327
|
-
MISS,
|
328
|
-
shadow_id,
|
329
|
-
pack_id_begin,
|
330
|
-
pack_id_end
|
331
|
-
].pack( 'Q>CQ>Q>Q>' )
|
332
|
-
|
333
|
-
send_pack( p2, ctlmsg, info[ :p1_addr ] )
|
334
|
-
pack_count += ( pack_id_end - pack_id_begin + 1 )
|
335
|
-
end
|
336
|
-
end
|
337
|
-
when MISS
|
338
|
-
return if sockaddr != info[ :p1_addr ]
|
339
|
-
|
340
|
-
app_id, pack_id_begin, pack_id_end = data[ 9, 24 ].unpack( 'Q>Q>Q>' )
|
341
|
-
ext = info[ :app_exts ][ app_id ]
|
342
|
-
return unless ext
|
343
|
-
|
344
|
-
( pack_id_begin..pack_id_end ).each do | pack_id |
|
345
|
-
send_at = ext[ :send_ats ][ pack_id ]
|
346
|
-
|
347
|
-
if send_at
|
348
|
-
break if now - send_at < STATUS_INTERVAL
|
349
|
-
|
350
|
-
info[ :resendings ] << [ app_id, pack_id ]
|
351
|
-
end
|
352
|
-
end
|
353
|
-
|
354
|
-
add_write( p2 )
|
355
|
-
when FIN1
|
356
|
-
return if sockaddr != info[ :p1_addr ]
|
357
|
-
|
358
|
-
shadow_id = data[ 9, 8 ].unpack( 'Q>' ).first
|
359
|
-
ctlmsg = [
|
360
|
-
0,
|
361
|
-
GOT_FIN1,
|
362
|
-
shadow_id
|
363
|
-
].pack( 'Q>CQ>' )
|
364
|
-
|
365
|
-
# puts "debug 2-1. recv fin1 -> send got_fin1 -> ext.is_shadow_closed = true #{ shadow_id } #{ Time.new }"
|
366
|
-
send_pack( p2, ctlmsg, info[ :p1_addr ] )
|
367
|
-
|
368
|
-
app_id = info[ :shadow_ids ][ shadow_id ]
|
369
|
-
return unless app_id
|
370
|
-
|
371
|
-
ext = info[ :app_exts ][ app_id ]
|
372
|
-
return unless ext
|
373
|
-
|
374
|
-
ext[ :is_shadow_closed ] = true
|
375
|
-
when GOT_FIN1
|
376
|
-
return if sockaddr != info[ :p1_addr ]
|
377
|
-
|
378
|
-
# puts "debug 1-2. recv got_fin1 -> break loop #{ Time.new }"
|
379
|
-
app_id = data[ 9, 8 ].unpack( 'Q>' ).first
|
380
|
-
info[ :fin1s ].delete( app_id )
|
381
|
-
when FIN2
|
382
|
-
return if sockaddr != info[ :p1_addr ]
|
383
|
-
|
384
|
-
# puts "debug 1-3. recv fin2 -> send got_fin2 -> del ext #{ Time.new }"
|
385
|
-
shadow_id = data[ 9, 8 ].unpack( 'Q>' ).first
|
386
|
-
ctlmsg = [
|
387
|
-
0,
|
388
|
-
GOT_FIN2,
|
389
|
-
shadow_id
|
390
|
-
].pack( 'Q>CQ>' )
|
391
|
-
|
392
|
-
send_pack( p2, ctlmsg, info[ :p1_addr ] )
|
393
|
-
|
394
|
-
app_id = info[ :shadow_ids ][ shadow_id ]
|
395
|
-
return unless app_id
|
396
|
-
|
397
|
-
del_app_ext( info, app_id )
|
398
|
-
when GOT_FIN2
|
399
|
-
return if sockaddr != info[ :p1_addr ]
|
400
|
-
|
401
|
-
# puts "debug 2-4. recv got_fin2 -> break loop #{ Time.new }"
|
402
|
-
app_id = data[ 9, 8 ].unpack( 'Q>' ).first
|
403
|
-
info[ :fin2s ].delete( app_id )
|
404
|
-
when P1_FIN
|
405
|
-
return if sockaddr != info[ :p1_addr ]
|
406
|
-
puts "recv p1 fin #{ Time.new }"
|
407
|
-
add_closing( p2 )
|
408
|
-
end
|
409
|
-
|
410
|
-
return
|
411
|
-
end
|
412
|
-
|
413
|
-
return if sockaddr != info[ :p1_addr ]
|
414
|
-
|
415
|
-
app_id = info[ :shadow_ids ][ shadow_id ]
|
416
|
-
return unless app_id
|
417
|
-
|
418
|
-
ext = info[ :app_exts ][ app_id ]
|
419
|
-
return if ext.nil? || ext[ :app ].closed?
|
420
|
-
|
421
|
-
pack_id = data[ 8, 8 ].unpack( 'Q>' ).first
|
422
|
-
return if ( pack_id <= ext[ :continue_shadow_pack_id ] ) || ext[ :pieces ].include?( pack_id )
|
423
|
-
|
424
|
-
data = data[ 16..-1 ]
|
425
|
-
|
426
|
-
# 解混淆
|
427
|
-
if pack_id == 1
|
428
|
-
data = @hex.decode( data )
|
429
|
-
end
|
430
|
-
|
431
|
-
# 放进shadow的写前缓存,跳号放碎片缓存
|
432
|
-
if pack_id - ext[ :continue_shadow_pack_id ] == 1
|
433
|
-
while ext[ :pieces ].include?( pack_id + 1 )
|
434
|
-
data << ext[ :pieces ].delete( pack_id + 1 )
|
435
|
-
pack_id += 1
|
436
|
-
end
|
437
|
-
|
438
|
-
ext[ :continue_shadow_pack_id ] = pack_id
|
439
|
-
ext[ :wbuff ] << data
|
440
|
-
|
441
|
-
if ext[ :wbuff ].bytesize >= CHUNK_SIZE
|
442
|
-
spring = ext[ :chunks ].size > 0 ? ( ext[ :spring ] + 1 ) : 0
|
443
|
-
filename = "#{ app_id }.#{ spring }"
|
444
|
-
chunk_path = File.join( @app_chunk_dir, filename )
|
445
|
-
IO.binwrite( chunk_path, ext[ :wbuff ] )
|
446
|
-
ext[ :chunks ] << filename
|
447
|
-
ext[ :spring ] = spring
|
448
|
-
ext[ :wbuff ].clear
|
449
|
-
end
|
450
|
-
|
451
|
-
add_write( ext[ :app ] )
|
452
|
-
ext[ :last_traffic_at ] = now
|
453
|
-
info[ :last_traffic_at ] = now
|
454
|
-
else
|
455
|
-
ext[ :pieces ][ pack_id ] = data
|
456
|
-
end
|
457
|
-
|
458
|
-
ext[ :last_recv_at ] = now
|
459
|
-
end
|
460
|
-
|
461
|
-
##
|
462
|
-
# write app
|
463
|
-
#
|
464
|
-
def write_app( app )
|
465
|
-
if @closings.include?( app )
|
466
|
-
close_app( app )
|
467
|
-
return
|
468
|
-
end
|
469
|
-
|
470
|
-
info = @infos[ app ]
|
471
|
-
p2 = info[ :p2 ]
|
472
|
-
|
473
|
-
if p2.closed?
|
474
|
-
add_closing( app )
|
475
|
-
return
|
476
|
-
end
|
477
|
-
|
478
|
-
p2_info = @infos[ p2 ]
|
479
|
-
app_id = @socks[ app ]
|
480
|
-
ext = p2_info[ :app_exts ][ app_id ]
|
481
|
-
|
482
|
-
# 取写前
|
483
|
-
data = ext[ :cache ]
|
484
|
-
from = :cache
|
485
|
-
|
486
|
-
if data.empty?
|
487
|
-
if ext[ :chunks ].any?
|
488
|
-
path = File.join( @app_chunk_dir, ext[ :chunks ].shift )
|
489
|
-
|
490
|
-
begin
|
491
|
-
data = IO.binread( path )
|
492
|
-
File.delete( path )
|
493
|
-
rescue Errno::ENOENT
|
494
|
-
add_closing( app )
|
495
|
-
return
|
496
|
-
end
|
497
|
-
else
|
498
|
-
data = ext[ :wbuff ]
|
499
|
-
from = :wbuff
|
500
|
-
end
|
501
|
-
end
|
502
|
-
|
503
|
-
if data.empty?
|
504
|
-
if ext[ :is_shadow_closed ] && ( ext[ :biggest_shadow_pack_id ] == ext[ :continue_shadow_pack_id ] )
|
505
|
-
# puts "debug 2-2. all sent && ext.biggest_shadow_pack_id == ext.continue_shadow_pack_id -> add closing app #{ Time.new }"
|
506
|
-
add_closing( app )
|
507
|
-
return
|
508
|
-
end
|
509
|
-
|
510
|
-
@writes.delete( app )
|
511
|
-
return
|
512
|
-
end
|
513
|
-
|
514
|
-
begin
|
515
|
-
written = app.write_nonblock( data )
|
516
|
-
rescue IO::WaitWritable, Errno::EINTR => e
|
517
|
-
ext[ from ] = data
|
518
|
-
return
|
519
|
-
rescue Exception => e
|
520
|
-
add_closing( app )
|
521
|
-
return
|
522
|
-
end
|
523
|
-
|
524
|
-
data = data[ written..-1 ]
|
525
|
-
ext[ from ] = data
|
526
|
-
end
|
527
|
-
|
528
|
-
##
|
529
|
-
# write p2
|
530
|
-
#
|
531
|
-
def write_p2( p2 )
|
532
|
-
if @closings.include?( p2 )
|
533
|
-
close_p2( p2 )
|
534
|
-
return
|
14
|
+
def initialize( config_path = nil )
|
15
|
+
unless config_path
|
16
|
+
config_path = File.expand_path( '../p2p2.conf.json', __FILE__ )
|
535
17
|
end
|
536
18
|
|
537
|
-
|
538
|
-
|
539
|
-
|
540
|
-
# 重传
|
541
|
-
while info[ :resendings ].any?
|
542
|
-
app_id, pack_id = info[ :resendings ].shift
|
543
|
-
ext = info[ :app_exts ][ app_id ]
|
544
|
-
|
545
|
-
if ext
|
546
|
-
pack = ext[ :wmems ][ pack_id ]
|
547
|
-
|
548
|
-
if pack
|
549
|
-
send_pack( p2, pack, info[ :p1_addr ] )
|
550
|
-
ext[ :last_traffic_at ] = now
|
551
|
-
info[ :last_traffic_at ] = now
|
552
|
-
return
|
553
|
-
end
|
554
|
-
end
|
19
|
+
unless File.exist?( config_path )
|
20
|
+
raise "missing config file #{ config_path }"
|
555
21
|
end
|
556
22
|
|
557
|
-
|
558
|
-
|
559
|
-
|
560
|
-
|
561
|
-
|
562
|
-
|
23
|
+
conf = JSON.parse( IO.binread( config_path ), symbolize_names: true )
|
24
|
+
p2pd_host = conf[ :p2pd_host ]
|
25
|
+
p2pd_port = conf[ :p2pd_port ]
|
26
|
+
room = conf[ :room ]
|
27
|
+
sdwd_host = conf[ :sdwd_host ]
|
28
|
+
sdwd_port = conf[ :sdwd_port ]
|
29
|
+
p2_tmp_dir = conf[ :p2_tmp_dir ]
|
563
30
|
|
564
|
-
|
565
|
-
|
31
|
+
unless p2pd_host
|
32
|
+
raise "missing p2pd host"
|
566
33
|
end
|
567
34
|
|
568
|
-
|
569
|
-
|
570
|
-
app_id, data = info[ :caches ].shift
|
571
|
-
elsif info[ :chunks ].any?
|
572
|
-
path = File.join( @p2_chunk_dir, info[ :chunks ].shift )
|
573
|
-
|
574
|
-
begin
|
575
|
-
data = IO.binread( path )
|
576
|
-
File.delete( path )
|
577
|
-
rescue Errno::ENOENT
|
578
|
-
add_closing( p2 )
|
579
|
-
return
|
580
|
-
end
|
581
|
-
|
582
|
-
caches = []
|
583
|
-
|
584
|
-
until data.empty?
|
585
|
-
app_id, pack_size = data[ 0, 10 ].unpack( 'Q>n' )
|
586
|
-
caches << [ app_id, data[ 10, pack_size ] ]
|
587
|
-
data = data[ ( 10 + pack_size )..-1 ]
|
588
|
-
end
|
589
|
-
|
590
|
-
app_id, data = caches.shift
|
591
|
-
info[ :caches ] = caches
|
592
|
-
elsif info[ :wbuffs ].any?
|
593
|
-
app_id, data = info[ :wbuffs ].shift
|
594
|
-
else
|
595
|
-
@writes.delete( p2 )
|
596
|
-
return
|
35
|
+
unless room
|
36
|
+
raise "missing room"
|
597
37
|
end
|
598
38
|
|
599
|
-
|
600
|
-
|
601
|
-
if ext
|
602
|
-
pack_id = ext[ :biggest_pack_id ] + 1
|
603
|
-
|
604
|
-
if pack_id == 1
|
605
|
-
data = @hex.encode( data )
|
606
|
-
end
|
607
|
-
|
608
|
-
pack = "#{ [ app_id, pack_id ].pack( 'Q>Q>' ) }#{ data }"
|
609
|
-
send_pack( p2, pack, info[ :p1_addr ] )
|
610
|
-
ext[ :biggest_pack_id ] = pack_id
|
611
|
-
ext[ :wmems ][ pack_id ] = pack
|
612
|
-
ext[ :send_ats ][ pack_id ] = now
|
613
|
-
ext[ :last_traffic_at ] = now
|
614
|
-
info[ :last_traffic_at ] = now
|
39
|
+
unless p2pd_port
|
40
|
+
p2pd_port = 2020
|
615
41
|
end
|
616
|
-
end
|
617
|
-
|
618
|
-
def new_appd
|
619
|
-
appd = Socket.new( Socket::AF_INET, Socket::SOCK_STREAM, 0 )
|
620
|
-
appd.setsockopt( Socket::SOL_SOCKET, Socket::SO_REUSEADDR, 1 )
|
621
|
-
appd.setsockopt( Socket::SOL_TCP, Socket::TCP_NODELAY, 1 )
|
622
|
-
appd.bind( @appd_sockaddr )
|
623
|
-
appd.listen( 511 )
|
624
|
-
|
625
|
-
@roles[ appd ] = :appd
|
626
|
-
add_read( appd )
|
627
|
-
end
|
628
|
-
|
629
|
-
def new_p2
|
630
|
-
p2 = Socket.new( Socket::AF_INET, Socket::SOCK_DGRAM, 0 )
|
631
|
-
p2.setsockopt( Socket::SOL_SOCKET, Socket::SO_REUSEADDR, 1 )
|
632
|
-
p2.bind( Socket.sockaddr_in( 0, '0.0.0.0' ) )
|
633
|
-
p2_id = @hex.gen_random_num
|
634
|
-
p2_info = {
|
635
|
-
id: p2_id,
|
636
|
-
waitings: {}, # 还没连上p1,或者还没配上shadow,暂存流量 app_id => buffs[]
|
637
|
-
wbuffs: [], # 写前缓存 [ app_id, data ]
|
638
|
-
caches: [], # 块读出缓存 [ app_id, data ]
|
639
|
-
chunks: [], # 块队列 filename
|
640
|
-
spring: 0, # 块后缀,结块时,如果块队列不为空,则自增,为空,则置为0
|
641
|
-
peer_addr: nil, # 对面地址,连发心跳包打洞,离p2pd近的一方通常会撞死几个直到对面出来
|
642
|
-
p1_addr: nil, # p1地址
|
643
|
-
app_exts: {}, # 传输相关 app_id => {}
|
644
|
-
app_ids: {}, # app_id => shadow_id
|
645
|
-
shadow_ids: {}, # shadow_id => app_id
|
646
|
-
fin1s: [], # fin1: app已关闭,等待对面收完流量 app_id
|
647
|
-
fin2s: [], # fin2: 流量已收完 app_id
|
648
|
-
paused: false, # 是否暂停写
|
649
|
-
resendings: [], # 重传队列 [ app_id, pack_id ]
|
650
|
-
last_traffic_at: nil # 收到有效流量,或者发出流量的时间戳
|
651
|
-
}
|
652
|
-
|
653
|
-
@p2 = p2
|
654
|
-
@p2_info = p2_info
|
655
|
-
@roles[ p2 ] = :p2
|
656
|
-
@infos[ p2 ] = p2_info
|
657
|
-
@socks[ p2 ] = p2_id
|
658
|
-
@sock_ids[ p2_id ] = p2
|
659
42
|
|
660
|
-
|
661
|
-
|
662
|
-
loop_send_char( p2 )
|
663
|
-
end
|
664
|
-
|
665
|
-
def loop_send_char( p2 )
|
666
|
-
Thread.new do
|
667
|
-
is_timeout = true
|
668
|
-
|
669
|
-
20.times do
|
670
|
-
sleep HEARTBEAT_INTERVAL
|
671
|
-
|
672
|
-
if p2.closed?
|
673
|
-
is_timeout = false
|
674
|
-
break
|
675
|
-
end
|
676
|
-
|
677
|
-
p2_info = @infos[ p2 ]
|
678
|
-
|
679
|
-
if p2_info[ :peer_addr ]
|
680
|
-
is_timeout = false
|
681
|
-
break
|
682
|
-
end
|
683
|
-
|
684
|
-
@mutex.synchronize do
|
685
|
-
send_pack( p2, [ rand( 128 ) ].pack( 'C' ), @p2pd_sockaddr )
|
686
|
-
end
|
687
|
-
end
|
688
|
-
|
689
|
-
if is_timeout
|
690
|
-
@mutex.synchronize do
|
691
|
-
p2_id = @socks[ p2 ]
|
692
|
-
@ctlw.write( [ CTL_CLOSE, p2_id ].pack( 'CQ>' ) )
|
693
|
-
end
|
694
|
-
end
|
43
|
+
unless sdwd_host
|
44
|
+
sdwd_host = '0.0.0.0'
|
695
45
|
end
|
696
|
-
end
|
697
|
-
|
698
|
-
def loop_punch_peer( p2 )
|
699
|
-
Thread.new do
|
700
|
-
20.times do
|
701
|
-
break if p2.closed?
|
702
|
-
|
703
|
-
p2_info = @infos[ p2 ]
|
704
46
|
|
705
|
-
|
706
|
-
|
707
|
-
end
|
708
|
-
|
709
|
-
sleep STATUS_INTERVAL
|
710
|
-
end
|
711
|
-
|
712
|
-
if !p2.closed?
|
713
|
-
p2_info = @infos[ p2 ]
|
714
|
-
|
715
|
-
unless p2_info[ :p1_addr ]
|
716
|
-
@mutex.synchronize do
|
717
|
-
p2_id = @socks[ p2 ]
|
718
|
-
@ctlw.write( [ CTL_CLOSE, p2_id ].pack( 'CQ>' ) )
|
719
|
-
end
|
720
|
-
end
|
721
|
-
end
|
47
|
+
unless sdwd_port
|
48
|
+
sdwd_port = 2222
|
722
49
|
end
|
723
|
-
end
|
724
50
|
|
725
|
-
|
726
|
-
|
727
|
-
loop do
|
728
|
-
sleep HEARTBEAT_INTERVAL
|
729
|
-
break if p2.closed?
|
730
|
-
|
731
|
-
@mutex.synchronize do
|
732
|
-
p2_info = @infos[ p2 ]
|
733
|
-
send_heartbeat( p2, p2_info[ :p1_addr ] )
|
734
|
-
end
|
735
|
-
end
|
51
|
+
unless p2_tmp_dir
|
52
|
+
p2_tmp_dir = '/tmp/p2p2.p2'
|
736
53
|
end
|
737
|
-
end
|
738
|
-
|
739
|
-
def loop_check_expire( p2 )
|
740
|
-
Thread.new do
|
741
|
-
loop do
|
742
|
-
sleep 60
|
743
|
-
break if p2.closed?
|
744
|
-
|
745
|
-
now = Time.new
|
746
|
-
p2_info = @infos[ p2 ]
|
747
|
-
|
748
|
-
if now - p2_info[ :last_traffic_at ] > EXPIRE_AFTER
|
749
|
-
@mutex.synchronize do
|
750
|
-
p2_id = @socks[ p2 ]
|
751
|
-
# puts "debug ctlw close p2 #{ p2_id } #{ Time.new } p#{ Process.pid }"
|
752
|
-
@ctlw.write( [ CTL_CLOSE, p2_id ].pack( 'CQ>' ) )
|
753
|
-
end
|
754
|
-
|
755
|
-
break
|
756
|
-
end
|
757
|
-
|
758
|
-
exts = p2_info[ :app_exts ].select{ | _, ext | now - ext[ :created_at ] > 5 }
|
759
54
|
|
760
|
-
|
761
|
-
|
762
|
-
exts.each do | app_id, ext |
|
763
|
-
if ext[ :last_recv_at ].nil? || ( now - ext[ :last_recv_at ] > EXPIRE_AFTER )
|
764
|
-
# puts "debug ctlw close app #{ app_id } #{ Time.new } p#{ Process.pid }"
|
765
|
-
@ctlw.write( [ CTL_CLOSE, app_id ].pack( 'CQ>' ) )
|
766
|
-
end
|
767
|
-
end
|
768
|
-
end
|
769
|
-
end
|
770
|
-
end
|
55
|
+
unless File.exist?( p2_tmp_dir )
|
56
|
+
Dir.mkdir( p2_tmp_dir )
|
771
57
|
end
|
772
|
-
end
|
773
|
-
|
774
|
-
def loop_send_status( p2 )
|
775
|
-
Thread.new do
|
776
|
-
loop do
|
777
|
-
sleep STATUS_INTERVAL
|
778
|
-
|
779
|
-
if p2.closed?
|
780
|
-
# puts "debug p2 is closed, break send status loop #{ Time.new }"
|
781
|
-
break
|
782
|
-
end
|
783
58
|
|
784
|
-
|
59
|
+
src_chunk_dir = File.join( p2_tmp_dir, 'src.chunk' )
|
785
60
|
|
786
|
-
|
787
|
-
|
788
|
-
now = Time.new
|
789
|
-
|
790
|
-
p2_info[ :app_exts ].each do | app_id, ext |
|
791
|
-
if ext[ :last_traffic_at ] && ( now - ext[ :last_traffic_at ] < SEND_STATUS_UNTIL )
|
792
|
-
ctlmsg = [
|
793
|
-
0,
|
794
|
-
APP_STATUS,
|
795
|
-
app_id,
|
796
|
-
ext[ :biggest_pack_id ],
|
797
|
-
ext[ :continue_shadow_pack_id ]
|
798
|
-
].pack( 'Q>CQ>Q>Q>' )
|
799
|
-
|
800
|
-
send_pack( p2, ctlmsg, p2_info[ :p1_addr ] )
|
801
|
-
end
|
802
|
-
end
|
803
|
-
end
|
804
|
-
end
|
805
|
-
|
806
|
-
if p2_info[ :paused ] && ( p2_info[ :app_exts ].map{ | _, ext | ext[ :wmems ].size }.sum < RESUME_BELOW )
|
807
|
-
@mutex.synchronize do
|
808
|
-
p2_id = @socks[ p2 ]
|
809
|
-
puts "ctlw resume #{ p2_id } #{ Time.new }"
|
810
|
-
@ctlw.write( [ CTL_RESUME, p2_id ].pack( 'CQ>' ) )
|
811
|
-
p2_info[ :paused ] = false
|
812
|
-
end
|
813
|
-
end
|
814
|
-
end
|
61
|
+
unless Dir.exist?( src_chunk_dir )
|
62
|
+
Dir.mkdir( src_chunk_dir )
|
815
63
|
end
|
816
|
-
end
|
817
64
|
|
818
|
-
|
819
|
-
Thread.new do
|
820
|
-
100.times do
|
821
|
-
break if p2.closed?
|
65
|
+
tun_chunk_dir = File.join( p2_tmp_dir, 'tun.chunk' )
|
822
66
|
|
823
|
-
|
824
|
-
|
825
|
-
|
826
|
-
unless p2_info[ :fin1s ].include?( app_id )
|
827
|
-
# puts "debug break send fin1 loop #{ Time.new }"
|
828
|
-
break
|
829
|
-
end
|
830
|
-
|
831
|
-
@mutex.synchronize do
|
832
|
-
ctlmsg = [
|
833
|
-
0,
|
834
|
-
FIN1,
|
835
|
-
app_id
|
836
|
-
].pack( 'Q>CQ>' )
|
837
|
-
|
838
|
-
# puts "debug send FIN1 #{ app_id } #{ Time.new }"
|
839
|
-
send_pack( p2, ctlmsg, p2_info[ :p1_addr ] )
|
840
|
-
end
|
841
|
-
|
842
|
-
sleep 1
|
843
|
-
end
|
67
|
+
unless Dir.exist?( tun_chunk_dir )
|
68
|
+
Dir.mkdir( tun_chunk_dir )
|
844
69
|
end
|
845
|
-
end
|
846
70
|
|
847
|
-
|
848
|
-
|
849
|
-
|
850
|
-
|
71
|
+
title = "p2p2 p2 #{ P2p2::VERSION }"
|
72
|
+
puts title
|
73
|
+
puts "p2pd host #{ p2pd_host }"
|
74
|
+
puts "p2pd port #{ p2pd_port }"
|
75
|
+
puts "room #{ room }"
|
76
|
+
puts "sdwd host #{ sdwd_host }"
|
77
|
+
puts "sdwd port #{ sdwd_port }"
|
78
|
+
puts "p2 tmp dir #{ p2_tmp_dir }"
|
79
|
+
puts "src chunk dir #{ src_chunk_dir }"
|
80
|
+
puts "tun chunk dir #{ tun_chunk_dir }"
|
851
81
|
|
852
|
-
|
853
|
-
|
854
|
-
|
855
|
-
unless p2_info[ :fin2s ].include?( app_id )
|
856
|
-
# puts "debug break send fin2 loop #{ Time.new }"
|
857
|
-
break
|
858
|
-
end
|
82
|
+
if RUBY_PLATFORM.include?( 'linux' )
|
83
|
+
$0 = title
|
859
84
|
|
860
|
-
|
861
|
-
|
862
|
-
|
863
|
-
FIN2,
|
864
|
-
app_id
|
865
|
-
].pack( 'Q>CQ>' )
|
85
|
+
pid = fork do
|
86
|
+
$0 = 'p2p2 p2 worker'
|
87
|
+
worker = P2p2::P2Worker.new( p2pd_host, p2pd_port, room, sdwd_host, sdwd_port, src_chunk_dir, tun_chunk_dir )
|
866
88
|
|
867
|
-
|
868
|
-
|
89
|
+
Signal.trap( :TERM ) do
|
90
|
+
puts 'exit'
|
91
|
+
worker.quit!
|
869
92
|
end
|
870
93
|
|
871
|
-
|
872
|
-
end
|
873
|
-
end
|
874
|
-
end
|
875
|
-
|
876
|
-
def loop_send_a_new_app( app )
|
877
|
-
Thread.new do
|
878
|
-
100.times do
|
879
|
-
break if app.closed?
|
880
|
-
|
881
|
-
app_info = @infos[ app ]
|
882
|
-
p2 = app_info[ :p2 ]
|
883
|
-
break if p2.closed?
|
884
|
-
|
885
|
-
p2_info = @infos[ p2 ]
|
886
|
-
|
887
|
-
if p2_info[ :p1_addr ]
|
888
|
-
app_id = @socks[ app ]
|
889
|
-
shadow_id = p2_info[ :app_ids ][ app_id ]
|
890
|
-
|
891
|
-
if shadow_id
|
892
|
-
# puts "debug break a new app loop #{ Time.new }"
|
893
|
-
break
|
894
|
-
end
|
895
|
-
|
896
|
-
@mutex.synchronize do
|
897
|
-
ctlmsg = [ 0, A_NEW_APP, app_id ].pack( 'Q>CQ>' )
|
898
|
-
# puts "debug send a new app #{ Time.new }"
|
899
|
-
send_pack( p2, ctlmsg, p2_info[ :p1_addr ] )
|
900
|
-
end
|
901
|
-
end
|
902
|
-
|
903
|
-
sleep 1
|
904
|
-
end
|
905
|
-
end
|
906
|
-
end
|
907
|
-
|
908
|
-
def send_heartbeat( p2, target_addr )
|
909
|
-
ctlmsg = [ 0, HEARTBEAT, rand( 128 ) ].pack( 'Q>CC' )
|
910
|
-
send_pack( p2, ctlmsg, target_addr )
|
911
|
-
end
|
912
|
-
|
913
|
-
def send_pack( sock, data, target_sockaddr )
|
914
|
-
begin
|
915
|
-
sock.sendmsg( data, 0, target_sockaddr )
|
916
|
-
rescue IO::WaitWritable, Errno::EINTR => e
|
917
|
-
puts "sendmsg #{ e.class } #{ Time.new }"
|
918
|
-
end
|
919
|
-
end
|
920
|
-
|
921
|
-
def add_read( sock )
|
922
|
-
return if sock.closed? || @reads.include?( sock )
|
923
|
-
|
924
|
-
@reads << sock
|
925
|
-
end
|
926
|
-
|
927
|
-
def add_write( sock, data = nil )
|
928
|
-
return if sock.closed? || @writes.include?( sock )
|
929
|
-
|
930
|
-
@writes << sock
|
931
|
-
end
|
932
|
-
|
933
|
-
def add_closing( sock )
|
934
|
-
return if sock.closed? || @closings.include?( sock )
|
935
|
-
|
936
|
-
@reads.delete( sock )
|
937
|
-
@closings << sock
|
938
|
-
add_write( sock )
|
939
|
-
end
|
940
|
-
|
941
|
-
def close_p2( p2 )
|
942
|
-
info = close_sock( p2 )
|
943
|
-
|
944
|
-
info[ :chunks ].each do | filename |
|
945
|
-
begin
|
946
|
-
File.delete( File.join( @p2_chunk_dir, filename ) )
|
947
|
-
rescue Errno::ENOENT
|
94
|
+
worker.looping
|
948
95
|
end
|
949
|
-
end
|
950
|
-
|
951
|
-
info[ :app_exts ].each{ | _, ext | add_closing( ext[ :app ] ) }
|
952
|
-
end
|
953
96
|
|
954
|
-
|
955
|
-
|
956
|
-
p2 = info[ :p2 ]
|
957
|
-
return if p2.closed?
|
97
|
+
Signal.trap( :TERM ) do
|
98
|
+
puts 'trap TERM'
|
958
99
|
|
959
|
-
app_id = info[ :id ]
|
960
|
-
p2_info = @infos[ p2 ]
|
961
|
-
ext = p2_info[ :app_exts ][ app_id ]
|
962
|
-
return unless ext
|
963
|
-
|
964
|
-
ext[ :chunks ].each do | filename |
|
965
|
-
begin
|
966
|
-
File.delete( File.join( @app_chunk_dir, filename ) )
|
967
|
-
rescue Errno::ENOENT
|
968
|
-
end
|
969
|
-
end
|
970
|
-
|
971
|
-
if ext[ :is_shadow_closed ]
|
972
|
-
del_app_ext( p2_info, app_id )
|
973
|
-
|
974
|
-
unless p2_info[ :fin2s ].include?( app_id )
|
975
|
-
# puts "debug 2-3. app.close -> ext.is_shadow_closed ? yes -> del ext -> loop send fin2 #{ Time.new }"
|
976
|
-
p2_info[ :fin2s ] << app_id
|
977
|
-
loop_send_fin2( p2, app_id )
|
978
|
-
end
|
979
|
-
elsif !p2_info[ :fin1s ].include?( app_id )
|
980
|
-
# puts "debug 1-1. app.close -> ext.is_shadow_closed ? no -> send fin1 loop #{ Time.new }"
|
981
|
-
p2_info[ :fin1s ] << app_id
|
982
|
-
loop_send_fin1( p2, app_id )
|
983
|
-
end
|
984
|
-
end
|
985
|
-
|
986
|
-
def close_sock( sock )
|
987
|
-
sock.close
|
988
|
-
@reads.delete( sock )
|
989
|
-
@writes.delete( sock )
|
990
|
-
@closings.delete( sock )
|
991
|
-
@roles.delete( sock )
|
992
|
-
info = @infos.delete( sock )
|
993
|
-
sock_id = @socks.delete( sock )
|
994
|
-
@sock_ids.delete( sock_id )
|
995
|
-
|
996
|
-
info
|
997
|
-
end
|
998
|
-
|
999
|
-
def del_app_ext( p2_info, app_id )
|
1000
|
-
p2_info[ :waitings ].delete( app_id )
|
1001
|
-
ext = p2_info[ :app_exts ].delete( app_id )
|
1002
|
-
|
1003
|
-
if ext
|
1004
|
-
ext[ :chunks ].each do | filename |
|
1005
100
|
begin
|
1006
|
-
|
1007
|
-
rescue Errno::
|
101
|
+
Process.kill( :TERM, pid )
|
102
|
+
rescue Errno::ESRCH => e
|
103
|
+
puts e.class
|
1008
104
|
end
|
1009
105
|
end
|
1010
|
-
end
|
1011
106
|
|
1012
|
-
|
1013
|
-
|
1014
|
-
|
1015
|
-
p2_info[ :shadow_ids ].delete( shadow_id )
|
107
|
+
Process.waitall
|
108
|
+
else
|
109
|
+
P2p2::P2Worker.new( p2pd_host, p2pd_port, room, sdwd_host, sdwd_port, src_chunk_dir, tun_chunk_dir ).looping
|
1016
110
|
end
|
1017
111
|
end
|
1018
112
|
|