uo2(      !"#$%&'"HResource record types. There store the actual data in the DNS database.  There's one for each DNSType  $a list of preferences and hostnames Error codes. RFC 1035, 4.1.1. The name server refuses to perform the specified operation for policy reasons. For example, a name server may not wish to provide the information to the particular requester, or a name server may not wish to perform a particular operation (e.g., zone transfer) for particular data. >The name server does not support the requested kind of query. Meaningful only for responses from an authoritative name server, this code signifies that the domain name referenced in the query does not exist WThe name server was unable to process this query due to a problem with the name server 2The name server was unable to interpret the query )Types of DNS resources. RFC 1035, 3.2.2. $This is for internal error handling , and should never be used or seen outside  Network.DNS  !4Given an RR, this tells you the resource type of it "  !"   !"     !$()*+,(A DNS protocol header. RFC 1035, 4.1.1. -./0123456789:'Types of DNS queries. RFC 1035, 4.1.1. ;<=>MParse an enum from a Word8 in a monad and fail if the value is out of range.  It'Js assumed that the enum is defined at every value between the min and max  bound ?@A=Break a DNS name (e.g. www.google.com) into a list of labels B?Convert a split name into the length-prefixed DNS wire format. C FIXME: should work with the IDNA system. Returns Nothing if the  name couldn't be serialised. 3 FIXME: catch invalid charactors and > 255 parts CEConvert a list of labels to a normal string by interspersing periods DEthe encoded name (see serialiseDNSName) the type of the question FGHIJK$()*+,-./0123456789:;<=>?@ABCDEFGHIJK$()**+, -./0123456789-./0123456789:=<;;<=>?@ABCDEFGHIJKLJThis is the result of parsing a resolv.conf like file. The search path is  either taken from a search line in the config, a domain line in the ; config or from the domainname of the current host. If it's taken from the , config, the last line takes precedent. It's in a form like:  0 [["london", "myorg", "org"], ["myorg", "org"]] KThe maybe members are set to the found values if they are there. Otherwise  they are Nothing. MN#a list of IPs in big-endian format Othe search path PQRLMNOPQRSLMNOPQRMNOPQR6TUVWXGThis is a list of lists of labels. If a requested domain name is short  enougth (see ndots) it'"s tried with these suffixes first Y?If a name has this many dots, we try an initial absolute query ZNumber of attempts per request [-Number of seconds to wait for the nameserver \#This is the next nameserver to try ])This is an infinite list of random seeds ^_` ip address a&do we believe that this server is up? bc*how many requests have timed out in a row defthe question section ghthe current name being queried ialternative names to try jnumber of times transmitted k the timeout lthe type of the query ; | In the case that we need to always send this request to ! a specific nameserver (e.g. it's a probe packet), this " is set to a non-Nothing value. m"6This is the type of errors from the library. Either it's one of the first @ two errors (which are generated from within this code), or it' s an error ! directly from the DNS server. #errors from the DNS server $6this is returned when the DNS server returned a valid  answer, but the answer didn't include the information we & were looking for. Firstly, this isn't a recursive : resolver, so if you point it at a non-recursive server  you'6ll get this for nearly every query as the server will 1 just be telling us the location of the roots. 6This can also occur when you ask for a resource which  doesn'1t exist - like a AAAA record from www.google.com %the DNS server didn' t answer noDThis is the max number of requests which can be outstanding against K any one server at a time. Since, to generate ids, we roll until we find I a good id setting this > 60000 is dangerous. If it hit 2**16 we would  livelock pDThis is a socket that is bound, locally, to a port and all outgoing  packets are written to it. It'%s also the socket that we listen on. q Lookup a reply from the network The id of the reply The IP address of the source r!This function never returns an it's expected that it runs in it's own - thread, forever reading from the network. sIThere can only ever really be a single config in action at any one time, " because there is only a single  readerThread. One could imaging having a M socket bound to get packets only from a single nameserver, and that would / work so long as the sets of nameservers didn't overlap. However, I don't  think that' s a common requirement, so I don't support it. t"Build a ResolverConfig by parsing etc resolv.conf uHPick a nameserver from a config. We try to round robin the nameservers, L avoiding the down nameservers. If all nameservers are down, we just pick  one anyway. vwIThis is the maximum number of timeouts, in a row, that can happen from a M single nameserver before we consider that server to be down. When we mark N a server as down we start sending probes to it. Once it responds to one of 0 those probes with anything save a Timeout, we'll mark it good again. xBThis is the callback from a probe request. If it came back with a 1 reasonable reply we mark the nameserver as up yAThis is a timeout callback. The timeout is called when we mark a N nameserver as down. This timeout is to start a probe. If the probe returns < any kind of DNS packet, we call the nameserver up again. z$the config when the request started *the id of the request which has timed out !the IP address of the nameserver {|}CIncrement the attempts, pop the next name from the search list and  transmit the given inflight ~CThis is for when we get a timeout or ServerError - there might not 4 be anything wrong with the query so we retry it. FThis is for when we have a harder error - either multiple timeouts or M NXDomain etc from the server. The timeout must have been canceled by here @This has to turn the information from the server into something D useful for the caller. At the moment this is pretty stupid, just * grab A records from the answer section &!Lookup some information from DNS &the type of DNS information requested the domain to query The RR values here will  always be of the correct  type for the requested  DNSType 'KThis is the same as resolve, below, put you get the answer asynchronously. H Blocking the thread which makes the callback in this case is bad - it'll ) block the DNS network reading thread. (  !"#$%&'&'"%$#"%$##$%&'      !"#$%&''()*+,--.//0123456789:;<=>?@ABCDEFGHIJKLMNNOPQRSTUVVWXYZ[\]^^_`abccdefghijklmnopqrstuvwxyz{|}~network-dns-0.1.2Network.DNS.TypesNetwork.DNS.ClientNetwork.DNS.CommonNetwork.DNS.ResolveConfParseRRRRAAAARRARRTXTRRSOAsoaNamesoaRname soaSerial soaRefreshsoaRetry soaExpire soaMinTTLRRPTRRRNSRRMXRRCNAME ResponseCode AccessDeniedNotImplementedNXDomain ServerError FormatErrorNoErrorDNSTypeUnknownDNSTypeAAAATXTMXPTRSOACNAMENSArrToTypeDNSErrorAnswerNotIncludedTimeoutresolve resolveAsynchtonlPacketEntryHeaderheadIdheadIsResponse headOpCodeheadIsAuthoritativeheadIsTruncatedheadRecursionDesiredheadRecursionAvailibleheadResponseCodeheadQuestionCountheadAnswerCount headNSCountheadAdditionalCount QueryType SERVERSTATUSIQUERYQUERY parseEnum parseHeaderserialiseHeader splitDNSNameserialiseDNSName fromDNSName parseDNSNameserialiseQuestion parseQuestion parseDNSTypedeserialiseQuestionparseGenericRRparseRR parsePacket ResolveConfresolveNameservers resolveSearch resolveNdotsresolveTimeoutresolveAttemptsparseResolveConfDNSDBResolverConfig rcNameservers rcSearchPathrcNdots rcAttempts rcTimeoutrcRobinrcSeeds Nameserver nsAddressnsUp nsInflight nsTimeoutsInflightRequest infRequest infCallback infCurrent infSearch infAttempts infTimeoutinfTypeinfSpecificNameserver queryHeadermaxInflightPerServer globalSocket lookupReply readerThread globalConfigresolverConfigFromResolvConfselectNameserversubmit4maxTimeoutsPerServer probeCallbackprobeNameserver handleTimeout handleReplytransmit sendInflighthandleTransientError handleFailure answersToDBdbGet parseQuerygetResolveConfig