Skip to content

Commit

Permalink
Add history to HTTP/2
Browse files Browse the repository at this point in the history
  • Loading branch information
masaori335 committed Feb 12, 2019
1 parent 7680a52 commit 84d59dc
Show file tree
Hide file tree
Showing 5 changed files with 59 additions and 3 deletions.
16 changes: 16 additions & 0 deletions proxy/http2/Http2ClientSession.cc
Original file line number Diff line number Diff line change
Expand Up @@ -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)
Expand All @@ -35,6 +41,7 @@

#define HTTP2_SET_SESSION_HANDLER(handler) \
do { \
REMEMBER(NO_EVENT, this->recursion); \
this->session_handler = (handler); \
} while (0)

Expand Down Expand Up @@ -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);
Expand All @@ -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);
Expand Down Expand Up @@ -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());
Expand Down Expand Up @@ -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);
}
6 changes: 6 additions & 0 deletions proxy/http2/Http2ClientSession.h
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down Expand Up @@ -304,6 +305,9 @@ class Http2ClientSession : public ProxySession
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;
Expand Down Expand Up @@ -333,6 +337,8 @@ class Http2ClientSession : public ProxySession
IpEndpoint cached_client_addr;
IpEndpoint cached_local_addr;

History<HISTORY_DEFAULT_SIZE> _history;

// For Upgrade: h2c
Http2UpgradeContext upgrade_context;

Expand Down
25 changes: 22 additions & 3 deletions proxy/http2/Http2ConnectionState.cc
Original file line number Diff line number Diff line change
Expand Up @@ -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__);

Expand Down Expand Up @@ -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
Expand All @@ -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;
Expand All @@ -911,13 +921,15 @@ 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;
} break;

// 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;
Expand Down Expand Up @@ -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
Expand All @@ -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;
Expand Down Expand Up @@ -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);
Expand Down Expand Up @@ -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;
Expand Down Expand Up @@ -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().
Expand Down Expand Up @@ -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) {
Expand All @@ -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;

Expand Down
12 changes: 12 additions & 0 deletions proxy/http2/Http2Stream.cc
Original file line number Diff line number Diff line change
Expand Up @@ -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__);

Expand All @@ -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
Expand Down Expand Up @@ -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
Expand Down Expand Up @@ -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);
Expand All @@ -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
Expand Down Expand Up @@ -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);
}

Expand Down Expand Up @@ -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
Expand Down
3 changes: 3 additions & 0 deletions proxy/http2/Http2Stream.h
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down Expand Up @@ -245,6 +246,8 @@ class Http2Stream : public ProxyTransaction
VIO read_vio;
VIO write_vio;

History<HISTORY_DEFAULT_SIZE> _history;

bool trailing_header = false;
bool body_done = false;
bool chunked = false;
Expand Down

0 comments on commit 84d59dc

Please sign in to comment.