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]

Reply via email to