[svn] commit: r3150 - in /branches/trac327/src: bin/recurse/ lib/asiolink/ lib/asiolink/internal/
BIND 10 source code commits
bind10-changes at lists.isc.org
Sat Oct 9 04:33:04 UTC 2010
Author: each
Date: Sat Oct 9 04:33:04 2010
New Revision: 3150
Log:
Refactored asiolink so that the many classes defined in asiolink.h and
asiolink.cc are now in multiple files (ioaddress.h, iosocket.h, etc).
Also removed some shared_ptr's that weren't really needed in tcpdns
and udpdns. This work isn't done yet, but committing now to simplify
the review a bit.
Added:
branches/trac327/src/lib/asiolink/Makefile.am
branches/trac327/src/lib/asiolink/ioaddress.cc
branches/trac327/src/lib/asiolink/ioaddress.h
branches/trac327/src/lib/asiolink/ioendpoint.cc
branches/trac327/src/lib/asiolink/ioendpoint.h
branches/trac327/src/lib/asiolink/iomessage.h
branches/trac327/src/lib/asiolink/iosocket.h
Modified:
branches/trac327/src/bin/recurse/recursor.cc
branches/trac327/src/lib/asiolink/asiolink.cc
branches/trac327/src/lib/asiolink/asiolink.h
branches/trac327/src/lib/asiolink/internal/tcpdns.h
branches/trac327/src/lib/asiolink/internal/udpdns.h
branches/trac327/src/lib/asiolink/tcpdns.cc
branches/trac327/src/lib/asiolink/udpdns.cc
Modified: branches/trac327/src/bin/recurse/recursor.cc
==============================================================================
--- branches/trac327/src/bin/recurse/recursor.cc (original)
+++ branches/trac327/src/bin/recurse/recursor.cc Sat Oct 9 04:33:04 2010
@@ -40,6 +40,7 @@
#include <dns/rrset.h>
#include <dns/rrttl.h>
#include <dns/message.h>
+#include <dns/messagerenderer.h>
#include <xfr/xfrout_client.h>
Modified: branches/trac327/src/lib/asiolink/asiolink.cc
==============================================================================
--- branches/trac327/src/lib/asiolink/asiolink.cc (original)
+++ branches/trac327/src/lib/asiolink/asiolink.cc Sat Oct 9 04:33:04 2010
@@ -41,83 +41,6 @@
using namespace isc::dns;
namespace asiolink {
-
-IOAddress::IOAddress(const string& address_str)
- // XXX: we cannot simply construct the address in the initialization list
- // because we'd like to throw our own exception on failure.
-{
- error_code err;
- asio_address_ = ip::address::from_string(address_str, err);
- if (err) {
- isc_throw(IOError, "Failed to convert string to address '"
- << address_str << "': " << err.message());
- }
-}
-
-IOAddress::IOAddress(const ip::address& asio_address) :
- asio_address_(asio_address)
-{}
-
-string
-IOAddress::toText() const {
- return (asio_address_.to_string());
-}
-
-short
-IOAddress::getFamily() const {
- if (asio_address_.is_v4()) {
- return (AF_INET);
- } else {
- return (AF_INET6);
- }
-}
-
-const IOEndpoint*
-IOEndpoint::create(const int protocol, const IOAddress& address,
- const unsigned short port)
-{
- if (protocol == IPPROTO_UDP) {
- return (new UDPEndpoint(address, port));
- } else if (protocol == IPPROTO_TCP) {
- return (new TCPEndpoint(address, port));
- }
- isc_throw(IOError,
- "IOEndpoint creation attempt for unsupported protocol: " <<
- protocol);
-}
-
-IOMessage::IOMessage(const void* data, const size_t data_size,
- const IOSocket& io_socket,
- const IOEndpoint& remote_endpoint) :
- data_(data), data_size_(data_size), io_socket_(io_socket),
- remote_endpoint_(remote_endpoint)
-{}
-
-RecursiveQuery::RecursiveQuery(IOService& io_service, const char& forward,
- uint16_t port) :
- io_service_(io_service), port_(port)
-{
- error_code err;
- ns_addr_ = ip::address::from_string(&forward, err);
- if (err) {
- isc_throw(IOError, "Invalid IP address '" << &ns_addr_ << "': "
- << err.message());
- }
-}
-
-void
-RecursiveQuery::sendQuery(const Question& question, OutputBufferPtr buffer,
- DNSServer* server)
-{
-
- // XXX: eventually we will need to be able to determine whether
- // the message should be sent via TCP or UDP, or sent initially via
- // UDP and then fall back to TCP on failure, but for the moment
- // we're only going to handle UDP.
- asio::io_service& io = io_service_.get_io_service();
- UDPQuery q(io, question, ns_addr_, port_, buffer, server);
- io.post(q);
-}
class IOServiceImpl {
public:
@@ -247,4 +170,30 @@
return (impl_->io_service_);
}
+RecursiveQuery::RecursiveQuery(IOService& io_service, const char& forward,
+ uint16_t port) :
+ io_service_(io_service), port_(port)
+{
+ error_code err;
+ ns_addr_ = ip::address::from_string(&forward, err);
+ if (err) {
+ isc_throw(IOError, "Invalid IP address '" << &ns_addr_ << "': "
+ << err.message());
+ }
}
+
+void
+RecursiveQuery::sendQuery(const Question& question, OutputBufferPtr buffer,
+ DNSServer* server)
+{
+
+ // XXX: eventually we will need to be able to determine whether
+ // the message should be sent via TCP or UDP, or sent initially via
+ // UDP and then fall back to TCP on failure, but for the moment
+ // we're only going to handle UDP.
+ asio::io_service& io = io_service_.get_io_service();
+ UDPQuery q(io, question, ns_addr_, port_, buffer, server);
+ io.post(q);
+}
+
+}
Modified: branches/trac327/src/lib/asiolink/asiolink.h
==============================================================================
--- branches/trac327/src/lib/asiolink/asiolink.h (original)
+++ branches/trac327/src/lib/asiolink/asiolink.h Sat Oct 9 04:33:04 2010
@@ -26,14 +26,16 @@
#include <functional>
#include <string>
-#include <boost/function.hpp>
-
#include <dns/buffer.h>
#include <dns/message.h>
-#include <dns/messagerenderer.h>
#include <dns/question.h>
#include <exceptions/exceptions.h>
+
+#include <asiolink/ioaddress.h>
+#include <asiolink/ioendpoint.h>
+#include <asiolink/iomessage.h>
+#include <asiolink/iosocket.h>
namespace asio {
// forward declaration for IOService::get_io_service() below
@@ -106,297 +108,6 @@
class SimpleCallback;
class DNSLookup;
class DNSAnswer;
-
-/// \brief The \c IOAddress class represents an IP addresses (version
-/// agnostic)
-///
-/// This class is a wrapper for the ASIO \c ip::address class.
-class IOAddress {
-public:
- ///
- /// \name Constructors and Destructor
- ///
- /// This class is copyable. We use default versions of copy constructor
- /// and the assignment operator.
- /// We use the default destructor.
- //@{
- /// \brief Constructor from string.
- ///
- /// This constructor converts a textual representation of IPv4 and IPv6
- /// addresses into an IOAddress object.
- /// If \c address_str is not a valid representation of any type of
- /// address, an exception of class \c IOError will be thrown.
- /// This constructor allocates memory for the object, and if that fails
- /// a corresponding standard exception will be thrown.
- ///
- /// \param address_str Textual representation of address.
- IOAddress(const std::string& address_str);
-
- /// \brief Constructor from an ASIO \c ip::address object.
- ///
- /// This constructor is intended to be used within the wrapper
- /// implementation; user applications of the wrapper API won't use it.
- ///
- /// This constructor never throws an exception.
- ///
- /// \param asio_address The ASIO \c ip::address to be converted.
- IOAddress(const asio::ip::address& asio_adress);
- //@}
-
- /// \brief Convert the address to a string.
- ///
- /// This method is basically expected to be exception free, but
- /// generating the string will involve resource allocation,
- /// and if it fails the corresponding standard exception will be thrown.
- ///
- /// \return A string representation of the address.
- std::string toText() const;
-
- /// \brief Returns the address family.
- virtual short getFamily() const;
-
-private:
- asio::ip::address asio_address_;
-};
-
-/// \brief The \c IOEndpoint class is an abstract base class to represent
-/// a communication endpoint.
-///
-/// This class is a wrapper for the ASIO endpoint classes such as
-/// \c ip::tcp::endpoint and \c ip::udp::endpoint.
-///
-/// Derived class implementations are completely hidden within the
-/// implementation. User applications only get access to concrete
-/// \c IOEndpoint objects via the abstract interfaces.
-class IOEndpoint {
- ///
- /// \name Constructors and Destructor
- ///
- /// Note: The copy constructor and the assignment operator are
- /// intentionally defined as private, making this class non-copyable.
- //@{
-private:
- IOEndpoint(const IOEndpoint& source);
- IOEndpoint& operator=(const IOEndpoint& source);
-protected:
- /// \brief The default constructor.
- ///
- /// This is intentionally defined as \c protected as this base class
- /// should never be instantiated (except as part of a derived class).
- IOEndpoint() {}
-public:
- /// The destructor.
- virtual ~IOEndpoint() {}
- //@}
-
- /// \brief Returns the address of the endpoint.
- ///
- /// This method returns an IOAddress object corresponding to \c this
- /// endpoint.
- ///
- /// Note that the return value is a real object, not a reference or
- /// a pointer.
- ///
- /// This is aligned with the interface of the ASIO counterpart:
- /// the \c address() method of \c ip::xxx::endpoint classes returns
- /// an \c ip::address object.
- ///
- /// This also means handling the address of an endpoint using this method
- /// can be expensive. If the address information is necessary in a
- /// performance sensitive context and there's a more efficient interface
- /// for that purpose, it's probably better to avoid using this method.
- ///
- /// This method never throws an exception.
- ///
- /// \return A copy of \c IOAddress object corresponding to the endpoint.
- virtual IOAddress getAddress() const = 0;
-
- /// \brief Returns the port of the endpoint.
- virtual uint16_t getPort() const = 0;
-
- /// \brief Returns the protocol number of the endpoint (TCP, UDP...)
- virtual short getProtocol() const = 0;
-
- /// \brief Returns the address family of the endpoint.
- virtual short getFamily() const = 0;
-
- /// \brief A polymorphic factory of endpoint from address and port.
- ///
- /// This method creates a new instance of (a derived class of)
- /// \c IOEndpoint object that identifies the pair of given address
- /// and port.
- /// The appropriate derived class is chosen based on the specified
- /// transport protocol. If the \c protocol doesn't specify a protocol
- /// supported in this implementation, an exception of class \c IOError
- /// will be thrown.
- ///
- /// Memory for the created object will be dynamically allocated. It's
- /// the caller's responsibility to \c delete it later.
- /// If resource allocation for the new object fails, a corresponding
- /// standard exception will be thrown.
- ///
- /// \param protocol The transport protocol used for the endpoint.
- /// Currently, only \c IPPROTO_UDP and \c IPPROTO_TCP can be specified.
- /// \param address The (IP) address of the endpoint.
- /// \param port The transport port number of the endpoint
- /// \return A pointer to a newly created \c IOEndpoint object.
- static const IOEndpoint* create(const int protocol,
- const IOAddress& address,
- const unsigned short port);
-};
-
-/// \brief The \c IOSocket class is an abstract base class to represent
-/// various types of network sockets.
-///
-/// This class is a wrapper for the ASIO socket classes such as
-/// \c ip::tcp::socket and \c ip::udp::socket.
-///
-/// Derived class implementations are completely hidden within the
-/// implementation. User applications only get access to concrete
-/// \c IOSocket objects via the abstract interfaces.
-///
-/// We may revisit this decision when we generalize the wrapper and more
-/// modules use it. Also, at that point we may define a separate (visible)
-/// derived class for testing purposes rather than providing factory methods
-/// (i.e., getDummy variants below).
-class IOSocket {
- ///
- /// \name Constructors and Destructor
- ///
- /// Note: The copy constructor and the assignment operator are
- /// intentionally defined as private, making this class non-copyable.
- //@{
-private:
- IOSocket(const IOSocket& source);
- IOSocket& operator=(const IOSocket& source);
-protected:
- /// \brief The default constructor.
- ///
- /// This is intentionally defined as \c protected as this base class
- /// should never be instantiated (except as part of a derived class).
- IOSocket() {}
-public:
- /// The destructor.
- virtual ~IOSocket() {}
- //@}
-
- /// \brief Return the "native" representation of the socket.
- ///
- /// In practice, this is the file descriptor of the socket for
- /// UNIX-like systems so the current implementation simply uses
- /// \c int as the type of the return value.
- /// We may have to need revisit this decision later.
- ///
- /// In general, the application should avoid using this method;
- /// it essentially discloses an implementation specific "handle" that
- /// can change the internal state of the socket (consider the
- /// application closes it, for example).
- /// But we sometimes need to perform very low-level operations that
- /// requires the native representation. Passing the file descriptor
- /// to a different process is one example.
- /// This method is provided as a necessary evil for such limited purposes.
- ///
- /// This method never throws an exception.
- ///
- /// \return The native representation of the socket. This is the socket
- /// file descriptor for UNIX-like systems.
- virtual int getNative() const = 0;
-
- /// \brief Return the transport protocol of the socket.
- ///
- /// Currently, it returns \c IPPROTO_UDP for UDP sockets, and
- /// \c IPPROTO_TCP for TCP sockets.
- ///
- /// This method never throws an exception.
- ///
- /// \return IPPROTO_UDP for UDP sockets
- /// \return IPPROTO_TCP for TCP sockets
- virtual int getProtocol() const = 0;
-
- /// \brief Return a non-usable "dummy" UDP socket for testing.
- ///
- /// This is a class method that returns a "mock" of UDP socket.
- /// This is not associated with any actual socket, and its only
- /// responsibility is to return \c IPPROTO_UDP from \c getProtocol().
- /// The only feasible usage of this socket is for testing so that
- /// the test code can prepare some "UDP data" even without opening any
- /// actual socket.
- ///
- /// This method never throws an exception.
- ///
- /// \return A reference to an \c IOSocket object whose \c getProtocol()
- /// returns \c IPPROTO_UDP.
- static IOSocket& getDummyUDPSocket();
-
- /// \brief Return a non-usable "dummy" TCP socket for testing.
- ///
- /// See \c getDummyUDPSocket(). This method is its TCP version.
- ///
- /// \return A reference to an \c IOSocket object whose \c getProtocol()
- /// returns \c IPPROTO_TCP.
- static IOSocket& getDummyTCPSocket();
-};
-
-/// \brief The \c IOMessage class encapsulates an incoming message received
-/// on a socket.
-///
-/// An \c IOMessage object represents a tuple of a chunk of data
-/// (a UDP packet or some segment of TCP stream), the socket over which the
-/// data is passed, the information about the other end point of the
-/// communication, and perhaps more.
-///
-/// The current design and interfaces of this class is tentative.
-/// It only provides a minimal level of support that is necessary for
-/// the current implementation of the authoritative server.
-/// A future version of this class will definitely support more.
-class IOMessage {
- ///
- /// \name Constructors and Destructor
- ///
- /// Note: The copy constructor and the assignment operator are
- /// intentionally defined as private, making this class non-copyable.
- //@{
-private:
- IOMessage(const IOMessage& source);
- IOMessage& operator=(const IOMessage& source);
-public:
- /// \brief Constructor from message information.
- ///
- /// This constructor needs to handle the ASIO \c ip::address class,
- /// and is intended to be used within this wrapper implementation.
- /// Once the \c IOMessage object is created, the application can
- /// get access to the information via the wrapper interface such as
- /// \c getRemoteAddress().
- ///
- /// This constructor never throws an exception.
- ///
- /// \param data A pointer to the message data.
- /// \param data_size The size of the message data in bytes.
- /// \param io_socket The socket over which the data is given.
- /// \param remote_endpoint The other endpoint of the socket, that is,
- /// the sender of the message.
- IOMessage(const void* data, const size_t data_size,
- const IOSocket& io_socket, const IOEndpoint& remote_endpoint);
- //@}
-
- /// \brief Returns a pointer to the received data.
- const void* getData() const { return (data_); }
-
- /// \brief Returns the size of the received data in bytes.
- size_t getDataSize() const { return (data_size_); }
-
- /// \brief Returns the socket on which the message arrives.
- const IOSocket& getSocket() const { return (io_socket_); }
-
- /// \brief Returns the endpoint that sends the message.
- const IOEndpoint& getRemoteEndpoint() const { return (remote_endpoint_); }
-
-private:
- const void* data_;
- const size_t data_size_;
- const IOSocket& io_socket_;
- const IOEndpoint& remote_endpoint_;
-};
/// \brief The \c IOService class is a wrapper for the ASIO \c io_service
/// class.
Modified: branches/trac327/src/lib/asiolink/internal/tcpdns.h
==============================================================================
--- branches/trac327/src/lib/asiolink/internal/tcpdns.h (original)
+++ branches/trac327/src/lib/asiolink/internal/tcpdns.h Sat Oct 9 04:33:04 2010
@@ -137,17 +137,6 @@
// are not copyable.
boost::shared_ptr<asio::ip::tcp::socket> socket_;
- // An \c IOSocket object to wrap socket_
- boost::shared_ptr<asiolink::IOSocket> iosock_;
-
- // An \c IOEndpoint object to wrap the remote endpoint of socket_
- boost::shared_ptr<asiolink::IOEndpoint> peer_;
-
- // A small buffer for writing the length of a DNS message;
- // this is prepended to the actual response buffer when sending a reply
- // to the client.
- boost::shared_ptr<isc::dns::OutputBuffer> lenbuf_;
-
// The buffer into which the response is written
boost::shared_ptr<isc::dns::OutputBuffer> respbuf_;
Modified: branches/trac327/src/lib/asiolink/internal/udpdns.h
==============================================================================
--- branches/trac327/src/lib/asiolink/internal/udpdns.h (original)
+++ branches/trac327/src/lib/asiolink/internal/udpdns.h Sat Oct 9 04:33:04 2010
@@ -129,14 +129,8 @@
// are not copyable.
boost::shared_ptr<asio::ip::udp::socket> socket_;
- // An \c IOSocket object to wrap socket_
- boost::shared_ptr<asiolink::IOSocket> iosock_;
-
// The ASIO-enternal endpoint object representing the client
boost::shared_ptr<asio::ip::udp::endpoint> sender_;
-
- // An \c IOEndpoint object to wrap sender_
- boost::shared_ptr<asiolink::IOEndpoint> peer_;
// \c IOMessage and \c Message objects to be passed to the
// DNS lookup and answer providers
Modified: branches/trac327/src/lib/asiolink/tcpdns.cc
==============================================================================
--- branches/trac327/src/lib/asiolink/tcpdns.cc (original)
+++ branches/trac327/src/lib/asiolink/tcpdns.cc Sat Oct 9 04:33:04 2010
@@ -24,7 +24,6 @@
#include <asio/ip/address.hpp>
#include <boost/array.hpp>
-#include <boost/lexical_cast.hpp>
#include <boost/shared_ptr.hpp>
#include <dns/buffer.h>
@@ -105,13 +104,11 @@
acceptor_->set_option(tcp::acceptor::reuse_address(true));
acceptor_->bind(endpoint);
acceptor_->listen();
-
- lenbuf_.reset(new OutputBuffer(TCP_MESSAGE_LENGTHSIZE));
- respbuf_.reset(new OutputBuffer(0));
}
void
TCPServer::operator()(error_code ec, size_t length) {
+ /// In the event of an error, just exit. The coroutine will be deleted.
if (ec) {
return;
}
@@ -120,6 +117,9 @@
/// a switch statement, inline variable declarations are not
/// permitted. Certain variables used below can be declared here.
boost::array<const_buffer,2> bufs;
+ OutputBuffer* lenbuf;
+ IOEndpoint* peer;
+ IOSocket* iosock;
CORO_REENTER (this) {
do {
@@ -153,9 +153,13 @@
}
// Create an \c IOMessage object to store the query.
- peer_.reset(new TCPEndpoint(socket_->remote_endpoint()));
- iosock_.reset(new TCPSocket(*socket_));
- io_message_.reset(new IOMessage(data_.get(), length, *iosock_, *peer_));
+ //
+ // (XXX: It would be good to write a factory function
+ // that would quickly generate an IOMessage object without
+ // all these calls to "new".)
+ peer = new TCPEndpoint(socket_->remote_endpoint());
+ iosock = new TCPSocket(*socket_);
+ io_message_.reset(new IOMessage(data_.get(), length, *iosock, *peer));
bytes_ = length;
// Perform any necessary operations prior to processing the incoming
@@ -176,7 +180,7 @@
// Reset or instantiate objects that will be needed by the
// DNS lookup and the write call.
- respbuf_->clear();
+ respbuf_.reset(new OutputBuffer(0));
message_.reset(new Message(Message::PARSE));
// Schedule a DNS lookup, and yield. When the lookup is
@@ -195,9 +199,9 @@
(*answer_callback_)(*io_message_, message_, respbuf_);
// Set up the response, beginning with two length bytes.
- lenbuf_->clear();
- lenbuf_->writeUint16(respbuf_->getLength());
- bufs[0] = buffer(lenbuf_->getData(), lenbuf_->getLength());
+ lenbuf = new OutputBuffer(TCP_MESSAGE_LENGTHSIZE);
+ lenbuf->writeUint16(respbuf_->getLength());
+ bufs[0] = buffer(lenbuf->getData(), lenbuf->getLength());
bufs[1] = buffer(respbuf_->getData(), respbuf_->getLength());
// Begin an asynchronous send, and then yield. When the
Modified: branches/trac327/src/lib/asiolink/udpdns.cc
==============================================================================
--- branches/trac327/src/lib/asiolink/udpdns.cc (original)
+++ branches/trac327/src/lib/asiolink/udpdns.cc Sat Oct 9 04:33:04 2010
@@ -16,8 +16,6 @@
#include <config.h>
-#include <list>
-
#include <unistd.h> // for some IPC/network system calls
#include <sys/socket.h>
#include <netinet/in.h>
@@ -25,7 +23,6 @@
#include <boost/bind.hpp>
#include <asio.hpp>
-#include <boost/lexical_cast.hpp>
#include <boost/shared_ptr.hpp>
@@ -113,6 +110,12 @@
/// pattern; see internal/coroutine.h for details.
void
UDPServer::operator()(error_code ec, size_t length) {
+ /// Because the coroutine reeentry block is implemented as
+ /// a switch statement, inline variable declarations are not
+ /// permitted. Certain variables used below can be declared here.
+ IOEndpoint* peer;
+ IOSocket* iosock;
+
CORO_REENTER (this) {
do {
// Instantiate the data buffer and endpoint that will
@@ -139,9 +142,13 @@
} while (is_parent());
// Create an \c IOMessage object to store the query.
- peer_.reset(new UDPEndpoint(*sender_));
- iosock_.reset(new UDPSocket(*socket_));
- io_message_.reset(new IOMessage(data_.get(), bytes_, *iosock_, *peer_));
+ //
+ // (XXX: It would be good to write a factory function
+ // that would quickly generate an IOMessage object without
+ // all these calls to "new".)
+ peer = new UDPEndpoint(*sender_);
+ iosock = new UDPSocket(*socket_);
+ io_message_.reset(new IOMessage(data_.get(), bytes_, *iosock, *peer));
// Perform any necessary operations prior to processing an incoming
// query (e.g., checking for queued configuration messages).
More information about the bind10-changes
mailing list