Class: NetworkClipboard::Discovery

Inherits:
Object
  • Object
show all
Defined in:
lib/network_clipboard/discovery.rb

Instance Attribute Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(config) ⇒ Discovery

Returns a new instance of Discovery.



9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
# File 'lib/network_clipboard/discovery.rb', line 9

def initialize(config)
  @config = config

  @receive_socket = UDPSocket.new()
  @receive_socket.setsockopt(:IPPROTO_IP, :IP_ADD_MEMBERSHIP, multicast_addr.hton + bind_addr.hton)
  @receive_socket.bind(bind_addr.to_s,port)

  @send_socket = UDPSocket.new()
  @send_socket.setsockopt(:IPPROTO_IP, :IP_MULTICAST_TTL, 1)
  @send_socket.connect(multicast_addr.to_s,port)

  @authenticated_client_id = [
    @config.client_id,
    Digest::HMAC.digest(@config.secret,@config.client_id,Digest::SHA256),
  ].pack("H32A32")
end

Instance Attribute Details

#receive_socketObject (readonly)

Returns the value of attribute receive_socket.



7
8
9
# File 'lib/network_clipboard/discovery.rb', line 7

def receive_socket
  @receive_socket
end

Instance Method Details

#announceObject



38
39
40
# File 'lib/network_clipboard/discovery.rb', line 38

def announce
  @send_socket.send(@authenticated_client_id,0)
end

#bind_addrObject



30
31
32
# File 'lib/network_clipboard/discovery.rb', line 30

def bind_addr
  @bind_addr ||= IPAddr.new('0.0.0.0')
end

#get_peer_announcementObject



42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
# File 'lib/network_clipboard/discovery.rb', line 42

def get_peer_announcement
  while true
    msg,ip = @receive_socket.recvfrom(65536)
    other_client_id,other_digest = msg.unpack('H32A32')

    # Retry if we got our own announcement.
    next if other_client_id == @config.client_id

    # We could do a constant time string compare, but an attacker can
    # just listen to announces and rebroadcast them as his own anyway.
    # This is just to skip other honest clients with different secrets
    # on the network, to avoid wasting time on a failed handshake.
    next unless other_digest == Digest::HMAC.digest(@config.secret,other_client_id,Digest::SHA256)

    return [other_client_id,ip[2]]
  end
end

#multicast_addrObject



34
35
36
# File 'lib/network_clipboard/discovery.rb', line 34

def multicast_addr
  @multicast_addr ||= IPAddr.new(@config.multicast_ip)
end

#portObject



26
27
28
# File 'lib/network_clipboard/discovery.rb', line 26

def port
  @port ||= @config.port
end