Index: src/resolver.cr ================================================================== --- src/resolver.cr +++ src/resolver.cr @@ -1,5 +1,6 @@ +require "./rr" require "./settings" module AsyncDNS class Resolver getter :settings ADDED src/rr.cr Index: src/rr.cr ================================================================== --- /dev/null +++ src/rr.cr @@ -0,0 +1,103 @@ +require "socket" + +module AsyncDNS + abstract struct RR + property :name, :class, :type, :ttl + + def initialize(@name : String, @class : DNSClass, @type : RRType, + @ttl : Int32) + end + + struct A < RR + property :address + + def initialize(name, @address : Socket::IPAddress, ttl) + super(name, DNSClass::IN, RRType::A, ttl) + end + end + + struct AAAA < RR + property :address + + def initialize(name, @address : Socket::IPAddress, ttl) + super(name, DNSClass::IN, RRType::AAAA, ttl) + end + end + + struct CNAME < RR + property :alias + + def initialize(name, @alias : String, ttl) + super(name, DNSClass::IN, RRType::CNAME, ttl) + end + end + + struct HINFO < RR + property :cpu, :os + + def initialize(name, @cpu : String, @os : String, ttl) + super(name, DNSClass::IN, RRType::HINFO, ttl) + end + end + + struct MX < RR + property :preference, :mx + + def initialize(name, @preference : UInt16, @mx : String, ttl) + super(name, DNSClass::IN, RRType::MX, ttl) + end + end + + struct NS < RR + property :authority + + def initialize(name, @authority : String, ttl) + super(name, DNSClass::IN, RRType::NS, ttl) + end + end + + struct PTR < RR + property :domain + + def initialize(name, @domain : String, ttl) + super(name, DNSClass::IN, RRType::PTR, ttl) + end + end + + struct RP < RR + property :mailbox, :domain + + def initialize(name, @mailbox : String, @domain : String, ttl) + super(name, DNSClass::IN, RRType::RP, ttl) + end + end + + struct SOA < RR + property :primary_ns, :responsible, :serial, :refresh, :retry, + :expire, :min_ttl + + def initialize(name, @primary_ns : String, @responsible : String, + @serial : UInt32, @refresh : UInt32, @retry : UInt32, + @expire : UInt32, @min_ttl : UInt32) + super(name, DNSClass::IN, RRType::SOA, ttl) + end + end + + struct SRV < RR + property :prio, :weight, :target, :port + + def initialize(name, @prio : UInt16, @weight : UInt16, @target : String, + @port : UInt16, ttl) + super(name, DNSClass::IN, RRType::SRV, ttl) + end + end + + struct TXT < RR + property :text + + def initialize(name, @text : Array(String), ttl) + super(name, DNSClass::IN, RRType::TXT) + end + end + end +end Index: src/settings.cr ================================================================== --- src/settings.cr +++ src/settings.cr @@ -1,12 +1,8 @@ -require "time" - module AsyncDNS class Settings @local_domain : String? - @reload_period : Time::Span - @last_reload : Time? property static_hosts, nameservers, local_domain, search_domains, uses_tcp getter timeout, max_attempts, abs_num_dots def timeout=(timeout) @@ -38,21 +34,29 @@ @timeout = Time::Span.new(seconds: 2) @max_attempts = 3 @abs_num_dots = 1 @uses_tcp = false @reload_period = Time::Span.new(seconds: 2) + @last_reload = Time::Span.zero - self.reload + reload end def reload - {% if flag?(:unix) %} - self.parse_hosts "/etc/hosts" - self.parse_resolv_conf "/etc/resolv.conf" + return if Time.monotonic - @last_reload < @reload_period + + {% if flag?(:haiku) %} + parse_hosts "/system/settings/network/hosts" + parse_resolv_conf "/system/settings/network/resolv.conf" + {% elsif flag?(:unix) %} + parse_hosts "/etc/hosts" + parse_resolv_conf "/etc/resolv.conf" {% else %} - {% raise "Your OS is not supported by AsyncDNS" %} + {% raise "Your OS is not supported by AsyncDNS" %} {% end %} + + @last_reload = Time.monotonic end def parse_hosts(path) @static_hosts.clear Index: tests/example.cr ================================================================== --- tests/example.cr +++ tests/example.cr @@ -1,14 +1,9 @@ require "../src/asyncdns" AsyncDNS::Query.new("crystal-lang.org", AsyncDNS::DNSClass::IN, AsyncDNS::RRType::A) -settings = AsyncDNS::Settings.new -p settings.static_hosts -p settings.nameservers -p settings.local_domain -p settings.search_domains -p settings.uses_tcp -p settings.timeout -p settings.max_attempts -p settings.abs_num_dots +resolver = AsyncDNS::Resolver.new + +AsyncDNS::RR::A.new("crystal-lang.org", Socket::IPAddress.new("127.0.0.1", 0), + 1234)