Commit fe8946dd authored by Tatsuhiro Tsujikawa's avatar Tatsuhiro Tsujikawa

nghttpx: Fix bug that mruby is incorrectly shared between backends

Previously, mruby context is wrongly shared by multiple patterns if
the underlying SharedDownstreamAddr is shared by multiple
DownstreamAddrGroups.  This commit fixes it.
parent f8933fe5
...@@ -193,7 +193,7 @@ Downstream::~Downstream() { ...@@ -193,7 +193,7 @@ Downstream::~Downstream() {
if (dconn_) { if (dconn_) {
const auto &group = dconn_->get_downstream_addr_group(); const auto &group = dconn_->get_downstream_addr_group();
if (group) { if (group) {
const auto &mruby_ctx = group->mruby_ctx; const auto &mruby_ctx = group->shared_addr->mruby_ctx;
mruby_ctx->delete_downstream(this); mruby_ctx->delete_downstream(this);
} }
} }
...@@ -231,7 +231,7 @@ void Downstream::detach_downstream_connection() { ...@@ -231,7 +231,7 @@ void Downstream::detach_downstream_connection() {
#ifdef HAVE_MRUBY #ifdef HAVE_MRUBY
const auto &group = dconn_->get_downstream_addr_group(); const auto &group = dconn_->get_downstream_addr_group();
if (group) { if (group) {
const auto &mruby_ctx = group->mruby_ctx; const auto &mruby_ctx = group->shared_addr->mruby_ctx;
mruby_ctx->delete_downstream(this); mruby_ctx->delete_downstream(this);
} }
#endif // HAVE_MRUBY #endif // HAVE_MRUBY
...@@ -256,7 +256,7 @@ std::unique_ptr<DownstreamConnection> Downstream::pop_downstream_connection() { ...@@ -256,7 +256,7 @@ std::unique_ptr<DownstreamConnection> Downstream::pop_downstream_connection() {
const auto &group = dconn_->get_downstream_addr_group(); const auto &group = dconn_->get_downstream_addr_group();
if (group) { if (group) {
const auto &mruby_ctx = group->mruby_ctx; const auto &mruby_ctx = group->shared_addr->mruby_ctx;
mruby_ctx->delete_downstream(this); mruby_ctx->delete_downstream(this);
} }
#endif // HAVE_MRUBY #endif // HAVE_MRUBY
......
...@@ -492,7 +492,7 @@ void Http2Upstream::initiate_downstream(Downstream *downstream) { ...@@ -492,7 +492,7 @@ void Http2Upstream::initiate_downstream(Downstream *downstream) {
#ifdef HAVE_MRUBY #ifdef HAVE_MRUBY
const auto &group = dconn_ptr->get_downstream_addr_group(); const auto &group = dconn_ptr->get_downstream_addr_group();
if (group) { if (group) {
const auto &mruby_ctx = group->mruby_ctx; const auto &mruby_ctx = group->shared_addr->mruby_ctx;
if (mruby_ctx->run_on_request_proc(downstream) != 0) { if (mruby_ctx->run_on_request_proc(downstream) != 0) {
if (error_reply(downstream, 500) != 0) { if (error_reply(downstream, 500) != 0) {
rst_stream(downstream, NGHTTP2_INTERNAL_ERROR); rst_stream(downstream, NGHTTP2_INTERNAL_ERROR);
...@@ -1665,7 +1665,7 @@ int Http2Upstream::on_downstream_header_complete(Downstream *downstream) { ...@@ -1665,7 +1665,7 @@ int Http2Upstream::on_downstream_header_complete(Downstream *downstream) {
auto dconn = downstream->get_downstream_connection(); auto dconn = downstream->get_downstream_connection();
const auto &group = dconn->get_downstream_addr_group(); const auto &group = dconn->get_downstream_addr_group();
if (group) { if (group) {
const auto &dmruby_ctx = group->mruby_ctx; const auto &dmruby_ctx = group->shared_addr->mruby_ctx;
if (dmruby_ctx->run_on_response_proc(downstream) != 0) { if (dmruby_ctx->run_on_response_proc(downstream) != 0) {
if (error_reply(downstream, 500) != 0) { if (error_reply(downstream, 500) != 0) {
......
...@@ -481,7 +481,7 @@ int htp_hdrs_completecb(llhttp_t *htp) { ...@@ -481,7 +481,7 @@ int htp_hdrs_completecb(llhttp_t *htp) {
#ifdef HAVE_MRUBY #ifdef HAVE_MRUBY
const auto &group = dconn_ptr->get_downstream_addr_group(); const auto &group = dconn_ptr->get_downstream_addr_group();
if (group) { if (group) {
const auto &dmruby_ctx = group->mruby_ctx; const auto &dmruby_ctx = group->shared_addr->mruby_ctx;
if (dmruby_ctx->run_on_request_proc(downstream) != 0) { if (dmruby_ctx->run_on_request_proc(downstream) != 0) {
resp.http_status = 500; resp.http_status = 500;
...@@ -1087,7 +1087,7 @@ int HttpsUpstream::on_downstream_header_complete(Downstream *downstream) { ...@@ -1087,7 +1087,7 @@ int HttpsUpstream::on_downstream_header_complete(Downstream *downstream) {
assert(dconn); assert(dconn);
const auto &group = dconn->get_downstream_addr_group(); const auto &group = dconn->get_downstream_addr_group();
if (group) { if (group) {
const auto &dmruby_ctx = group->mruby_ctx; const auto &dmruby_ctx = group->shared_addr->mruby_ctx;
if (dmruby_ctx->run_on_response_proc(downstream) != 0) { if (dmruby_ctx->run_on_response_proc(downstream) != 0) {
error_reply(500); error_reply(500);
......
...@@ -79,11 +79,12 @@ using DownstreamKey = ...@@ -79,11 +79,12 @@ using DownstreamKey =
size_t, Proto, uint32_t, uint32_t, size_t, Proto, uint32_t, uint32_t,
uint32_t, bool, bool, bool, bool>>, uint32_t, bool, bool, bool, bool>>,
bool, SessionAffinity, StringRef, StringRef, bool, SessionAffinity, StringRef, StringRef,
SessionAffinityCookieSecure, int64_t, int64_t>; SessionAffinityCookieSecure, int64_t, int64_t, StringRef>;
namespace { namespace {
DownstreamKey create_downstream_key( DownstreamKey
const std::shared_ptr<SharedDownstreamAddr> &shared_addr) { create_downstream_key(const std::shared_ptr<SharedDownstreamAddr> &shared_addr,
const StringRef &mruby_file) {
DownstreamKey dkey; DownstreamKey dkey;
auto &addrs = std::get<0>(dkey); auto &addrs = std::get<0>(dkey);
...@@ -117,6 +118,7 @@ DownstreamKey create_downstream_key( ...@@ -117,6 +118,7 @@ DownstreamKey create_downstream_key(
auto &timeout = shared_addr->timeout; auto &timeout = shared_addr->timeout;
std::get<6>(dkey) = timeout.read; std::get<6>(dkey) = timeout.read;
std::get<7>(dkey) = timeout.write; std::get<7>(dkey) = timeout.write;
std::get<8>(dkey) = mruby_file;
return dkey; return dkey;
} }
...@@ -231,16 +233,6 @@ void Worker::replace_downstream_config( ...@@ -231,16 +233,6 @@ void Worker::replace_downstream_config(
dst = std::make_shared<DownstreamAddrGroup>(); dst = std::make_shared<DownstreamAddrGroup>();
dst->pattern = dst->pattern =
ImmutableString{std::begin(src.pattern), std::end(src.pattern)}; ImmutableString{std::begin(src.pattern), std::end(src.pattern)};
#ifdef HAVE_MRUBY
auto mruby_ctx_it = shared_mruby_ctxs.find(src.mruby_file);
if (mruby_ctx_it == std::end(shared_mruby_ctxs)) {
dst->mruby_ctx = mruby::create_mruby_context(src.mruby_file);
assert(dst->mruby_ctx);
shared_mruby_ctxs.emplace(src.mruby_file, dst->mruby_ctx);
} else {
dst->mruby_ctx = (*mruby_ctx_it).second;
}
#endif // HAVE_MRUBY
auto shared_addr = std::make_shared<SharedDownstreamAddr>(); auto shared_addr = std::make_shared<SharedDownstreamAddr>();
...@@ -297,10 +289,21 @@ void Worker::replace_downstream_config( ...@@ -297,10 +289,21 @@ void Worker::replace_downstream_config(
loop_, cl_ssl_ctx_, this, &dst_addr, randgen_); loop_, cl_ssl_ctx_, this, &dst_addr, randgen_);
} }
#ifdef HAVE_MRUBY
auto mruby_ctx_it = shared_mruby_ctxs.find(src.mruby_file);
if (mruby_ctx_it == std::end(shared_mruby_ctxs)) {
shared_addr->mruby_ctx = mruby::create_mruby_context(src.mruby_file);
assert(shared_addr->mruby_ctx);
shared_mruby_ctxs.emplace(src.mruby_file, shared_addr->mruby_ctx);
} else {
shared_addr->mruby_ctx = (*mruby_ctx_it).second;
}
#endif // HAVE_MRUBY
// share the connection if patterns have the same set of backend // share the connection if patterns have the same set of backend
// addresses. // addresses.
auto dkey = create_downstream_key(shared_addr); auto dkey = create_downstream_key(shared_addr, src.mruby_file);
auto it = addr_groups_indexer.find(dkey); auto it = addr_groups_indexer.find(dkey);
if (it == std::end(addr_groups_indexer)) { if (it == std::end(addr_groups_indexer)) {
......
...@@ -206,6 +206,9 @@ struct SharedDownstreamAddr { ...@@ -206,6 +206,9 @@ struct SharedDownstreamAddr {
// Bunch of session affinity hash. Only used if affinity == // Bunch of session affinity hash. Only used if affinity ==
// SessionAffinity::IP. // SessionAffinity::IP.
std::vector<AffinityHash> affinity_hash; std::vector<AffinityHash> affinity_hash;
#ifdef HAVE_MRUBY
std::shared_ptr<mruby::MRubyContext> mruby_ctx;
#endif // HAVE_MRUBY
// Configuration for session affinity // Configuration for session affinity
AffinityConfig affinity; AffinityConfig affinity;
// Session affinity // Session affinity
...@@ -230,9 +233,6 @@ struct DownstreamAddrGroup { ...@@ -230,9 +233,6 @@ struct DownstreamAddrGroup {
ImmutableString pattern; ImmutableString pattern;
std::shared_ptr<SharedDownstreamAddr> shared_addr; std::shared_ptr<SharedDownstreamAddr> shared_addr;
#ifdef HAVE_MRUBY
std::shared_ptr<mruby::MRubyContext> mruby_ctx;
#endif // HAVE_MRUBY
// true if this group is no longer used for new request. If this is // true if this group is no longer used for new request. If this is
// true, the connection made using one of address in shared_addr // true, the connection made using one of address in shared_addr
// must not be pooled. // must not be pooled.
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment