p2p2 0.22.0 → 0.27.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.rb +3 -3
- data/lib/p2p2/concurrent_hash.rb +36 -0
- data/lib/p2p2/head.rb +11 -29
- data/lib/p2p2/p1.rb +57 -114
- data/lib/p2p2/p1_worker.rb +727 -927
- data/lib/p2p2/p2.rb +57 -114
- data/lib/p2p2/p2_worker.rb +682 -980
- data/lib/p2p2/paird.rb +42 -0
- data/lib/p2p2/paird_worker.rb +158 -0
- data/lib/p2p2/version.rb +3 -3
- data/p2p2.gemspec +32 -34
- metadata +10 -13
- data/lib/p2p2/custom.rb +0 -12
- data/lib/p2p2/p1_custom.rb +0 -7
- data/lib/p2p2/p2_custom.rb +0 -7
- data/lib/p2p2/p2pd.rb +0 -120
- data/lib/p2p2/p2pd_worker.rb +0 -78
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 707396700d8514b51e69c74e0afe93349dd068cd2748ed3b298e0e41efe8fc8f
|
4
|
+
data.tar.gz: f5d8449949b2dc30d3b2013b529938bca812e2a683ae334fb5e9c076f449e484
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: a87a15f1bf1281bb961f2b87d88b6a1ae33e3dc85bc37eb955ba1eb6ae9ec407c9333d7ea3891599f9f8dd061e6cb1a854f246a9edfe13060886fdd4c1cbc4b7
|
7
|
+
data.tar.gz: 0b56adf766ed041c1aa87d927c0e71e04cf58264da61531c39c1e3d27fa7b25e2710561d613c6bd10be33cd914c5cd45de32f78dc1e0e33247bbdade309c1621
|
data/lib/p2p2.rb
CHANGED
@@ -1,3 +1,3 @@
|
|
1
|
-
require 'p2p2/p1'
|
2
|
-
require 'p2p2/p2'
|
3
|
-
require 'p2p2/p2pd'
|
1
|
+
require 'p2p2/p1'
|
2
|
+
require 'p2p2/p2'
|
3
|
+
require 'p2p2/p2pd'
|
@@ -0,0 +1,36 @@
|
|
1
|
+
module P2p2
|
2
|
+
class ConcurrentHash < Hash
|
3
|
+
def initialize
|
4
|
+
super
|
5
|
+
@mutex = Mutex.new
|
6
|
+
end
|
7
|
+
|
8
|
+
def []( *args )
|
9
|
+
@mutex.synchronize { super }
|
10
|
+
end
|
11
|
+
|
12
|
+
def []=( *args )
|
13
|
+
@mutex.synchronize { super }
|
14
|
+
end
|
15
|
+
|
16
|
+
def clear( *args )
|
17
|
+
@mutex.synchronize { super }
|
18
|
+
end
|
19
|
+
|
20
|
+
def delete( *args )
|
21
|
+
@mutex.synchronize { super }
|
22
|
+
end
|
23
|
+
|
24
|
+
def each( *args )
|
25
|
+
@mutex.synchronize { super }
|
26
|
+
end
|
27
|
+
|
28
|
+
def include?( *args )
|
29
|
+
@mutex.synchronize { super }
|
30
|
+
end
|
31
|
+
|
32
|
+
def select( *args )
|
33
|
+
@mutex.synchronize { super }
|
34
|
+
end
|
35
|
+
end
|
36
|
+
end
|
data/lib/p2p2/head.rb
CHANGED
@@ -1,29 +1,11 @@
|
|
1
|
-
module P2p2
|
2
|
-
|
3
|
-
|
4
|
-
|
5
|
-
|
6
|
-
|
7
|
-
|
8
|
-
|
9
|
-
|
10
|
-
|
11
|
-
|
12
|
-
BREAK_SEND_MISS = 10_000 # miss包个数上限,达到上限忽略要后面的段,可控碎片缓存
|
13
|
-
CONFUSE_UNTIL = 5 # 混淆前几个包
|
14
|
-
HEARTBEAT_INTERVAL = 5 # 心跳间隔
|
15
|
-
UPDATE_ROOM_INTERVAL = 60 # 刷新房间间隔
|
16
|
-
PEER_ADDR = 1
|
17
|
-
HEARTBEAT = 2
|
18
|
-
A_NEW_SOURCE = 3
|
19
|
-
PAIRED = 4
|
20
|
-
DEST_STATUS = 5
|
21
|
-
SOURCE_STATUS = 6
|
22
|
-
MISS = 7
|
23
|
-
FIN1 = 8
|
24
|
-
GOT_FIN1 = 9
|
25
|
-
FIN2 = 10
|
26
|
-
GOT_FIN2 = 11
|
27
|
-
TUND_FIN = 12
|
28
|
-
TUN_FIN = 13
|
29
|
-
end
|
1
|
+
module P2p2
|
2
|
+
READ_SIZE = 1024 * 1024 # 一次读多少
|
3
|
+
WBUFF_LIMIT = 50 * 1024 * 1024 # 写前上限,超过上限暂停读
|
4
|
+
RESUME_BELOW = WBUFF_LIMIT / 2 # 降到多少以下恢复读
|
5
|
+
RENEW_CTL_INTERVAL = 10 # p1心跳间隔,部分光猫udp端口映射过期时间只有10秒
|
6
|
+
CHECK_STATE_INTERVAL = 1 # 检查过期,恢复读间隔
|
7
|
+
EXPIRE_AFTER = 86400 # 多久没有新流量,过期
|
8
|
+
ROOM_TITLE_LIMIT = 16 # 房间名称字数
|
9
|
+
PUNCH_LIMIT = 5 # p2p重试次数
|
10
|
+
TO = ':' # 找房间前缀
|
11
|
+
end
|
data/lib/p2p2/p1.rb
CHANGED
@@ -1,114 +1,57 @@
|
|
1
|
-
require 'json'
|
2
|
-
require 'p2p2/
|
3
|
-
require 'p2p2/
|
4
|
-
require 'p2p2/p1_worker'
|
5
|
-
require 'p2p2/version'
|
6
|
-
require 'socket'
|
7
|
-
|
8
|
-
##
|
9
|
-
# P2p2::P1 -
|
10
|
-
#
|
11
|
-
module P2p2
|
12
|
-
class P1
|
13
|
-
|
14
|
-
def initialize( config_path = nil )
|
15
|
-
unless config_path
|
16
|
-
config_path = File.expand_path( '../p2p2.conf.json', __FILE__ )
|
17
|
-
end
|
18
|
-
|
19
|
-
unless File.exist?( config_path )
|
20
|
-
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
-
|
25
|
-
|
26
|
-
|
27
|
-
|
28
|
-
|
29
|
-
|
30
|
-
|
31
|
-
unless
|
32
|
-
|
33
|
-
end
|
34
|
-
|
35
|
-
unless
|
36
|
-
|
37
|
-
end
|
38
|
-
|
39
|
-
unless
|
40
|
-
|
41
|
-
end
|
42
|
-
|
43
|
-
|
44
|
-
|
45
|
-
|
46
|
-
|
47
|
-
|
48
|
-
|
49
|
-
|
50
|
-
|
51
|
-
|
52
|
-
|
53
|
-
|
54
|
-
|
55
|
-
|
56
|
-
|
57
|
-
|
58
|
-
|
59
|
-
dst_chunk_dir = File.join( p1_tmp_dir, 'dst.chunk' )
|
60
|
-
|
61
|
-
unless Dir.exist?( dst_chunk_dir )
|
62
|
-
Dir.mkdir( dst_chunk_dir )
|
63
|
-
end
|
64
|
-
|
65
|
-
tund_chunk_dir = File.join( p1_tmp_dir, 'tund.chunk' )
|
66
|
-
|
67
|
-
unless Dir.exist?( tund_chunk_dir )
|
68
|
-
Dir.mkdir( tund_chunk_dir )
|
69
|
-
end
|
70
|
-
|
71
|
-
title = "p2p2 p1 #{ P2p2::VERSION }"
|
72
|
-
puts title
|
73
|
-
puts "p2pd host #{ p2pd_host }"
|
74
|
-
puts "p2pd port #{ p2pd_port }"
|
75
|
-
puts "room #{ room }"
|
76
|
-
puts "appd host #{ appd_host }"
|
77
|
-
puts "appd port #{ appd_port }"
|
78
|
-
puts "p1 tmp dir #{ p1_tmp_dir }"
|
79
|
-
puts "dst chunk dir #{ dst_chunk_dir }"
|
80
|
-
puts "tund chunk dir #{ tund_chunk_dir }"
|
81
|
-
|
82
|
-
if RUBY_PLATFORM.include?( 'linux' )
|
83
|
-
$0 = title
|
84
|
-
|
85
|
-
pid = fork do
|
86
|
-
$0 = 'p2p2 p1 worker'
|
87
|
-
worker = P2p2::P1Worker.new( p2pd_host, p2pd_port, room, appd_host, appd_port, dst_chunk_dir, tund_chunk_dir )
|
88
|
-
|
89
|
-
Signal.trap( :TERM ) do
|
90
|
-
puts 'exit'
|
91
|
-
worker.quit!
|
92
|
-
end
|
93
|
-
|
94
|
-
worker.looping
|
95
|
-
end
|
96
|
-
|
97
|
-
Signal.trap( :TERM ) do
|
98
|
-
puts 'trap TERM'
|
99
|
-
|
100
|
-
begin
|
101
|
-
Process.kill( :TERM, pid )
|
102
|
-
rescue Errno::ESRCH => e
|
103
|
-
puts e.class
|
104
|
-
end
|
105
|
-
end
|
106
|
-
|
107
|
-
Process.waitall
|
108
|
-
else
|
109
|
-
P2p2::P1Worker.new( p2pd_host, p2pd_port, room, appd_host, appd_port, dst_chunk_dir, tund_chunk_dir ).looping
|
110
|
-
end
|
111
|
-
end
|
112
|
-
|
113
|
-
end
|
114
|
-
end
|
1
|
+
require 'json'
|
2
|
+
require 'p2p2/concurrent_hash'
|
3
|
+
require 'p2p2/head'
|
4
|
+
require 'p2p2/p1_worker'
|
5
|
+
require 'p2p2/version'
|
6
|
+
require 'socket'
|
7
|
+
|
8
|
+
##
|
9
|
+
# P2p2::P1 - p1端
|
10
|
+
#
|
11
|
+
module P2p2
|
12
|
+
class P1
|
13
|
+
|
14
|
+
def initialize( config_path = nil )
|
15
|
+
unless config_path then
|
16
|
+
config_path = File.expand_path( '../p2p2.conf.json', __FILE__ )
|
17
|
+
end
|
18
|
+
|
19
|
+
raise "missing config file #{ config_path }" unless File.exist?( config_path )
|
20
|
+
|
21
|
+
conf = JSON.parse( IO.binread( config_path ), symbolize_names: true )
|
22
|
+
paird_host = conf[ :paird_host ]
|
23
|
+
paird_port = conf[ :paird_port ]
|
24
|
+
room = conf[ :room ]
|
25
|
+
appd_host = conf[ :appd_host ]
|
26
|
+
appd_port = conf[ :appd_port ]
|
27
|
+
|
28
|
+
raise 'missing paird host' unless paird_host
|
29
|
+
raise 'missing room' unless room
|
30
|
+
|
31
|
+
unless paird_port then
|
32
|
+
paird_port = 4040
|
33
|
+
end
|
34
|
+
|
35
|
+
unless appd_host then
|
36
|
+
appd_host = '127.0.0.1'
|
37
|
+
end
|
38
|
+
|
39
|
+
unless appd_port then
|
40
|
+
appd_port = 22
|
41
|
+
end
|
42
|
+
|
43
|
+
puts "p2p2 p1 #{ P2p2::VERSION }"
|
44
|
+
puts "paird #{ paird_host } #{ paird_port } room #{ room } appd #{ appd_host } #{ appd_port }"
|
45
|
+
|
46
|
+
worker = P2p2::P1Worker.new( paird_host, paird_port, room, appd_host, appd_port )
|
47
|
+
|
48
|
+
Signal.trap( :TERM ) do
|
49
|
+
puts 'exit'
|
50
|
+
worker.quit!
|
51
|
+
end
|
52
|
+
|
53
|
+
worker.looping
|
54
|
+
end
|
55
|
+
|
56
|
+
end
|
57
|
+
end
|
data/lib/p2p2/p1_worker.rb
CHANGED
@@ -1,927 +1,727 @@
|
|
1
|
-
module P2p2
|
2
|
-
class P1Worker
|
3
|
-
|
4
|
-
##
|
5
|
-
# initialize
|
6
|
-
#
|
7
|
-
def initialize(
|
8
|
-
@
|
9
|
-
@
|
10
|
-
@
|
11
|
-
@
|
12
|
-
@
|
13
|
-
@
|
14
|
-
@
|
15
|
-
@
|
16
|
-
@
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
-
|
25
|
-
|
26
|
-
|
27
|
-
|
28
|
-
|
29
|
-
|
30
|
-
|
31
|
-
|
32
|
-
|
33
|
-
|
34
|
-
|
35
|
-
|
36
|
-
|
37
|
-
|
38
|
-
|
39
|
-
|
40
|
-
|
41
|
-
|
42
|
-
|
43
|
-
|
44
|
-
|
45
|
-
|
46
|
-
|
47
|
-
|
48
|
-
|
49
|
-
|
50
|
-
|
51
|
-
|
52
|
-
|
53
|
-
|
54
|
-
|
55
|
-
|
56
|
-
|
57
|
-
|
58
|
-
|
59
|
-
|
60
|
-
|
61
|
-
|
62
|
-
|
63
|
-
|
64
|
-
|
65
|
-
|
66
|
-
|
67
|
-
|
68
|
-
|
69
|
-
|
70
|
-
|
71
|
-
|
72
|
-
|
73
|
-
|
74
|
-
|
75
|
-
|
76
|
-
|
77
|
-
|
78
|
-
|
79
|
-
|
80
|
-
|
81
|
-
|
82
|
-
#
|
83
|
-
|
84
|
-
|
85
|
-
|
86
|
-
|
87
|
-
|
88
|
-
|
89
|
-
|
90
|
-
|
91
|
-
|
92
|
-
|
93
|
-
|
94
|
-
|
95
|
-
|
96
|
-
|
97
|
-
|
98
|
-
|
99
|
-
|
100
|
-
|
101
|
-
|
102
|
-
|
103
|
-
|
104
|
-
|
105
|
-
|
106
|
-
|
107
|
-
|
108
|
-
|
109
|
-
|
110
|
-
|
111
|
-
|
112
|
-
|
113
|
-
|
114
|
-
|
115
|
-
|
116
|
-
|
117
|
-
|
118
|
-
|
119
|
-
|
120
|
-
|
121
|
-
|
122
|
-
|
123
|
-
|
124
|
-
|
125
|
-
|
126
|
-
|
127
|
-
|
128
|
-
|
129
|
-
|
130
|
-
|
131
|
-
|
132
|
-
|
133
|
-
|
134
|
-
|
135
|
-
|
136
|
-
|
137
|
-
|
138
|
-
|
139
|
-
|
140
|
-
|
141
|
-
|
142
|
-
|
143
|
-
|
144
|
-
|
145
|
-
|
146
|
-
|
147
|
-
|
148
|
-
|
149
|
-
|
150
|
-
|
151
|
-
|
152
|
-
|
153
|
-
|
154
|
-
|
155
|
-
|
156
|
-
|
157
|
-
|
158
|
-
|
159
|
-
|
160
|
-
|
161
|
-
|
162
|
-
|
163
|
-
|
164
|
-
|
165
|
-
|
166
|
-
|
167
|
-
|
168
|
-
|
169
|
-
|
170
|
-
|
171
|
-
|
172
|
-
|
173
|
-
|
174
|
-
|
175
|
-
|
176
|
-
|
177
|
-
|
178
|
-
|
179
|
-
|
180
|
-
|
181
|
-
|
182
|
-
|
183
|
-
|
184
|
-
|
185
|
-
|
186
|
-
|
187
|
-
|
188
|
-
|
189
|
-
|
190
|
-
|
191
|
-
|
192
|
-
|
193
|
-
|
194
|
-
|
195
|
-
|
196
|
-
|
197
|
-
|
198
|
-
|
199
|
-
|
200
|
-
|
201
|
-
|
202
|
-
|
203
|
-
|
204
|
-
|
205
|
-
|
206
|
-
|
207
|
-
|
208
|
-
|
209
|
-
|
210
|
-
#
|
211
|
-
|
212
|
-
|
213
|
-
|
214
|
-
|
215
|
-
|
216
|
-
|
217
|
-
|
218
|
-
|
219
|
-
|
220
|
-
|
221
|
-
|
222
|
-
|
223
|
-
|
224
|
-
|
225
|
-
|
226
|
-
|
227
|
-
|
228
|
-
|
229
|
-
|
230
|
-
|
231
|
-
|
232
|
-
|
233
|
-
|
234
|
-
|
235
|
-
|
236
|
-
|
237
|
-
|
238
|
-
|
239
|
-
|
240
|
-
|
241
|
-
|
242
|
-
|
243
|
-
|
244
|
-
|
245
|
-
|
246
|
-
|
247
|
-
|
248
|
-
|
249
|
-
#
|
250
|
-
|
251
|
-
|
252
|
-
|
253
|
-
|
254
|
-
|
255
|
-
|
256
|
-
if
|
257
|
-
puts "
|
258
|
-
|
259
|
-
|
260
|
-
|
261
|
-
|
262
|
-
|
263
|
-
|
264
|
-
|
265
|
-
|
266
|
-
|
267
|
-
|
268
|
-
|
269
|
-
|
270
|
-
|
271
|
-
|
272
|
-
|
273
|
-
|
274
|
-
|
275
|
-
|
276
|
-
|
277
|
-
|
278
|
-
|
279
|
-
|
280
|
-
|
281
|
-
|
282
|
-
|
283
|
-
|
284
|
-
|
285
|
-
|
286
|
-
|
287
|
-
|
288
|
-
|
289
|
-
|
290
|
-
|
291
|
-
|
292
|
-
|
293
|
-
|
294
|
-
|
295
|
-
|
296
|
-
|
297
|
-
|
298
|
-
|
299
|
-
|
300
|
-
|
301
|
-
|
302
|
-
|
303
|
-
|
304
|
-
|
305
|
-
|
306
|
-
|
307
|
-
|
308
|
-
|
309
|
-
|
310
|
-
|
311
|
-
|
312
|
-
|
313
|
-
|
314
|
-
|
315
|
-
|
316
|
-
|
317
|
-
|
318
|
-
|
319
|
-
|
320
|
-
|
321
|
-
|
322
|
-
|
323
|
-
|
324
|
-
|
325
|
-
|
326
|
-
|
327
|
-
|
328
|
-
|
329
|
-
|
330
|
-
|
331
|
-
|
332
|
-
|
333
|
-
|
334
|
-
|
335
|
-
|
336
|
-
|
337
|
-
|
338
|
-
|
339
|
-
|
340
|
-
|
341
|
-
|
342
|
-
|
343
|
-
|
344
|
-
|
345
|
-
|
346
|
-
|
347
|
-
|
348
|
-
|
349
|
-
|
350
|
-
|
351
|
-
|
352
|
-
|
353
|
-
|
354
|
-
end
|
355
|
-
|
356
|
-
##
|
357
|
-
#
|
358
|
-
#
|
359
|
-
def
|
360
|
-
|
361
|
-
|
362
|
-
|
363
|
-
|
364
|
-
|
365
|
-
|
366
|
-
|
367
|
-
|
368
|
-
|
369
|
-
|
370
|
-
|
371
|
-
|
372
|
-
|
373
|
-
|
374
|
-
|
375
|
-
|
376
|
-
|
377
|
-
|
378
|
-
|
379
|
-
|
380
|
-
|
381
|
-
|
382
|
-
|
383
|
-
|
384
|
-
|
385
|
-
|
386
|
-
|
387
|
-
|
388
|
-
|
389
|
-
|
390
|
-
|
391
|
-
|
392
|
-
|
393
|
-
|
394
|
-
|
395
|
-
|
396
|
-
|
397
|
-
|
398
|
-
|
399
|
-
|
400
|
-
|
401
|
-
|
402
|
-
|
403
|
-
|
404
|
-
|
405
|
-
|
406
|
-
|
407
|
-
|
408
|
-
|
409
|
-
|
410
|
-
|
411
|
-
|
412
|
-
|
413
|
-
|
414
|
-
|
415
|
-
|
416
|
-
|
417
|
-
|
418
|
-
|
419
|
-
|
420
|
-
|
421
|
-
|
422
|
-
|
423
|
-
|
424
|
-
|
425
|
-
|
426
|
-
|
427
|
-
|
428
|
-
|
429
|
-
|
430
|
-
|
431
|
-
|
432
|
-
|
433
|
-
|
434
|
-
|
435
|
-
|
436
|
-
|
437
|
-
|
438
|
-
|
439
|
-
#
|
440
|
-
|
441
|
-
|
442
|
-
|
443
|
-
|
444
|
-
|
445
|
-
|
446
|
-
|
447
|
-
|
448
|
-
|
449
|
-
|
450
|
-
|
451
|
-
|
452
|
-
|
453
|
-
|
454
|
-
|
455
|
-
|
456
|
-
|
457
|
-
|
458
|
-
|
459
|
-
|
460
|
-
|
461
|
-
|
462
|
-
|
463
|
-
|
464
|
-
|
465
|
-
|
466
|
-
|
467
|
-
|
468
|
-
|
469
|
-
|
470
|
-
|
471
|
-
|
472
|
-
|
473
|
-
|
474
|
-
|
475
|
-
|
476
|
-
|
477
|
-
|
478
|
-
|
479
|
-
|
480
|
-
|
481
|
-
|
482
|
-
|
483
|
-
|
484
|
-
|
485
|
-
|
486
|
-
|
487
|
-
|
488
|
-
|
489
|
-
|
490
|
-
|
491
|
-
|
492
|
-
|
493
|
-
|
494
|
-
|
495
|
-
|
496
|
-
|
497
|
-
|
498
|
-
|
499
|
-
if
|
500
|
-
|
501
|
-
|
502
|
-
|
503
|
-
|
504
|
-
|
505
|
-
|
506
|
-
|
507
|
-
|
508
|
-
|
509
|
-
|
510
|
-
|
511
|
-
|
512
|
-
|
513
|
-
|
514
|
-
|
515
|
-
|
516
|
-
|
517
|
-
|
518
|
-
|
519
|
-
|
520
|
-
|
521
|
-
|
522
|
-
|
523
|
-
|
524
|
-
|
525
|
-
|
526
|
-
#
|
527
|
-
|
528
|
-
|
529
|
-
|
530
|
-
|
531
|
-
return
|
532
|
-
end
|
533
|
-
|
534
|
-
|
535
|
-
|
536
|
-
|
537
|
-
|
538
|
-
|
539
|
-
|
540
|
-
|
541
|
-
|
542
|
-
|
543
|
-
|
544
|
-
|
545
|
-
|
546
|
-
|
547
|
-
|
548
|
-
|
549
|
-
|
550
|
-
|
551
|
-
|
552
|
-
|
553
|
-
|
554
|
-
|
555
|
-
|
556
|
-
|
557
|
-
|
558
|
-
|
559
|
-
|
560
|
-
|
561
|
-
|
562
|
-
|
563
|
-
|
564
|
-
|
565
|
-
|
566
|
-
|
567
|
-
|
568
|
-
|
569
|
-
|
570
|
-
|
571
|
-
|
572
|
-
|
573
|
-
|
574
|
-
|
575
|
-
|
576
|
-
|
577
|
-
|
578
|
-
|
579
|
-
|
580
|
-
|
581
|
-
end
|
582
|
-
|
583
|
-
|
584
|
-
|
585
|
-
|
586
|
-
|
587
|
-
|
588
|
-
|
589
|
-
|
590
|
-
|
591
|
-
|
592
|
-
|
593
|
-
|
594
|
-
|
595
|
-
|
596
|
-
|
597
|
-
|
598
|
-
|
599
|
-
|
600
|
-
|
601
|
-
|
602
|
-
|
603
|
-
|
604
|
-
|
605
|
-
|
606
|
-
|
607
|
-
|
608
|
-
|
609
|
-
|
610
|
-
|
611
|
-
|
612
|
-
|
613
|
-
|
614
|
-
|
615
|
-
|
616
|
-
|
617
|
-
|
618
|
-
|
619
|
-
|
620
|
-
|
621
|
-
|
622
|
-
|
623
|
-
|
624
|
-
|
625
|
-
|
626
|
-
|
627
|
-
|
628
|
-
|
629
|
-
|
630
|
-
|
631
|
-
|
632
|
-
|
633
|
-
|
634
|
-
|
635
|
-
|
636
|
-
|
637
|
-
|
638
|
-
|
639
|
-
|
640
|
-
|
641
|
-
|
642
|
-
|
643
|
-
|
644
|
-
|
645
|
-
|
646
|
-
|
647
|
-
|
648
|
-
|
649
|
-
|
650
|
-
|
651
|
-
|
652
|
-
|
653
|
-
|
654
|
-
|
655
|
-
|
656
|
-
|
657
|
-
|
658
|
-
|
659
|
-
|
660
|
-
|
661
|
-
|
662
|
-
|
663
|
-
|
664
|
-
|
665
|
-
|
666
|
-
|
667
|
-
return
|
668
|
-
|
669
|
-
|
670
|
-
|
671
|
-
|
672
|
-
|
673
|
-
|
674
|
-
|
675
|
-
|
676
|
-
|
677
|
-
|
678
|
-
|
679
|
-
|
680
|
-
|
681
|
-
|
682
|
-
|
683
|
-
|
684
|
-
|
685
|
-
|
686
|
-
|
687
|
-
end
|
688
|
-
|
689
|
-
##
|
690
|
-
#
|
691
|
-
#
|
692
|
-
def
|
693
|
-
|
694
|
-
|
695
|
-
|
696
|
-
|
697
|
-
|
698
|
-
|
699
|
-
|
700
|
-
|
701
|
-
|
702
|
-
|
703
|
-
|
704
|
-
|
705
|
-
|
706
|
-
|
707
|
-
|
708
|
-
|
709
|
-
|
710
|
-
|
711
|
-
|
712
|
-
|
713
|
-
|
714
|
-
|
715
|
-
|
716
|
-
|
717
|
-
|
718
|
-
|
719
|
-
|
720
|
-
|
721
|
-
|
722
|
-
|
723
|
-
|
724
|
-
|
725
|
-
|
726
|
-
|
727
|
-
|
728
|
-
dst_local_port = 0
|
729
|
-
end
|
730
|
-
else
|
731
|
-
dst = Socket.new( Socket::AF_INET, Socket::SOCK_STREAM, 0 )
|
732
|
-
|
733
|
-
if RUBY_PLATFORM.include?( 'linux' )
|
734
|
-
dst.setsockopt( Socket::SOL_TCP, Socket::TCP_NODELAY, 1 )
|
735
|
-
end
|
736
|
-
|
737
|
-
begin
|
738
|
-
dst.connect_nonblock( @appd_addr )
|
739
|
-
rescue IO::WaitWritable
|
740
|
-
rescue Exception => e
|
741
|
-
puts "#{ Time.new } connect appd #{ e.class }"
|
742
|
-
return
|
743
|
-
end
|
744
|
-
|
745
|
-
dst_local_port = dst.local_address.ip_port
|
746
|
-
|
747
|
-
@dst_infos[ dst ] = {
|
748
|
-
local_port: dst_local_port, # 本地端口
|
749
|
-
biggest_pack_id: 0, # 最大包号码
|
750
|
-
wbuff: '', # 写前
|
751
|
-
cache: '', # 块读出缓存
|
752
|
-
chunks: [], # 块队列,写前达到块大小时结一个块 filename
|
753
|
-
spring: 0, # 块后缀,结块时,如果块队列不为空,则自增,为空,则置为0
|
754
|
-
created_at: Time.new, # 创建时间
|
755
|
-
last_recv_at: nil, # 上一次收到流量的时间,过期关闭
|
756
|
-
is_closing: false # 是否准备关闭
|
757
|
-
}
|
758
|
-
add_read( dst, :dst )
|
759
|
-
|
760
|
-
@tund_info[ :dst_local_ports ][ src_id ] = dst_local_port
|
761
|
-
@tund_info[ :dst_exts ][ dst_local_port ] = {
|
762
|
-
dst: dst, # dst
|
763
|
-
src_id: src_id, # 近端src id
|
764
|
-
wmems: {}, # 写后 pack_id => data
|
765
|
-
send_ats: {}, # 上一次发出时间 pack_id => send_at
|
766
|
-
relay_pack_id: 0, # 转发到几
|
767
|
-
continue_src_pack_id: 0, # 收到几
|
768
|
-
pieces: {}, # 跳号包 src_pack_id => data
|
769
|
-
is_src_closed: false, # src是否已关闭
|
770
|
-
biggest_src_pack_id: 0, # src最大包号码
|
771
|
-
completed_pack_id: 0, # 完成到几(对面收到几)
|
772
|
-
last_continue_at: Time.new # 创建,或者上一次收到连续流量,或者发出新包的时间
|
773
|
-
}
|
774
|
-
end
|
775
|
-
|
776
|
-
data2 = [ 0, PAIRED, src_id, dst_local_port ].pack( 'Q>CQ>n' )
|
777
|
-
# puts "debug1 add ctlmsg paired #{ data2.inspect }"
|
778
|
-
add_tund_ctlmsg( data2 )
|
779
|
-
when SOURCE_STATUS
|
780
|
-
return unless is_match_tun_addr( addrinfo )
|
781
|
-
|
782
|
-
src_id, relay_src_pack_id, continue_dst_pack_id = data[ 9, 24 ].unpack( 'Q>Q>Q>' )
|
783
|
-
|
784
|
-
dst_local_port = @tund_info[ :dst_local_ports ][ src_id ]
|
785
|
-
return unless dst_local_port
|
786
|
-
|
787
|
-
dst_ext = @tund_info[ :dst_exts ][ dst_local_port ]
|
788
|
-
return unless dst_ext
|
789
|
-
|
790
|
-
# puts "debug2 got source status"
|
791
|
-
|
792
|
-
release_wmems( dst_ext, continue_dst_pack_id )
|
793
|
-
|
794
|
-
# 发miss
|
795
|
-
if !dst_ext[ :dst ].closed? && ( dst_ext[ :continue_src_pack_id ] < relay_src_pack_id )
|
796
|
-
ranges = []
|
797
|
-
curr_pack_id = dst_ext[ :continue_src_pack_id ] + 1
|
798
|
-
|
799
|
-
dst_ext[ :pieces ].keys.sort.each do | pack_id |
|
800
|
-
if pack_id > curr_pack_id
|
801
|
-
ranges << [ curr_pack_id, pack_id - 1 ]
|
802
|
-
end
|
803
|
-
|
804
|
-
curr_pack_id = pack_id + 1
|
805
|
-
end
|
806
|
-
|
807
|
-
if curr_pack_id <= relay_src_pack_id
|
808
|
-
ranges << [ curr_pack_id, relay_src_pack_id ]
|
809
|
-
end
|
810
|
-
|
811
|
-
pack_count = 0
|
812
|
-
# puts "debug1 continue/relay #{ dst_ext[ :continue_src_pack_id ] }/#{ relay_src_pack_id } send MISS #{ ranges.size }"
|
813
|
-
|
814
|
-
ranges.each do | pack_id_begin, pack_id_end |
|
815
|
-
if pack_count >= BREAK_SEND_MISS
|
816
|
-
puts "#{ Time.new } break send miss at #{ pack_id_begin }"
|
817
|
-
break
|
818
|
-
end
|
819
|
-
|
820
|
-
data2 = [ 0, MISS, src_id, pack_id_begin, pack_id_end ].pack( 'Q>CQ>Q>Q>' )
|
821
|
-
add_tund_ctlmsg( data2 )
|
822
|
-
pack_count += ( pack_id_end - pack_id_begin + 1 )
|
823
|
-
end
|
824
|
-
end
|
825
|
-
when MISS
|
826
|
-
return unless is_match_tun_addr( addrinfo )
|
827
|
-
|
828
|
-
dst_local_port, pack_id_begin, pack_id_end = data[ 9, 18 ].unpack( 'nQ>Q>' )
|
829
|
-
|
830
|
-
dst_ext = @tund_info[ :dst_exts ][ dst_local_port ]
|
831
|
-
return unless dst_ext
|
832
|
-
|
833
|
-
( pack_id_begin..pack_id_end ).each do | pack_id |
|
834
|
-
send_at = dst_ext[ :send_ats ][ pack_id ]
|
835
|
-
|
836
|
-
if send_at
|
837
|
-
break if now - send_at < STATUS_INTERVAL
|
838
|
-
@tund_info[ :resendings ] << [ dst_local_port, pack_id ]
|
839
|
-
end
|
840
|
-
end
|
841
|
-
|
842
|
-
add_write( tund )
|
843
|
-
when FIN1
|
844
|
-
return unless is_match_tun_addr( addrinfo )
|
845
|
-
|
846
|
-
src_id, biggest_src_pack_id, continue_dst_pack_id = data[ 9, 24 ].unpack( 'Q>Q>Q>' )
|
847
|
-
|
848
|
-
dst_local_port = @tund_info[ :dst_local_ports ][ src_id ]
|
849
|
-
return unless dst_local_port
|
850
|
-
|
851
|
-
dst_ext = @tund_info[ :dst_exts ][ dst_local_port ]
|
852
|
-
return unless dst_ext
|
853
|
-
|
854
|
-
# puts "debug1 got fin1 #{ src_id } biggest src pack #{ biggest_src_pack_id } completed dst pack #{ continue_dst_pack_id }"
|
855
|
-
dst_ext[ :is_src_closed ] = true
|
856
|
-
dst_ext[ :biggest_src_pack_id ] = biggest_src_pack_id
|
857
|
-
release_wmems( dst_ext, continue_dst_pack_id )
|
858
|
-
|
859
|
-
if biggest_src_pack_id == dst_ext[ :continue_src_pack_id ]
|
860
|
-
# puts "debug1 4-1. tund recv fin1 -> all traffic received ? -> close dst after write"
|
861
|
-
set_is_closing( dst_ext[ :dst ] )
|
862
|
-
end
|
863
|
-
when FIN2
|
864
|
-
return unless is_match_tun_addr( addrinfo )
|
865
|
-
|
866
|
-
src_id = data[ 9, 8 ].unpack( 'Q>' ).first
|
867
|
-
|
868
|
-
dst_local_port = @tund_info[ :dst_local_ports ][ src_id ]
|
869
|
-
return unless dst_local_port
|
870
|
-
|
871
|
-
# puts "debug1 3-2. tund recv fin2 -> del dst ext"
|
872
|
-
del_dst_ext( dst_local_port )
|
873
|
-
when TUN_FIN
|
874
|
-
return unless is_match_tun_addr( addrinfo )
|
875
|
-
|
876
|
-
puts "#{ Time.new } recv tun fin"
|
877
|
-
set_is_closing( tund )
|
878
|
-
end
|
879
|
-
|
880
|
-
return
|
881
|
-
end
|
882
|
-
|
883
|
-
return unless is_match_tun_addr( addrinfo )
|
884
|
-
|
885
|
-
src_id = data[ 8, 8 ].unpack( 'Q>' ).first
|
886
|
-
|
887
|
-
dst_local_port = @tund_info[ :dst_local_ports ][ src_id ]
|
888
|
-
return unless dst_local_port
|
889
|
-
|
890
|
-
dst_ext = @tund_info[ :dst_exts ][ dst_local_port ]
|
891
|
-
return if dst_ext.nil? || dst_ext[ :dst ].closed?
|
892
|
-
return if ( pack_id <= dst_ext[ :continue_src_pack_id ] ) || dst_ext[ :pieces ].include?( pack_id )
|
893
|
-
|
894
|
-
data = data[ 16..-1 ]
|
895
|
-
# puts "debug2 got pack #{ pack_id }"
|
896
|
-
|
897
|
-
if pack_id <= CONFUSE_UNTIL
|
898
|
-
# puts "debug2 #{ data.inspect }"
|
899
|
-
data = @custom.decode( data )
|
900
|
-
# puts "debug1 decoded pack #{ pack_id }"
|
901
|
-
end
|
902
|
-
|
903
|
-
# 放进写前,跳号放碎片缓存
|
904
|
-
if pack_id - dst_ext[ :continue_src_pack_id ] == 1
|
905
|
-
while dst_ext[ :pieces ].include?( pack_id + 1 )
|
906
|
-
data << dst_ext[ :pieces ].delete( pack_id + 1 )
|
907
|
-
pack_id += 1
|
908
|
-
end
|
909
|
-
|
910
|
-
dst_ext[ :continue_src_pack_id ] = pack_id
|
911
|
-
dst_ext[ :last_continue_at ] = now
|
912
|
-
add_dst_wbuff( dst_ext[ :dst ], data )
|
913
|
-
# puts "debug2 update continue src pack #{ pack_id }"
|
914
|
-
|
915
|
-
# 接到流量,若对面已关闭,且流量正好收全,关闭dst
|
916
|
-
if dst_ext[ :is_src_closed ] && ( pack_id == dst_ext[ :biggest_src_pack_id ] )
|
917
|
-
# puts "debug1 4-2. tund recv traffic -> src closed and all traffic received ? -> close dst after write"
|
918
|
-
set_is_closing( dst_ext[ :dst ] )
|
919
|
-
return
|
920
|
-
end
|
921
|
-
else
|
922
|
-
dst_ext[ :pieces ][ pack_id ] = data
|
923
|
-
end
|
924
|
-
end
|
925
|
-
|
926
|
-
end
|
927
|
-
end
|
1
|
+
module P2p2
|
2
|
+
class P1Worker
|
3
|
+
|
4
|
+
##
|
5
|
+
# initialize
|
6
|
+
#
|
7
|
+
def initialize( paird_host, paird_port, title, appd_host, appd_port )
|
8
|
+
@paird_host = paird_host
|
9
|
+
@paird_port = paird_port
|
10
|
+
@title = title
|
11
|
+
@appd_addr = Socket.sockaddr_in( appd_port, appd_host )
|
12
|
+
@reads = []
|
13
|
+
@writes = []
|
14
|
+
@roles = {} # sock => :dotr / :ctl / :tun / :dst
|
15
|
+
@dst_infos = ConcurrentHash.new
|
16
|
+
@tun_infos = ConcurrentHash.new
|
17
|
+
|
18
|
+
new_a_pipe
|
19
|
+
new_a_ctl
|
20
|
+
end
|
21
|
+
|
22
|
+
##
|
23
|
+
# looping
|
24
|
+
#
|
25
|
+
def looping
|
26
|
+
puts "#{ Time.new } looping"
|
27
|
+
loop_renew_ctl
|
28
|
+
loop_check_state
|
29
|
+
|
30
|
+
loop do
|
31
|
+
rs, ws = IO.select( @reads, @writes )
|
32
|
+
|
33
|
+
rs.each do | sock |
|
34
|
+
role = @roles[ sock ]
|
35
|
+
|
36
|
+
case role
|
37
|
+
when :dotr then
|
38
|
+
read_dotr( sock )
|
39
|
+
when :ctl then
|
40
|
+
read_ctl( sock )
|
41
|
+
when :tun then
|
42
|
+
read_tun( sock )
|
43
|
+
when :dst then
|
44
|
+
read_dst( sock )
|
45
|
+
else
|
46
|
+
puts "#{ Time.new } read unknown role #{ role }"
|
47
|
+
close_sock( sock )
|
48
|
+
end
|
49
|
+
end
|
50
|
+
|
51
|
+
ws.each do | sock |
|
52
|
+
role = @roles[ sock ]
|
53
|
+
|
54
|
+
case role
|
55
|
+
when :tun then
|
56
|
+
write_tun( sock )
|
57
|
+
when :dst then
|
58
|
+
write_dst( sock )
|
59
|
+
else
|
60
|
+
puts "#{ Time.new } write unknown role #{ role }"
|
61
|
+
close_sock( sock )
|
62
|
+
end
|
63
|
+
end
|
64
|
+
end
|
65
|
+
rescue Interrupt => e
|
66
|
+
puts e.class
|
67
|
+
quit!
|
68
|
+
end
|
69
|
+
|
70
|
+
##
|
71
|
+
# quit!
|
72
|
+
#
|
73
|
+
def quit!
|
74
|
+
# puts "debug exit"
|
75
|
+
exit
|
76
|
+
end
|
77
|
+
|
78
|
+
private
|
79
|
+
|
80
|
+
##
|
81
|
+
# add dst rbuff
|
82
|
+
#
|
83
|
+
def add_dst_rbuff( dst, data )
|
84
|
+
return if dst.nil? || dst.closed?
|
85
|
+
dst_info = @dst_infos[ dst ]
|
86
|
+
dst_info[ :rbuff ] << data
|
87
|
+
|
88
|
+
if dst_info[ :rbuff ].bytesize >= WBUFF_LIMIT then
|
89
|
+
puts "#{ Time.new } dst.rbuff full"
|
90
|
+
close_dst( dst )
|
91
|
+
end
|
92
|
+
end
|
93
|
+
|
94
|
+
##
|
95
|
+
# add dst wbuff
|
96
|
+
#
|
97
|
+
def add_dst_wbuff( dst, data )
|
98
|
+
return if dst.nil? || dst.closed?
|
99
|
+
dst_info = @dst_infos[ dst ]
|
100
|
+
dst_info[ :wbuff ] << data
|
101
|
+
dst_info[ :last_recv_at ] = Time.new
|
102
|
+
add_write( dst )
|
103
|
+
|
104
|
+
if dst_info[ :wbuff ].bytesize >= WBUFF_LIMIT then
|
105
|
+
tun = dst_info[ :tun ]
|
106
|
+
|
107
|
+
if tun && !tun.closed? then
|
108
|
+
puts "#{ Time.new } pause tun"
|
109
|
+
@reads.delete( tun )
|
110
|
+
tun_info = @tun_infos[ tun ]
|
111
|
+
tun_info[ :paused ] = true
|
112
|
+
end
|
113
|
+
end
|
114
|
+
end
|
115
|
+
|
116
|
+
##
|
117
|
+
# add read
|
118
|
+
#
|
119
|
+
def add_read( sock, role = nil )
|
120
|
+
return if sock.nil? || sock.closed? || @reads.include?( sock )
|
121
|
+
@reads << sock
|
122
|
+
|
123
|
+
if role then
|
124
|
+
@roles[ sock ] = role
|
125
|
+
end
|
126
|
+
end
|
127
|
+
|
128
|
+
##
|
129
|
+
# add tun wbuff
|
130
|
+
#
|
131
|
+
def add_tun_wbuff( tun, data )
|
132
|
+
return if tun.nil? || tun.closed?
|
133
|
+
tun_info = @tun_infos[ tun ]
|
134
|
+
tun_info[ :wbuff ] << data
|
135
|
+
add_write( tun )
|
136
|
+
|
137
|
+
if tun_info[ :wbuff ].bytesize >= WBUFF_LIMIT then
|
138
|
+
dst = tun_info[ :dst ]
|
139
|
+
|
140
|
+
if dst && !dst.closed? then
|
141
|
+
puts "#{ Time.new } pause dst"
|
142
|
+
@reads.delete( dst )
|
143
|
+
dst_info = @dst_infos[ dst ]
|
144
|
+
dst_info[ :paused ] = true
|
145
|
+
end
|
146
|
+
end
|
147
|
+
end
|
148
|
+
|
149
|
+
##
|
150
|
+
# add write
|
151
|
+
#
|
152
|
+
def add_write( sock )
|
153
|
+
return if sock.nil? || sock.closed? || @writes.include?( sock )
|
154
|
+
@writes << sock
|
155
|
+
end
|
156
|
+
|
157
|
+
##
|
158
|
+
# close ctl
|
159
|
+
#
|
160
|
+
def close_ctl
|
161
|
+
return if @ctl.nil? || @ctl.closed?
|
162
|
+
close_sock( @ctl )
|
163
|
+
end
|
164
|
+
|
165
|
+
##
|
166
|
+
# close dst
|
167
|
+
#
|
168
|
+
def close_dst( dst )
|
169
|
+
return if dst.nil? || dst.closed?
|
170
|
+
puts "#{ Time.new } close dst"
|
171
|
+
close_sock( dst )
|
172
|
+
@dst_infos.delete( dst )
|
173
|
+
end
|
174
|
+
|
175
|
+
##
|
176
|
+
# close read dst
|
177
|
+
#
|
178
|
+
def close_read_dst( dst )
|
179
|
+
return if dst.nil? || dst.closed?
|
180
|
+
# puts "debug close read dst"
|
181
|
+
dst.close_read
|
182
|
+
@reads.delete( dst )
|
183
|
+
|
184
|
+
if dst.closed? then
|
185
|
+
# puts "debug dst closed"
|
186
|
+
@writes.delete( dst )
|
187
|
+
@roles.delete( dst )
|
188
|
+
@dst_infos.delete( dst )
|
189
|
+
end
|
190
|
+
end
|
191
|
+
|
192
|
+
##
|
193
|
+
# close read tun
|
194
|
+
#
|
195
|
+
def close_read_tun( tun )
|
196
|
+
return if tun.nil? || tun.closed?
|
197
|
+
# puts "debug close read tun"
|
198
|
+
tun.close_read
|
199
|
+
@reads.delete( tun )
|
200
|
+
|
201
|
+
if tun.closed? then
|
202
|
+
# puts "debug tun closed"
|
203
|
+
@writes.delete( tun )
|
204
|
+
@roles.delete( tun )
|
205
|
+
@tun_infos.delete( tun )
|
206
|
+
end
|
207
|
+
end
|
208
|
+
|
209
|
+
##
|
210
|
+
# close sock
|
211
|
+
#
|
212
|
+
def close_sock( sock )
|
213
|
+
return if sock.nil? || sock.closed?
|
214
|
+
sock.close
|
215
|
+
@reads.delete( sock )
|
216
|
+
@writes.delete( sock )
|
217
|
+
@roles.delete( sock )
|
218
|
+
end
|
219
|
+
|
220
|
+
##
|
221
|
+
# close tun
|
222
|
+
#
|
223
|
+
def close_tun( tun )
|
224
|
+
return if tun.nil? || tun.closed?
|
225
|
+
puts "#{ Time.new } close tun"
|
226
|
+
close_sock( tun )
|
227
|
+
@tun_infos.delete( tun )
|
228
|
+
end
|
229
|
+
|
230
|
+
##
|
231
|
+
# close write dst
|
232
|
+
#
|
233
|
+
def close_write_dst( dst )
|
234
|
+
return if dst.nil? || dst.closed?
|
235
|
+
# puts "debug close write dst"
|
236
|
+
dst.close_write
|
237
|
+
@writes.delete( dst )
|
238
|
+
|
239
|
+
if dst.closed? then
|
240
|
+
# puts "debug dst closed"
|
241
|
+
@reads.delete( dst )
|
242
|
+
@roles.delete( dst )
|
243
|
+
@dst_infos.delete( dst )
|
244
|
+
end
|
245
|
+
end
|
246
|
+
|
247
|
+
##
|
248
|
+
# close write tun
|
249
|
+
#
|
250
|
+
def close_write_tun( tun )
|
251
|
+
return if tun.nil? || tun.closed?
|
252
|
+
# puts "debug close write tun"
|
253
|
+
tun.close_write
|
254
|
+
@writes.delete( tun )
|
255
|
+
|
256
|
+
if tun.closed? then
|
257
|
+
# puts "debug tun closed"
|
258
|
+
@reads.delete( tun )
|
259
|
+
@roles.delete( tun )
|
260
|
+
@tun_infos.delete( tun )
|
261
|
+
end
|
262
|
+
end
|
263
|
+
|
264
|
+
##
|
265
|
+
# loop check state
|
266
|
+
#
|
267
|
+
def loop_check_state
|
268
|
+
Thread.new do
|
269
|
+
loop do
|
270
|
+
sleep CHECK_STATE_INTERVAL
|
271
|
+
now = Time.new
|
272
|
+
|
273
|
+
@dst_infos.select{ | dst, _ | !dst.closed? }.each do | dst, dst_info |
|
274
|
+
last_recv_at = dst_info[ :last_recv_at ] || dst_info[ :created_at ]
|
275
|
+
last_sent_at = dst_info[ :last_sent_at ] || dst_info[ :created_at ]
|
276
|
+
is_expire = ( now - last_recv_at >= EXPIRE_AFTER ) && ( now - last_sent_at >= EXPIRE_AFTER )
|
277
|
+
|
278
|
+
if is_expire then
|
279
|
+
puts "#{ Time.new } expire dst"
|
280
|
+
dst_info[ :closing ] = true
|
281
|
+
next_tick
|
282
|
+
elsif dst_info[ :paused ] then
|
283
|
+
tun = dst_info[ :tun ]
|
284
|
+
|
285
|
+
if tun && !tun.closed? then
|
286
|
+
tun_info = @tun_infos[ tun ]
|
287
|
+
|
288
|
+
if tun_info[ :wbuff ].bytesize < RESUME_BELOW then
|
289
|
+
puts "#{ Time.new } resume dst"
|
290
|
+
add_read( dst )
|
291
|
+
dst_info[ :paused ] = false
|
292
|
+
next_tick
|
293
|
+
end
|
294
|
+
end
|
295
|
+
end
|
296
|
+
end
|
297
|
+
|
298
|
+
@tun_infos.select{ | tun, info | !tun.closed? && info[ :paused ] }.each do | tun, tun_info |
|
299
|
+
dst = tun_info[ :dst ]
|
300
|
+
|
301
|
+
if dst && !dst.closed? then
|
302
|
+
dst_info = @dst_infos[ dst ]
|
303
|
+
|
304
|
+
if dst_info[ :wbuff ].bytesize < RESUME_BELOW then
|
305
|
+
puts "#{ Time.new } resume tun"
|
306
|
+
add_read( tun )
|
307
|
+
tun_info[ :paused ] = false
|
308
|
+
next_tick
|
309
|
+
end
|
310
|
+
end
|
311
|
+
end
|
312
|
+
end
|
313
|
+
end
|
314
|
+
end
|
315
|
+
|
316
|
+
##
|
317
|
+
# loop renew ctl
|
318
|
+
#
|
319
|
+
def loop_renew_ctl
|
320
|
+
Thread.new do
|
321
|
+
loop do
|
322
|
+
sleep RENEW_CTL_INTERVAL
|
323
|
+
set_ctl_closing
|
324
|
+
end
|
325
|
+
end
|
326
|
+
end
|
327
|
+
|
328
|
+
##
|
329
|
+
# new a ctl
|
330
|
+
#
|
331
|
+
def new_a_ctl
|
332
|
+
ctl = Socket.new( Socket::AF_INET, Socket::SOCK_DGRAM, 0 )
|
333
|
+
ctl.setsockopt( Socket::SOL_SOCKET, Socket::SO_REUSEADDR, 1 )
|
334
|
+
|
335
|
+
if RUBY_PLATFORM.include?( 'linux' ) then
|
336
|
+
ctl.setsockopt( Socket::SOL_SOCKET, Socket::SO_REUSEPORT, 1 )
|
337
|
+
end
|
338
|
+
|
339
|
+
paird_port = @paird_port + 10.times.to_a.sample
|
340
|
+
paird_addr = Socket.sockaddr_in( paird_port, @paird_host )
|
341
|
+
|
342
|
+
@ctl = ctl
|
343
|
+
@ctl_info = {
|
344
|
+
paird_addr: paird_addr,
|
345
|
+
peer_addr: nil,
|
346
|
+
dst: nil,
|
347
|
+
closing: false
|
348
|
+
}
|
349
|
+
|
350
|
+
add_read( ctl, :ctl )
|
351
|
+
|
352
|
+
puts "#{ Time.new } #{ @title.inspect } #{ Addrinfo.new( @ctl_info[ :paird_addr ] ).inspect }"
|
353
|
+
send_title
|
354
|
+
end
|
355
|
+
|
356
|
+
##
|
357
|
+
# new a dst
|
358
|
+
#
|
359
|
+
def new_a_dst
|
360
|
+
dst = Socket.new( Socket::AF_INET, Socket::SOCK_STREAM, 0 )
|
361
|
+
dst.setsockopt( Socket::IPPROTO_TCP, Socket::TCP_NODELAY, 1 )
|
362
|
+
|
363
|
+
begin
|
364
|
+
dst.connect_nonblock( @appd_addr )
|
365
|
+
rescue IO::WaitWritable
|
366
|
+
rescue Exception => e
|
367
|
+
puts "#{ Time.new } dst connect appd addr #{ e.class }"
|
368
|
+
dst.close
|
369
|
+
renew_ctl
|
370
|
+
return nil
|
371
|
+
end
|
372
|
+
|
373
|
+
@dst_infos[ dst ] = {
|
374
|
+
rbuff: '',
|
375
|
+
wbuff: '',
|
376
|
+
closing_write: false,
|
377
|
+
closing: false,
|
378
|
+
paused: false,
|
379
|
+
created_at: Time.new,
|
380
|
+
last_recv_at: nil,
|
381
|
+
last_sent_at: nil,
|
382
|
+
tun: nil,
|
383
|
+
punch_times: 0
|
384
|
+
}
|
385
|
+
|
386
|
+
puts "#{ Time.new } dst infos #{ @dst_infos.size }"
|
387
|
+
add_read( dst, :dst )
|
388
|
+
dst
|
389
|
+
end
|
390
|
+
|
391
|
+
##
|
392
|
+
# new a pipe
|
393
|
+
#
|
394
|
+
def new_a_pipe
|
395
|
+
dotr, dotw = IO.pipe
|
396
|
+
@dotw = dotw
|
397
|
+
add_read( dotr, :dotr )
|
398
|
+
end
|
399
|
+
|
400
|
+
##
|
401
|
+
# new a tun
|
402
|
+
#
|
403
|
+
def new_a_tun
|
404
|
+
return if @ctl.nil? || @ctl.closed? || @ctl_info[ :peer_addr ].nil?
|
405
|
+
dst = @ctl_info[ :dst ]
|
406
|
+
return if dst.nil? || dst.closed?
|
407
|
+
tun = Socket.new( Socket::AF_INET, Socket::SOCK_STREAM, 0 )
|
408
|
+
tun.setsockopt( Socket::IPPROTO_TCP, Socket::TCP_NODELAY, 1 )
|
409
|
+
tun.bind( @ctl.local_address )
|
410
|
+
|
411
|
+
begin
|
412
|
+
tun.connect_nonblock( @ctl_info[ :peer_addr ] )
|
413
|
+
rescue IO::WaitWritable
|
414
|
+
rescue Exception => e
|
415
|
+
puts "#{ Time.new } connect peer addr #{ e.class }"
|
416
|
+
tun.close
|
417
|
+
renew_ctl
|
418
|
+
return nil
|
419
|
+
end
|
420
|
+
|
421
|
+
@tun_infos[ tun ] = {
|
422
|
+
connected: false,
|
423
|
+
wbuff: '',
|
424
|
+
closing_write: false,
|
425
|
+
paused: false,
|
426
|
+
dst: dst
|
427
|
+
}
|
428
|
+
|
429
|
+
add_read( tun, :tun )
|
430
|
+
add_write( tun )
|
431
|
+
dst_info = @dst_infos[ dst ]
|
432
|
+
dst_info[ :tun ] = tun
|
433
|
+
dst_info[ :punch_times ] += 1
|
434
|
+
puts "#{ Time.new } #{ tun.local_address.inspect } connect #{ Addrinfo.new( @ctl_info[ :peer_addr ] ).inspect } tun infos #{ @tun_infos.size }"
|
435
|
+
tun
|
436
|
+
end
|
437
|
+
|
438
|
+
##
|
439
|
+
# next tick
|
440
|
+
#
|
441
|
+
def next_tick
|
442
|
+
@dotw.write( '.' )
|
443
|
+
end
|
444
|
+
|
445
|
+
##
|
446
|
+
# renew ctl
|
447
|
+
#
|
448
|
+
def renew_ctl
|
449
|
+
close_ctl
|
450
|
+
new_a_ctl
|
451
|
+
end
|
452
|
+
|
453
|
+
##
|
454
|
+
# renew paired ctl
|
455
|
+
#
|
456
|
+
def renew_paired_ctl
|
457
|
+
if @ctl && !@ctl.closed? && @ctl_info[ :peer_addr ] then
|
458
|
+
puts "#{ Time.new } renew paired ctl"
|
459
|
+
renew_ctl
|
460
|
+
end
|
461
|
+
end
|
462
|
+
|
463
|
+
##
|
464
|
+
# send title
|
465
|
+
#
|
466
|
+
def send_title
|
467
|
+
begin
|
468
|
+
@ctl.sendmsg( @title, 0, @ctl_info[ :paird_addr ] )
|
469
|
+
rescue Exception => e
|
470
|
+
puts "#{ Time.new } ctl sendmsg #{ e.class }"
|
471
|
+
set_ctl_closing
|
472
|
+
end
|
473
|
+
end
|
474
|
+
|
475
|
+
##
|
476
|
+
# set ctl closing
|
477
|
+
#
|
478
|
+
def set_ctl_closing
|
479
|
+
return if @ctl.nil? || @ctl.closed? || @ctl_info[ :closing ]
|
480
|
+
@ctl_info[ :closing ] = true
|
481
|
+
next_tick
|
482
|
+
end
|
483
|
+
|
484
|
+
##
|
485
|
+
# set dst closing write
|
486
|
+
#
|
487
|
+
def set_dst_closing_write( dst )
|
488
|
+
return if dst.nil? || dst.closed?
|
489
|
+
dst_info = @dst_infos[ dst ]
|
490
|
+
return if dst_info[ :closing_write ]
|
491
|
+
dst_info[ :closing_write ] = true
|
492
|
+
add_write( dst )
|
493
|
+
end
|
494
|
+
|
495
|
+
##
|
496
|
+
# set tun closing write
|
497
|
+
#
|
498
|
+
def set_tun_closing_write( tun )
|
499
|
+
return if tun.nil? || tun.closed?
|
500
|
+
tun_info = @tun_infos[ tun ]
|
501
|
+
return if tun_info[ :closing_write ]
|
502
|
+
tun_info[ :closing_write ] = true
|
503
|
+
add_write( tun )
|
504
|
+
end
|
505
|
+
|
506
|
+
##
|
507
|
+
# read dotr
|
508
|
+
#
|
509
|
+
def read_dotr( dotr )
|
510
|
+
dotr.read_nonblock( READ_SIZE )
|
511
|
+
|
512
|
+
if @ctl && !@ctl.closed? && @ctl_info[ :closing ] then
|
513
|
+
renew_ctl
|
514
|
+
end
|
515
|
+
|
516
|
+
@dst_infos.select{ | _, info | info[ :closing ] }.keys.each do | dst |
|
517
|
+
dst_info = close_dst( dst )
|
518
|
+
|
519
|
+
if dst_info then
|
520
|
+
close_tun( dst_info[ :tun ] )
|
521
|
+
end
|
522
|
+
end
|
523
|
+
end
|
524
|
+
|
525
|
+
##
|
526
|
+
# read ctl
|
527
|
+
#
|
528
|
+
def read_ctl( ctl )
|
529
|
+
if ctl.closed? then
|
530
|
+
puts "#{ Time.new } read ctl but ctl closed?"
|
531
|
+
return
|
532
|
+
end
|
533
|
+
|
534
|
+
data, addrinfo, rflags, *controls = ctl.recvmsg
|
535
|
+
|
536
|
+
if @ctl_info[ :peer_addr ] then
|
537
|
+
puts "#{ Time.new } peer addr already exist"
|
538
|
+
return
|
539
|
+
end
|
540
|
+
|
541
|
+
if addrinfo.to_sockaddr != @ctl_info[ :paird_addr ] then
|
542
|
+
puts "#{ Time.new } paird addr not match #{ addrinfo.inspect } #{ Addrinfo.new( @ctl_info[ :paird_addr ] ).inspect }"
|
543
|
+
return
|
544
|
+
end
|
545
|
+
|
546
|
+
puts "#{ Time.new } read ctl #{ data.inspect }"
|
547
|
+
@ctl_info[ :peer_addr ] = data
|
548
|
+
@ctl_info[ :dst ] = new_a_dst
|
549
|
+
new_a_tun
|
550
|
+
end
|
551
|
+
|
552
|
+
##
|
553
|
+
# read tun
|
554
|
+
#
|
555
|
+
def read_tun( tun )
|
556
|
+
if tun.closed? then
|
557
|
+
puts "#{ Time.new } read tun but tun closed?"
|
558
|
+
return
|
559
|
+
end
|
560
|
+
|
561
|
+
tun_info = @tun_infos[ tun ]
|
562
|
+
dst = tun_info[ :dst ]
|
563
|
+
|
564
|
+
if dst.nil? || dst.closed? then
|
565
|
+
puts "#{ Time.new } read tun but dst already closed"
|
566
|
+
close_tun( tun )
|
567
|
+
return
|
568
|
+
end
|
569
|
+
|
570
|
+
begin
|
571
|
+
data = tun.read_nonblock( READ_SIZE )
|
572
|
+
rescue Errno::ECONNREFUSED => e
|
573
|
+
dst_info = @dst_infos[ dst ]
|
574
|
+
|
575
|
+
if dst_info[ :punch_times ] >= PUNCH_LIMIT then
|
576
|
+
puts "#{ Time.new } out of limit"
|
577
|
+
close_tun( tun )
|
578
|
+
close_dst( dst )
|
579
|
+
renew_ctl
|
580
|
+
return
|
581
|
+
end
|
582
|
+
|
583
|
+
puts "#{ Time.new } read tun #{ e.class } #{ dst_info[ :punch_times ] }"
|
584
|
+
close_tun( tun )
|
585
|
+
|
586
|
+
unless new_a_tun then
|
587
|
+
close_dst( dst )
|
588
|
+
renew_ctl
|
589
|
+
end
|
590
|
+
|
591
|
+
return
|
592
|
+
rescue Exception => e
|
593
|
+
puts "#{ Time.new } read tun #{ e.class }"
|
594
|
+
close_read_tun( tun )
|
595
|
+
set_dst_closing_write( dst )
|
596
|
+
renew_paired_ctl
|
597
|
+
return
|
598
|
+
end
|
599
|
+
|
600
|
+
add_dst_wbuff( dst, data )
|
601
|
+
end
|
602
|
+
|
603
|
+
##
|
604
|
+
# read dst
|
605
|
+
#
|
606
|
+
def read_dst( dst )
|
607
|
+
if dst.closed? then
|
608
|
+
puts "#{ Time.new } read dst but dst closed?"
|
609
|
+
return
|
610
|
+
end
|
611
|
+
|
612
|
+
dst_info = @dst_infos[ dst ]
|
613
|
+
tun = dst_info[ :tun ]
|
614
|
+
|
615
|
+
begin
|
616
|
+
data = dst.read_nonblock( READ_SIZE )
|
617
|
+
rescue Exception => e
|
618
|
+
puts "#{ Time.new } read dst #{ e.class }"
|
619
|
+
close_read_dst( dst )
|
620
|
+
set_tun_closing_write( tun )
|
621
|
+
renew_paired_ctl
|
622
|
+
return
|
623
|
+
end
|
624
|
+
|
625
|
+
if tun && !tun.closed? && @tun_infos[ tun ][ :connected ] then
|
626
|
+
add_tun_wbuff( tun, data )
|
627
|
+
else
|
628
|
+
puts "#{ Time.new } tun not connected, save data to dst.rbuff #{ data.inspect }"
|
629
|
+
add_dst_rbuff( dst, data )
|
630
|
+
end
|
631
|
+
end
|
632
|
+
|
633
|
+
##
|
634
|
+
# write tun
|
635
|
+
#
|
636
|
+
def write_tun( tun )
|
637
|
+
if tun.closed? then
|
638
|
+
puts "#{ Time.new } write tun but tun closed?"
|
639
|
+
return
|
640
|
+
end
|
641
|
+
|
642
|
+
tun_info = @tun_infos[ tun ]
|
643
|
+
dst = tun_info[ :dst ]
|
644
|
+
dst_info = @dst_infos[ dst ]
|
645
|
+
|
646
|
+
unless tun_info[ :connected ] then
|
647
|
+
puts "#{ Time.new } connected"
|
648
|
+
tun_info[ :connected ] = true
|
649
|
+
|
650
|
+
if dst && !dst.closed? then
|
651
|
+
tun_info[ :wbuff ] << dst_info[ :rbuff ]
|
652
|
+
end
|
653
|
+
|
654
|
+
renew_ctl
|
655
|
+
end
|
656
|
+
|
657
|
+
data = tun_info[ :wbuff ]
|
658
|
+
|
659
|
+
# 写前为空,处理关闭写
|
660
|
+
if data.empty? then
|
661
|
+
if tun_info[ :closing_write ] then
|
662
|
+
close_write_tun( tun )
|
663
|
+
else
|
664
|
+
@writes.delete( tun )
|
665
|
+
end
|
666
|
+
|
667
|
+
return
|
668
|
+
end
|
669
|
+
|
670
|
+
# 写入
|
671
|
+
begin
|
672
|
+
written = tun.write_nonblock( data )
|
673
|
+
rescue Exception => e
|
674
|
+
puts "#{ Time.new } write tun #{ e.class }"
|
675
|
+
close_write_tun( tun )
|
676
|
+
close_read_dst( dst )
|
677
|
+
renew_paired_ctl
|
678
|
+
return
|
679
|
+
end
|
680
|
+
|
681
|
+
data = data[ written..-1 ]
|
682
|
+
tun_info[ :wbuff ] = data
|
683
|
+
|
684
|
+
if dst && !dst.closed? then
|
685
|
+
dst_info[ :last_sent_at ] = Time.new
|
686
|
+
end
|
687
|
+
end
|
688
|
+
|
689
|
+
##
|
690
|
+
# write dst
|
691
|
+
#
|
692
|
+
def write_dst( dst )
|
693
|
+
if dst.closed? then
|
694
|
+
puts "#{ Time.new } write dst but dst closed?"
|
695
|
+
return
|
696
|
+
end
|
697
|
+
|
698
|
+
dst_info = @dst_infos[ dst ]
|
699
|
+
data = dst_info[ :wbuff ]
|
700
|
+
|
701
|
+
# 写前为空,处理关闭写
|
702
|
+
if data.empty? then
|
703
|
+
if dst_info[ :closing_write ] then
|
704
|
+
close_write_dst( dst )
|
705
|
+
else
|
706
|
+
@writes.delete( dst )
|
707
|
+
end
|
708
|
+
|
709
|
+
return
|
710
|
+
end
|
711
|
+
|
712
|
+
# 写入
|
713
|
+
begin
|
714
|
+
written = dst.write_nonblock( data )
|
715
|
+
rescue Exception => e
|
716
|
+
puts "#{ Time.new } write dst #{ e.class }"
|
717
|
+
close_write_dst( dst )
|
718
|
+
close_read_tun( dst_info[ :tun ] )
|
719
|
+
renew_paired_ctl
|
720
|
+
return
|
721
|
+
end
|
722
|
+
|
723
|
+
data = data[ written..-1 ]
|
724
|
+
dst_info[ :wbuff ] = data
|
725
|
+
end
|
726
|
+
end
|
727
|
+
end
|