diff --git a/src/address.cpp b/src/address.cpp index 7553d8292..6a4c3d1f0 100644 --- a/src/address.cpp +++ b/src/address.cpp @@ -16,6 +16,8 @@ #include "address.hpp" +#include "macros.hpp" + #include #include @@ -24,13 +26,18 @@ namespace cass { const Address Address::EMPTY_KEY("0.0.0.0", 0); const Address Address::DELETED_KEY("0.0.0.0", 1); +const Address Address::BIND_ANY_IPV4("0.0.0.0", 0); +const Address Address::BIND_ANY_IPV6("::", 0); + Address::Address() { init(); } Address::Address(const std::string& ip, int port) { init(); - from_string(ip, port, this); + bool result = from_string(ip, port, this); + UNUSED_(result); + assert(result); } bool Address::from_string(const std::string& ip, int port, Address* output) { @@ -47,7 +54,7 @@ bool Address::from_string(const std::string& ip, int port, Address* output) { #else uv_ip4_addr(ip.c_str(), port, &addr); #endif - output->init(copy_cast(&addr)); + output->init(&addr); } return true; #if UV_VERSION_MAJOR == 0 @@ -62,7 +69,7 @@ bool Address::from_string(const std::string& ip, int port, Address* output) { #else uv_ip6_addr(ip.c_str(), port, &addr); #endif - output->init(copy_cast(&addr)); + output->init(&addr); } return true; } else { @@ -70,12 +77,17 @@ bool Address::from_string(const std::string& ip, int port, Address* output) { } } -void Address::from_inet(const char* data, size_t size, int port, Address* output) { +bool Address::from_inet(const char* data, size_t size, int port, Address* output) { - assert(size == 4 || size == 16); if (size == 4) { char buf[INET_ADDRSTRLEN]; - uv_inet_ntop(AF_INET, data, buf, sizeof(buf)); +#if UV_VERSION_MAJOR == 0 + if (uv_inet_ntop(AF_INET, data, buf, sizeof(buf)).code != UV_OK) { +#else + if (uv_inet_ntop(AF_INET, data, buf, sizeof(buf)) != 0) { +#endif + return false; + } if (output != NULL) { struct sockaddr_in addr; #if UV_VERSION_MAJOR == 0 @@ -83,11 +95,19 @@ void Address::from_inet(const char* data, size_t size, int port, Address* output #else uv_ip4_addr(buf, port, &addr); #endif - output->init(copy_cast(&addr)); + output->init(&addr); } + + return true; } else { char buf[INET6_ADDRSTRLEN]; - uv_inet_ntop(AF_INET6, data, buf, sizeof(buf)); +#if UV_VERSION_MAJOR == 0 + if (uv_inet_ntop(AF_INET6, data, buf, sizeof(buf)).code != UV_OK) { +#else + if (uv_inet_ntop(AF_INET6, data, buf, sizeof(buf)) != 0) { +#endif + return false; + } if (output != NULL) { struct sockaddr_in6 addr; #if UV_VERSION_MAJOR == 0 @@ -95,31 +115,40 @@ void Address::from_inet(const char* data, size_t size, int port, Address* output #else uv_ip6_addr(buf, port, &addr); #endif - output->init(copy_cast(&addr)); + output->init(&addr); } + + return true; } + return false; } bool Address::init(const sockaddr* addr) { if (addr->sa_family == AF_INET) { - memcpy(&addr_, addr, sizeof(struct sockaddr_in)); + memcpy(addr_in(), addr, sizeof(struct sockaddr_in)); return true; } else if (addr->sa_family == AF_INET6) { - memcpy(&addr_, addr, sizeof(struct sockaddr_in6)); + memcpy(addr_in6(), addr, sizeof(struct sockaddr_in6)); return true; } return false; } +void Address::init(const struct sockaddr_in* addr) { + *addr_in() = *addr; +} + +void Address::init(const struct sockaddr_in6* addr) { + *addr_in6() = *addr; +} + int Address::port() const { if (family() == AF_INET) { return htons(addr_in()->sin_port); } else if (family() == AF_INET6) { return htons(addr_in6()->sin6_port); - } else { - assert(false); - return -1; } + return -1; } std::string Address::to_string(bool with_port) const { @@ -136,8 +165,6 @@ std::string Address::to_string(bool with_port) const { if (with_port) ss << "["; ss << host; if (with_port) ss << "]:" << port(); - } else { - assert(false); } return ss.str(); } @@ -146,17 +173,18 @@ uint8_t Address::to_inet(uint8_t* data) const { if (family() == AF_INET) { memcpy(data, &addr_in()->sin_addr, 4); return 4; - } else { + } else if (family() == AF_INET6) { memcpy(data, &addr_in6()->sin6_addr, 16); return 16; } + return 0; } -int Address::compare(const Address& a) const { +int Address::compare(const Address& a, bool with_port) const { if (family() != a.family()) { return family() < a.family() ? -1 : 1; } - if (port() != a.port()) { + if (with_port && port() != a.port()) { return port() < a.port() ? -1 : 1; } if (family() == AF_INET) { @@ -166,11 +194,8 @@ int Address::compare(const Address& a) const { } else if (family() == AF_INET6) { return memcmp(&(addr_in6()->sin6_addr), &(a.addr_in6()->sin6_addr), sizeof(addr_in6()->sin6_addr)); - } else { - assert(false); - return -1; } return 0; } -} +} // namespace cass diff --git a/src/address.hpp b/src/address.hpp index 5c4dd107d..063c98d83 100644 --- a/src/address.hpp +++ b/src/address.hpp @@ -18,12 +18,11 @@ #define __CASS_ADDRESS_HPP_INCLUDED__ #include "hash.hpp" -#include "utils.hpp" #include +#include #include -#include #include #include #include @@ -35,62 +34,70 @@ class Address { static const Address EMPTY_KEY; static const Address DELETED_KEY; - Address(); - - Address(const std::string& ip, int port); + static const Address BIND_ANY_IPV4; + static const Address BIND_ANY_IPV6; + Address(); + Address(const std::string& ip, int port); // Tests only static bool from_string(const std::string& ip, int port, Address* output = NULL); - static void from_inet(const char* data, size_t size, int port, + static bool from_inet(const char* data, size_t size, int port, Address* output = NULL); bool init(const struct sockaddr* addr); - const struct sockaddr* addr() const { - return copy_cast(&addr_); - } - - struct sockaddr_in* addr_in() { - return copy_cast(&addr_); - } - - const struct sockaddr_in* addr_in() const { - return copy_cast(&addr_); - } - - struct sockaddr_in6* addr_in6() { - return copy_cast(&addr_); - } - - const struct sockaddr_in6* addr_in6() const { - return copy_cast(&addr_); - } - - int family() const { return addr_.ss_family; } +#ifdef _WIN32 + const struct sockaddr* addr() const { return reinterpret_cast(&addr_); } + const struct sockaddr_in* addr_in() const { return reinterpret_cast(&addr_); } + const struct sockaddr_in6* addr_in6() const { return reinterpret_cast(&addr_); } +#else + const struct sockaddr* addr() const { return &addr_; } + const struct sockaddr_in* addr_in() const { return &addr_in_; } + const struct sockaddr_in6* addr_in6() const { return &addr_in6_; } +#endif + int family() const { return addr()->sa_family; } int port() const; std::string to_string(bool with_port = false) const; uint8_t to_inet(uint8_t* data) const; - int compare(const Address& a) const; + int compare(const Address& a, bool with_port = true) const; private: - void init() { memset(&addr_, 0, sizeof(addr_)); } + void init() { addr()->sa_family = AF_UNSPEC; } + void init(const struct sockaddr_in* addr); + void init(const struct sockaddr_in6* addr); + +#ifdef _WIN32 + struct sockaddr* addr() { return reinterpret_cast(&addr_); } + struct sockaddr_in* addr_in() { return reinterpret_cast(&addr_); } + struct sockaddr_in6* addr_in6() { return reinterpret_cast(&addr_); } struct sockaddr_storage addr_; +#else + struct sockaddr* addr() { return &addr_; } + struct sockaddr_in* addr_in() { return &addr_in_; } + struct sockaddr_in6* addr_in6() { return &addr_in6_; } + + union { + struct sockaddr addr_; + struct sockaddr_in addr_in_; + struct sockaddr_in6 addr_in6_; + }; +#endif }; struct AddressHash { std::size_t operator()(const cass::Address& a) const { if (a.family() == AF_INET) { - return cass::hash::fnv1a(reinterpret_cast(a.addr_in()), - sizeof(struct sockaddr_in)); + return cass::hash::fnv1a(reinterpret_cast(a.addr()), + sizeof(struct sockaddr_in)); } else if (a.family() == AF_INET6) { - return cass::hash::fnv1a(reinterpret_cast(a.addr_in6()), - sizeof(struct sockaddr_in6)); + return cass::hash::fnv1a(reinterpret_cast(a.addr()), + sizeof(struct sockaddr_in6)); } return 0; } diff --git a/src/async_queue.hpp b/src/async_queue.hpp index 6217156e4..941b7fb6b 100644 --- a/src/async_queue.hpp +++ b/src/async_queue.hpp @@ -17,8 +17,6 @@ #ifndef __CASS_ASYNC_QUEUE_HPP_INCLUDED__ #define __CASS_ASYNC_QUEUE_HPP_INCLUDED__ -#include "utils.hpp" - #include namespace cass { @@ -35,7 +33,7 @@ class AsyncQueue { } void close_handles() { - uv_close(copy_cast(&async_), NULL); + uv_close(reinterpret_cast(&async_), NULL); } void send() { diff --git a/src/connection.cpp b/src/connection.cpp index 1d91c55b8..2b6325f92 100644 --- a/src/connection.cpp +++ b/src/connection.cpp @@ -34,7 +34,6 @@ #include "error_response.hpp" #include "event_response.hpp" #include "logger.hpp" -#include "utils.hpp" #ifdef HAVE_NOSIGPIPE #include @@ -344,14 +343,14 @@ void Connection::internal_close(ConnectionState close_state) { if (state_ != CONNECTION_STATE_CLOSE && state_ != CONNECTION_STATE_CLOSE_DEFUNCT) { - uv_handle_t* handle = copy_cast(&socket_); + uv_handle_t* handle = reinterpret_cast(&socket_); if (!uv_is_closing(handle)) { heartbeat_timer_.stop(); terminate_timer_.stop(); connect_timer_.stop(); if (state_ == CONNECTION_STATE_CONNECTED || state_ == CONNECTION_STATE_READY) { - uv_read_stop(copy_cast(&socket_)); + uv_read_stop(reinterpret_cast(&socket_)); } set_state(close_state); uv_close(handle, on_close); @@ -530,12 +529,12 @@ void Connection::on_connect(Connector* connector) { connection->host_->address_string().c_str(), static_cast(connection)); -#ifdef HAVE_NOSIGPIPE +#if defined(HAVE_NOSIGPIPE) && UV_VERSION_MAJOR >= 1 // This must be done after connection for the socket file descriptor to be // valid. uv_os_fd_t fd = 0; int enabled = 1; - if (uv_fileno(copy_cast(&connection->socket_), &fd) != 0 || + if (uv_fileno(reinterpret_cast(&connection->socket_), &fd) != 0 || setsockopt(fd, SOL_SOCKET, SO_NOSIGPIPE, (void *)&enabled, sizeof(int)) != 0) { LOG_WARN("Unable to set socket option SO_NOSIGPIPE for host %s", connection->host_->address_string().c_str()); @@ -543,10 +542,10 @@ void Connection::on_connect(Connector* connector) { #endif if (connection->ssl_session_) { - uv_read_start(copy_cast(&connection->socket_), + uv_read_start(reinterpret_cast(&connection->socket_), Connection::alloc_buffer_ssl, Connection::on_read_ssl); } else { - uv_read_start(copy_cast(&connection->socket_), + uv_read_start(reinterpret_cast(&connection->socket_), Connection::alloc_buffer, Connection::on_read); } @@ -1036,7 +1035,7 @@ void Connection::PendingWrite::flush() { } is_flushed_ = true; - uv_stream_t* sock_stream = copy_cast(&connection_->socket_); + uv_stream_t* sock_stream = reinterpret_cast(&connection_->socket_); uv_write(&req_, sock_stream, bufs.data(), bufs.size(), PendingWrite::on_write); } } @@ -1106,7 +1105,7 @@ void Connection::PendingWriteSsl::flush() { LOG_TRACE("Sending %u encrypted bytes", static_cast(encrypted_size_)); - uv_stream_t* sock_stream = copy_cast(&connection_->socket_); + uv_stream_t* sock_stream = reinterpret_cast(&connection_->socket_); uv_write(&req_, sock_stream, bufs.data(), bufs.size(), PendingWriteSsl::on_write); is_flushed_ = true; @@ -1123,7 +1122,7 @@ void Connection::PendingWriteSsl::on_write(uv_write_t* req, int status) { bool Connection::SslHandshakeWriter::write(Connection* connection, char* buf, size_t buf_size) { SslHandshakeWriter* writer = new SslHandshakeWriter(connection, buf, buf_size); - uv_stream_t* stream = copy_cast(&connection->socket_); + uv_stream_t* stream = reinterpret_cast(&connection->socket_); int rc = uv_write(&writer->req_, stream, &writer->uv_buf_, 1, SslHandshakeWriter::on_write); if (rc != 0) { diff --git a/src/control_connection.cpp b/src/control_connection.cpp index bbddffa8f..7aa1ff7cc 100644 --- a/src/control_connection.cpp +++ b/src/control_connection.cpp @@ -86,20 +86,25 @@ bool ControlConnection::determine_address_for_peer_host(const Address& connected const Value* rpc_value, Address* output) { Address peer_address; - Address::from_inet(peer_value->data(), peer_value->size(), - connected_address.port(), &peer_address); + if (!Address::from_inet(peer_value->data(), peer_value->size(), + connected_address.port(), &peer_address)) { + LOG_WARN("Invalid address format for peer address"); + return false; + } if (rpc_value->size() > 0) { - Address::from_inet(rpc_value->data(), rpc_value->size(), - connected_address.port(), output); - if (connected_address.compare(*output) == 0 || - connected_address.compare(peer_address) == 0) { + if (Address::from_inet(rpc_value->data(), rpc_value->size(), + connected_address.port(), output)) { + LOG_WARN("Invalid address format for rpc address"); + return false; + } + if (connected_address == *output || connected_address == peer_address) { LOG_DEBUG("system.peers on %s contains a line with rpc_address for itself. " "This is not normal, but is a known problem for some versions of DSE. " "Ignoring this entry.", connected_address.to_string(false).c_str()); return false; } - if (bind_any_ipv4_.compare(*output) == 0 || - bind_any_ipv6_.compare(*output) == 0) { + if (Address::BIND_ANY_IPV4.compare(*output, false) == 0 || + Address::BIND_ANY_IPV6.compare(*output, false) == 0) { LOG_WARN("Found host with 'bind any' for rpc_address; using listen_address (%s) to contact instead. " "If this is incorrect you should configure a specific interface for rpc_address on the server.", peer_address.to_string(false).c_str()); @@ -628,7 +633,7 @@ void ControlConnection::refresh_node_info(SharedRefPtr host, return; } - bool is_connected_host = host->address().compare(connection_->address()) == 0; + bool is_connected_host = host->address() == connection_->address(); std::string query; ControlHandler::ResponseCallback response_callback; @@ -719,7 +724,7 @@ void ControlConnection::on_refresh_node_info_all(ControlConnection* control_conn row->get_by_name("peer"), row->get_by_name("rpc_address"), &address); - if (is_valid_address && data.host->address().compare(address) == 0) { + if (is_valid_address && data.host->address() == address) { control_connection->update_node_info(data.host, row, UPDATE_HOST_AND_BUILD); if (data.is_new_node) { control_connection->session_->on_add(data.host, false); @@ -745,10 +750,13 @@ void ControlConnection::update_node_info(SharedRefPtr host, const Row* row v = row->get_by_name("peer"); if (v != NULL) { Address listen_address; - Address::from_inet(v->data(), v->size(), - connection_->address().port(), - &listen_address); - host->set_listen_address(listen_address.to_string()); + if (Address::from_inet(v->data(), v->size(), + connection_->address().port(), + &listen_address)) { + host->set_listen_address(listen_address.to_string()); + } else { + LOG_WARN("Invalid address format for listen address"); + } } if ((!rack.empty() && rack != host->rack()) || @@ -772,7 +780,7 @@ void ControlConnection::update_node_info(SharedRefPtr host, const Row* row } if (token_aware_routing_) { - bool is_connected_host = connection_ != NULL && host->address().compare(connection_->address()) == 0; + bool is_connected_host = connection_ != NULL && host->address() == connection_->address(); std::string partitioner; if (is_connected_host && row->get_string_by_name("partitioner", &partitioner)) { if (!session_->token_map_) { @@ -1115,7 +1123,4 @@ void ControlConnection::ControlMultipleRequestHandler::on_set( response_callback_(control_connection_, data_, responses); } -Address ControlConnection::bind_any_ipv4_("0.0.0.0", 0); -Address ControlConnection::bind_any_ipv6_("::", 0); - } // namespace cass diff --git a/src/control_connection.hpp b/src/control_connection.hpp index 011e345e9..f39502f14 100644 --- a/src/control_connection.hpp +++ b/src/control_connection.hpp @@ -257,9 +257,6 @@ class ControlConnection : public Connection::Listener { bool use_schema_; bool token_aware_routing_; - static Address bind_any_ipv4_; - static Address bind_any_ipv6_; - private: DISALLOW_COPY_AND_ASSIGN(ControlConnection); }; diff --git a/src/io_worker.cpp b/src/io_worker.cpp index 0f16275cb..99f73011b 100644 --- a/src/io_worker.cpp +++ b/src/io_worker.cpp @@ -244,7 +244,7 @@ void IOWorker::close_handles() { EventThread::close_handles(); request_queue_.close_handles(); uv_prepare_stop(&prepare_); - uv_close(copy_cast(&prepare_), NULL); + uv_close(reinterpret_cast(&prepare_), NULL); } void IOWorker::on_event(const IOWorkerEvent& event) { diff --git a/src/loop_thread.hpp b/src/loop_thread.hpp index b203894a1..c4d8df59c 100644 --- a/src/loop_thread.hpp +++ b/src/loop_thread.hpp @@ -92,7 +92,7 @@ class LoopThread { void close_handles() { #if defined(HAVE_SIGTIMEDWAIT) && !defined(HAVE_NOSIGPIPE) uv_prepare_stop(&prepare_); - uv_close(copy_cast(&prepare_), NULL); + uv_close(reinterpret_cast(&prepare_), NULL); #endif } diff --git a/src/mpmc_queue.hpp b/src/mpmc_queue.hpp index c8a167b85..e73c7f299 100644 --- a/src/mpmc_queue.hpp +++ b/src/mpmc_queue.hpp @@ -24,8 +24,8 @@ #include "atomic.hpp" #include "cassconfig.hpp" -#include "utils.hpp" #include "macros.hpp" +#include "utils.hpp" #include diff --git a/src/periodic_task.hpp b/src/periodic_task.hpp index 9a91287b0..3b64bd2fb 100644 --- a/src/periodic_task.hpp +++ b/src/periodic_task.hpp @@ -46,7 +46,7 @@ class PeriodicTask : public RefCounted { private: static void close(PeriodicTask* task) { - uv_close(copy_cast(&task->timer_handle_), on_close); + uv_close(reinterpret_cast(&task->timer_handle_), on_close); } #if UV_VERSION_MAJOR == 0 diff --git a/src/resolver.hpp b/src/resolver.hpp index 51ac9c234..4d69d40cc 100644 --- a/src/resolver.hpp +++ b/src/resolver.hpp @@ -26,7 +26,6 @@ #include "address.hpp" #include "ref_counted.hpp" #include "timer.hpp" -#include "utils.hpp" namespace cass { @@ -100,7 +99,7 @@ class Resolver { static void on_timeout(Timer* timer) { Resolver* resolver = static_cast(timer->data()); resolver->status_ = FAILED_TIMED_OUT; - uv_cancel(copy_cast(&resolver->req_)); + uv_cancel(reinterpret_cast(&resolver->req_)); } private: @@ -208,7 +207,7 @@ class NameResolver { static void on_timeout(Timer* timer) { NameResolver* resolver = static_cast(timer->data()); resolver->status_ = FAILED_TIMED_OUT; - uv_cancel(copy_cast(&resolver->req_)); + uv_cancel(reinterpret_cast(&resolver->req_)); } private: diff --git a/src/spsc_queue.hpp b/src/spsc_queue.hpp index d70985f0e..45747e0d4 100644 --- a/src/spsc_queue.hpp +++ b/src/spsc_queue.hpp @@ -31,8 +31,8 @@ #include "atomic.hpp" #include "cassconfig.hpp" -#include "utils.hpp" #include "macros.hpp" +#include "utils.hpp" namespace cass { diff --git a/src/ssl/ssl_openssl_impl.cpp b/src/ssl/ssl_openssl_impl.cpp index 9471760c8..0c292e93a 100644 --- a/src/ssl/ssl_openssl_impl.cpp +++ b/src/ssl/ssl_openssl_impl.cpp @@ -324,14 +324,12 @@ class OpenSslVerifyIdentity { } static Result match_subject_alt_names_ipadd(X509* cert, const Address& addr) { - char addr_buf[16]; + uint8_t addr_buf[16]; size_t addr_buf_size; - if (addr.family() == AF_INET) { - addr_buf_size = 4; - memcpy(addr_buf, &addr.addr_in()->sin_addr.s_addr, addr_buf_size); - } else { - addr_buf_size = 16; - memcpy(addr_buf, &addr.addr_in6()->sin6_addr, addr_buf_size); + + addr_buf_size = addr.to_inet(addr_buf); + if (addr_buf_size == 0) { + return NO_MATCH; } STACK_OF(GENERAL_NAME)* names diff --git a/src/timer.hpp b/src/timer.hpp index fdf09c89e..32b265e8b 100644 --- a/src/timer.hpp +++ b/src/timer.hpp @@ -18,7 +18,6 @@ #define __CASS_TIMER_HPP_INCLUDED__ #include "macros.hpp" -#include "utils.hpp" #include @@ -40,7 +39,7 @@ class Timer { bool is_running() const { if (handle_ == NULL) return false; - return uv_is_active(copy_cast(handle_)) != 0; + return uv_is_active(reinterpret_cast(handle_)) != 0; } void start(uv_loop_t* loop, uint64_t timeout, void* data, @@ -58,7 +57,7 @@ class Timer { void stop() { if (handle_ == NULL) return; // This also stops the timer - uv_close(copy_cast(handle_), on_close); + uv_close(reinterpret_cast(handle_), on_close); handle_ = NULL; } @@ -78,7 +77,7 @@ class Timer { } static void on_close(uv_handle_t* handle) { - delete copy_cast(handle); + delete reinterpret_cast(handle); } private: diff --git a/test/unit_tests/src/test_address.cpp b/test/unit_tests/src/test_address.cpp index 714a2ac48..4301ebb76 100644 --- a/test/unit_tests/src/test_address.cpp +++ b/test/unit_tests/src/test_address.cpp @@ -32,5 +32,12 @@ BOOST_AUTO_TEST_CASE(compare_ipv4) BOOST_CHECK(cass::Address("1.2.3.4", 9042).compare(cass::Address("1.2.3.4", 9042)) == 0); } +BOOST_AUTO_TEST_CASE(compare_no_port) +{ + BOOST_CHECK(cass::Address("0.0.0.0", 0).compare(cass::Address("0.0.0.0", 1), false) == 0); + BOOST_CHECK(cass::Address("0.0.0.0", 0).compare(cass::Address("0.0.0.0", 1), true) < 0); + BOOST_CHECK(cass::Address("0.0.0.0", 1).compare(cass::Address("0.0.0.0", 0), true) > 0); +} + BOOST_AUTO_TEST_SUITE_END() diff --git a/test/unit_tests/src/test_load_balancing.cpp b/test/unit_tests/src/test_load_balancing.cpp index fa897ec13..a0ef58948 100644 --- a/test/unit_tests/src/test_load_balancing.cpp +++ b/test/unit_tests/src/test_load_balancing.cpp @@ -52,9 +52,13 @@ const string BACKUP_DC = "backup"; #define VECTOR_FROM(t, a) std::vector(a, a + sizeof(a)/sizeof(a[0])) cass::Address addr_for_sequence(size_t i) { - cass::Address addr("0.0.0.0", 9042); - addr.addr_in()->sin_addr.s_addr = i; - return addr; + char temp[64]; + sprintf(temp, "%d.%d.%d.%d", + static_cast(i & 0xFF), + static_cast((i >> 8) & 0xFF), + static_cast((i >> 16) & 0xFF), + static_cast((i >> 24) & 0xFF)); + return cass::Address(temp, 9042); } cass::SharedRefPtr host_for_addr(const cass::Address addr, @@ -77,14 +81,12 @@ void populate_hosts(size_t count, const std::string& rack, } void verify_sequence(cass::QueryPlan* qp, const std::vector& sequence) { - cass::Address expected("0.0.0.0", 9042); cass::Address received; for (std::vector::const_iterator it = sequence.begin(); it!= sequence.end(); ++it) { BOOST_REQUIRE(qp->compute_next(&received)); - expected.addr_in()->sin_addr.s_addr = *it; - BOOST_CHECK_EQUAL(expected, received); + BOOST_CHECK_EQUAL(addr_for_sequence(*it), received); } BOOST_CHECK(!qp->compute_next(&received)); }