From 2a9b23bfab71d8bf25cacd71cddaa61f94c6a3a4 Mon Sep 17 00:00:00 2001 From: Tatsuhiro Tsujikawa Date: Sun, 7 Feb 2016 18:22:57 +0900 Subject: [PATCH] nghttpx: Store pointer to DownstreamAddr --- src/shrpx_http2_downstream_connection.cc | 5 +- src/shrpx_http2_session.cc | 58 ++++++++++-------------- src/shrpx_http2_session.h | 8 ++-- src/shrpx_http_downstream_connection.cc | 26 ++++------- src/shrpx_http_downstream_connection.h | 4 +- 5 files changed, 39 insertions(+), 62 deletions(-) diff --git a/src/shrpx_http2_downstream_connection.cc b/src/shrpx_http2_downstream_connection.cc index 3ca718c1..663599af 100644 --- a/src/shrpx_http2_downstream_connection.cc +++ b/src/shrpx_http2_downstream_connection.cc @@ -268,10 +268,7 @@ int Http2DownstreamConnection::push_request_headers() { // http2session_ has already in CONNECTED state, so we can get // addr_idx here. - auto addr_idx = http2session_->get_addr_idx(); - auto group = http2session_->get_group(); - const auto &downstream_hostport = - get_config()->conn.downstream.addr_groups[group].addrs[addr_idx].hostport; + const auto &downstream_hostport = http2session_->get_addr()->hostport; // For HTTP/1.0 request, there is no authority in request. In that // case, we use backend server's host nonetheless. diff --git a/src/shrpx_http2_session.cc b/src/shrpx_http2_session.cc index 77502f7d..5cbe571c 100644 --- a/src/shrpx_http2_session.cc +++ b/src/shrpx_http2_session.cc @@ -153,10 +153,10 @@ Http2Session::Http2Session(struct ev_loop *loop, SSL_CTX *ssl_ctx, worker_(worker), connect_blocker_(connect_blocker), ssl_ctx_(ssl_ctx), + addr_(nullptr), session_(nullptr), data_pending_(nullptr), data_pendinglen_(0), - addr_idx_(0), group_(group), index_(idx), state_(DISCONNECTED), @@ -202,7 +202,7 @@ int Http2Session::disconnect(bool hard) { conn_.disconnect(); - addr_idx_ = 0; + addr_ = nullptr; if (proxy_htp_) { proxy_htp_.reset(); @@ -245,12 +245,6 @@ int Http2Session::disconnect(bool hard) { return 0; } -int Http2Session::check_cert() { - return ssl::check_cert( - conn_.tls.ssl, - &get_config()->conn.downstream.addr_groups[group_].addrs[addr_idx_]); -} - int Http2Session::initiate_connection() { int rv = 0; @@ -266,19 +260,18 @@ int Http2Session::initiate_connection() { } auto &next_downstream = worker_->get_dgrp(group_)->next; - addr_idx_ = next_downstream; + addr_ = &addrs[next_downstream]; + + if (LOG_ENABLED(INFO)) { + SSLOG(INFO, this) << "Using downstream address idx=" << next_downstream + << " out of " << addrs.size(); + } + if (++next_downstream >= addrs.size()) { next_downstream = 0; } - - if (LOG_ENABLED(INFO)) { - SSLOG(INFO, this) << "Using downstream address idx=" << addr_idx_ - << " out of " << addrs.size(); - } } - auto &downstream_addr = addrs[addr_idx_]; - const auto &proxy = get_config()->downstream_http_proxy; if (!proxy.host.empty() && state_ == DISCONNECTED) { if (LOG_ENABLED(INFO)) { @@ -341,7 +334,7 @@ int Http2Session::initiate_connection() { auto sni_name = !get_config()->tls.backend_sni_name.empty() ? StringRef(get_config()->tls.backend_sni_name) - : StringRef(downstream_addr.host); + : StringRef(addr_->host); if (!util::numeric_host(sni_name.c_str())) { // TLS extensions: SNI. There is no documentation about the return @@ -354,8 +347,8 @@ int Http2Session::initiate_connection() { if (state_ == DISCONNECTED) { assert(conn_.fd == -1); - conn_.fd = util::create_nonblock_socket( - downstream_addr.addr.su.storage.ss_family); + conn_.fd = + util::create_nonblock_socket(addr_->addr.su.storage.ss_family); if (conn_.fd == -1) { connect_blocker_->on_failure(); return -1; @@ -363,8 +356,8 @@ int Http2Session::initiate_connection() { rv = connect(conn_.fd, // TODO maybe not thread-safe? - const_cast(&downstream_addr.addr.su.sa), - downstream_addr.addr.len); + const_cast(&addr_->addr.su.sa), + addr_->addr.len); if (rv != 0 && errno != EINPROGRESS) { connect_blocker_->on_failure(); return -1; @@ -380,17 +373,16 @@ int Http2Session::initiate_connection() { // Without TLS and proxy. assert(conn_.fd == -1); - conn_.fd = util::create_nonblock_socket( - downstream_addr.addr.su.storage.ss_family); + conn_.fd = + util::create_nonblock_socket(addr_->addr.su.storage.ss_family); if (conn_.fd == -1) { connect_blocker_->on_failure(); return -1; } - rv = connect(conn_.fd, - const_cast(&downstream_addr.addr.su.sa), - downstream_addr.addr.len); + rv = connect(conn_.fd, const_cast(&addr_->addr.su.sa), + addr_->addr.len); if (rv != 0 && errno != EINPROGRESS) { connect_blocker_->on_failure(); return -1; @@ -516,17 +508,15 @@ int Http2Session::downstream_connect_proxy() { if (LOG_ENABLED(INFO)) { SSLOG(INFO, this) << "Connected to the proxy"; } - auto &downstream_addr = - get_config()->conn.downstream.addr_groups[group_].addrs[addr_idx_]; std::string req = "CONNECT "; - req.append(downstream_addr.hostport.c_str(), downstream_addr.hostport.size()); - if (downstream_addr.port == 80 || downstream_addr.port == 443) { + req.append(addr_->hostport.c_str(), addr_->hostport.size()); + if (addr_->port == 80 || addr_->port == 443) { req += ':'; - req += util::utos(downstream_addr.port); + req += util::utos(addr_->port); } req += " HTTP/1.1\r\nHost: "; - req.append(downstream_addr.host.c_str(), downstream_addr.host.size()); + req += addr_->host; req += "\r\n"; const auto &proxy = get_config()->downstream_http_proxy; if (!proxy.userinfo.empty()) { @@ -1761,7 +1751,7 @@ int Http2Session::tls_handshake() { } if (!get_config()->conn.downstream.no_tls && !get_config()->tls.insecure && - check_cert() != 0) { + ssl::check_cert(conn_.tls.ssl, addr_) != 0) { return -1; } @@ -1854,7 +1844,7 @@ bool Http2Session::should_hard_fail() const { } } -size_t Http2Session::get_addr_idx() const { return addr_idx_; } +const DownstreamAddr *Http2Session::get_addr() const { return addr_; } size_t Http2Session::get_group() const { return group_; } diff --git a/src/shrpx_http2_session.h b/src/shrpx_http2_session.h index 84e7af77..28fc9f63 100644 --- a/src/shrpx_http2_session.h +++ b/src/shrpx_http2_session.h @@ -62,8 +62,6 @@ public: size_t idx); ~Http2Session(); - int check_cert(); - // If hard is true, all pending requests are abandoned and // associated ClientHandlers will be deleted. int disconnect(bool hard = false); @@ -147,7 +145,7 @@ public: void submit_pending_requests(); - size_t get_addr_idx() const; + const DownstreamAddr *get_addr() const; size_t get_group() const; @@ -205,11 +203,11 @@ private: ConnectBlocker *connect_blocker_; // NULL if no TLS is configured SSL_CTX *ssl_ctx_; + // Address of remote endpoint + const DownstreamAddr *addr_; nghttp2_session *session_; const uint8_t *data_pending_; size_t data_pendinglen_; - // index of get_config()->downstream_addrs this object uses - size_t addr_idx_; size_t group_; // index inside group, this is used to pin frontend to certain // HTTP/2 backend for better throughput. diff --git a/src/shrpx_http_downstream_connection.cc b/src/shrpx_http_downstream_connection.cc index e67f4955..bb4db4d4 100644 --- a/src/shrpx_http_downstream_connection.cc +++ b/src/shrpx_http_downstream_connection.cc @@ -124,19 +124,16 @@ HttpDownstreamConnection::HttpDownstreamConnection( do_write_(&HttpDownstreamConnection::noop), worker_(worker), ssl_ctx_(worker->get_cl_ssl_ctx()), + addr_(nullptr), ioctrl_(&conn_.rlimit), response_htp_{0}, - group_(group), - addr_idx_(0) {} + group_(group) {} HttpDownstreamConnection::~HttpDownstreamConnection() { if (conn_.tls.ssl) { auto session = SSL_get1_session(conn_.tls.ssl); if (session) { - auto &downstreamconf = get_config()->conn.downstream; - auto &addr = downstreamconf.addr_groups[group_].addrs[addr_idx_]; - - worker_->cache_downstream_tls_session(&addr, session); + worker_->cache_downstream_tls_session(addr_, session); } } } @@ -173,7 +170,7 @@ int HttpDownstreamConnection::attach_downstream(Downstream *downstream) { auto &addrs = downstreamconf.addr_groups[group_].addrs; for (;;) { auto &addr = addrs[next_downstream]; - auto i = next_downstream; + if (++next_downstream >= addrs.size()) { next_downstream = 0; } @@ -211,17 +208,17 @@ int HttpDownstreamConnection::attach_downstream(Downstream *downstream) { DCLOG(INFO, this) << "Connecting to downstream server"; } - addr_idx_ = i; + addr_ = &addr; if (ssl_ctx_) { auto sni_name = !get_config()->tls.backend_sni_name.empty() ? StringRef(get_config()->tls.backend_sni_name) - : StringRef(addrs[i].host); + : StringRef(addr_->host); if (!util::numeric_host(sni_name.c_str())) { SSL_set_tlsext_host_name(conn_.tls.ssl, sni_name.c_str()); } - auto session = worker_->reuse_downstream_tls_session(&addrs[i]); + auto session = worker_->reuse_downstream_tls_session(addr_); if (session) { SSL_set_session(conn_.tls.ssl, session); SSL_SESSION_free(session); @@ -257,10 +254,7 @@ int HttpDownstreamConnection::attach_downstream(Downstream *downstream) { } int HttpDownstreamConnection::push_request_headers() { - const auto &downstream_hostport = get_config() - ->conn.downstream.addr_groups[group_] - .addrs[addr_idx_] - .hostport; + const auto &downstream_hostport = addr_->hostport; const auto &req = downstream_->request(); auto connect_method = req.method == HTTP_CONNECT; @@ -870,9 +864,7 @@ int HttpDownstreamConnection::tls_handshake() { } if (!get_config()->tls.insecure && - ssl::check_cert(conn_.tls.ssl, &get_config() - ->conn.downstream.addr_groups[group_] - .addrs[addr_idx_]) != 0) { + ssl::check_cert(conn_.tls.ssl, addr_) != 0) { return -1; } diff --git a/src/shrpx_http_downstream_connection.h b/src/shrpx_http_downstream_connection.h index a905a9fc..b65db9ac 100644 --- a/src/shrpx_http_downstream_connection.h +++ b/src/shrpx_http_downstream_connection.h @@ -81,11 +81,11 @@ private: Worker *worker_; // nullptr if TLS is not used. SSL_CTX *ssl_ctx_; + // Address of remote endpoint + const DownstreamAddr *addr_; IOControl ioctrl_; http_parser response_htp_; size_t group_; - // index of get_config()->downstream_addrs this object is using - size_t addr_idx_; }; } // namespace shrpx