p2p2 0.26.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.
data/lib/p2p2/paird.rb ADDED
@@ -0,0 +1,42 @@
1
+ require 'json'
2
+ require 'p2p2/head'
3
+ require 'p2p2/paird_worker'
4
+ require 'p2p2/version'
5
+ require 'socket'
6
+
7
+ ##
8
+ # P2p2::Paird - 配对服务。
9
+ #
10
+ module P2p2
11
+ class Paird
12
+
13
+ def initialize( config_path = nil )
14
+ if config_path then
15
+ conf = JSON.parse( IO.binread( config_path ), symbolize_names: true )
16
+ paird_port = conf[ :paird_port ]
17
+ infod_port = conf[ :infod_port ]
18
+ end
19
+
20
+ unless paird_port then
21
+ paird_port = 4040
22
+ end
23
+
24
+ unless infod_port then
25
+ infod_port = 4050
26
+ end
27
+
28
+ puts "p2p2 paird #{ P2p2::VERSION }"
29
+ puts "paird #{ paird_port } infod #{ infod_port }"
30
+
31
+ worker = P2p2::PairdWorker.new( paird_port, infod_port )
32
+
33
+ Signal.trap( :TERM ) do
34
+ puts 'exit'
35
+ worker.quit!
36
+ end
37
+
38
+ worker.looping
39
+ end
40
+
41
+ end
42
+ end
@@ -0,0 +1,158 @@
1
+ module P2p2
2
+ class PairdWorker
3
+
4
+ ##
5
+ # initialize
6
+ #
7
+ def initialize( paird_port, infod_port )
8
+ @reads = []
9
+ @roles = {} # :paird / :infod
10
+ @room_infos = {} # title => { p1_paird, p1_addrinfo, p2_paird, p2_addrinfo, updated_at }
11
+ new_pairds( paird_port )
12
+ new_a_infod( infod_port )
13
+ end
14
+
15
+ ##
16
+ # looping
17
+ #
18
+ def looping
19
+ puts "#{ Time.new } looping"
20
+
21
+ loop do
22
+ rs, _ = IO.select( @reads )
23
+
24
+ rs.each do | sock |
25
+ role = @roles[ sock ]
26
+
27
+ case role
28
+ when :paird
29
+ read_paird( sock )
30
+ when :infod
31
+ read_infod( sock )
32
+ else
33
+ puts "#{ Time.new } read unknown role #{ role }"
34
+ end
35
+ end
36
+ end
37
+ rescue Interrupt => e
38
+ puts e.class
39
+ quit!
40
+ end
41
+
42
+ ##
43
+ # quit!
44
+ #
45
+ def quit!
46
+ exit
47
+ end
48
+
49
+ private
50
+
51
+ ##
52
+ # add read
53
+ #
54
+ def add_read( sock, role = nil )
55
+ return if sock.nil? || sock.closed? || @reads.include?( sock )
56
+ @reads << sock
57
+
58
+ if role then
59
+ @roles[ sock ] = role
60
+ end
61
+ end
62
+
63
+ ##
64
+ # new a infod
65
+ #
66
+ def new_a_infod( infod_port )
67
+ infod = Socket.new( Socket::AF_INET, Socket::SOCK_DGRAM, 0 )
68
+ infod.setsockopt( Socket::SOL_SOCKET, Socket::SO_REUSEPORT, 1 )
69
+ infod.bind( Socket.sockaddr_in( infod_port, '127.0.0.1' ) )
70
+
71
+ puts "#{ Time.new } infod bind on #{ infod_port }"
72
+ add_read( infod, :infod )
73
+ end
74
+
75
+ ##
76
+ # new pairds
77
+ #
78
+ def new_pairds( begin_port )
79
+ 10.times do | i |
80
+ paird_port = begin_port + i
81
+ paird = Socket.new( Socket::AF_INET, Socket::SOCK_DGRAM, 0 )
82
+ paird.setsockopt( Socket::SOL_SOCKET, Socket::SO_REUSEPORT, 1 )
83
+ paird.bind( Socket.sockaddr_in( paird_port, '0.0.0.0' ) )
84
+ puts "#{ Time.new } paird bind on #{ paird_port }"
85
+ add_read( paird, :paird )
86
+ end
87
+ end
88
+
89
+ ##
90
+ # send data
91
+ #
92
+ def send_data( sock, data, target_addr )
93
+ begin
94
+ sock.sendmsg_nonblock( data, 0, target_addr )
95
+ rescue Exception => e
96
+ puts "#{ Time.new } sendmsg #{ e.class }"
97
+ end
98
+ end
99
+
100
+ ##
101
+ # read paird
102
+ #
103
+ def read_paird( paird )
104
+ data, addrinfo, rflags, *controls = paird.recvmsg
105
+ return if data =~ /\r|\n/
106
+
107
+ is_p2 = ( data[ 0 ] == TO )
108
+ title = is_p2 ? data[ 1..-1 ] : data
109
+ return if title.empty? || ( title.size > ROOM_TITLE_LIMIT )
110
+
111
+ room_info = @room_infos[ title ]
112
+
113
+ unless is_p2 then
114
+ if room_info then
115
+ room_info[ :p1_paird ] = paird
116
+ room_info[ :p1_addrinfo ] = addrinfo
117
+ room_info[ :updated_at ] = Time.new
118
+ else
119
+ @room_infos[ title ] = {
120
+ p1_paird: paird,
121
+ p1_addrinfo: addrinfo,
122
+ p2_paird: nil,
123
+ p2_addrinfo: nil,
124
+ updated_at: Time.new
125
+ }
126
+ end
127
+
128
+ return
129
+ end
130
+
131
+ return unless room_info
132
+
133
+ room_info[ :p2_paird ] = paird
134
+ room_info[ :p2_addrinfo ] = addrinfo
135
+
136
+ puts "#{ Time.new } paired #{ room_info[ :p1_addrinfo ].inspect } #{ room_info[ :p2_addrinfo ].inspect }"
137
+ send_data( room_info[ :p1_paird ], room_info[ :p2_addrinfo ].to_sockaddr, room_info[ :p1_addrinfo ] )
138
+ send_data( room_info[ :p2_paird ], room_info[ :p1_addrinfo ].to_sockaddr, room_info[ :p2_addrinfo ] )
139
+ end
140
+
141
+ ##
142
+ # read infod
143
+ #
144
+ def read_infod( infod )
145
+ data, addrinfo, rflags, *controls = infod.recvmsg
146
+
147
+ data2 = @room_infos.sort_by{ | _, info | info[ :updated_at ] }.reverse.map do | title, info |
148
+ [
149
+ info[ :updated_at ],
150
+ title + ' ' * ( ROOM_TITLE_LIMIT - title.size ),
151
+ info[ :p1_addrinfo ].ip_unpack.join( ':' )
152
+ ].join( ' ' )
153
+ end.join( "\n" )
154
+
155
+ send_data( infod, data2, addrinfo )
156
+ end
157
+ end
158
+ end
data/lib/p2p2/version.rb CHANGED
@@ -1,3 +1,3 @@
1
- module P2p2
2
- VERSION = '0.26.0'.freeze
3
- end
1
+ module P2p2
2
+ VERSION = '0.27.0'.freeze
3
+ end
data/p2p2.gemspec CHANGED
@@ -1,34 +1,32 @@
1
-
2
- lib = File.expand_path("../lib", __FILE__)
3
- $LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
4
- require "p2p2/version"
5
-
6
- Gem::Specification.new do |spec|
7
- spec.name = "p2p2"
8
- spec.version = P2p2::VERSION
9
- spec.authors = ["takafan"]
10
- spec.email = ["qqtakafan@gmail.com"]
11
-
12
- spec.summary = %q{p2p}
13
- spec.description = %q{p2p通道。nat穿透。}
14
- spec.homepage = "https://github.com/takafan/p2p2"
15
- spec.license = "MIT"
16
-
17
- spec.files = %w[
18
- p2p2.gemspec
19
- lib/p2p2.rb
20
- lib/p2p2/custom.rb
21
- lib/p2p2/head.rb
22
- lib/p2p2/p1_custom.rb
23
- lib/p2p2/p1_worker.rb
24
- lib/p2p2/p1.rb
25
- lib/p2p2/p2_custom.rb
26
- lib/p2p2/p2_worker.rb
27
- lib/p2p2/p2.rb
28
- lib/p2p2/p2pd_worker.rb
29
- lib/p2p2/p2pd.rb
30
- lib/p2p2/version.rb
31
- ]
32
-
33
- spec.require_paths = ["lib"]
34
- end
1
+
2
+ lib = File.expand_path("../lib", __FILE__)
3
+ $LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
4
+ require "p2p2/version"
5
+
6
+ Gem::Specification.new do |spec|
7
+ spec.name = "p2p2"
8
+ spec.version = P2p2::VERSION
9
+ spec.authors = ["takafan"]
10
+ spec.email = ["qqtakafan@gmail.com"]
11
+
12
+ spec.summary = %q{p2p}
13
+ spec.description = %q{p2p连回家。}
14
+ spec.homepage = "https://github.com/takafan/p2p2"
15
+ spec.license = "MIT"
16
+
17
+ spec.files = %w[
18
+ p2p2.gemspec
19
+ lib/p2p2.rb
20
+ lib/p2p2/concurrent_hash.rb
21
+ lib/p2p2/head.rb
22
+ lib/p2p2/p1_worker.rb
23
+ lib/p2p2/p1.rb
24
+ lib/p2p2/p2_worker.rb
25
+ lib/p2p2/p2.rb
26
+ lib/p2p2/paird_worker.rb
27
+ lib/p2p2/paird.rb
28
+ lib/p2p2/version.rb
29
+ ]
30
+
31
+ spec.require_paths = ["lib"]
32
+ end
metadata CHANGED
@@ -1,16 +1,16 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: p2p2
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.26.0
4
+ version: 0.27.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - takafan
8
- autorequire:
8
+ autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2020-08-29 00:00:00.000000000 Z
11
+ date: 2021-07-05 00:00:00.000000000 Z
12
12
  dependencies: []
13
- description: p2p通道。nat穿透。
13
+ description: p2p连回家。
14
14
  email:
15
15
  - qqtakafan@gmail.com
16
16
  executables: []
@@ -18,23 +18,21 @@ extensions: []
18
18
  extra_rdoc_files: []
19
19
  files:
20
20
  - lib/p2p2.rb
21
- - lib/p2p2/custom.rb
21
+ - lib/p2p2/concurrent_hash.rb
22
22
  - lib/p2p2/head.rb
23
23
  - lib/p2p2/p1.rb
24
- - lib/p2p2/p1_custom.rb
25
24
  - lib/p2p2/p1_worker.rb
26
25
  - lib/p2p2/p2.rb
27
- - lib/p2p2/p2_custom.rb
28
26
  - lib/p2p2/p2_worker.rb
29
- - lib/p2p2/p2pd.rb
30
- - lib/p2p2/p2pd_worker.rb
27
+ - lib/p2p2/paird.rb
28
+ - lib/p2p2/paird_worker.rb
31
29
  - lib/p2p2/version.rb
32
30
  - p2p2.gemspec
33
31
  homepage: https://github.com/takafan/p2p2
34
32
  licenses:
35
33
  - MIT
36
34
  metadata: {}
37
- post_install_message:
35
+ post_install_message:
38
36
  rdoc_options: []
39
37
  require_paths:
40
38
  - lib
@@ -49,8 +47,8 @@ required_rubygems_version: !ruby/object:Gem::Requirement
49
47
  - !ruby/object:Gem::Version
50
48
  version: '0'
51
49
  requirements: []
52
- rubygems_version: 3.1.2
53
- signing_key:
50
+ rubygems_version: 3.2.15
51
+ signing_key:
54
52
  specification_version: 4
55
53
  summary: p2p
56
54
  test_files: []
data/lib/p2p2/custom.rb DELETED
@@ -1,12 +0,0 @@
1
- module P2p2
2
- module Custom
3
- def encode( data )
4
- # overwrite me, you'll be free
5
- data
6
- end
7
-
8
- def decode( data )
9
- data
10
- end
11
- end
12
- end
@@ -1,7 +0,0 @@
1
- require 'p2p2/custom'
2
-
3
- module P2p2
4
- class P1Custom
5
- include Custom
6
- end
7
- end
@@ -1,7 +0,0 @@
1
- require 'p2p2/custom'
2
-
3
- module P2p2
4
- class P2Custom
5
- include Custom
6
- end
7
- end
data/lib/p2p2/p2pd.rb DELETED
@@ -1,120 +0,0 @@
1
- require 'json'
2
- require 'p2p2/head'
3
- require 'p2p2/p2pd_worker'
4
- require 'p2p2/version'
5
- require 'socket'
6
-
7
- ##
8
- # P2p2::P2pd - 配对服务。
9
- #
10
- # 包结构
11
- # ======
12
- #
13
- # tund-p2pd, tun-p2pd:
14
- #
15
- # room
16
- #
17
- # p2pd-tund, p2pd-tun:
18
- #
19
- # Q>: 0 ctlmsg -> C: 1 peer addr -> tun sockaddr / tund sockaddr
20
- #
21
- # tun-tund:
22
- #
23
- # Q>: 0 ctlmsg -> C: 2 heartbeat -> C: random char
24
- # 3 a new source -> Q>: src id
25
- # 4 paired -> Q>: src id -> n: dst port
26
- # 5 dest status -> n: dst port -> Q>: biggest relayed dst pack id -> Q>: continue src pack id
27
- # 6 source status -> Q>: src id -> Q>: biggest relayed src pack id -> Q>: continue dst pack id
28
- # 7 miss -> Q>/n: src id / dst port -> Q>: pack id begin -> Q>: pack id end
29
- # 8 fin1 -> Q>/n: src id / dst port -> Q>: biggest src pack id / biggest dst pack id -> Q>: continue dst pack id / continue src pack id
30
- # 9 not use
31
- # 10 fin2 -> Q>/n: src id / dst port
32
- # 11 not use
33
- # 12 tund fin
34
- # 13 tun fin
35
- #
36
- # Q>: 1+ pack_id -> Q>/n: src id / dst port -> traffic
37
- #
38
- # close logic
39
- # ===========
40
- #
41
- # 1-1. after close src -> dst closed ? no -> send fin1
42
- # 1-2. tun recv fin2 -> del src ext
43
- #
44
- # 2-1. tun recv fin1 -> all traffic received ? -> close src after write
45
- # 2-2. tun recv traffic -> dst closed and all traffic received ? -> close src after write
46
- # 2-3. after close src -> dst closed ? yes -> del src ext -> send fin2
47
- #
48
- # 3-1. after close dst -> src closed ? no -> send fin1
49
- # 3-2. tund recv fin2 -> del dst ext
50
- #
51
- # 4-1. tund recv fin1 -> all traffic received ? -> close dst after write
52
- # 4-2. tund recv traffic -> src closed and all traffic received ? -> close dst after write
53
- # 4-3. after close dst -> src closed ? yes -> del dst ext -> send fin2
54
- #
55
- module P2p2
56
- class P2pd
57
-
58
- def initialize( config_path = nil )
59
- unless config_path
60
- config_path = File.expand_path( '../p2p2.conf.json', __FILE__ )
61
- end
62
-
63
- unless File.exist?( config_path )
64
- raise "missing config file #{ config_path }"
65
- end
66
-
67
- conf = JSON.parse( IO.binread( config_path ), symbolize_names: true )
68
- p2pd_port = conf[ :p2pd_port ]
69
- p2pd_tmp_dir = conf[ :p2pd_tmp_dir ]
70
-
71
- unless p2pd_port
72
- p2pd_port = 2020
73
- end
74
-
75
- unless p2pd_tmp_dir
76
- p2pd_tmp_dir = '/tmp/p2p2.p2pd'
77
- end
78
-
79
- unless File.exist?( p2pd_tmp_dir )
80
- Dir.mkdir( p2pd_tmp_dir )
81
- end
82
-
83
- title = "p2p2 p2pd #{ P2p2::VERSION }"
84
- puts title
85
- puts "p2pd port #{ p2pd_port }"
86
- puts "p2pd tmp dir #{ p2pd_tmp_dir }"
87
-
88
- if RUBY_PLATFORM.include?( 'linux' )
89
- $0 = title
90
-
91
- pid = fork do
92
- $0 = 'p2p2 p2pd worker'
93
- worker = P2p2::P2pdWorker.new( p2pd_port, p2pd_tmp_dir )
94
-
95
- Signal.trap( :TERM ) do
96
- puts 'exit'
97
- worker.quit!
98
- end
99
-
100
- worker.looping
101
- end
102
-
103
- Signal.trap( :TERM ) do
104
- puts 'trap TERM'
105
-
106
- begin
107
- Process.kill( :TERM, pid )
108
- rescue Errno::ESRCH => e
109
- puts e.class
110
- end
111
- end
112
-
113
- Process.waitall
114
- else
115
- P2p2::P2pdWorker.new( p2pd_port, p2pd_tmp_dir ).looping
116
- end
117
- end
118
-
119
- end
120
- end