You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@qpid.apache.org by as...@apache.org on 2020/09/30 20:42:34 UTC

[qpid-proton] branch master updated: PROTON-2278: Events are received after PN_RAW_CONNECTION_DISCONNECTED if connection refused - Change raw_connect to carry on after connections refused - Add a unit test that replicates the bug - Small refactor changing an internal API to allow us to fix bug

This is an automated email from the ASF dual-hosted git repository.

astitcher pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/qpid-proton.git


The following commit(s) were added to refs/heads/master by this push:
     new 341d30f  PROTON-2278: Events are received after PN_RAW_CONNECTION_DISCONNECTED if connection refused - Change raw_connect to carry on after connections refused - Add a unit test that replicates the bug - Small refactor changing an internal API to allow us to fix bug
341d30f is described below

commit 341d30f8cff0ba98bac65604ad87e4d01062080c
Author: Andrew Stitcher <as...@apache.org>
AuthorDate: Wed Sep 30 13:31:46 2020 -0400

    PROTON-2278: Events are received after PN_RAW_CONNECTION_DISCONNECTED if connection refused
    - Change raw_connect to carry on after connections refused
    - Add a unit test that replicates the bug
    - Small refactor changing an internal API to allow us to fix bug
---
 c/examples/raw_connect.c                 |  6 ++++--
 c/src/proactor/epoll_raw_connection.c    |  2 +-
 c/src/proactor/raw_connection-internal.h |  2 +-
 c/src/proactor/raw_connection.c          |  8 +++++++-
 c/tests/raw_connection_test.cpp          | 20 ++++++++++++++++++++
 5 files changed, 33 insertions(+), 5 deletions(-)

diff --git a/c/examples/raw_connect.c b/c/examples/raw_connect.c
index d38a3d7..8101ad3 100644
--- a/c/examples/raw_connect.c
+++ b/c/examples/raw_connect.c
@@ -59,13 +59,14 @@ static void close_all(pn_raw_connection_t *c, app_data_t *app) {
   if (app->listener) pn_listener_close(app->listener);
 }
 
-static void check_condition(pn_event_t *e, pn_condition_t *cond, app_data_t *app) {
+static int check_condition(pn_event_t *e, pn_condition_t *cond, app_data_t *app) {
   if (pn_condition_is_set(cond)) {
     fprintf(stderr, "%s: %s: %s\n", pn_event_type_name(pn_event_type(e)),
             pn_condition_get_name(cond), pn_condition_get_description(cond));
     close_all(pn_event_raw_connection(e), app);
-    exit_code = 1;
+    return 1;
   }
+  return 0;
 }
 
 static void send_message(pn_raw_connection_t *c, const char* msg) {
@@ -138,6 +139,7 @@ static void handle_send(app_data_t* app, pn_event_t* event) {
     case PN_RAW_CONNECTION_DISCONNECTED: {
       pn_raw_connection_t *c = pn_event_raw_connection(event);
       connection_data_t *cd = (connection_data_t*) pn_raw_connection_get_context(c);
+      pn_raw_connection_set_context(c, NULL);
       free(cd);
       printf("**raw connection disconnected\n");
       app->disconnects++;
diff --git a/c/src/proactor/epoll_raw_connection.c b/c/src/proactor/epoll_raw_connection.c
index 2b9c4d4..1799b39 100644
--- a/c/src/proactor/epoll_raw_connection.c
+++ b/c/src/proactor/epoll_raw_connection.c
@@ -320,7 +320,7 @@ pn_event_batch_t *pni_raw_connection_process(pcontext_t *c, bool sched_wake) {
       praw_connection_maybe_connect_lh(rc);
     }
     if (rc->disconnected) {
-      pni_raw_disconnect(&rc->raw_connection);
+      pni_raw_connect_failed(&rc->raw_connection);
       return &rc->batch;
     }
     if (events & (EPOLLHUP | EPOLLERR)) {
diff --git a/c/src/proactor/raw_connection-internal.h b/c/src/proactor/raw_connection-internal.h
index 02c3af2..019de62 100644
--- a/c/src/proactor/raw_connection-internal.h
+++ b/c/src/proactor/raw_connection-internal.h
@@ -91,7 +91,7 @@ struct pn_raw_connection_t {
  */
 bool pni_raw_validate(pn_raw_connection_t *conn);
 void pni_raw_connected(pn_raw_connection_t *conn);
-void pni_raw_disconnect(pn_raw_connection_t *conn);
+void pni_raw_connect_failed(pn_raw_connection_t *conn);
 void pni_raw_process(pn_raw_connection_t *conn, int events, bool wake);
 void pni_raw_wake(pn_raw_connection_t *conn);
 void pni_raw_read(pn_raw_connection_t *conn, int sock, long (*recv)(int, void*, size_t), void (*set_error)(pn_raw_connection_t *, const char *, int));
diff --git a/c/src/proactor/raw_connection.c b/c/src/proactor/raw_connection.c
index a225df9..18bcb9a 100644
--- a/c/src/proactor/raw_connection.c
+++ b/c/src/proactor/raw_connection.c
@@ -311,7 +311,7 @@ static inline void pni_raw_release_buffers(pn_raw_connection_t *conn) {
   conn->wdrainpending = (bool)(conn->wbuffer_first_written);
 }
 
-void pni_raw_disconnect(pn_raw_connection_t *conn) {
+static inline void pni_raw_disconnect(pn_raw_connection_t *conn) {
   pni_raw_release_buffers(conn);
   conn->disconnectpending = true;
 }
@@ -321,6 +321,12 @@ void pni_raw_connected(pn_raw_connection_t *conn) {
   pni_raw_put_event(conn, PN_RAW_CONNECTION_CONNECTED);
 }
 
+void pni_raw_connect_failed(pn_raw_connection_t *conn) {
+  conn->rclosed = true;
+  conn->wclosed = true;
+  pni_raw_disconnect(conn);
+}
+
 void pni_raw_wake(pn_raw_connection_t *conn) {
   conn->wakepending = true;
 }
diff --git a/c/tests/raw_connection_test.cpp b/c/tests/raw_connection_test.cpp
index 1ddc977..65f192a 100644
--- a/c/tests/raw_connection_test.cpp
+++ b/c/tests/raw_connection_test.cpp
@@ -324,6 +324,26 @@ char message[] =
 "And the mome raths outgrabe.\n"
 ;
 
+TEST_CASE("raw connection refused") {
+  auto_free<pn_raw_connection_t, free_raw_connection> p(mk_raw_connection());
+
+  REQUIRE(p);
+  REQUIRE(pni_raw_validate(p));
+  CHECK_FALSE(pn_raw_connection_is_read_closed(p));
+  CHECK_FALSE(pn_raw_connection_is_write_closed(p));
+
+  size_t rbuff_count = pn_raw_connection_read_buffers_capacity(p);
+  CHECK(rbuff_count>0);
+  size_t wbuff_count = pn_raw_connection_write_buffers_capacity(p);
+  CHECK(wbuff_count>0);
+
+  // Simulate connection refused
+  pni_raw_connect_failed(p);
+
+  REQUIRE(pn_event_type(pni_raw_event_next(p)) == PN_RAW_CONNECTION_DISCONNECTED);
+  REQUIRE(pn_event_type(pni_raw_event_next(p)) == PN_EVENT_NONE);
+}
+
 TEST_CASE("raw connection") {
   auto_free<pn_raw_connection_t, free_raw_connection> p(mk_raw_connection());
   max_send_size = 0;


---------------------------------------------------------------------
To unsubscribe, e-mail: commits-unsubscribe@qpid.apache.org
For additional commands, e-mail: commits-help@qpid.apache.org