Skip to content

Instantly share code, notes, and snippets.

@sj26
Created October 18, 2014 06:07
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save sj26/f61464f3814f4fc5094d to your computer and use it in GitHub Desktop.
Save sj26/f61464f3814f4fc5094d to your computer and use it in GitHub Desktop.
require "ipaddr"
require "resolv"
require "socket"
class MDNS
IP = "224.0.0.251"
PORT = 5353
TTL = 255
def initialize(hosts=[])
@host = Socket.gethostname
@addr = Socket.getaddrinfo(@host, 0, Socket::AF_INET, Socket::SOCK_STREAM)[0][3]
@hosts = Array(hosts)
@socket = UDPSocket.new
@socket.setsockopt(Socket::SOL_SOCKET, Socket::SO_REUSEADDR, true)
@socket.setsockopt(Socket::SOL_SOCKET, Socket::SO_REUSEPORT, true)
@socket.setsockopt(Socket::IPPROTO_IP, Socket::IP_ADD_MEMBERSHIP, IPAddr.new(IP).hton + IPAddr.new(addr).hton)
@socket.setsockopt(Socket::IPPROTO_IP, Socket::IP_TTL, TTL)
@socket.setsockopt(Socket::IPPROTO_IP, Socket::IP_MULTICAST_TTL, TTL)
@socket.bind(Socket::INADDR_ANY, PORT)
end
attr_reader :host, :addr
attr_accessor :hosts
def run
Socket.udp_server_loop_on([@socket]) do |data, source|
begin
request = Resolv::DNS::Message.decode(data)
p request: request
if request.qr == 0
asked_hosts = request.question.map(&:first).map(&:to_s)
have_hosts = asked_hosts & hosts
unless have_hosts.empty?
response = Resolv::DNS::Message.new(request.id)
response.rd = 0
response.qr = 1
response.aa = 1
have_hosts.each do |host|
response.add_answer(host, TTL, Resolv::DNS::Resource::IN::A.new(addr))
end
p response: response
source.reply(response.encode)
end
end
rescue
puts "Error responding to: #{data.inspect} #{source.inspect}:", $!, *$!.backtrace
end
end
end
end
MDNS.new(["github.com", "railscamp.local", "railscamps.local", "rubygems.local", "twetter.local", "twitter.local"]).run
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment