p2p2 0.22.0 → 0.27.0

Sign up to get free protection for your applications and to get access to all the features.
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.22.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{内网里的任意应用,访问另一个内网里的应用服务端。}
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.22.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-07-08 00:00:00.000000000 Z
11
+ date: 2021-07-05 00:00:00.000000000 Z
12
12
  dependencies: []
13
- description: 内网里的任意应用,访问另一个内网里的应用服务端。
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,9 +47,8 @@ required_rubygems_version: !ruby/object:Gem::Requirement
49
47
  - !ruby/object:Gem::Version
50
48
  version: '0'
51
49
  requirements: []
52
- rubyforge_project:
53
- rubygems_version: 2.7.6.2
54
- signing_key:
50
+ rubygems_version: 3.2.15
51
+ signing_key:
55
52
  specification_version: 4
56
53
  summary: p2p
57
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