Commit 84bdd045 authored by JINMEI Tatuya's avatar JINMEI Tatuya

on second thought, it would be better to separate constructors for the...

on second thought, it would be better to separate constructors for the explicit address case and the "any" address case.
This will make the validation process a lot easier and helps reduce code duplicate.
option conflict between -a and -4|-6 is now caught in main.cc.


git-svn-id: svn://bind10.isc.org/svn/bind10/branches/trac221b@2471 e5f2f494-b856-4b98-b285-d166d9295462
parent a146928f
......@@ -295,17 +295,17 @@ private:
class TCPServer {
public:
TCPServer(AuthSrv* auth_server, io_service& io_service,
int af, uint16_t port) :
const ip::address& addr, const uint16_t port) :
auth_server_(auth_server), io_service_(io_service),
acceptor_(io_service_), listening_(new TCPClient(auth_server_,
io_service_)),
custom_callback_(NULL)
{
tcp::endpoint endpoint(af == AF_INET6 ? tcp::v6() : tcp::v4(), port);
tcp::endpoint endpoint(addr, port);
acceptor_.open(endpoint.protocol());
// Set v6-only (we use a different instantiation for v4,
// otherwise asio will bind to both v4 and v6
if (af == AF_INET6) {
if (addr.is_v6()) {
acceptor_.set_option(ip::v6_only(true));
}
acceptor_.set_option(tcp::acceptor::reuse_address(true));
......@@ -316,23 +316,6 @@ public:
listening_, placeholders::error));
}
TCPServer(AuthSrv* auth_server, io_service& io_service,
asio::ip::address addr, uint16_t port) :
auth_server_(auth_server),
io_service_(io_service), acceptor_(io_service_),
listening_(new TCPClient(auth_server, io_service_))
{
tcp::endpoint endpoint(addr, port);
acceptor_.open(endpoint.protocol());
acceptor_.set_option(tcp::acceptor::reuse_address(true));
acceptor_.bind(endpoint);
acceptor_.listen();
acceptor_.async_accept(listening_->getSocket(),
boost::bind(&TCPServer::handleAccept, this,
listening_, placeholders::error));
}
~TCPServer() { delete listening_; }
void handleAccept(TCPClient* new_client,
......@@ -370,10 +353,10 @@ private:
class UDPServer {
public:
UDPServer(AuthSrv* auth_server, io_service& io_service,
int af, uint16_t port) :
const ip::address& addr, const uint16_t port) :
auth_server_(auth_server),
io_service_(io_service),
socket_(io_service, af == AF_INET6 ? udp::v6() : udp::v4()),
socket_(io_service, addr.is_v6() ? udp::v6() : udp::v4()),
io_socket_(socket_),
response_buffer_(0),
response_renderer_(response_buffer_),
......@@ -382,29 +365,15 @@ public:
{
// Set v6-only (we use a different instantiation for v4,
// otherwise asio will bind to both v4 and v6
if (af == AF_INET6) {
if (addr.is_v6()) {
socket_.set_option(asio::ip::v6_only(true));
socket_.bind(udp::endpoint(udp::v6(), port));
socket_.bind(udp::endpoint(addr, port));
} else {
socket_.bind(udp::endpoint(udp::v4(), port));
socket_.bind(udp::endpoint(addr, port));
}
startReceive();
}
UDPServer(AuthSrv* auth_server, io_service& io_service,
asio::ip::address addr, uint16_t port) :
auth_server_(auth_server), io_service_(io_service),
socket_(io_service, addr.is_v6() ? udp::v6() : udp::v4()),
io_socket_(socket_),
response_buffer_(0),
response_renderer_(response_buffer_),
dns_message_(Message::PARSE),
custom_callback_(NULL)
{
socket_.bind(udp::endpoint(addr, port));
startReceive();
}
void handleRequest(const asio::error_code& error,
size_t bytes_recvd)
{
......@@ -483,8 +452,8 @@ private:
class IOServiceImpl {
public:
IOServiceImpl(AuthSrv* auth_server, const char* address, const char& port,
const bool use_ipv4, const bool use_ipv6);
IOServiceImpl(AuthSrv* auth_server, const char& port,
const ip::address& v4addr, const ip::address& v6addr);
asio::io_service io_service_;
AuthSrv* auth_server_;
......@@ -499,9 +468,9 @@ public:
IOService::IOCallBack callback_;
};
IOServiceImpl::IOServiceImpl(AuthSrv* auth_server, const char* const address,
const char& port, const bool use_ipv4,
const bool use_ipv6) :
IOServiceImpl::IOServiceImpl(AuthSrv* auth_server, const char& port,
const ip::address& v4addr,
const ip::address& v6addr) :
auth_server_(auth_server),
udp4_server_(UDPServerPtr()), udp6_server_(UDPServerPtr()),
tcp4_server_(TCPServerPtr()), tcp6_server_(TCPServerPtr())
......@@ -515,57 +484,45 @@ IOServiceImpl::IOServiceImpl(AuthSrv* auth_server, const char* const address,
ex.what());
}
if (address != NULL) {
error_code err;
const ip::address addr = ip::address::from_string(address, err);
if (err) {
isc_throw(IOError, "Invalid IP address '" << address << "': "
<< err.message());
}
if (addr.is_v6() && !use_ipv6) {
isc_throw(IOError,
"IPv6 address is specified while IPv6 is disabled: "
<< addr);
}
if (addr.is_v4() && !use_ipv4) {
isc_throw(IOError,
"IPv4 address is specified while IPv4 is disabled: "
<< addr);
}
if (v4addr.is_v4()) {
udp4_server_ = UDPServerPtr(new UDPServer(auth_server, io_service_,
v4addr, portnum));
tcp4_server_ = TCPServerPtr(new TCPServer(auth_server, io_service_,
v4addr, portnum));
}
if (v6addr.is_v6()) {
udp6_server_ = UDPServerPtr(new UDPServer(auth_server, io_service_,
v6addr, portnum));
tcp6_server_ = TCPServerPtr(new TCPServer(auth_server, io_service_,
v6addr, portnum));
}
}
if (addr.is_v4()) {
udp4_server_ = UDPServerPtr(new UDPServer(auth_server, io_service_,
addr, portnum));
tcp4_server_ = TCPServerPtr(new TCPServer(auth_server, io_service_,
addr, portnum));
} else {
udp6_server_ = UDPServerPtr(new UDPServer(auth_server, io_service_,
addr, portnum));
tcp6_server_ = TCPServerPtr(new TCPServer(auth_server, io_service_,
addr, portnum));
}
} else {
if (use_ipv4) {
udp4_server_ = UDPServerPtr(new UDPServer(auth_server, io_service_,
AF_INET, portnum));
tcp4_server_ = TCPServerPtr(new TCPServer(auth_server, io_service_,
AF_INET, portnum));
}
if (use_ipv6) {
udp6_server_ = UDPServerPtr(new UDPServer(auth_server, io_service_,
AF_INET6, portnum));
tcp6_server_ = TCPServerPtr(new TCPServer(auth_server, io_service_,
AF_INET6, portnum));
}
IOService::IOService(AuthSrv* auth_server, const char& port,
const char& address) :
impl_(NULL)
{
error_code err;
const ip::address addr = ip::address::from_string(&address, err);
if (err) {
isc_throw(IOError, "Invalid IP address '" << &address << "': "
<< err.message());
}
impl_ = new IOServiceImpl(auth_server, port,
addr.is_v4() ? addr : ip::address::address(),
addr.is_v6() ? addr : ip::address::address());
}
IOService::IOService(AuthSrv* auth_server, const char* const address,
const char& port, const bool use_ipv4,
const bool use_ipv6) {
impl_ = new IOServiceImpl(auth_server, address, port, use_ipv4, use_ipv6);
IOService::IOService(AuthSrv* auth_server, const char& port,
const bool use_ipv4, const bool use_ipv6) :
impl_(NULL)
{
const ip::address v4addr = use_ipv4 ? ip::address(ip::address_v4::any()) :
ip::address::address();
const ip::address v6addr = use_ipv6 ? ip::address(ip::address_v6::any()) :
ip::address::address();
impl_ = new IOServiceImpl(auth_server, port, v4addr, v6addr);
}
IOService::~IOService() {
......
......@@ -389,8 +389,9 @@ private:
public:
/// \brief The constructor. Currently very specific to the authoritative
/// server implementation.
IOService(AuthSrv* auth_server, const char* const address,
const char& port, bool use_ipv4, bool use_ipv6);
IOService(AuthSrv* auth_server, const char& address, const char& port);
IOService(AuthSrv* auth_server, const char& port,
const bool use_ipv4, const bool use_ipv6);
/// \brief The destructor.
~IOService();
//@}
......
......@@ -101,7 +101,7 @@ main(int argc, char* argv[]) {
const char* address = NULL;
bool use_ipv4 = true, use_ipv6 = true, cache = true;
while ((ch = getopt(argc, argv, "46np:v")) != -1) {
while ((ch = getopt(argc, argv, "a:46np:v")) != -1) {
switch (ch) {
case '4':
// Note that -4 means "ipv4 only", we need to set "use_ipv6" here,
......@@ -141,6 +141,11 @@ main(int argc, char* argv[]) {
usage();
}
if ((!use_ipv4 || !use_ipv6) && address != NULL) {
cerr << "[b10-auth] Error: -4|-6 and -a can't coexist" << endl;
usage();
}
int ret = 0;
// XXX: we should eventually pass io_service here.
......@@ -162,8 +167,13 @@ main(int argc, char* argv[]) {
auth_server->setVerbose(verbose_mode);
cout << "[b10-auth] Server created." << endl;
io_service = new asio_link::IOService(auth_server, address, *port,
use_ipv4, use_ipv6);
if (address != NULL) {
io_service = new asio_link::IOService(auth_server, *port,
*address);
} else {
io_service = new asio_link::IOService(auth_server, *port,
use_ipv4, use_ipv6);
}
cout << "[b10-auth] IOService created." << endl;
cc_session = new Session(io_service->get_io_service());
......
......@@ -90,25 +90,18 @@ TEST(IOSocketTest, dummySockets) {
}
TEST(IOServiceTest, badPort) {
EXPECT_THROW(IOService(NULL, NULL, *"65536", true, false), IOError);
EXPECT_THROW(IOService(NULL, NULL, *"5300.0", true, false), IOError);
EXPECT_THROW(IOService(NULL, NULL, *"-1", true, false), IOError);
EXPECT_THROW(IOService(NULL, NULL, *"domain", true, false), IOError);
EXPECT_THROW(IOService(NULL, *"65536", true, false), IOError);
EXPECT_THROW(IOService(NULL, *"5300.0", true, false), IOError);
EXPECT_THROW(IOService(NULL, *"-1", true, false), IOError);
EXPECT_THROW(IOService(NULL, *"domain", true, false), IOError);
}
TEST(IOServiceTest, badAddress) {
EXPECT_THROW(IOService(NULL, "192.0.2.1.1", *TEST_PORT, true, false),
EXPECT_THROW(IOService(NULL, *TEST_PORT, *"192.0.2.1.1"),
IOError);
EXPECT_THROW(IOService(NULL, "2001:db8:::1", *TEST_PORT, true, false),
EXPECT_THROW(IOService(NULL, *TEST_PORT, *"2001:db8:::1"),
IOError);
EXPECT_THROW(IOService(NULL, "localhost", *TEST_PORT, true, false),
IOError);
}
TEST(IOServiceTest, addressFamilyMismatch) {
EXPECT_THROW(IOService(NULL, "192.0.2.1", *TEST_PORT, false, true),
IOError);
EXPECT_THROW(IOService(NULL, "2001:db8::1", *TEST_PORT, true, false),
EXPECT_THROW(IOService(NULL, *TEST_PORT, *"localhost"),
IOError);
}
......@@ -207,7 +200,7 @@ private:
};
ASIOLinkTest::ASIOLinkTest() :
io_service_(NULL, NULL, *TEST_PORT, true, true),
io_service_(NULL, *TEST_PORT, true, true),
sock_(-1), res_(NULL)
{
io_service_.setCallBack(ASIOCallBack(this));
......
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