sping 1.0.3 → 1.0.4
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/errors.rb +20 -0
- data/lib/last_acks.rb +23 -21
- data/lib/session.rb +24 -6
- data/lib/session_manager.rb +44 -34
- metadata +4 -3
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 9f7679b3fb31d07d034182114e576f3e272ef8223954f592bb30a98378b98fd5
|
4
|
+
data.tar.gz: b8d21d6a58ffb3c57481cc421d61f8fc25da32646fb8d5ae160829017d01fb14
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: a6a2c6897ead8f7371b2f1a83719c1a8f2c07d44957a9c302bc548855d25671858435fe0d6e8162e14737e065f6bbcede37defd2ea21e23561d19e7f8d5ef63f
|
7
|
+
data.tar.gz: 2618e70abea52acc38364f7fb431dafa12a4d48ad8f07665f93ac76e316784e6a2f8f5d2b463a55053da88b10f46dc23adf16846abb1a4b1d4677eb9eef09e7f
|
data/lib/errors.rb
ADDED
@@ -0,0 +1,20 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
# sharable_constant_value: literal
|
3
|
+
|
4
|
+
module SPing
|
5
|
+
class SPingError < StandardError; end
|
6
|
+
|
7
|
+
class SessionManagerError < SPingError; end
|
8
|
+
class OutOfSessions < SessionManagerError; end
|
9
|
+
|
10
|
+
class SessionError < SPingError; end
|
11
|
+
class TCPHandshakeError < SessionError; end
|
12
|
+
|
13
|
+
class PeerError < SPingError; end
|
14
|
+
class InvalidPacketError < PeerError; end
|
15
|
+
class InvalidMessageError < InvalidPacketError; end
|
16
|
+
class UnknownPacketError < InvalidPacketError; end
|
17
|
+
class SignalizedError < PeerError; end
|
18
|
+
class UnknownVersionError < PeerError; end
|
19
|
+
class UnknownSessionError < PeerError; end
|
20
|
+
end
|
data/lib/last_acks.rb
CHANGED
@@ -1,34 +1,36 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
# sharable_constant_value: literal
|
3
3
|
|
4
|
-
|
5
|
-
|
4
|
+
module SPing
|
5
|
+
class LastAcks
|
6
|
+
attr_reader :size
|
6
7
|
|
7
|
-
|
8
|
-
|
9
|
-
|
10
|
-
|
8
|
+
def initialize(size = 32)
|
9
|
+
@size = size
|
10
|
+
@acks = []
|
11
|
+
@acks_mutex = Mutex.new
|
11
12
|
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
|
13
|
+
@size.times do |index|
|
14
|
+
@acks[index] = {
|
15
|
+
'R' => 0,
|
16
|
+
'U' => Time.at(0),
|
17
|
+
'X' => Time.at(0)
|
18
|
+
}
|
19
|
+
end
|
18
20
|
end
|
19
|
-
end
|
20
21
|
|
21
|
-
|
22
|
-
|
23
|
-
|
22
|
+
def acks
|
23
|
+
@acks_mutex.synchronize do
|
24
|
+
return @acks.dup
|
25
|
+
end
|
24
26
|
end
|
25
|
-
end
|
26
27
|
|
27
|
-
|
28
|
-
|
29
|
-
|
28
|
+
def add_ack(ack)
|
29
|
+
@acks_mutex.synchronize do
|
30
|
+
@acks << ack
|
30
31
|
|
31
|
-
|
32
|
+
@acks.shift if @acks.length > @size
|
33
|
+
end
|
32
34
|
end
|
33
35
|
end
|
34
36
|
end
|
data/lib/session.rb
CHANGED
@@ -2,8 +2,7 @@
|
|
2
2
|
# sharable_constant_value: literal
|
3
3
|
|
4
4
|
module SPing
|
5
|
-
|
6
|
-
class TCPHandshakeError < SessionError; end
|
5
|
+
require_relative 'errors'
|
7
6
|
|
8
7
|
class Session
|
9
8
|
attr_reader :created, :last_rx, :madebyme
|
@@ -24,7 +23,7 @@ module SPing
|
|
24
23
|
@tcp_handshake_complete = false
|
25
24
|
@udp_handshake_complete = false
|
26
25
|
|
27
|
-
@last_acks = LastAcks.new
|
26
|
+
@last_acks = SPing::LastAcks.new
|
28
27
|
end
|
29
28
|
|
30
29
|
def do_tcp_handshake1(socket, session_id)
|
@@ -157,15 +156,34 @@ module SPing
|
|
157
156
|
end
|
158
157
|
|
159
158
|
def handle_ping(packet, rxtime, peeraddr)
|
160
|
-
if packet[
|
161
|
-
|
162
|
-
|
159
|
+
if !(packet.keys - %w[M Y E I T A S]).empty? ||
|
160
|
+
# M, Y are already checked in handle_packet from session manager
|
161
|
+
!packet['E'].is_a?(Integer) ||
|
162
|
+
!packet['I'].is_a?(Integer) ||
|
163
|
+
!packet['T'].is_a?(Time) ||
|
164
|
+
!packet['A'].is_a?(Array)
|
165
|
+
raise InvalidPacketError, 'The peer has sent an invalid message. The ping packet is incorrectly coded.'
|
163
166
|
end
|
164
167
|
|
168
|
+
raise SignalizedError, "Package displays an error message: #{packet['E']} Processing aborted." if packet['E'] != 0
|
169
|
+
|
165
170
|
id = packet['I']
|
166
171
|
txtime = packet['T']
|
167
172
|
remote_last_acks = packet['A']
|
168
173
|
|
174
|
+
if remote_last_acks.length != 32
|
175
|
+
raise InvalidMessageError, 'The peer has sent an invalid message. It does not contain any 32-Acks.'
|
176
|
+
end
|
177
|
+
|
178
|
+
remote_last_acks.each do |block_ack|
|
179
|
+
if !(block_ack.keys - %w[R U X]).empty? ||
|
180
|
+
!block_ack['R'].is_a?(Integer) ||
|
181
|
+
!block_ack['U'].is_a?(Time) ||
|
182
|
+
!block_ack['X'].is_a?(Time)
|
183
|
+
raise InvalidMessageError, 'The peer has sent an invalid message. An Ack is formatted invalid.'
|
184
|
+
end
|
185
|
+
end
|
186
|
+
|
169
187
|
ack = {
|
170
188
|
'R' => id,
|
171
189
|
'U' => txtime,
|
data/lib/session_manager.rb
CHANGED
@@ -2,8 +2,7 @@
|
|
2
2
|
# sharable_constant_value: literal
|
3
3
|
|
4
4
|
module SPing
|
5
|
-
|
6
|
-
class OutOfSessions < SessionManagerError; end
|
5
|
+
require_relative 'errors'
|
7
6
|
|
8
7
|
class SessionManager
|
9
8
|
require 'socket'
|
@@ -187,12 +186,20 @@ module SPing
|
|
187
186
|
peerport = buf[1][1]
|
188
187
|
$logger.debug "Packet received from #{peeraddr} port #{peerport}."
|
189
188
|
|
190
|
-
packet = MessagePack.unpack(buf[0])
|
189
|
+
packet = MessagePack.unpack(buf[0]).to_h
|
190
|
+
|
191
|
+
if !packet.key?('M') ||
|
192
|
+
!packet.key?('Y') ||
|
193
|
+
!packet.key?('S') ||
|
194
|
+
!packet['M'].is_a?(Integer) ||
|
195
|
+
!packet['Y'].is_a?(Integer) ||
|
196
|
+
!packet['S'].is_a?(Integer)
|
197
|
+
raise InvalidMessageError, 'The peer has sent an invalid message. The packet is incorrectly coded.'
|
198
|
+
end
|
191
199
|
|
192
200
|
# Check whether the Magic Number is the correct one.
|
193
201
|
if packet['M'] != 11_181
|
194
|
-
|
195
|
-
return
|
202
|
+
raise UnknownPacketError, 'Package contains incorrect magic number. Processing is canceled.'
|
196
203
|
end
|
197
204
|
|
198
205
|
type = packet['Y'].chr
|
@@ -202,52 +209,55 @@ module SPing
|
|
202
209
|
when 't'
|
203
210
|
handle_ping packet, rxtime, peeraddr, peerport
|
204
211
|
else
|
205
|
-
|
212
|
+
raise UnknownPacketError, "Package is of unknown type: #{type}"
|
206
213
|
end
|
214
|
+
rescue MessagePack::MalformedFormatError => e
|
215
|
+
$logger.error "Packet cannot be decoded: #{e.message}"
|
216
|
+
rescue PeerError => e
|
217
|
+
$logger.error "Perr error: #{e.message}"
|
207
218
|
end
|
208
219
|
|
209
220
|
def handle_udp_handshake(packet, peeraddr, peerport)
|
221
|
+
if !(packet.keys - %w[M Y V S]).empty? ||
|
222
|
+
# M, Y are already checked in handle_packet from session manager
|
223
|
+
!packet['V'].is_a?(Integer)
|
224
|
+
raise InvalidMessageError, 'The peer has sent an invalid message. The handshake packet is incorrectly coded.'
|
225
|
+
end
|
226
|
+
|
210
227
|
session_id = packet['S']
|
211
228
|
session = @sessions[session_id]
|
212
|
-
|
213
|
-
|
214
|
-
$logger.warn "UDP handshake uses an unsupported version: #{packet['V']}"
|
215
|
-
return
|
216
|
-
end
|
217
|
-
|
218
|
-
session.set_endpoint peeraddr, peerport
|
219
|
-
|
220
|
-
unless session.madebyme
|
221
|
-
# If the session was not started by me, the other peer expects a
|
222
|
-
# confirmation of the handshake in which the same is sent back.
|
223
|
-
$logger.debug "Send UDP Handshake back for session id #{session_id}."
|
224
|
-
session.send_udp_handshake
|
225
|
-
end
|
229
|
+
raise UnknownSessionError, 'UDP handshake received for uninitiated session.' unless session
|
230
|
+
raise UnknownVersionError, "UDP handshake uses an unsupported version: #{packet['V']}" if packet['V'] != 3
|
226
231
|
|
227
|
-
|
228
|
-
$logger.warn 'UDP handshake is received, although a previous one was already successful.'
|
229
|
-
return
|
230
|
-
end
|
232
|
+
session.set_endpoint peeraddr, peerport
|
231
233
|
|
232
|
-
|
233
|
-
|
234
|
+
unless session.madebyme
|
235
|
+
# If the session was not started by me, the other peer expects a
|
236
|
+
# confirmation of the handshake in which the same is sent back.
|
237
|
+
$logger.debug "Send UDP Handshake back for session id #{session_id}."
|
238
|
+
session.send_udp_handshake
|
239
|
+
end
|
234
240
|
|
235
|
-
|
236
|
-
|
237
|
-
$logger.warn 'UDP handshake received for uninitiated session.'
|
241
|
+
if session.udp_handshake_complete
|
242
|
+
$logger.warn 'UDP handshake is received, although a previous one was already successful.'
|
238
243
|
return
|
239
244
|
end
|
245
|
+
|
246
|
+
session.udp_handshake_recived
|
247
|
+
$logger.info "UDP handshake for session ID #{session_id} was successful."
|
248
|
+
|
249
|
+
session.start_pinger
|
240
250
|
end
|
241
251
|
|
242
252
|
def handle_ping(packet, rxtime, peeraddr, peerport)
|
243
253
|
session_id = packet['S']
|
244
254
|
session = @sessions[session_id]
|
245
|
-
|
246
|
-
|
247
|
-
session.handle_ping packet, rxtime, peeraddr
|
248
|
-
else
|
249
|
-
$logger.warn "Ping packet received for non-initiated session id #{session_id}."
|
255
|
+
unless session&.tcp_handshake_complete && session&.udp_handshake_complete
|
256
|
+
raise UnknownSessionError, "Ping packet received for non-initiated session id #{session_id}."
|
250
257
|
end
|
258
|
+
|
259
|
+
session.set_endpoint peeraddr, peerport
|
260
|
+
session.handle_ping packet, rxtime, peeraddr
|
251
261
|
end
|
252
262
|
|
253
263
|
def handle_client(client)
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: sping
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 1.0.
|
4
|
+
version: 1.0.4
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Marek Küthe
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2023-11-
|
11
|
+
date: 2023-11-10 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: msgpack
|
@@ -43,6 +43,7 @@ files:
|
|
43
43
|
- LICENSE
|
44
44
|
- README.md
|
45
45
|
- bin/sping
|
46
|
+
- lib/errors.rb
|
46
47
|
- lib/last_acks.rb
|
47
48
|
- lib/session.rb
|
48
49
|
- lib/session_manager.rb
|
@@ -68,7 +69,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
68
69
|
- !ruby/object:Gem::Version
|
69
70
|
version: '0'
|
70
71
|
requirements: []
|
71
|
-
rubygems_version: 3.4.
|
72
|
+
rubygems_version: 3.4.22
|
72
73
|
signing_key:
|
73
74
|
specification_version: 4
|
74
75
|
summary: Reimplementation of sping in Ruby.
|