summaryrefslogtreecommitdiffstats
path: root/src/lib/d2srv/dns_client.h
diff options
context:
space:
mode:
Diffstat (limited to 'src/lib/d2srv/dns_client.h')
-rw-r--r--src/lib/d2srv/dns_client.h157
1 files changed, 157 insertions, 0 deletions
diff --git a/src/lib/d2srv/dns_client.h b/src/lib/d2srv/dns_client.h
new file mode 100644
index 0000000..c63a7a0
--- /dev/null
+++ b/src/lib/d2srv/dns_client.h
@@ -0,0 +1,157 @@
+// Copyright (C) 2013-2021 Internet Systems Consortium, Inc. ("ISC")
+//
+// This Source Code Form is subject to the terms of the Mozilla Public
+// License, v. 2.0. If a copy of the MPL was not distributed with this
+// file, You can obtain one at http://mozilla.org/MPL/2.0/.
+
+#ifndef DNS_CLIENT_H
+#define DNS_CLIENT_H
+
+#include <asiolink/io_service.h>
+#include <asiodns/io_fetch.h>
+#include <d2srv/d2_tsig_key.h>
+#include <d2srv/d2_update_message.h>
+#include <util/buffer.h>
+
+namespace isc {
+namespace d2 {
+
+class DNSClient;
+typedef boost::shared_ptr<DNSClient> DNSClientPtr;
+
+/// DNSClient class implementation.
+class DNSClientImpl;
+
+/// @brief The @c DNSClient class handles communication with the DNS server.
+///
+/// Communication with the DNS server is asynchronous. Caller must provide a
+/// callback, which will be invoked when the response from the DNS server is
+/// received, a timeout has occurred or IO service has been stopped for any
+/// reason. The caller-supplied callback is called by the internal callback
+/// operator implemented by @c DNSClient. This callback is responsible for
+/// initializing the @c D2UpdateMessage instance which encapsulates the response
+/// from the DNS. This initialization does not take place if the response from
+/// DNS is not received.
+///
+/// Caller must supply a pointer to the @c D2UpdateMessage object, which will
+/// encapsulate DNS response, through class constructor. An exception will be
+/// thrown if the pointer is not initialized by the caller.
+///
+/// @todo Ultimately, this class will support both TCP and UDP Transport.
+/// Currently only UDP is supported and can be specified as a preferred
+/// protocol. @c DNSClient constructor will throw an exception if TCP is
+/// specified. Once both protocols are supported, the @c DNSClient logic will
+/// try to obey caller's preference. However, it may use the other protocol if
+/// on its own discretion, when there is a legitimate reason to do so. For
+/// example, if communication with the server using preferred protocol fails.
+class DNSClient {
+public:
+
+ /// @brief Transport layer protocol used by a DNS Client to communicate
+ /// with a server.
+ enum Protocol {
+ UDP,
+ TCP
+ };
+
+ /// @brief A status code of the DNSClient.
+ enum Status {
+ SUCCESS, ///< Response received and is ok.
+ TIMEOUT, ///< No response, timeout.
+ IO_STOPPED, ///< IO was stopped.
+ INVALID_RESPONSE, ///< Response received but invalid.
+ OTHER ///< Other, unclassified error.
+ };
+
+ /// @brief Callback for the @c DNSClient class.
+ ///
+ /// This is an abstract class which represents the external callback for the
+ /// @c DNSClient. Caller must implement this class and supply its instance
+ /// in the @c DNSClient constructor to get callbacks when the DNS Update
+ /// exchange is complete (@see @c DNSClient).
+ class Callback {
+ public:
+ /// @brief Virtual destructor.
+ virtual ~Callback() { }
+
+ /// @brief Function operator implementing a callback.
+ ///
+ /// @param status a @c DNSClient::Status enum representing status code
+ /// of DNSClient operation.
+ virtual void operator()(DNSClient::Status status) = 0;
+ };
+
+ /// @brief Constructor.
+ ///
+ /// @param response_placeholder Message object pointer which will be updated
+ /// with dynamically allocated object holding the DNS server's response.
+ /// @param callback Pointer to an object implementing @c DNSClient::Callback
+ /// class. This object will be called when DNS message exchange completes or
+ /// if an error occurs. NULL value disables callback invocation.
+ /// @param proto caller's preference regarding Transport layer protocol to
+ /// be used by DNS Client to communicate with a server.
+ DNSClient(D2UpdateMessagePtr& response_placeholder, Callback* callback,
+ const Protocol proto = UDP);
+
+ /// @brief Virtual destructor, does nothing.
+ ~DNSClient();
+
+ ///
+ /// @name Copy constructor and assignment operator
+ ///
+ /// Copy constructor and assignment operator are private because there are
+ /// no use cases when a DNSClient instance will need to be copied. Also, it
+ /// is desired to avoid copying a DNSClient::impl_ pointer and external
+ /// callbacks.
+ ///
+ //@{
+private:
+ DNSClient(const DNSClient& source);
+ DNSClient& operator=(const DNSClient& source);
+ //@}
+
+public:
+
+ /// @brief Returns maximal allowed timeout value accepted by
+ /// @c DNSClient::doUpdate.
+ ///
+ /// @return maximal allowed timeout value accepted by @c DNSClient::doUpdate
+ static unsigned int getMaxTimeout();
+
+ /// @brief Start asynchronous DNS Update with TSIG.
+ ///
+ /// This function starts asynchronous DNS Update and returns. The DNS Update
+ /// will be executed by the specified IO service. Once the message exchange
+ /// with a DNS server is complete, timeout occurs or IO operation is
+ /// interrupted, the caller-supplied callback function will be invoked.
+ ///
+ /// An address and port of the DNS server is specified through the function
+ /// arguments so as the same instance of the @c DNSClient can be used to
+ /// initiate multiple message exchanges.
+ ///
+ /// @param io_service IO service to be used to run the message exchange.
+ /// @param ns_addr DNS server address.
+ /// @param ns_port DNS server port.
+ /// @param update A DNS Update message to be sent to the server.
+ /// @param wait A timeout (in milliseconds) for the response. If a response
+ /// is not received within the timeout, exchange is interrupted. This value
+ /// must not exceed maximal value for 'int' data type.
+ /// @param tsig_key A pointer to an @c D2TsigKeyPtr object that will
+ /// (if not null) be used to sign the DNS Update message and verify the
+ /// response.
+ void doUpdate(asiolink::IOService& io_service,
+ const asiolink::IOAddress& ns_addr,
+ const uint16_t ns_port,
+ D2UpdateMessage& update,
+ const unsigned int wait,
+ const D2TsigKeyPtr& tsig_key = D2TsigKeyPtr());
+
+private:
+ /// @brief Pointer to DNSClient implementation.
+ std::unique_ptr<DNSClientImpl> impl_;
+};
+
+} // namespace d2
+} // namespace isc
+
+#endif // DNS_CLIENT_H