You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@trafficserver.apache.org by bc...@apache.org on 2016/10/06 00:04:47 UTC
[trafficserver] branch 7.0.x updated: TS-4813: Fix lingering stream.
This is an automated email from the ASF dual-hosted git repository.
bcall pushed a commit to branch 7.0.x
in repository https://git-dual.apache.org/repos/asf/trafficserver.git
The following commit(s) were added to refs/heads/7.0.x by this push:
new 8dc35e0 TS-4813: Fix lingering stream.
8dc35e0 is described below
commit 8dc35e04a8a0b4fb6b1ea2bebcfaa915e7acdbf5
Author: Susan Hinrichs <sh...@ieee.org>
AuthorDate: Tue Sep 27 16:24:11 2016 +0000
TS-4813: Fix lingering stream.
(cherry picked from commit dc8be341578aa0fa900c84265d0a336414dfad9b)
---
iocore/net/SSLNetVConnection.cc | 18 ++++++++++------
proxy/http/HttpTunnel.cc | 20 +++++++++---------
proxy/http2/Http2ConnectionState.cc | 41 ++++++++++++++++++++++---------------
proxy/http2/Http2Stream.cc | 2 +-
4 files changed, 48 insertions(+), 33 deletions(-)
diff --git a/iocore/net/SSLNetVConnection.cc b/iocore/net/SSLNetVConnection.cc
index 2e96eb3..39243c8 100644
--- a/iocore/net/SSLNetVConnection.cc
+++ b/iocore/net/SSLNetVConnection.cc
@@ -349,12 +349,18 @@ SSLNetVConnection::read_raw_data()
b = b->next.get();
}
- ink_assert(niov > 0);
- ink_assert(niov <= countof(tiovec));
- r = socketManager.readv(this->con.fd, &tiovec[0], niov);
-
- NET_INCREMENT_DYN_STAT(net_calls_to_read_stat);
- total_read += rattempted;
+ // If there was no room to write into the buffer then skip the read
+ if (niov > 0) {
+ ink_assert(niov > 0);
+ ink_assert(niov <= countof(tiovec));
+ 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;
+ }
} 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 b018cae..9b1b0aa 100644
--- a/proxy/http/HttpTunnel.cc
+++ b/proxy/http/HttpTunnel.cc
@@ -1211,8 +1211,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:
@@ -1268,14 +1266,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 212536e..1fd0f88 100644
--- a/proxy/http2/Http2ConnectionState.cc
+++ b/proxy/http2/Http2ConnectionState.cc
@@ -797,6 +797,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);
@@ -964,9 +965,8 @@ Http2ConnectionState::cleanup_streams()
this->delete_stream(s);
s = next;
}
+ ink_assert(stream_list.head == NULL);
- client_streams_in_count = 0;
- client_streams_out_count = 0;
if (!is_state_closed()) {
ua_session->get_netvc()->add_to_keep_alive_queue();
ua_session->get_netvc()->cancel_active_timeout();
@@ -976,6 +976,11 @@ 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) {
@@ -994,31 +999,31 @@ Http2ConnectionState::delete_stream(Http2Stream *stream)
stream_list.remove(stream);
stream->initiating_close();
-
- if (http2_is_client_streamid(stream->get_id())) {
- ink_assert(client_streams_in_count > 0);
- --client_streams_in_count;
- } else {
- ink_assert(client_streams_out_count > 0);
- --client_streams_out_count;
- }
-
- if (client_streams_in_count == 0 && client_streams_out_count == 0 && ua_session) {
- ua_session->get_netvc()->add_to_keep_alive_queue();
- ua_session->get_netvc()->cancel_active_timeout();
- }
}
void
Http2ConnectionState::release_stream(Http2Stream *stream)
{
+ // Update stream counts
if (stream) {
--total_client_streams_count;
+ if (http2_is_client_streamid(stream->get_id())) {
+ ink_assert(client_streams_in_count > 0);
+ --client_streams_in_count;
+ } else {
+ ink_assert(client_streams_out_count > 0);
+ --client_streams_out_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) {
@@ -1172,7 +1177,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 || stream->get_state() == HTTP2_STREAM_STATE_HALF_CLOSED_LOCAL) {
+ // 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 84cb02e..8eb35fb 100644
--- a/proxy/http2/Http2Stream.cc
+++ b/proxy/http2/Http2Stream.cc
@@ -330,7 +330,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
['"commits@trafficserver.apache.org" <co...@trafficserver.apache.org>'].