diff --git a/proxy/http/Http1ClientSession.cc b/proxy/http/Http1ClientSession.cc index 4fae601b216..31ed45dec0a 100644 --- a/proxy/http/Http1ClientSession.cc +++ b/proxy/http/Http1ClientSession.cc @@ -218,7 +218,7 @@ Http1ClientSession::new_connection(NetVConnection *new_vc, MIOBuffer *iobuf, IOB VIO * Http1ClientSession::do_io_read(Continuation *c, int64_t nbytes, MIOBuffer *buf) { - return client_vc->do_io_read(c, nbytes, buf); + return (client_vc) ? client_vc->do_io_read(c, nbytes, buf) : nullptr; } VIO * diff --git a/proxy/http/HttpSM.cc b/proxy/http/HttpSM.cc index 1c07d2d37d5..1a85a6c76a5 100644 --- a/proxy/http/HttpSM.cc +++ b/proxy/http/HttpSM.cc @@ -128,9 +128,10 @@ std::atomic next_sm_id(0); ClassAllocator httpSMAllocator("httpSMAllocator"); -HttpVCTable::HttpVCTable() +HttpVCTable::HttpVCTable(HttpSM *mysm) { memset(&vc_table, 0, sizeof(vc_table)); + sm = mysm; } HttpVCTableEntry * @@ -138,6 +139,7 @@ HttpVCTable::new_entry() { for (int i = 0; i < vc_table_max_entries; i++) { if (vc_table[i].vc == nullptr) { + vc_table[i].sm = sm; return vc_table + i; } } @@ -191,6 +193,26 @@ HttpVCTable::remove_entry(HttpVCTableEntry *e) free_MIOBuffer(e->write_buffer); e->write_buffer = nullptr; } + if (e->read_vio != nullptr && e->read_vio->cont == sm) { + // Cleanup dangling i/o + if (e == sm->get_ua_entry() && sm->get_ua_txn() != nullptr) { + e->read_vio = sm->get_ua_txn()->do_io_read(nullptr, 0, nullptr); + } else if (e == sm->get_server_entry() && sm->get_server_session()) { + e->read_vio = sm->get_server_session()->do_io_read(nullptr, 0, nullptr); + } else { + ink_release_assert(false); + } + } + if (e->write_vio != nullptr && e->write_vio->cont == sm) { + // Cleanup dangling i/o + if (e == sm->get_ua_entry() && sm->get_ua_txn()) { + e->write_vio = sm->get_ua_txn()->do_io_write(nullptr, 0, nullptr); + } else if (e == sm->get_server_entry() && sm->get_server_session()) { + e->write_vio = sm->get_server_session()->do_io_write(nullptr, 0, nullptr); + } else { + ink_release_assert(false); + } + } e->read_vio = nullptr; e->write_vio = nullptr; e->vc_handler = nullptr; @@ -258,9 +280,8 @@ HttpVCTable::cleanup_all() default_handler = _h; \ } -HttpSM::HttpSM() : Continuation(nullptr) +HttpSM::HttpSM() : Continuation(nullptr), vc_table(this) { - ink_zero(vc_table); ink_zero(http_parser); } @@ -1753,8 +1774,9 @@ HttpSM::state_http_server_open(int event, void *data) do_http_server_open(); } break; - case VC_EVENT_ERROR: case VC_EVENT_INACTIVITY_TIMEOUT: + case VC_EVENT_ACTIVE_TIMEOUT: + case VC_EVENT_ERROR: case NET_EVENT_OPEN_FAILED: t_state.current.state = HttpTransact::CONNECTION_ERROR; // save the errno from the connect fail for future use (passed as negative value, flip back) @@ -2659,7 +2681,10 @@ HttpSM::tunnel_handler_post(int event, void *data) if (ua_entry->write_buffer) { free_MIOBuffer(ua_entry->write_buffer); ua_entry->write_buffer = nullptr; - ua_entry->vc->do_io_write(this, 0, nullptr); + ua_entry->vc->do_io_write(nullptr, 0, nullptr); + } + if (!p->handler_state) { + p->handler_state = HTTP_SM_POST_UA_FAIL; } break; case VC_EVENT_READ_READY: @@ -2996,6 +3021,11 @@ HttpSM::tunnel_handler_server(int event, HttpTunnelProducer *p) ink_assert(p->vc_type == HT_HTTP_SERVER); ink_assert(p->vc == server_session); + // The server session has been released. Clean all pointer + // Calling remove_entry instead of server_entry because we don't + // want to close the server VC at this point + vc_table.remove_entry(server_entry); + if (close_connection) { p->vc->do_io_close(); p->read_vio = nullptr; @@ -3027,9 +3057,6 @@ HttpSM::tunnel_handler_server(int event, HttpTunnelProducer *p) } } - // The server session has been released. Clean all pointer - server_entry->in_tunnel = true; // to avid cleaning in clenup_entry - vc_table.cleanup_entry(server_entry); server_session = nullptr; // Because p->vc == server_session server_entry = nullptr; @@ -3410,7 +3437,7 @@ HttpSM::tunnel_handler_post_ua(int event, HttpTunnelProducer *p) // if it is active timeout case, we need to give another chance to send 408 response; ua_txn->set_active_timeout(HRTIME_SECONDS(t_state.txn_conf->transaction_active_timeout_in)); - p->vc->do_io_write(this, 0, nullptr); + p->vc->do_io_write(nullptr, 0, nullptr); p->vc->do_io_shutdown(IO_SHUTDOWN_READ); return 0; diff --git a/proxy/http/HttpSM.h b/proxy/http/HttpSM.h index 6948d60ac2e..cac3cf7fb57 100644 --- a/proxy/http/HttpSM.h +++ b/proxy/http/HttpSM.h @@ -105,13 +105,14 @@ struct HttpVCTableEntry { VIO *write_vio; HttpSMHandler vc_handler; HttpVC_t vc_type; + HttpSM *sm; bool eos; bool in_tunnel; }; struct HttpVCTable { static const int vc_table_max_entries = 4; - HttpVCTable(); + HttpVCTable(HttpSM *); HttpVCTableEntry *new_entry(); HttpVCTableEntry *find_entry(VConnection *); @@ -123,6 +124,7 @@ struct HttpVCTable { private: HttpVCTableEntry vc_table[vc_table_max_entries]; + HttpSM *sm = nullptr; }; inline bool @@ -220,8 +222,9 @@ class HttpSM : public Continuation virtual void destroy(); static HttpSM *allocate(); - HttpCacheSM &get_cache_sm(); // Added to get the object of CacheSM YTS Team, yamsat - HttpVCTableEntry *get_ua_entry(); // Added to get the ua_entry pointer - YTS-TEAM + HttpCacheSM &get_cache_sm(); // Added to get the object of CacheSM YTS Team, yamsat + HttpVCTableEntry *get_ua_entry(); // Added to get the ua_entry pointer - YTS-TEAM + HttpVCTableEntry *get_server_entry(); // Added to get the server_entry pointer void init(); @@ -240,6 +243,12 @@ class HttpSM : public Continuation return server_session; } + ProxyClientTransaction * + get_ua_txn() + { + return ua_txn; + } + // Called by transact. Updates are fire and forget // so there are no callbacks and are safe to do // directly from transact @@ -635,6 +644,12 @@ HttpSM::get_ua_entry() return ua_entry; } +inline HttpVCTableEntry * +HttpSM::get_server_entry() +{ + return server_entry; +} + inline HttpSM * HttpSM::allocate() { diff --git a/proxy/http/HttpServerSession.cc b/proxy/http/HttpServerSession.cc index 9f946a59cb8..ab479dfcbc1 100644 --- a/proxy/http/HttpServerSession.cc +++ b/proxy/http/HttpServerSession.cc @@ -101,13 +101,13 @@ HttpServerSession::enable_outbound_connection_tracking(OutboundConnTrack::Group VIO * HttpServerSession::do_io_read(Continuation *c, int64_t nbytes, MIOBuffer *buf) { - return server_vc->do_io_read(c, nbytes, buf); + return server_vc ? server_vc->do_io_read(c, nbytes, buf) : nullptr; } VIO * HttpServerSession::do_io_write(Continuation *c, int64_t nbytes, IOBufferReader *buf, bool owner) { - return server_vc->do_io_write(c, nbytes, buf, owner); + return server_vc ? server_vc->do_io_write(c, nbytes, buf, owner) : nullptr; } void diff --git a/proxy/http2/Http2ClientSession.cc b/proxy/http2/Http2ClientSession.cc index 0bdccaae288..01d2ed7be00 100644 --- a/proxy/http2/Http2ClientSession.cc +++ b/proxy/http2/Http2ClientSession.cc @@ -233,13 +233,21 @@ Http2ClientSession::set_upgrade_context(HTTPHdr *h) VIO * Http2ClientSession::do_io_read(Continuation *c, int64_t nbytes, MIOBuffer *buf) { - return this->client_vc->do_io_read(c, nbytes, buf); + if (client_vc) { + return this->client_vc->do_io_read(c, nbytes, buf); + } else { + return nullptr; + } } VIO * Http2ClientSession::do_io_write(Continuation *c, int64_t nbytes, IOBufferReader *buf, bool owner) { - return this->client_vc->do_io_write(c, nbytes, buf, owner); + if (client_vc) { + return this->client_vc->do_io_write(c, nbytes, buf, owner); + } else { + return nullptr; + } } void