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

sorber pushed a commit to branch 6.2.x
in repository https://git-dual.apache.org/repos/asf/trafficserver.git

commit 9b7189fbc0cf1f9bbd29f5510fd308a69016159e
Author: Susan Hinrichs <[email protected]>
AuthorDate: Tue Sep 27 16:24:11 2016 +0000

    TS-4813: Fix lingering stream.
    (cherry picked from commit dc8be341578aa0fa900c84265d0a336414dfad9b)
    
    Conflicts:
        iocore/net/SSLNetVConnection.cc
        proxy/http2/Http2ConnectionState.cc
---
 iocore/net/SSLNetVConnection.cc     | 13 ++++++++-----
 proxy/http/HttpTunnel.cc            | 20 ++++++++++----------
 proxy/http2/Http2ConnectionState.cc | 29 ++++++++++++++++++++---------
 proxy/http2/Http2Stream.cc          |  2 +-
 4 files changed, 39 insertions(+), 25 deletions(-)

diff --git a/iocore/net/SSLNetVConnection.cc b/iocore/net/SSLNetVConnection.cc
index 44ae638..450c577 100644
--- a/iocore/net/SSLNetVConnection.cc
+++ b/iocore/net/SSLNetVConnection.cc
@@ -364,13 +364,16 @@ SSLNetVConnection::read_raw_data()
         b = b->next;
       }
 
-      if (niov == 1) {
-        r = socketManager.read(this->con.fd, tiovec[0].iov_base, 
tiovec[0].iov_len);
-      } else {
+      // If there was no room to write into the buffer then skip the read
+      if (niov > 0) {
         r = socketManager.readv(this->con.fd, &tiovec[0], niov);
+
+        NET_INCREMENT_DYN_STAT(net_calls_to_read_stat);
+        total_read += rattempted;
+      } else { // No more space to write, break out
+        r = 0;
+        break;
       }
-      NET_INCREMENT_DYN_STAT(net_calls_to_read_stat);
-      total_read += rattempted;
     } while (rattempted && r == rattempted && total_read < toread);
 
     // if we have already moved some bytes successfully, summarize in r
diff --git a/proxy/http/HttpTunnel.cc b/proxy/http/HttpTunnel.cc
index 32694c4..a58b251 100644
--- a/proxy/http/HttpTunnel.cc
+++ b/proxy/http/HttpTunnel.cc
@@ -1198,8 +1198,6 @@ HttpTunnel::producer_handler(int event, 
HttpTunnelProducer *p)
 
   Debug("http_redirect", "[HttpTunnel::producer_handler] enable_redirection: 
[%d %d %d] event: %d", p->alive == true,
         sm->enable_redirection, (p->self_consumer && p->self_consumer->alive 
== true), event);
-  ink_assert(p->alive == true || event == HTTP_TUNNEL_EVENT_PRECOMPLETE || 
event == VC_EVENT_EOS || sm->enable_redirection ||
-             (p->self_consumer && p->self_consumer->alive == true));
 
   switch (event) {
   case VC_EVENT_READ_READY:
@@ -1255,14 +1253,16 @@ HttpTunnel::producer_handler(int event, 
HttpTunnelProducer *p)
   case VC_EVENT_ACTIVE_TIMEOUT:
   case VC_EVENT_INACTIVITY_TIMEOUT:
   case HTTP_TUNNEL_EVENT_CONSUMER_DETACH:
-    p->alive      = false;
-    p->bytes_read = p->read_vio->ndone;
-    // Interesting tunnel event, call SM
-    jump_point = p->vc_handler;
-    (sm->*jump_point)(event, p);
-    sm_callback = true;
-    // Failure case anyway
-    p->update_state_if_not_set(HTTP_SM_POST_UA_FAIL);
+    if (p->alive) {
+      p->alive      = false;
+      p->bytes_read = p->read_vio->ndone;
+      // Interesting tunnel event, call SM
+      jump_point = p->vc_handler;
+      (sm->*jump_point)(event, p);
+      sm_callback = true;
+      // Failure case anyway
+      p->update_state_if_not_set(HTTP_SM_POST_UA_FAIL);
+    }
     break;
 
   case VC_EVENT_WRITE_READY:
diff --git a/proxy/http2/Http2ConnectionState.cc 
b/proxy/http2/Http2ConnectionState.cc
index 8dcec8c..d1279c6 100644
--- a/proxy/http2/Http2ConnectionState.cc
+++ b/proxy/http2/Http2ConnectionState.cc
@@ -793,6 +793,7 @@ Http2ConnectionState::main_event_handler(int event, void 
*edata)
 
   // Finalize HTTP/2 Connection
   case HTTP2_SESSION_EVENT_FINI: {
+    ink_assert(this->fini_received == false);
     this->fini_received = true;
     cleanup_streams();
     SET_HANDLER(&Http2ConnectionState::state_closed);
@@ -937,8 +938,8 @@ Http2ConnectionState::cleanup_streams()
     this->delete_stream(s);
     s = next;
   }
+  ink_assert(stream_list.head == NULL);
 
-  client_streams_count = 0;
   if (!is_state_closed()) {
     ua_session->get_netvc()->add_to_keep_alive_queue();
   }
@@ -947,6 +948,13 @@ Http2ConnectionState::cleanup_streams()
 void
 Http2ConnectionState::delete_stream(Http2Stream *stream)
 {
+  // If stream has already been removed from the list, just go on
+  if (!stream_list.in(stream)) {
+    return;
+  }
+
+  DebugHttp2Stream(ua_session, stream->get_id(), "Delete stream");
+
   if (Http2::stream_priority_enabled) {
     DependencyTree::Node *node = stream->priority_node;
     if (node != NULL && node->active) {
@@ -956,25 +964,24 @@ Http2ConnectionState::delete_stream(Http2Stream *stream)
 
   stream_list.remove(stream);
   stream->initiating_close();
-
-  ink_assert(client_streams_count > 0);
-  --client_streams_count;
-
-  if (client_streams_count == 0 && ua_session) {
-    ua_session->get_netvc()->add_to_keep_alive_queue();
-  }
 }
 
 void
 Http2ConnectionState::release_stream(Http2Stream *stream)
 {
+  // Update stream counts
   if (stream) {
     --total_client_streams_count;
+    stream_list.remove(stream);
   }
 
   // If the number of clients is 0, then mark the connection as inactive
   if (total_client_streams_count == 0 && ua_session) {
     ua_session->clear_session_active();
+    if (ua_session->get_netvc()) {
+      ua_session->get_netvc()->add_to_keep_alive_queue();
+      ua_session->get_netvc()->cancel_active_timeout();
+    }
   }
 
   if (ua_session && fini_received && total_client_streams_count == 0) {
@@ -1125,7 +1132,11 @@ Http2ConnectionState::send_a_data_frame(Http2Stream 
*stream, size_t &payload_len
 void
 Http2ConnectionState::send_data_frames(Http2Stream *stream)
 {
-  if (stream->get_state() == HTTP2_STREAM_STATE_CLOSED) {
+  // To follow RFC 7540 must not send more frames other than priority on
+  // a closed stream.  So we return without sending
+  if (stream->get_state() == HTTP2_STREAM_STATE_HALF_CLOSED_LOCAL || 
stream->get_state() == HTTP2_STREAM_STATE_CLOSED) {
+    DebugSsn(this->ua_session, "http2_cs", "Shutdown half closed local stream 
%d", stream->get_id());
+    this->delete_stream(stream);
     return;
   }
 
diff --git a/proxy/http2/Http2Stream.cc b/proxy/http2/Http2Stream.cc
index b505941..cb42673 100644
--- a/proxy/http2/Http2Stream.cc
+++ b/proxy/http2/Http2Stream.cc
@@ -285,7 +285,7 @@ Http2Stream::do_io_close(int /* flags */)
       static_cast<Http2ClientSession 
*>(parent)->connection_state.send_data_frames(this);
     }
     // Check to see if the stream is in the closed state
-    ink_assert(get_state() == HTTP2_STREAM_STATE_CLOSED);
+    ink_assert(get_state() == HTTP2_STREAM_STATE_CLOSED || get_state() == 
HTTP2_STREAM_STATE_HALF_CLOSED_REMOTE);
 
     clear_timers();
     clear_io_events();

-- 
To stop receiving notification emails like this one, please contact
"[email protected]" <[email protected]>.

Reply via email to