class MDNS
Constants
- MDNS_PORT
- MULTICAST_IP
- VERSION
Public Class Methods
add_record(host, ttl, ip)
click to toggle source
# File lib/mdns.rb, line 70 def add_record(host, ttl, ip) records[host] = Record.new(host, ttl, ip) respond(records[host]) end
hosts()
click to toggle source
# File lib/mdns.rb, line 79 def hosts records.keys end
records()
click to toggle source
# File lib/mdns.rb, line 75 def records @records ||= {} end
reset()
click to toggle source
# File lib/mdns.rb, line 83 def reset @records = nil stop end
respond(record, query = nil, ip = MULTICAST_IP, port = MDNS_PORT)
click to toggle source
# File lib/mdns.rb, line 53 def respond(record, query = nil, ip = MULTICAST_IP, port = MDNS_PORT) return if !@socket || @socket.closed? # I have no idea what I'm doing response = Resolv::DNS::Message.new(query ? query.id : 0) response.qr = 1 response.opcode = 0 response.aa = 1 response.rd = 0 response.ra = 0 response.rcode = 0 if query response.add_question(*query.question.first) end response.add_answer(record.host, record.ttl, Resolv::DNS::Resource::IN::A.new(record.ip)) @socket.send(response.encode, 0, ip, port) end
start()
click to toggle source
# File lib/mdns.rb, line 12 def start @socket = UDPSocket.new @socket.setsockopt(Socket::SOL_SOCKET, Socket::SO_REUSEADDR, true) @socket.setsockopt(Socket::SOL_SOCKET, Socket::SO_REUSEPORT, true) if Socket.const_defined?("SO_REUSEPORT") ip_mreq = IPAddr.new(MULTICAST_IP).hton + IPAddr.new('0.0.0.0').hton @socket.setsockopt(Socket::IPPROTO_IP, Socket::IP_ADD_MEMBERSHIP, ip_mreq) @socket.setsockopt(Socket::IPPROTO_IP, Socket::IP_TTL, 255) @socket.setsockopt(Socket::IPPROTO_IP, Socket::IP_MULTICAST_TTL, 255) @socket.bind(Socket::INADDR_ANY, MDNS_PORT) Thread.abort_on_exception = true @thr = Thread.new do loop do data, address = @socket.recvfrom(1024) packet = begin Resolv::DNS::Message.decode(data) rescue Resolv::DNS::DecodeError nil # Invalid DNS data rescue nil # Sometimes it errors out due to non DNS data end next if packet.nil? if packet.qr == 0 hosts = packet.question.map(&:first).map(&:to_s) matches = self.hosts & hosts matches.each do |host| respond(records[host], packet, address[3], address[1]) end end end end # Broadcast records records.values.each do |record| respond(record) end at_exit do stop end end
stop()
click to toggle source
# File lib/mdns.rb, line 88 def stop if @thr @thr.kill @thr = nil end if @socket && !@socket.closed? @socket.close end end