nghttpx: Fix crash with backend failure
This commit is contained in:
parent
53989dc70c
commit
0af9629cc1
|
@ -97,9 +97,6 @@ int Http2DownstreamConnection::attach_downstream(Downstream *downstream) {
|
||||||
http2session_->add_downstream_connection(this);
|
http2session_->add_downstream_connection(this);
|
||||||
if (http2session_->get_state() == Http2Session::DISCONNECTED) {
|
if (http2session_->get_state() == Http2Session::DISCONNECTED) {
|
||||||
http2session_->signal_write();
|
http2session_->signal_write();
|
||||||
if (http2session_->get_state() == Http2Session::DISCONNECTED) {
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
downstream_ = downstream;
|
downstream_ = downstream;
|
||||||
|
|
|
@ -165,6 +165,22 @@ void writecb(struct ev_loop *loop, ev_io *w, int revents) {
|
||||||
}
|
}
|
||||||
} // namespace
|
} // namespace
|
||||||
|
|
||||||
|
namespace {
|
||||||
|
void initiate_connection_cb(struct ev_loop *loop, ev_timer *w, int revents) {
|
||||||
|
auto http2session = static_cast<Http2Session *>(w->data);
|
||||||
|
ev_timer_stop(loop, w);
|
||||||
|
if (http2session->initiate_connection() != 0) {
|
||||||
|
if (LOG_ENABLED(INFO)) {
|
||||||
|
SSLOG(INFO, http2session) << "Could not initiate backend connection";
|
||||||
|
}
|
||||||
|
http2session->disconnect(true);
|
||||||
|
assert(http2session->get_num_dconns() == 0);
|
||||||
|
delete http2session;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} // namespace
|
||||||
|
|
||||||
Http2Session::Http2Session(struct ev_loop *loop, SSL_CTX *ssl_ctx,
|
Http2Session::Http2Session(struct ev_loop *loop, SSL_CTX *ssl_ctx,
|
||||||
Worker *worker, DownstreamAddrGroup *group)
|
Worker *worker, DownstreamAddrGroup *group)
|
||||||
: dlnext(nullptr),
|
: dlnext(nullptr),
|
||||||
|
@ -199,6 +215,9 @@ Http2Session::Http2Session(struct ev_loop *loop, SSL_CTX *ssl_ctx,
|
||||||
ev_timer_init(&settings_timer_, settings_timeout_cb, 0., 10.);
|
ev_timer_init(&settings_timer_, settings_timeout_cb, 0., 10.);
|
||||||
|
|
||||||
settings_timer_.data = this;
|
settings_timer_.data = this;
|
||||||
|
|
||||||
|
ev_timer_init(&initiate_connection_timer_, initiate_connection_cb, 0., 0.);
|
||||||
|
initiate_connection_timer_.data = this;
|
||||||
}
|
}
|
||||||
|
|
||||||
Http2Session::~Http2Session() {
|
Http2Session::~Http2Session() {
|
||||||
|
@ -224,6 +243,7 @@ int Http2Session::disconnect(bool hard) {
|
||||||
conn_.rlimit.stopw();
|
conn_.rlimit.stopw();
|
||||||
conn_.wlimit.stopw();
|
conn_.wlimit.stopw();
|
||||||
|
|
||||||
|
ev_timer_stop(conn_.loop, &initiate_connection_timer_);
|
||||||
ev_timer_stop(conn_.loop, &settings_timer_);
|
ev_timer_stop(conn_.loop, &settings_timer_);
|
||||||
ev_timer_stop(conn_.loop, &connchk_timer_);
|
ev_timer_stop(conn_.loop, &connchk_timer_);
|
||||||
|
|
||||||
|
@ -1600,14 +1620,15 @@ int Http2Session::downstream_write() {
|
||||||
void Http2Session::signal_write() {
|
void Http2Session::signal_write() {
|
||||||
switch (state_) {
|
switch (state_) {
|
||||||
case Http2Session::DISCONNECTED:
|
case Http2Session::DISCONNECTED:
|
||||||
|
if (!ev_is_active(&initiate_connection_timer_)) {
|
||||||
if (LOG_ENABLED(INFO)) {
|
if (LOG_ENABLED(INFO)) {
|
||||||
LOG(INFO) << "Start connecting to backend server";
|
LOG(INFO) << "Start connecting to backend server";
|
||||||
}
|
}
|
||||||
if (initiate_connection() != 0) {
|
// Since the timer is set to 0., these will feed 2 events. We
|
||||||
if (LOG_ENABLED(INFO)) {
|
// will stop the timer in the initiate_connection_timer_ to void
|
||||||
SSLOG(INFO, this) << "Could not initiate backend connection";
|
// 2nd event.
|
||||||
}
|
ev_timer_start(conn_.loop, &initiate_connection_timer_);
|
||||||
disconnect(true);
|
ev_feed_event(conn_.loop, &initiate_connection_timer_, 0);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case Http2Session::CONNECTED:
|
case Http2Session::CONNECTED:
|
||||||
|
|
|
@ -211,6 +211,8 @@ private:
|
||||||
// connection check has started, this timer is started again and
|
// connection check has started, this timer is started again and
|
||||||
// traps PING ACK timeout.
|
// traps PING ACK timeout.
|
||||||
ev_timer connchk_timer_;
|
ev_timer connchk_timer_;
|
||||||
|
// timer to initiate connection. usually, this fires immediately.
|
||||||
|
ev_timer initiate_connection_timer_;
|
||||||
DList<Http2DownstreamConnection> dconns_;
|
DList<Http2DownstreamConnection> dconns_;
|
||||||
DList<StreamData> streams_;
|
DList<StreamData> streams_;
|
||||||
std::function<int(Http2Session &)> read_, write_;
|
std::function<int(Http2Session &)> read_, write_;
|
||||||
|
|
Loading…
Reference in New Issue