sping 1.0.3 → 1.0.4

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 74faa9103509651e47d2f098c22b66fae80ca1ba0b71b132aa636d26bf1e0f04
4
- data.tar.gz: 9ae6b44c52ded9e1999eb3fe467216b6d640747d11a8b69f4eed864efeb30a03
3
+ metadata.gz: 9f7679b3fb31d07d034182114e576f3e272ef8223954f592bb30a98378b98fd5
4
+ data.tar.gz: b8d21d6a58ffb3c57481cc421d61f8fc25da32646fb8d5ae160829017d01fb14
5
5
  SHA512:
6
- metadata.gz: c08fcd7358309abe6a7f67044bbf267f31cba483786dc387b78ef14e8ce32801b067bd2ca8e2a545e141d3ffe843d004a4427d1a91cba1cbdd8d154679344653
7
- data.tar.gz: 56ea68be301c25d116657775aabf26a9fb9fdf41cf2224ff9dcd72be1b897f20b076e9d0f4a1154ec777c53f20eeff173ded69985c993c99169198290f66a092
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
- class LastAcks
5
- attr_reader :size
4
+ module SPing
5
+ class LastAcks
6
+ attr_reader :size
6
7
 
7
- def initialize(size = 32)
8
- @size = size
9
- @acks = []
10
- @acks_mutex = Mutex.new
8
+ def initialize(size = 32)
9
+ @size = size
10
+ @acks = []
11
+ @acks_mutex = Mutex.new
11
12
 
12
- @size.times do |index|
13
- @acks[index] = {
14
- 'R' => 0,
15
- 'U' => Time.at(0),
16
- 'X' => Time.at(0)
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
- def acks
22
- @acks_mutex.synchronize do
23
- return @acks.dup
22
+ def acks
23
+ @acks_mutex.synchronize do
24
+ return @acks.dup
25
+ end
24
26
  end
25
- end
26
27
 
27
- def add_ack(ack)
28
- @acks_mutex.synchronize do
29
- @acks << ack
28
+ def add_ack(ack)
29
+ @acks_mutex.synchronize do
30
+ @acks << ack
30
31
 
31
- @acks.shift if @acks.length > @size
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
- class SessionError < StandardError; end
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['E'] != 0
161
- $logger.error "Package displays an error message: #{packet['E']} Processing aborted."
162
- return
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,
@@ -2,8 +2,7 @@
2
2
  # sharable_constant_value: literal
3
3
 
4
4
  module SPing
5
- class SessionManagerError < StandardError; end
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
- $logger.warn 'Package contains incorrect magic number. Processing is canceled.'
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
- $logger.warn "Package is of unknown type: #{type}"
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
- if session
213
- if packet['V'] != 3
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
- if session.udp_handshake_complete
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
- session.udp_handshake_recived
233
- $logger.info "UDP handshake for session ID #{session_id} was successful."
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
- session.start_pinger
236
- else
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
- if session&.tcp_handshake_complete && session&.udp_handshake_complete
246
- session.set_endpoint peeraddr, peerport
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.3
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-09 00:00:00.000000000 Z
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.21
72
+ rubygems_version: 3.4.22
72
73
  signing_key:
73
74
  specification_version: 4
74
75
  summary: Reimplementation of sping in Ruby.