Sha256: a3f8db7952e9931ac7376a893adaed22199ab39137da9f9d5c712c6f64e328aa
Contents?: true
Size: 1.97 KB
Versions: 2
Compression:
Stored size: 1.97 KB
Contents
# frozen_string_literal: true require 'resolv' class UringMachine class DNSResolver def initialize(machine) @machine = machine @requests = UM::Queue.new @nameservers = get_nameservers @fiber = @machine.spin { handle_requests_loop } @last_id = 0 @cache = {} end def resolve(hostname, type) @machine.push(@requests, [hostname, type, Fiber.current]) @machine.yield end def handle_requests_loop while true hostname, type, fiber = @machine.shift(@requests) res = do_resolve(hostname, type) @machine.schedule(fiber, res) end end def get_nameservers nameservers = [] IO.readlines('/etc/resolv.conf').each do |line| if line =~ /^nameserver (.+)$/ nameservers << $1.split(/\s+/).first end end nameservers end def socket_fd @socket_fd ||= prepare_socket end def prepare_socket fd = @machine.socket(UM::AF_INET, UM::SOCK_DGRAM, 0, 0) @machine.bind(fd, '0.0.0.0', 0) @machine.connect(fd, @nameservers.sample, 53) fd end def do_resolve(hostname, type, try_count = 0) fd = socket_fd req = prepare_request_packet(hostname, type) msg = req.encode @machine.send(fd, msg, msg.bytesize, 0) buf = +'' @machine.recv(fd, buf, 16384, 0) msg = Resolv::DNS::Message.decode buf addrs = [] msg.each_answer do |name, ttl, data| p [name, ttl, data] if data.kind_of?(Resolv::DNS::Resource::IN::A) || data.kind_of?(Resolv::DNS::Resource::IN::AAAA) addrs << data.address.to_s end end addrs end def prepare_request_packet(hostname, type) msg = Resolv::DNS::Message.new msg.id = (@last_id += 1) msg.rd = 1 msg.add_question hostname, msg_type(type) msg end def msg_type(type) # TODO: add support for other types Resolv::DNS::Resource::IN::A end end end
Version data entries
2 entries across 2 versions & 1 rubygems
Version | Path |
---|---|
uringmachine-0.5.1 | lib/uringmachine/dns_resolver.rb |
uringmachine-0.5 | lib/uringmachine/dns_resolver.rb |