[TS-3794]: Enhance post SSL handshake read race condition for SPDY and H2 scenarios.
Project: http://git-wip-us.apache.org/repos/asf/trafficserver/repo Commit: http://git-wip-us.apache.org/repos/asf/trafficserver/commit/3838cf2c Tree: http://git-wip-us.apache.org/repos/asf/trafficserver/tree/3838cf2c Diff: http://git-wip-us.apache.org/repos/asf/trafficserver/diff/3838cf2c Branch: refs/heads/6.0.x Commit: 3838cf2c1033eb5c4b37170e4903c294610bcaed Parents: 1cb87d2 Author: Sudheer Vinukonda <sudhe...@yahoo-inc.com> Authored: Thu Jul 23 19:15:40 2015 +0000 Committer: Sudheer Vinukonda <sudhe...@yahoo-inc.com> Committed: Thu Jul 23 19:53:23 2015 +0000 ---------------------------------------------------------------------- iocore/net/SSLNetVConnection.cc | 2 +- proxy/http/HttpSM.cc | 2 +- proxy/http2/Http2ClientSession.cc | 7 +++++++ proxy/http2/Http2SessionAccept.cc | 10 +++++++++- proxy/spdy/SpdyClientSession.cc | 7 ++++++- proxy/spdy/SpdySessionAccept.cc | 10 +++++++++- 6 files changed, 33 insertions(+), 5 deletions(-) ---------------------------------------------------------------------- http://git-wip-us.apache.org/repos/asf/trafficserver/blob/3838cf2c/iocore/net/SSLNetVConnection.cc ---------------------------------------------------------------------- diff --git a/iocore/net/SSLNetVConnection.cc b/iocore/net/SSLNetVConnection.cc index ed04ed3..5e2b0ef 100644 --- a/iocore/net/SSLNetVConnection.cc +++ b/iocore/net/SSLNetVConnection.cc @@ -488,7 +488,7 @@ SSLNetVConnection::net_read_io(NetHandler *nh, EThread *lthread) if (ret == EVENT_ERROR) { this->read.triggered = 0; readSignalError(nh, err); - } else if (ret == SSL_HANDSHAKE_WANT_READ || ret == SSL_HANDSHAKE_WANT_ACCEPT || ret == EVENT_CONT) { + } else if (ret == SSL_HANDSHAKE_WANT_READ || ret == SSL_HANDSHAKE_WANT_ACCEPT) { if (SSLConfigParams::ssl_handshake_timeout_in > 0) { double handshake_time = ((double)(Thread::get_hrtime() - sslHandshakeBeginTime) / 1000000000); Debug("ssl", "ssl handshake for vc %p, took %.3f seconds, configured handshake_timer: %d", this, handshake_time, http://git-wip-us.apache.org/repos/asf/trafficserver/blob/3838cf2c/proxy/http/HttpSM.cc ---------------------------------------------------------------------- diff --git a/proxy/http/HttpSM.cc b/proxy/http/HttpSM.cc index 3f4dd72..4ac8d4a 100644 --- a/proxy/http/HttpSM.cc +++ b/proxy/http/HttpSM.cc @@ -614,7 +614,7 @@ HttpSM::state_read_client_request_header(int event, void *data) // time we've been called. The timeout had been set to // the accept timeout by the HttpClientSession // - if (client_request_hdr_bytes == 0) { + if ((ua_buffer_reader->read_avail() > 0) && (client_request_hdr_bytes == 0)) { milestones[TS_MILESTONE_UA_FIRST_READ] = Thread::get_hrtime(); ua_session->get_netvc()->set_inactivity_timeout(HRTIME_SECONDS(t_state.txn_conf->transaction_no_activity_timeout_in)); } http://git-wip-us.apache.org/repos/asf/trafficserver/blob/3838cf2c/proxy/http2/Http2ClientSession.cc ---------------------------------------------------------------------- diff --git a/proxy/http2/Http2ClientSession.cc b/proxy/http2/Http2ClientSession.cc index 4e3b85e..0ea6fca 100644 --- a/proxy/http2/Http2ClientSession.cc +++ b/proxy/http2/Http2ClientSession.cc @@ -195,6 +195,13 @@ Http2ClientSession::do_io_close(int alerrno) DebugHttp2Ssn0("session closed"); ink_assert(this->mutex->thread_holding == this_ethread()); + if (client_vc) { + // clean up ssl's first byte iobuf + SSLNetVConnection *ssl_vc = dynamic_cast<SSLNetVConnection *>(client_vc); + if (ssl_vc) { + ssl_vc->set_ssl_iobuf(NULL); + } + } HTTP2_DECREMENT_THREAD_DYN_STAT(HTTP2_STAT_CURRENT_CLIENT_SESSION_COUNT, this->mutex->thread_holding); send_connection_event(&this->connection_state, HTTP2_SESSION_EVENT_FINI, this); do_api_callout(TS_HTTP_SSN_CLOSE_HOOK); http://git-wip-us.apache.org/repos/asf/trafficserver/blob/3838cf2c/proxy/http2/Http2SessionAccept.cc ---------------------------------------------------------------------- diff --git a/proxy/http2/Http2SessionAccept.cc b/proxy/http2/Http2SessionAccept.cc index fbb25db..ca3139f 100644 --- a/proxy/http2/Http2SessionAccept.cc +++ b/proxy/http2/Http2SessionAccept.cc @@ -65,7 +65,15 @@ Http2SessionAccept::mainEvent(int event, void *data) ink_release_assert((event == NET_EVENT_ACCEPT) ? (data != 0) : (1)); if (event == NET_EVENT_ACCEPT) { - this->accept(static_cast<NetVConnection *>(data), NULL, NULL); + NetVConnection *netvc = static_cast<NetVConnection *>(data); + SSLNetVConnection *ssl_vc = dynamic_cast<SSLNetVConnection *>(netvc); + MIOBuffer *iobuf = NULL; + IOBufferReader *reader = NULL; + if (ssl_vc) { + iobuf = ssl_vc->get_ssl_iobuf(); + reader = ssl_vc->get_ssl_reader(); + } + this->accept(static_cast<NetVConnection *>(data), iobuf, reader); return EVENT_CONT; } http://git-wip-us.apache.org/repos/asf/trafficserver/blob/3838cf2c/proxy/spdy/SpdyClientSession.cc ---------------------------------------------------------------------- diff --git a/proxy/spdy/SpdyClientSession.cc b/proxy/spdy/SpdyClientSession.cc index e0a0844..33c87bf 100644 --- a/proxy/spdy/SpdyClientSession.cc +++ b/proxy/spdy/SpdyClientSession.cc @@ -143,6 +143,11 @@ SpdyClientSession::clear() this->mutex = NULL; if (vc) { + // clean up ssl's first byte iobuf + SSLNetVConnection *ssl_vc = dynamic_cast<SSLNetVConnection *>(vc); + if (ssl_vc) { + ssl_vc->set_ssl_iobuf(NULL); + } TSVConnClose(reinterpret_cast<TSVConn>(vc)); vc = NULL; } @@ -203,7 +208,7 @@ SpdyClientSession::start() {SPDYLAY_SETTINGS_INITIAL_WINDOW_SIZE, SPDYLAY_ID_FLAG_SETTINGS_NONE, spdy_initial_window_size}}; int r; - if (TSIOBufferReaderAvail(this->req_reader) > 0) { + if (this->write_vio && (TSIOBufferReaderAvail(this->req_reader) > 0)) { spdy_process_read(TS_EVENT_VCONN_WRITE_READY, this); } http://git-wip-us.apache.org/repos/asf/trafficserver/blob/3838cf2c/proxy/spdy/SpdySessionAccept.cc ---------------------------------------------------------------------- diff --git a/proxy/spdy/SpdySessionAccept.cc b/proxy/spdy/SpdySessionAccept.cc index 98ff9ab..292cadb 100644 --- a/proxy/spdy/SpdySessionAccept.cc +++ b/proxy/spdy/SpdySessionAccept.cc @@ -45,7 +45,15 @@ SpdySessionAccept::mainEvent(int event, void *edata) #if TS_HAS_SPDY SpdyClientSession *sm = SpdyClientSession::alloc(); sm->version = this->version; - sm->new_connection(netvc, NULL, NULL, false); + + SSLNetVConnection *ssl_vc = dynamic_cast<SSLNetVConnection *>(netvc); + MIOBuffer *iobuf = NULL; + IOBufferReader *reader = NULL; + if (ssl_vc) { + iobuf = ssl_vc->get_ssl_iobuf(); + reader = ssl_vc->get_ssl_reader(); + } + sm->new_connection(netvc, iobuf, reader, false); #else Error("accepted a SPDY session, but SPDY support is not available"); netvc->do_io_close();