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