Class: Rex::Proto::Kademlia::BootstrapResponse

Inherits:
Message
  • Object
show all
Defined in:
lib/rex/proto/kademlia/bootstrap_response.rb

Overview

A Kademlia bootstrap response message

Constant Summary collapse

BOOTSTRAP_PEER_SIZE =

The minimum size of a peer in a KADEMLIA2_BOOTSTRAP_RES message: peer ID (16-bytes), IP (4 bytes), UDP port (2 bytes), TCP port (2 bytes) and version (1 byte)

25

Constants inherited from Message

Message::COMPRESSED_PACKET, Message::STANDARD_PACKET

Instance Attribute Summary collapse

Attributes inherited from Message

#body, #type

Class Method Summary collapse

Instance Method Summary collapse

Methods inherited from Message

#==, #to_str

Constructor Details

#initialize(peer_id, tcp_port, version, peers) ⇒ BootstrapResponse

Constructs a new bootstrap response

Parameters:

  • peer_id (String)

    the ID of this peer

  • tcp_port (Integer)

    the TCP port that this peer is listening on

  • version (Integer)

    the version of this peer

  • peers (Array<Hash<String, Object>>)

    the peer ID, IP address, UDP/TCP ports and version of each peer


29
30
31
32
33
34
# File 'lib/rex/proto/kademlia/bootstrap_response.rb', line 29

def initialize(peer_id, tcp_port, version, peers)
  @peer_id = peer_id
  @tcp_port = tcp_port
  @version = version
  @peers = peers
end

Instance Attribute Details

#peer_idString (readonly)

Returns the ID of the peer that send the bootstrap response.

Returns:

  • (String)

    the ID of the peer that send the bootstrap response


15
16
17
# File 'lib/rex/proto/kademlia/bootstrap_response.rb', line 15

def peer_id
  @peer_id
end

#peersArray<Hash<String, Object>> (readonly)

Returns the peer ID, IP address, UDP/TCP ports and version of each peer.

Returns:

  • (Array<Hash<String, Object>>)

    the peer ID, IP address, UDP/TCP ports and version of each peer


21
22
23
# File 'lib/rex/proto/kademlia/bootstrap_response.rb', line 21

def peers
  @peers
end

#tcp_portInteger (readonly)

Returns the TCP port that the responding peer is listening on.

Returns:

  • (Integer)

    the TCP port that the responding peer is listening on


17
18
19
# File 'lib/rex/proto/kademlia/bootstrap_response.rb', line 17

def tcp_port
  @tcp_port
end

#versionInteger (readonly)

Returns the version of this peer.

Returns:

  • (Integer)

    the version of this peer


19
20
21
# File 'lib/rex/proto/kademlia/bootstrap_response.rb', line 19

def version
  @version
end

Class Method Details

.from_data(data) ⇒ BootstrapResponse

Builds a bootstrap response from given data

Parameters:

  • data (String)

    the data to decode

Returns:


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
# File 'lib/rex/proto/kademlia/bootstrap_response.rb', line 45

def self.from_data(data)
  message = Message.from_data(data)
  # abort if this isn't a valid response
  return unless message
  return unless message.type == BOOTSTRAP_RESPONSE
  return unless message.body.size >= 23
  bootstrap_peer_id = Rex::Proto::Kademlia.decode_peer_id(message.body.slice!(0, 16))
  bootstrap_tcp_port, bootstrap_version, num_peers = message.body.slice!(0, 5).unpack('vCv')
  # protocol says there are no peers and the body confirms this, so just return with no peers
  if num_peers == 0 && message.body.to_s.strip.empty?
    peers = []
  else
    peers_data = message.body
    # peers data is too long/short, abort
    return if peers_data.size % BOOTSTRAP_PEER_SIZE != 0
    peers = []
    until peers_data.to_s.strip.empty?
      peer_data = peers_data.slice!(0, BOOTSTRAP_PEER_SIZE)
      peer_id = Rex::Proto::Kademlia.decode_peer_id(peer_data.slice!(0, 16))
      ip, udp_port, tcp_port, version = peer_data.unpack('VvvC')
      peers << {
        id: peer_id,
        ip: Rex::Socket.addr_itoa(ip),
        tcp_port: tcp_port,
        udp_port: udp_port,
        version: version
      }
    end
  end
  BootstrapResponse.new(bootstrap_peer_id, bootstrap_tcp_port, bootstrap_version, peers)
end