Commit ca39f460 authored by Evan Hunt's avatar Evan Hunt

Another step in asiolink refactoring; added some new methods

(getPort(), getFamily(), getProtocol()) to IOEndpoint and IOAddress
classes.

git-svn-id: svn://bind10.isc.org/svn/bind10/branches/trac327@3081 e5f2f494-b856-4b98-b285-d166d9295462
parent 53a82252
......@@ -42,7 +42,7 @@ b10_auth_LDADD += $(top_builddir)/src/lib/dns/libdns++.la
b10_auth_LDADD += $(top_builddir)/src/lib/config/libcfgclient.la
b10_auth_LDADD += $(top_builddir)/src/lib/cc/libcc.la
b10_auth_LDADD += $(top_builddir)/src/lib/exceptions/libexceptions.la
b10_auth_LDADD += $(top_builddir)/src/lib/asiolink/libasiolink.a
b10_auth_LDADD += $(top_builddir)/src/lib/asiolink/libasiolink.la
b10_auth_LDADD += $(top_builddir)/src/lib/xfr/libxfr.la
b10_auth_LDADD += $(SQLITE_LIBS)
......
......@@ -52,6 +52,18 @@ const char* const BADCONFIG_TESTDB =
"{ \"database_file\": \"" TEST_DATA_DIR "/nodir/notexist\"}";
const char* const DEFAULT_REMOTE_ADDRESS = "192.0.2.1";
class DummySocket : public IOSocket {
private:
DummySocket(const DummySocket& source);
DummySocket& operator=(const DummySocket& source);
public:
DummySocket(const int protocol) : protocol_(protocol) {}
virtual int getNative() const { return (-1); }
virtual int getProtocol() const { return (protocol_); }
private:
const int protocol_;
};
class AuthSrvTest : public ::testing::Test {
private:
class MockXfroutClient : public AbstractXfroutClient {
......@@ -136,6 +148,7 @@ protected:
const Name qname;
const RRClass qclass;
const RRType qtype;
IOSocket* io_sock;
IOMessage* io_message;
const IOEndpoint* endpoint;
OutputBuffer request_obuffer;
......@@ -260,16 +273,16 @@ AuthSrvTest::createDataFromFile(const char* const datafile,
const int protocol = IPPROTO_UDP)
{
delete io_message;
delete io_sock;
data.clear();
delete endpoint;
endpoint = IOEndpoint::create(protocol,
IOAddress(DEFAULT_REMOTE_ADDRESS), 5300);
UnitTestUtil::readWireData(datafile, data);
io_message = new IOMessage(&data[0], data.size(),
protocol == IPPROTO_UDP ?
IOSocket::getDummyUDPSocket() :
IOSocket::getDummyTCPSocket(), *endpoint);
io_sock = new DummySocket(protocol);
io_message = new IOMessage(&data[0], data.size(), *io_sock, *endpoint);
}
void
......@@ -299,13 +312,14 @@ AuthSrvTest::createRequestPacket(const int protocol = IPPROTO_UDP) {
request_message.toWire(request_renderer);
delete io_message;
delete io_sock;
endpoint = IOEndpoint::create(protocol,
IOAddress(DEFAULT_REMOTE_ADDRESS), 5300);
io_sock = new DummySocket(protocol);
io_message = new IOMessage(request_renderer.getData(),
request_renderer.getLength(),
protocol == IPPROTO_UDP ?
IOSocket::getDummyUDPSocket() :
IOSocket::getDummyTCPSocket(), *endpoint);
*io_sock, *endpoint);
}
void
......
......@@ -44,7 +44,7 @@ b10_recurse_LDADD = $(top_builddir)/src/lib/dns/libdns++.la
b10_recurse_LDADD += $(top_builddir)/src/lib/config/libcfgclient.la
b10_recurse_LDADD += $(top_builddir)/src/lib/cc/libcc.la
b10_recurse_LDADD += $(top_builddir)/src/lib/exceptions/libexceptions.la
b10_recurse_LDADD += $(top_builddir)/src/lib/asiolink/libasiolink.a
b10_recurse_LDADD += $(top_builddir)/src/lib/asiolink/libasiolink.la
b10_recurse_LDADD += $(top_builddir)/src/lib/xfr/libxfr.la
b10_recurse_LDFLAGS = -pthread
......
......@@ -45,6 +45,18 @@ using namespace asiolink;
namespace {
const char* const DEFAULT_REMOTE_ADDRESS = "192.0.2.1";
class DummySocket : public IOSocket {
private:
DummySocket(const DummySocket& source);
DummySocket& operator=(const DummySocket& source);
public:
DummySocket(const int protocol) : protocol_(protocol) {}
virtual int getNative() const { return (-1); }
virtual int getProtocol() const { return (protocol_); }
private:
const int protocol_;
};
class RecursorTest : public ::testing::Test {
private:
class MockSession : public AbstractSession {
......@@ -105,6 +117,7 @@ protected:
const RRClass qclass;
const RRType qtype;
IOMessage* io_message;
IOSocket* io_sock;
const IOEndpoint* endpoint;
OutputBuffer request_obuffer;
MessageRenderer request_renderer;
......@@ -204,10 +217,8 @@ RecursorTest::createDataFromFile(const char* const datafile,
endpoint = IOEndpoint::create(protocol,
IOAddress(DEFAULT_REMOTE_ADDRESS), 5300);
UnitTestUtil::readWireData(datafile, data);
io_message = new IOMessage(&data[0], data.size(),
protocol == IPPROTO_UDP ?
IOSocket::getDummyUDPSocket() :
IOSocket::getDummyTCPSocket(), *endpoint);
io_sock = new DummySocket(protocol);
io_message = new IOMessage(&data[0], data.size(), *io_sock, *endpoint);
}
void
......@@ -237,13 +248,13 @@ RecursorTest::createRequestPacket(const int protocol = IPPROTO_UDP) {
request_message.toWire(request_renderer);
delete io_message;
endpoint = IOEndpoint::create(protocol,
IOAddress(DEFAULT_REMOTE_ADDRESS), 5300);
io_sock = new DummySocket(protocol);
io_message = new IOMessage(request_renderer.getData(),
request_renderer.getLength(),
protocol == IPPROTO_UDP ?
IOSocket::getDummyUDPSocket() :
IOSocket::getDummyTCPSocket(), *endpoint);
*io_sock, *endpoint);
}
void
......@@ -412,37 +423,6 @@ TEST_F(RecursorTest, AXFRFail) {
QR_FLAG, 1, 0, 0, 0);
}
TEST_F(RecursorTest, DISABLED_notify) {
createRequestMessage(Opcode::NOTIFY(), Name("example.com"), RRClass::IN(),
RRType::SOA());
request_message.setHeaderFlag(MessageFlag::AA());
createRequestPacket(IPPROTO_UDP);
EXPECT_EQ(true, server.processMessage(*io_message, parse_message,
response_renderer));
// An internal command message should have been created and sent to an
// external module. Check them.
EXPECT_EQ("Zonemgr", notify_session.msg_destination);
EXPECT_EQ("notify",
notify_session.sent_msg->get("command")->get(0)->stringValue());
ConstElementPtr notify_args =
notify_session.sent_msg->get("command")->get(1);
EXPECT_EQ("example.com.", notify_args->get("zone_name")->stringValue());
EXPECT_EQ(DEFAULT_REMOTE_ADDRESS,
notify_args->get("master")->stringValue());
EXPECT_EQ("IN", notify_args->get("zone_class")->stringValue());
// On success, the server should return a response to the notify.
headerCheck(parse_message, default_qid, Rcode::NOERROR(),
Opcode::NOTIFY().getCode(), QR_FLAG | AA_FLAG, 1, 0, 0, 0);
// The question must be identical to that of the received notify
ConstQuestionPtr question = *parse_message.beginQuestion();
EXPECT_EQ(Name("example.com"), question->getName());
EXPECT_EQ(RRClass::IN(), question->getClass());
EXPECT_EQ(RRType::SOA(), question->getType());
}
TEST_F(RecursorTest, notifyFail) {
// Notify should always return NOTAUTH
request_message.clear(Message::RENDER);
......
......@@ -65,10 +65,19 @@ IOAddress::toText() const {
return (asio_address_.to_string());
}
short
IOAddress::getFamily() const {
if (asio_address_.is_v4()) {
return (AF_INET);
} else {
return (AF_INET6);
}
}
// Note: this implementation is optimized for the case where this object
// is created from an ASIO endpoint object in a receiving code path
// by avoiding to make a copy of the base endpoint. For TCP it may not be
// a bug deal, but when we receive UDP packets at a high rate, the copy
// a big deal, but when we receive UDP packets at a high rate, the copy
// overhead might be significant.
class TCPEndpoint : public IOEndpoint {
public:
......@@ -86,6 +95,15 @@ public:
virtual IOAddress getAddress() const {
return (asio_endpoint_.address());
}
virtual uint16_t getPort() const {
return (asio_endpoint_.port());
}
virtual short getProtocol() const {
return (asio_endpoint_.protocol().protocol());
}
virtual short getFamily() const {
return (asio_endpoint_.protocol().family());
}
private:
const tcp::endpoint* asio_endpoint_placeholder_;
const tcp::endpoint& asio_endpoint_;
......@@ -102,10 +120,20 @@ public:
UDPEndpoint(const udp::endpoint& asio_endpoint) :
asio_endpoint_placeholder_(NULL), asio_endpoint_(asio_endpoint)
{}
~UDPEndpoint() { delete asio_endpoint_placeholder_; }
virtual IOAddress getAddress() const {
return (asio_endpoint_.address());
}
virtual uint16_t getPort() const {
return (asio_endpoint_.port());
}
virtual short getProtocol() const {
return (asio_endpoint_.protocol().protocol());
}
virtual short getFamily() const {
return (asio_endpoint_.protocol().family());
}
private:
const udp::endpoint* asio_endpoint_placeholder_;
const udp::endpoint& asio_endpoint_;
......@@ -149,30 +177,6 @@ private:
udp::socket& socket_;
};
class DummySocket : public IOSocket {
private:
DummySocket(const DummySocket& source);
DummySocket& operator=(const DummySocket& source);
public:
DummySocket(const int protocol) : protocol_(protocol) {}
virtual int getNative() const { return (-1); }
virtual int getProtocol() const { return (protocol_); }
private:
const int protocol_;
};
IOSocket&
IOSocket::getDummyUDPSocket() {
static DummySocket socket(IPPROTO_UDP);
return (socket);
}
IOSocket&
IOSocket::getDummyTCPSocket() {
static DummySocket socket(IPPROTO_TCP);
return (socket);
}
IOMessage::IOMessage(const void* data, const size_t data_size,
IOSocket& io_socket, const IOEndpoint& remote_endpoint) :
data_(data), data_size_(data_size), io_socket_(io_socket),
......
......@@ -144,6 +144,10 @@ public:
///
/// \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_;
};
......@@ -197,6 +201,15 @@ public:
/// \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)
......
......@@ -24,7 +24,7 @@ run_unittests_LDADD = $(GTEST_LDADD)
run_unittests_LDADD += $(SQLITE_LIBS)
run_unittests_LDADD += $(top_builddir)/src/lib/dns/libdns++.la
run_unittests_LDADD += $(top_builddir)/src/lib/exceptions/libexceptions.la
run_unittests_LDADD += $(top_builddir)/src/lib/asiolink/libasiolink.a
run_unittests_LDADD += $(top_builddir)/src/lib/asiolink/libasiolink.la
endif
noinst_PROGRAMS = $(TESTS)
......@@ -38,6 +38,18 @@ const char* const TEST_IPV4_ADDR = "127.0.0.1";
// for the tests below.
const uint8_t test_data[] = {0, 4, 1, 2, 3, 4};
class DummySocket : public IOSocket {
private:
DummySocket(const DummySocket& source);
DummySocket& operator=(const DummySocket& source);
public:
DummySocket(const int protocol) : protocol_(protocol) {}
virtual int getNative() const { return (-1); }
virtual int getProtocol() const { return (protocol_); }
private:
const int protocol_;
};
TEST(IOAddressTest, fromText) {
IOAddress io_address_v4("192.0.2.1");
EXPECT_EQ("192.0.2.1", io_address_v4.toText());
......@@ -52,34 +64,57 @@ TEST(IOAddressTest, fromText) {
EXPECT_THROW(IOAddress("2001:db8:::1234"), IOError);
}
TEST(IOEndpointTest, create) {
TEST(IOEndpointTest, createUDPv4) {
const IOEndpoint* ep;
ep = IOEndpoint::create(IPPROTO_UDP, IOAddress("192.0.2.1"), 5300);
EXPECT_EQ("192.0.2.1", ep->getAddress().toText());
delete ep;
EXPECT_EQ(5300, ep->getPort());
EXPECT_EQ(AF_INET, ep->getFamily());
EXPECT_EQ(AF_INET, ep->getAddress().getFamily());
EXPECT_EQ(IPPROTO_UDP, ep->getProtocol());
}
ep = IOEndpoint::create(IPPROTO_TCP, IOAddress("192.0.2.1"), 5300);
TEST(IOEndpointTest, createTCPv4) {
const IOEndpoint* ep;
ep = IOEndpoint::create(IPPROTO_TCP, IOAddress("192.0.2.1"), 5301);
EXPECT_EQ("192.0.2.1", ep->getAddress().toText());
delete ep;
EXPECT_EQ(5301, ep->getPort());
EXPECT_EQ(AF_INET, ep->getFamily());
EXPECT_EQ(AF_INET, ep->getAddress().getFamily());
EXPECT_EQ(IPPROTO_TCP, ep->getProtocol());
}
ep = IOEndpoint::create(IPPROTO_UDP, IOAddress("2001:db8::1234"), 5300);
TEST(IOEndpointTest, createUDPv6) {
const IOEndpoint* ep;
ep = IOEndpoint::create(IPPROTO_UDP, IOAddress("2001:db8::1234"), 5302);
EXPECT_EQ("2001:db8::1234", ep->getAddress().toText());
delete ep;
EXPECT_EQ(5302, ep->getPort());
EXPECT_EQ(AF_INET6, ep->getFamily());
EXPECT_EQ(AF_INET6, ep->getAddress().getFamily());
EXPECT_EQ(IPPROTO_UDP, ep->getProtocol());
}
ep = IOEndpoint::create(IPPROTO_TCP, IOAddress("2001:db8::1234"), 5300);
TEST(IOEndpointTest, createTCPv6) {
const IOEndpoint* ep;
ep = IOEndpoint::create(IPPROTO_TCP, IOAddress("2001:db8::1234"), 5303);
EXPECT_EQ("2001:db8::1234", ep->getAddress().toText());
delete ep;
EXPECT_EQ(5303, ep->getPort());
EXPECT_EQ(AF_INET6, ep->getFamily());
EXPECT_EQ(AF_INET6, ep->getAddress().getFamily());
EXPECT_EQ(IPPROTO_TCP, ep->getProtocol());
}
TEST(IOEndpointTest, createIPProto) {
EXPECT_THROW(IOEndpoint::create(IPPROTO_IP, IOAddress("192.0.2.1"),
5300)->getAddress().toText(),
IOError);
}
TEST(IOSocketTest, dummySockets) {
EXPECT_EQ(IPPROTO_UDP, IOSocket::getDummyUDPSocket().getProtocol());
EXPECT_EQ(IPPROTO_TCP, IOSocket::getDummyTCPSocket().getProtocol());
EXPECT_EQ(-1, IOSocket::getDummyUDPSocket().getNative());
EXPECT_EQ(-1, IOSocket::getDummyTCPSocket().getNative());
EXPECT_EQ(IPPROTO_UDP, DummySocket(IPPROTO_UDP).getProtocol());
EXPECT_EQ(IPPROTO_TCP, DummySocket(IPPROTO_TCP).getProtocol());
EXPECT_EQ(-1, DummySocket(IPPROTO_UDP).getNative());
EXPECT_EQ(-1, DummySocket(IPPROTO_TCP).getNative());
}
TEST(IOServiceTest, badPort) {
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment