dns-4.2.0: DNS library in Haskell

Safe Haskell | Safe-Inferred
Language | Haskell2010

Network.DNS.IO

Contents

- Receiving DNS messages
- Sending pre-encoded messages
  - Encoding queries for transmission
  - Creating query response messages

Synopsis

- receive :: Socket -> IO DNSMessage
- receiveFrom :: Socket -> IO (DNSMessage, SockAddr)
- receiveVC :: Socket -> IO DNSMessage
- send :: Socket -> ByteString -> IO ()
- sendTo :: Socket -> ByteString -> SockAddr -> IO ()
- sendVC :: Socket -> ByteString -> IO ()
- sendAll :: Socket -> ByteString -> IO ()
- encodeQuestion :: Identifier -> Question -> QueryControls -> ByteString
- encodeVC :: ByteString -> ByteString
- responseA :: Identifier -> Question -> [IPv4] -> DNSMessage
- responseAAAA :: Identifier -> Question -> [IPv6] -> DNSMessage

# Receiving DNS messages

receive :: Socket -> IO DNSMessage Source #

Receive and decode a single `DNSMessage` from a UDP `Socket`, throwing away the client address. Messages longer than `maxUdpSize` are silently truncated, but this should not occur in practice, since we cap the advertised EDNS UDP buffer size limit at the same value. A `DNSError` is raised if I/O or message decoding fails.

receiveFrom :: Socket -> IO (DNSMessage, SockAddr) Source #

Receive and decode a single `DNSMessage` from a UDP `Socket`. Messages longer than `maxUdpSize` are silently truncated, but this should not occur in practice, since we cap the advertised EDNS UDP buffer size limit at the same value. A `DNSError` is raised if I/O or message decoding fails.

receiveVC :: Socket -> IO DNSMessage Source #

Receive and decode a single `DNSMesage` from a virtual-circuit (TCP). It is up to the caller to implement any desired timeout. An `DNSError` is raised if I/O or message decoding fails.

# Sending pre-encoded messages

send :: Socket -> ByteString -> IO () Source #

Send an encoded `DNSMessage` datagram over UDP. The message length is implicit in the size of the UDP datagram. With TCP you must use `sendVC`, because TCP does not have message boundaries, and each message needs to be prepended with an explicit length. The socket must be explicitly connected to the destination nameserver.

sendTo :: Socket -> ByteString -> SockAddr -> IO () Source #

Send an encoded `DNSMessage` datagram over UDP to a given address. The message length is implicit in the size of the UDP datagram. With TCP you must use `sendVC`, because TCP does not have message boundaries, and each message needs to be prepended with an explicit length.

sendVC :: Socket -> ByteString -> IO () Source #

Send a single encoded `DNSMessage` over TCP. An explicit length is prepended to the encoded buffer before transmission. If you want to send a batch of multiple encoded messages back-to-back over a single TCP connection, and then loop to collect the results, use `encodeVC` to prefix each message with a length, and then use `sendAll` to send a concatenated batch of the resulting encapsulated messages.

sendAll :: Socket -> ByteString -> IO () Source #

Send one or more encoded `DNSMessage` buffers over TCP, each allready encapsulated with an explicit length prefix (perhaps via `encodeVC`) and then concatenated into a single buffer. DO NOT use `sendAll` with UDP.

## Encoding queries for transmission

encodeQuestion Source #

Arguments

:: Identifier | Crypto random request id
-> Question | Query name and type
-> QueryControls | Query flag and EDNS overrides
-> ByteString |

The encoded `DNSMessage` has the specified request ID. The default values of the RD, AD, CD and DO flag bits, as well as various EDNS features, can be adjusted via the `QueryControls` parameter.

The caller is responsible for generating the ID via a securely seeded CSPRNG.

encodeVC :: ByteString -> ByteString Source #

Encapsulate an encoded `DNSMessage` buffer for transmission over a TCP virtual circuit. With TCP the buffer needs to start with an explicit length (the length is implicit with UDP).

## Creating query response messages

responseA :: Identifier -> Question -> [IPv4] -> DNSMessage Source #

Compose a response with a single IPv4 RRset. If the query had an EDNS pseudo-header, a suitable EDNS pseudo-header must be added to the response message, or else a `FormatErr` response must be sent. The response TTL defaults to 300 seconds, and should be updated (to the same value across all the RRs) if some other TTL value is more appropriate.

responseAAAA :: Identifier -> Question -> [IPv6] -> DNSMessage Source #

Compose a response with a single IPv6 RRset. If the query had an EDNS pseudo-header, a suitable EDNS pseudo-header must be added to the response message, or else a `FormatErr` response must be sent. The response TTL defaults to 300 seconds, and should be updated (to the same value across all the RRs) if some other TTL value is more appropriate.