This is an automated email from the ASF dual-hosted git repository.
masaori pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/trafficserver.git
The following commit(s) were added to refs/heads/master by this push:
new 84d59dc Add history to HTTP/2
84d59dc is described below
commit 84d59dc083a37a8b98d446c81fc2853bb131a11d
Author: Masaori Koshiba <[email protected]>
AuthorDate: Thu Feb 7 12:38:24 2019 +0900
Add history to HTTP/2
---
proxy/http2/Http2ClientSession.cc | 16 ++++++++++++++++
proxy/http2/Http2ClientSession.h | 6 ++++++
proxy/http2/Http2ConnectionState.cc | 25 ++++++++++++++++++++++---
proxy/http2/Http2Stream.cc | 12 ++++++++++++
proxy/http2/Http2Stream.h | 3 +++
5 files changed, 59 insertions(+), 3 deletions(-)
diff --git a/proxy/http2/Http2ClientSession.cc
b/proxy/http2/Http2ClientSession.cc
index e6037fd..7774d01 100644
--- a/proxy/http2/Http2ClientSession.cc
+++ b/proxy/http2/Http2ClientSession.cc
@@ -25,8 +25,14 @@
#include "HttpDebugNames.h"
#include "tscore/ink_base64.h"
+#define REMEMBER(e, r) \
+ { \
+ this->remember(MakeSourceLocation(), e, r); \
+ }
+
#define STATE_ENTER(state_name, event)
\
do {
\
+ REMEMBER(event, this->recursion)
\
SsnDebug(this, "http2_cs", "[%" PRId64 "] [%s, %s]",
this->connection_id(), #state_name, \
HttpDebugNames::get_event_name(event));
\
} while (0)
@@ -35,6 +41,7 @@
#define HTTP2_SET_SESSION_HANDLER(handler) \
do { \
+ REMEMBER(NO_EVENT, this->recursion); \
this->session_handler = (handler); \
} while (0)
@@ -65,6 +72,7 @@ Http2ClientSession::destroy()
{
if (!in_destroy) {
in_destroy = true;
+ REMEMBER(NO_EVENT, this->recursion)
Http2SsnDebug("session destroy");
// Let everyone know we are going down
do_api_callout(TS_HTTP_SSN_CLOSE_HOOK);
@@ -87,6 +95,7 @@ Http2ClientSession::free()
return;
}
+ REMEMBER(NO_EVENT, this->recursion)
Http2SsnDebug("session free");
HTTP2_DECREMENT_THREAD_DYN_STAT(HTTP2_STAT_CURRENT_CLIENT_SESSION_COUNT,
this->mutex->thread_holding);
@@ -253,6 +262,7 @@ Http2ClientSession::do_io_shutdown(ShutdownHowTo_t howto)
void
Http2ClientSession::do_io_close(int alerrno)
{
+ REMEMBER(NO_EVENT, this->recursion)
Http2SsnDebug("session closed");
ink_assert(this->mutex->thread_holding == this_ethread());
@@ -550,3 +560,9 @@
Http2ClientSession::decrement_current_active_client_connections_stat()
{
HTTP2_DECREMENT_THREAD_DYN_STAT(HTTP2_STAT_CURRENT_ACTIVE_CLIENT_CONNECTION_COUNT,
this_ethread());
}
+
+void
+Http2ClientSession::remember(const SourceLocation &location, int event, int
reentrant)
+{
+ this->_history.push_back(location, event, reentrant);
+}
diff --git a/proxy/http2/Http2ClientSession.h b/proxy/http2/Http2ClientSession.h
index 26636fb..9a2c5a1 100644
--- a/proxy/http2/Http2ClientSession.h
+++ b/proxy/http2/Http2ClientSession.h
@@ -29,6 +29,7 @@
#include "Http2ConnectionState.h"
#include <string_view>
#include "tscore/ink_inet.h"
+#include "tscore/History.h"
// Name Edata Description
// HTTP2_SESSION_EVENT_INIT Http2ClientSession * HTTP/2 session is born
@@ -304,6 +305,9 @@ public:
return write_buffer->max_read_avail();
}
+ // Record history from Http2ConnectionState
+ void remember(const SourceLocation &location, int event, int reentrant =
NO_REENTRANT);
+
// noncopyable
Http2ClientSession(Http2ClientSession &) = delete;
Http2ClientSession &operator=(const Http2ClientSession &) = delete;
@@ -333,6 +337,8 @@ private:
IpEndpoint cached_client_addr;
IpEndpoint cached_local_addr;
+ History<HISTORY_DEFAULT_SIZE> _history;
+
// For Upgrade: h2c
Http2UpgradeContext upgrade_context;
diff --git a/proxy/http2/Http2ConnectionState.cc
b/proxy/http2/Http2ConnectionState.cc
index 45689d7..3da2dd7 100644
--- a/proxy/http2/Http2ConnectionState.cc
+++ b/proxy/http2/Http2ConnectionState.cc
@@ -26,8 +26,16 @@
#include "Http2ClientSession.h"
#include "Http2Stream.h"
#include "Http2DebugNames.h"
+#include "HttpDebugNames.h"
#include <sstream>
+#define REMEMBER(e, r) \
+ { \
+ if (this->ua_session) { \
+ this->ua_session->remember(MakeSourceLocation(), e, r); \
+ } \
+ }
+
#define Http2ConDebug(ua_session, fmt, ...) \
SsnDebug(ua_session, "http2_con", "[%" PRId64 "] " fmt,
ua_session->connection_id(), ##__VA_ARGS__);
@@ -877,6 +885,7 @@ Http2ConnectionState::main_event_handler(int event, void
*edata)
case HTTP2_SESSION_EVENT_INIT: {
ink_assert(this->ua_session == nullptr);
this->ua_session = (Http2ClientSession *)edata;
+ REMEMBER(event, this->recursion);
// [RFC 7540] 3.5. HTTP/2 Connection Preface. Upon establishment of a TCP
connection and
// determination that HTTP/2 will be used by both peers, each endpoint MUST
@@ -902,6 +911,7 @@ Http2ConnectionState::main_event_handler(int event, void
*edata)
// Finalize HTTP/2 Connection
case HTTP2_SESSION_EVENT_FINI: {
SCOPED_MUTEX_LOCK(lock, this->mutex, this_ethread());
+ REMEMBER(event, this->recursion);
ink_assert(this->fini_received == false);
this->fini_received = true;
@@ -911,6 +921,7 @@ Http2ConnectionState::main_event_handler(int event, void
*edata)
} break;
case HTTP2_SESSION_EVENT_XMIT: {
+ REMEMBER(event, this->recursion);
SCOPED_MUTEX_LOCK(lock, this->mutex, this_ethread());
send_data_frames_depends_on_priority();
_scheduled = false;
@@ -918,6 +929,7 @@ Http2ConnectionState::main_event_handler(int event, void
*edata)
// Parse received HTTP/2 frames
case HTTP2_SESSION_EVENT_RECV: {
+ REMEMBER(event, this->recursion);
const Http2Frame *frame = (Http2Frame *)edata;
const Http2StreamId stream_id = frame->header().streamid;
Http2Error error;
@@ -964,6 +976,7 @@ Http2ConnectionState::main_event_handler(int event, void
*edata)
// Initiate a gracefull shutdown
case HTTP2_SESSION_EVENT_SHUTDOWN_INIT: {
+ REMEMBER(event, this->recursion);
ink_assert(shutdown_state == HTTP2_SHUTDOWN_NOT_INITIATED);
shutdown_state = HTTP2_SHUTDOWN_INITIATED;
// [RFC 7540] 6.8. GOAWAY
@@ -977,6 +990,7 @@ Http2ConnectionState::main_event_handler(int event, void
*edata)
// Continue a gracefull shutdown
case HTTP2_SESSION_EVENT_SHUTDOWN_CONT: {
+ REMEMBER(event, this->recursion);
ink_assert(shutdown_state == HTTP2_SHUTDOWN_INITIATED);
shutdown_cont_event = nullptr;
shutdown_state = HTTP2_SHUTDOWN_IN_PROGRESS;
@@ -1010,8 +1024,10 @@ Http2ConnectionState::main_event_handler(int event, void
*edata)
}
int
-Http2ConnectionState::state_closed(int /* event */, void *edata)
+Http2ConnectionState::state_closed(int event, void *edata)
{
+ REMEMBER(event, this->recursion);
+
if (edata == zombie_event) {
// Zombie session is still around. Assert!
ink_release_assert(zombie_event == nullptr);
@@ -1195,6 +1211,7 @@ Http2ConnectionState::delete_stream(Http2Stream *stream)
}
Http2StreamDebug(ua_session, stream->get_id(), "Delete stream");
+ REMEMBER(NO_EVENT, this->recursion);
if (Http2::stream_priority_enabled) {
Http2DependencyTree::Node *node = stream->priority_node;
@@ -1236,6 +1253,8 @@ Http2ConnectionState::delete_stream(Http2Stream *stream)
void
Http2ConnectionState::release_stream(Http2Stream *stream)
{
+ REMEMBER(NO_EVENT, this->recursion)
+
if (stream) {
// Decrement total_client_streams_count here, because it's a counter
include streams in the process of shutting down.
// Other counters (client_streams_in_count/client_streams_out_count) are
already decremented in delete_stream().
@@ -1770,6 +1789,8 @@ Http2ConnectionState::send_ping_frame(Http2StreamId id,
uint8_t flag, const uint
void
Http2ConnectionState::send_goaway_frame(Http2StreamId id, Http2ErrorCode ec)
{
+ ink_assert(this->ua_session != nullptr);
+
Http2ConDebug(ua_session, "Send GOAWAY frame, last_stream_id: %d", id);
if (ec != Http2ErrorCode::HTTP2_ERROR_NO_ERROR) {
@@ -1779,8 +1800,6 @@ Http2ConnectionState::send_goaway_frame(Http2StreamId id,
Http2ErrorCode ec)
Http2Frame frame(HTTP2_FRAME_TYPE_GOAWAY, 0, 0);
Http2Goaway goaway;
- ink_assert(this->ua_session != nullptr);
-
goaway.last_streamid = id;
goaway.error_code = ec;
diff --git a/proxy/http2/Http2Stream.cc b/proxy/http2/Http2Stream.cc
index 429b55f..fc6e3b4 100644
--- a/proxy/http2/Http2Stream.cc
+++ b/proxy/http2/Http2Stream.cc
@@ -26,6 +26,11 @@
#include "Http2ClientSession.h"
#include "../http/HttpSM.h"
+#define REMEMBER(e, r) \
+ { \
+ this->_history.push_back(MakeSourceLocation(), e, r); \
+ }
+
#define Http2StreamDebug(fmt, ...) \
SsnDebug(parent, "http2_stream", "[%" PRId64 "] [%u] " fmt,
parent->connection_id(), this->get_id(), ##__VA_ARGS__);
@@ -35,6 +40,7 @@ int
Http2Stream::main_event_handler(int event, void *edata)
{
SCOPED_MUTEX_LOCK(lock, this->mutex, this_ethread());
+ REMEMBER(event, this->reentrancy_count);
if (!this->_switch_thread_if_not_on_right_thread(event, edata)) {
// Not on the right thread
@@ -320,6 +326,7 @@ Http2Stream::do_io_close(int /* flags */)
super::release(nullptr);
if (!closed) {
+ REMEMBER(NO_EVENT, this->reentrancy_count);
Http2StreamDebug("do_io_close");
// When we get here, the SM has initiated the shutdown. Either it
received a WRITE_COMPLETE, or it is shutting down. Any
@@ -371,6 +378,8 @@ void
Http2Stream::terminate_if_possible()
{
if (terminate_stream && reentrancy_count == 0) {
+ REMEMBER(NO_EVENT, this->reentrancy_count);
+
Http2ClientSession *h2_parent = static_cast<Http2ClientSession *>(parent);
SCOPED_MUTEX_LOCK(lock, h2_parent->connection_state.mutex, this_ethread());
h2_parent->connection_state.delete_stream(this);
@@ -384,6 +393,7 @@ Http2Stream::initiating_close()
{
if (!closed) {
SCOPED_MUTEX_LOCK(lock, this->mutex, this_ethread());
+ REMEMBER(NO_EVENT, this->reentrancy_count);
Http2StreamDebug("initiating_close");
// Set the state of the connection to closed
@@ -452,6 +462,7 @@ Http2Stream::send_tracked_event(Event *event, int
send_event, VIO *vio)
}
if (event == nullptr) {
+ REMEMBER(send_event, this->reentrancy_count);
event = this_ethread()->schedule_imm(this, send_event, vio);
}
@@ -705,6 +716,7 @@ Http2Stream::reenable(VIO *vio)
void
Http2Stream::destroy()
{
+ REMEMBER(NO_EVENT, this->reentrancy_count);
Http2StreamDebug("Destroy stream, sent %" PRIu64 " bytes", this->bytes_sent);
SCOPED_MUTEX_LOCK(lock, this->mutex, this_ethread());
// Clean up after yourself if this was an EOS
diff --git a/proxy/http2/Http2Stream.h b/proxy/http2/Http2Stream.h
index e766ced..22030f4 100644
--- a/proxy/http2/Http2Stream.h
+++ b/proxy/http2/Http2Stream.h
@@ -28,6 +28,7 @@
#include "Http2DebugNames.h"
#include "../http/HttpTunnel.h" // To get ChunkedHandler
#include "Http2DependencyTree.h"
+#include "tscore/History.h"
class Http2Stream;
class Http2ConnectionState;
@@ -245,6 +246,8 @@ private:
VIO read_vio;
VIO write_vio;
+ History<HISTORY_DEFAULT_SIZE> _history;
+
bool trailing_header = false;
bool body_done = false;
bool chunked = false;