Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
47 changes: 47 additions & 0 deletions proxy/http2/Http2ClientSession.cc
Original file line number Diff line number Diff line change
Expand Up @@ -66,6 +66,12 @@ Http2ClientSession::destroy()
if (!in_destroy) {
in_destroy = true;
Http2SsnDebug("session destroy");

// Clear the H2 level inactivity tracking
// before going in the session callbacks with
// their different handlers
this->clear_inactive_timer();

// Let everyone know we are going down
do_api_callout(TS_HTTP_SSN_CLOSE_HOOK);
}
Expand Down Expand Up @@ -155,6 +161,36 @@ Http2ClientSession::start()
this->handleEvent(VC_EVENT_READ_READY, read_vio);
}

void
Http2ClientSession::set_inactivity_timeout(ink_hrtime timeout_in)
{
inactive_timeout = timeout_in;
if (inactive_timeout > 0) {
inactive_timeout_at = Thread::get_hrtime() + inactive_timeout;
if (!inactive_event) {
inactive_event = this_ethread()->schedule_every(this, HRTIME_SECONDS(1));
} else {
clear_inactive_timer();
}
}
}

void
Http2ClientSession::reset_inactivity_timeout()
{
set_inactivity_timeout(inactive_timeout);
}

void
Http2ClientSession::clear_inactive_timer()
{
inactive_timeout_at = 0;
if (inactive_event) {
inactive_event->cancel();
inactive_event = nullptr;
}
}

void
Http2ClientSession::new_connection(NetVConnection *new_vc, MIOBuffer *iobuf, IOBufferReader *reader, bool backdoor)
{
Expand All @@ -169,6 +205,7 @@ Http2ClientSession::new_connection(NetVConnection *new_vc, MIOBuffer *iobuf, IOB
this->con_id = ProxyClientSession::next_connection_id();
this->client_vc = new_vc;
client_vc->set_inactivity_timeout(HRTIME_SECONDS(Http2::accept_no_activity_timeout));
this->set_inactivity_timeout(HRTIME_SECONDS(Http2::accept_no_activity_timeout));
this->schedule_event = nullptr;
this->mutex = new_vc->mutex;
this->in_destroy = false;
Expand Down Expand Up @@ -303,6 +340,14 @@ Http2ClientSession::main_event_handler(int event, void *edata)
Event *e = static_cast<Event *>(edata);
if (e == schedule_event) {
schedule_event = nullptr;
} else if (e == inactive_event) {
if (inactive_timeout_at && inactive_timeout_at < Thread::get_hrtime()) {
event = VC_EVENT_INACTIVITY_TIMEOUT;
clear_inactive_timer();
} else {
// Not timed out
event = VC_EVENT_NONE;
}
}

switch (event) {
Expand All @@ -325,6 +370,7 @@ Http2ClientSession::main_event_handler(int event, void *edata)
case VC_EVENT_INACTIVITY_TIMEOUT:
case VC_EVENT_ERROR:
case VC_EVENT_EOS:
this->set_dying_event(event);
this->do_io_close();
retval = 0;
break;
Expand Down Expand Up @@ -391,6 +437,7 @@ Http2ClientSession::state_read_connection_preface(int event, void *edata)
HTTP2_SET_SESSION_HANDLER(&Http2ClientSession::state_start_frame_read);

client_vc->set_inactivity_timeout(HRTIME_SECONDS(Http2::no_activity_timeout_in));
this->set_inactivity_timeout(HRTIME_SECONDS(Http2::no_activity_timeout_in));
client_vc->set_active_timeout(HRTIME_SECONDS(Http2::active_timeout_in));

// XXX start the write VIO ...
Expand Down
8 changes: 8 additions & 0 deletions proxy/http2/Http2ClientSession.h
Original file line number Diff line number Diff line change
Expand Up @@ -322,6 +322,10 @@ class Http2ClientSession : public ProxyClientSession
Http2ClientSession(Http2ClientSession &) = delete;
Http2ClientSession &operator=(const Http2ClientSession &) = delete;

void set_inactivity_timeout(ink_hrtime timeout_in) override;
void clear_inactive_timer();
void reset_inactivity_timeout();

private:
int main_event_handler(int, void *);

Expand Down Expand Up @@ -356,6 +360,10 @@ class Http2ClientSession : public ProxyClientSession
bool half_close_local = false;
int recursion = 0;

ink_hrtime inactive_timeout = 0;
ink_hrtime inactive_timeout_at = 0;
Event *inactive_event = nullptr;

InkHashTable *h2_pushed_urls = nullptr;
uint32_t h2_pushed_urls_size = 0;
};
Expand Down
16 changes: 16 additions & 0 deletions proxy/http2/Http2ConnectionState.cc
Original file line number Diff line number Diff line change
Expand Up @@ -126,6 +126,8 @@ rcv_data_frame(Http2ConnectionState &cstate, const Http2Frame &frame)
}
}

cstate.ua_session->reset_inactivity_timeout();

// If Data length is 0, do nothing.
if (payload_length == 0) {
return Http2Error(Http2ErrorClass::HTTP2_ERROR_CLASS_NONE);
Expand Down Expand Up @@ -225,6 +227,8 @@ rcv_headers_frame(Http2ConnectionState &cstate, const Http2Frame &frame)
}
}

cstate.ua_session->reset_inactivity_timeout();

// keep track of how many bytes we get in the frame
stream->request_header_length += payload_length;
if (stream->request_header_length > Http2::max_request_header_size) {
Expand Down Expand Up @@ -363,6 +367,8 @@ rcv_priority_frame(Http2ConnectionState &cstate, const Http2Frame &frame)

Http2StreamDebug(cstate.ua_session, stream_id, "Received PRIORITY frame");

cstate.ua_session->reset_inactivity_timeout();

// If a PRIORITY frame is received with a stream identifier of 0x0, the
// recipient MUST respond with a connection error of type PROTOCOL_ERROR.
if (stream_id == 0) {
Expand Down Expand Up @@ -488,6 +494,8 @@ rcv_settings_frame(Http2ConnectionState &cstate, const Http2Frame &frame)

Http2StreamDebug(cstate.ua_session, stream_id, "Received SETTINGS frame");

cstate.ua_session->reset_inactivity_timeout();

// [RFC 7540] 6.5. The stream identifier for a SETTINGS frame MUST be zero.
// If an endpoint receives a SETTINGS frame whose stream identifier field is
// anything other than 0x0, the endpoint MUST respond with a connection
Expand Down Expand Up @@ -575,6 +583,8 @@ rcv_ping_frame(Http2ConnectionState &cstate, const Http2Frame &frame)

Http2StreamDebug(cstate.ua_session, stream_id, "Received PING frame");

// Not resetting the inactivity timer for client initiated ping

// If a PING frame is received with a stream identifier field value other
// than 0x0, the recipient MUST respond with a connection error of type
// PROTOCOL_ERROR.
Expand Down Expand Up @@ -644,6 +654,8 @@ rcv_window_update_frame(Http2ConnectionState &cstate, const Http2Frame &frame)
uint32_t size;
const Http2StreamId stream_id = frame.header().streamid;

cstate.ua_session->reset_inactivity_timeout();

// A WINDOW_UPDATE frame with a length other than 4 octets MUST be
// treated as a connection error of type FRAME_SIZE_ERROR.
if (frame.header().length != HTTP2_WINDOW_UPDATE_LEN) {
Expand Down Expand Up @@ -746,6 +758,8 @@ rcv_continuation_frame(Http2ConnectionState &cstate, const Http2Frame &frame)
"continuation bad client id");
}

cstate.ua_session->reset_inactivity_timeout();

// Find opened stream
// CONTINUATION frames MUST be associated with a stream. If a
// CONTINUATION frame is received whose stream identifier field is 0x0,
Expand Down Expand Up @@ -1297,6 +1311,7 @@ Http2ConnectionState::send_data_frames_depends_on_priority()
break;
}

ua_session->reset_inactivity_timeout();
this_ethread()->schedule_imm_local((Continuation *)this, HTTP2_SESSION_EVENT_XMIT);
return;
}
Expand Down Expand Up @@ -1367,6 +1382,7 @@ Http2ConnectionState::send_a_data_frame(Http2Stream *stream, size_t &payload_len

// xmit event
SCOPED_MUTEX_LOCK(lock, this->ua_session->mutex, this_ethread());
ua_session->reset_inactivity_timeout();
this->ua_session->handleEvent(HTTP2_SESSION_EVENT_XMIT, &data);

if (flags & HTTP2_FLAGS_DATA_END_STREAM) {
Expand Down