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 2019/07/12 20:04:16 UTC

[qpid-proton] 03/04: PROTON-1473: Better behaviour if peer disconnects in the middle of header exchange - Especially if the server disconnects the client because of authentication failure There is no more spurious 'Header mismatch' error.

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

commit 45dba0047dab66465e011a0b65d21af670772aa3
Author: Andrew Stitcher <as...@apache.org>
AuthorDate: Mon Jul 1 18:42:10 2019 -0400

    PROTON-1473: Better behaviour if peer disconnects in the middle of header exchange
    - Especially if the server disconnects the client because of authentication failure
      There is no more spurious 'Header mismatch' error.
---
 c/src/core/transport.c              | 12 +++++++++---
 c/src/sasl/sasl.c                   |  9 ++++++++-
 c/src/ssl/openssl.c                 |  5 ++++-
 python/tests/proton_tests/engine.py |  2 +-
 4 files changed, 22 insertions(+), 6 deletions(-)

diff --git a/c/src/core/transport.c b/c/src/core/transport.c
index 50bce64..9caa79d 100644
--- a/c/src/core/transport.c
+++ b/c/src/core/transport.c
@@ -274,7 +274,7 @@ ssize_t pn_io_layer_input_autodetect(pn_transport_t *transport, unsigned int lay
   const char* error;
   bool eos = transport->tail_closed;
   if (eos && available==0) {
-    pn_do_error(transport, "amqp:connection:framing-error", "No valid protocol header found");
+    pn_do_error(transport, "amqp:connection:framing-error", "No protocol header found (connection aborted)");
     pn_set_error_layer(transport);
     return PN_EOS;
   }
@@ -1848,7 +1848,7 @@ static ssize_t transport_consume(pn_transport_t *transport)
   // flow to the app the same way, but provides cleaner error messages
   // since we don't try to look for a protocol header when, e.g. the
   // connection was refused.
-  if (!transport->bytes_input && transport->tail_closed &&
+  if (!(transport->present_layers & LAYER_AMQP1) && transport->tail_closed &&
       pn_condition_is_set(&transport->condition)) {
     pn_do_error(transport, NULL, NULL);
     return PN_EOS;
@@ -2577,9 +2577,15 @@ static void pn_error_amqp(pn_transport_t* transport, unsigned int layer)
 static ssize_t pn_input_read_amqp_header(pn_transport_t* transport, unsigned int layer, const char* bytes, size_t available)
 {
   bool eos = transport->tail_closed;
+  if (eos && available==0) {
+    pn_do_error(transport, "amqp:connection:framing-error",
+                "Expected AMQP protocol header: no protocol header found (connection aborted)");
+    return PN_EOS;
+  }
   pni_protocol_type_t protocol = pni_sniff_header(bytes, available);
   switch (protocol) {
   case PNI_PROTOCOL_AMQP1:
+    transport->present_layers |= LAYER_AMQP1;
     if (transport->io_layers[layer] == &amqp_read_header_layer) {
       transport->io_layers[layer] = &amqp_layer;
     } else {
@@ -2597,7 +2603,7 @@ static ssize_t pn_input_read_amqp_header(pn_transport_t* transport, unsigned int
   char quoted[1024];
   pn_quote_data(quoted, 1024, bytes, available);
   pn_do_error(transport, "amqp:connection:framing-error",
-              "%s header mismatch: %s ['%s']%s", "AMQP", pni_protocol_name(protocol), quoted,
+              "Expected AMQP protocol header got: %s ['%s']%s", pni_protocol_name(protocol), quoted,
               !eos ? "" : " (connection aborted)");
   return PN_EOS;
 }
diff --git a/c/src/sasl/sasl.c b/c/src/sasl/sasl.c
index 3b257ab..454877e 100644
--- a/c/src/sasl/sasl.c
+++ b/c/src/sasl/sasl.c
@@ -542,9 +542,16 @@ static void pn_error_sasl(pn_transport_t* transport, unsigned int layer)
 static ssize_t pn_input_read_sasl_header(pn_transport_t* transport, unsigned int layer, const char* bytes, size_t available)
 {
   bool eos = transport->tail_closed;
+  if (eos && available==0) {
+    pn_do_error(transport, "amqp:connection:framing-error",
+                "Expected SASL protocol header: no protocol header found (connection aborted)");
+    pn_set_error_layer(transport);
+    return PN_EOS;
+  }
   pni_protocol_type_t protocol = pni_sniff_header(bytes, available);
   switch (protocol) {
   case PNI_PROTOCOL_AMQP_SASL:
+    transport->present_layers |= LAYER_AMQPSASL;
     if (transport->io_layers[layer] == &sasl_read_header_layer) {
         transport->io_layers[layer] = &sasl_layer;
     } else {
@@ -563,7 +570,7 @@ static ssize_t pn_input_read_sasl_header(pn_transport_t* transport, unsigned int
   char quoted[1024];
   pn_quote_data(quoted, 1024, bytes, available);
   pn_do_error(transport, "amqp:connection:framing-error",
-              "%s header mismatch: %s ['%s']%s", "SASL", pni_protocol_name(protocol), quoted,
+              "Expected SASL protocol header got: %s ['%s']%s", pni_protocol_name(protocol), quoted,
               !eos ? "" : " (connection aborted)");
   pn_set_error_layer(transport);
   return PN_EOS;
diff --git a/c/src/ssl/openssl.c b/c/src/ssl/openssl.c
index 4adf630..8e325a6 100644
--- a/c/src/ssl/openssl.c
+++ b/c/src/ssl/openssl.c
@@ -1012,7 +1012,10 @@ static int start_ssl_shutdown(pn_transport_t *transport)
 static ssize_t process_input_ssl( pn_transport_t *transport, unsigned int layer, const char *input_data, size_t available)
 {
   pni_ssl_t *ssl = transport->ssl;
-  if (ssl->ssl == NULL && init_ssl_socket(transport, ssl, NULL)) return PN_EOS;
+  if (ssl->ssl == NULL) {
+    if (init_ssl_socket(transport, ssl, NULL)) return PN_EOS;
+    transport->present_layers |= LAYER_SSL;
+  }
 
   ssl_log( transport, "process_input_ssl( data size=%d )",available );
 
diff --git a/python/tests/proton_tests/engine.py b/python/tests/proton_tests/engine.py
index 41857c2..3736cbc 100644
--- a/python/tests/proton_tests/engine.py
+++ b/python/tests/proton_tests/engine.py
@@ -2453,7 +2453,7 @@ class EventTest(CollectorTest):
     self.expect(Event.TRANSPORT_ERROR, Event.TRANSPORT_TAIL_CLOSED)
     assert t.condition is not None
     assert t.condition.name == "amqp:connection:framing-error"
-    assert "AMQP header mismatch" in t.condition.description
+    assert "AMQP protocol header" in t.condition.description
     p = t.pending()
     assert p > 0
     t.pop(p)


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