This is an automated email from the ASF dual-hosted git repository. astitcher pushed a commit to branch main in repository https://gitbox.apache.org/repos/asf/qpid-proton.git
commit 10db7aa3f2ad22c4869ac93d5c7d677f876e92b0 Author: Rakhi Kumari <[email protected]> AuthorDate: Sat Oct 30 01:11:13 2021 +0530 PROTON-2441: Fix connection_options failover urls segfault --- cpp/src/connection_options.cpp | 10 ++++-- cpp/src/reconnect_test.cpp | 77 +++++++++++++++++++++++++++++++++++++++++- 2 files changed, 84 insertions(+), 3 deletions(-) diff --git a/cpp/src/connection_options.cpp b/cpp/src/connection_options.cpp index 6ae8d0f..2ee550e 100644 --- a/cpp/src/connection_options.cpp +++ b/cpp/src/connection_options.cpp @@ -124,7 +124,7 @@ class connection_options::impl { cc.reconnect_url_ = reconnect_url.value; cc.reconnect_context_->current_url_ = -1; } - if (failover_urls.set) { + if (failover_urls.set && !failover_urls.value.empty()) { failover_urls.set = false; cc.failover_urls_ = failover_urls.value; cc.reconnect_context_->current_url_ = 0; @@ -252,7 +252,13 @@ connection_options& connection_options::reconnect(const reconnect_options &r) { return *this; } connection_options& connection_options::reconnect_url(const std::string& u) { impl_->reconnect_url = u; return *this; } -connection_options& connection_options::failover_urls(const std::vector<std::string>& us) { impl_->failover_urls = us; return *this; } +connection_options & +connection_options::failover_urls(const std::vector<std::string> &us) { + if (!us.empty()) { + impl_->failover_urls = us; + } + return *this; +} connection_options& connection_options::ssl_client_options(const class ssl_client_options &c) { impl_->ssl_client_options = c; return *this; } connection_options& connection_options::ssl_server_options(const class ssl_server_options &c) { impl_->ssl_server_options = c; return *this; } connection_options& connection_options::sasl_enabled(bool b) { impl_->sasl_enabled = b; return *this; } diff --git a/cpp/src/reconnect_test.cpp b/cpp/src/reconnect_test.cpp index 58e5751..6b6c377 100644 --- a/cpp/src/reconnect_test.cpp +++ b/cpp/src/reconnect_test.cpp @@ -188,9 +188,10 @@ class tester : public proton::messaging_handler, public waiter { // Could be > 3, unpredictable number reconnects while listener comes up. ASSERT(2 < transport_error_count); // Last reconnect fails before opening links - ASSERT(link_open_count > 1); + ASSERT(1 < link_open_count); // One final transport close, not an error ASSERT_EQUAL(1, transport_close_count); + } private: @@ -206,6 +207,79 @@ int test_failover_simple() { return 0; } +class empty_failover_tester : public proton::messaging_handler, public waiter { + public: + empty_failover_tester() : waiter(1), container_(*this, "reconnect_client"), + start_count(0), open_count(0), + link_open_count(0), transport_error_count(0), transport_close_count(0), + connection_error_count(0) {} + + void on_container_start(proton::container &c) override { + // Server that fails upon connection + s1.reset(new server_connection_handler(c, 0, *this)); + } + + // waiter::ready is called when a listener is ready. + void ready() override { + std::vector<std::string> urls; + container_.connect(s1->url(), proton::connection_options().failover_urls(urls)); + } + + void on_connection_open(proton::connection& c) override { + if (!c.reconnected()) { + start_count++; + c.open_sender("messages"); + } + ASSERT_EQUAL(bool(open_count), c.reconnected()); + open_count++; + } + + void on_connection_error (proton::connection& c) override { + connection_error_count++; + } + + void on_sender_open(proton::sender &s) override { + link_open_count++; + } + + void on_sendable(proton::sender& s) override { + s.send(proton::message("hello")); + } + + void on_tracker_accept(proton::tracker& d) override { + d.connection().close(); + } + + void on_transport_error(proton::transport& t) override { + ASSERT_EQUAL(bool(transport_error_count), t.connection().reconnected()); + transport_error_count++; + } + + void on_transport_close(proton::transport& t) override { + transport_close_count++; + } + + void run() { + container_.run(); + ASSERT_EQUAL(1, start_count); + ASSERT_EQUAL(1, open_count); + // Could be >=0, unpredictable number reconnects while listener comes up. + ASSERT(0 <= transport_error_count); + ASSERT(0 <= link_open_count); + ASSERT_EQUAL(1, transport_close_count); + ASSERT_EQUAL(1, connection_error_count); + } + + private: + proton::internal::pn_unique_ptr<server_connection_handler> s1; + proton::container container_; + int start_count, open_count, link_open_count, transport_error_count, transport_close_count, connection_error_count; +}; + +int test_empty_failover() { + empty_failover_tester().run(); + return 0; +} } @@ -493,6 +567,7 @@ private: int main(int argc, char **argv) { int failed = 0; RUN_ARGV_TEST(failed, test_failover_simple()); + RUN_ARGV_TEST(failed, test_empty_failover()); RUN_ARGV_TEST(failed, test_stop_reconnect()); RUN_ARGV_TEST(failed, test_auth_fail_reconnect()); RUN_ARGV_TEST(failed, test_reconnecting_close().run()); --------------------------------------------------------------------- To unsubscribe, e-mail: [email protected] For additional commands, e-mail: [email protected]
