nghttpx: Store pointer to DownstreamAddr

This commit is contained in:
Tatsuhiro Tsujikawa 2016-02-07 18:22:57 +09:00
parent 4fb4617d20
commit 2a9b23bfab
5 changed files with 39 additions and 62 deletions

View File

@ -268,10 +268,7 @@ int Http2DownstreamConnection::push_request_headers() {
// http2session_ has already in CONNECTED state, so we can get // http2session_ has already in CONNECTED state, so we can get
// addr_idx here. // addr_idx here.
auto addr_idx = http2session_->get_addr_idx(); const auto &downstream_hostport = http2session_->get_addr()->hostport;
auto group = http2session_->get_group();
const auto &downstream_hostport =
get_config()->conn.downstream.addr_groups[group].addrs[addr_idx].hostport;
// For HTTP/1.0 request, there is no authority in request. In that // For HTTP/1.0 request, there is no authority in request. In that
// case, we use backend server's host nonetheless. // case, we use backend server's host nonetheless.

View File

@ -153,10 +153,10 @@ Http2Session::Http2Session(struct ev_loop *loop, SSL_CTX *ssl_ctx,
worker_(worker), worker_(worker),
connect_blocker_(connect_blocker), connect_blocker_(connect_blocker),
ssl_ctx_(ssl_ctx), ssl_ctx_(ssl_ctx),
addr_(nullptr),
session_(nullptr), session_(nullptr),
data_pending_(nullptr), data_pending_(nullptr),
data_pendinglen_(0), data_pendinglen_(0),
addr_idx_(0),
group_(group), group_(group),
index_(idx), index_(idx),
state_(DISCONNECTED), state_(DISCONNECTED),
@ -202,7 +202,7 @@ int Http2Session::disconnect(bool hard) {
conn_.disconnect(); conn_.disconnect();
addr_idx_ = 0; addr_ = nullptr;
if (proxy_htp_) { if (proxy_htp_) {
proxy_htp_.reset(); proxy_htp_.reset();
@ -245,12 +245,6 @@ int Http2Session::disconnect(bool hard) {
return 0; 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 Http2Session::initiate_connection() {
int rv = 0; int rv = 0;
@ -266,19 +260,18 @@ int Http2Session::initiate_connection() {
} }
auto &next_downstream = worker_->get_dgrp(group_)->next; 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()) { if (++next_downstream >= addrs.size()) {
next_downstream = 0; 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; const auto &proxy = get_config()->downstream_http_proxy;
if (!proxy.host.empty() && state_ == DISCONNECTED) { if (!proxy.host.empty() && state_ == DISCONNECTED) {
if (LOG_ENABLED(INFO)) { if (LOG_ENABLED(INFO)) {
@ -341,7 +334,7 @@ int Http2Session::initiate_connection() {
auto sni_name = !get_config()->tls.backend_sni_name.empty() auto sni_name = !get_config()->tls.backend_sni_name.empty()
? StringRef(get_config()->tls.backend_sni_name) ? StringRef(get_config()->tls.backend_sni_name)
: StringRef(downstream_addr.host); : StringRef(addr_->host);
if (!util::numeric_host(sni_name.c_str())) { if (!util::numeric_host(sni_name.c_str())) {
// TLS extensions: SNI. There is no documentation about the return // TLS extensions: SNI. There is no documentation about the return
@ -354,8 +347,8 @@ int Http2Session::initiate_connection() {
if (state_ == DISCONNECTED) { if (state_ == DISCONNECTED) {
assert(conn_.fd == -1); assert(conn_.fd == -1);
conn_.fd = util::create_nonblock_socket( conn_.fd =
downstream_addr.addr.su.storage.ss_family); util::create_nonblock_socket(addr_->addr.su.storage.ss_family);
if (conn_.fd == -1) { if (conn_.fd == -1) {
connect_blocker_->on_failure(); connect_blocker_->on_failure();
return -1; return -1;
@ -363,8 +356,8 @@ int Http2Session::initiate_connection() {
rv = connect(conn_.fd, rv = connect(conn_.fd,
// TODO maybe not thread-safe? // TODO maybe not thread-safe?
const_cast<sockaddr *>(&downstream_addr.addr.su.sa), const_cast<sockaddr *>(&addr_->addr.su.sa),
downstream_addr.addr.len); addr_->addr.len);
if (rv != 0 && errno != EINPROGRESS) { if (rv != 0 && errno != EINPROGRESS) {
connect_blocker_->on_failure(); connect_blocker_->on_failure();
return -1; return -1;
@ -380,17 +373,16 @@ int Http2Session::initiate_connection() {
// Without TLS and proxy. // Without TLS and proxy.
assert(conn_.fd == -1); assert(conn_.fd == -1);
conn_.fd = util::create_nonblock_socket( conn_.fd =
downstream_addr.addr.su.storage.ss_family); util::create_nonblock_socket(addr_->addr.su.storage.ss_family);
if (conn_.fd == -1) { if (conn_.fd == -1) {
connect_blocker_->on_failure(); connect_blocker_->on_failure();
return -1; return -1;
} }
rv = connect(conn_.fd, rv = connect(conn_.fd, const_cast<sockaddr *>(&addr_->addr.su.sa),
const_cast<sockaddr *>(&downstream_addr.addr.su.sa), addr_->addr.len);
downstream_addr.addr.len);
if (rv != 0 && errno != EINPROGRESS) { if (rv != 0 && errno != EINPROGRESS) {
connect_blocker_->on_failure(); connect_blocker_->on_failure();
return -1; return -1;
@ -516,17 +508,15 @@ int Http2Session::downstream_connect_proxy() {
if (LOG_ENABLED(INFO)) { if (LOG_ENABLED(INFO)) {
SSLOG(INFO, this) << "Connected to the proxy"; SSLOG(INFO, this) << "Connected to the proxy";
} }
auto &downstream_addr =
get_config()->conn.downstream.addr_groups[group_].addrs[addr_idx_];
std::string req = "CONNECT "; std::string req = "CONNECT ";
req.append(downstream_addr.hostport.c_str(), downstream_addr.hostport.size()); req.append(addr_->hostport.c_str(), addr_->hostport.size());
if (downstream_addr.port == 80 || downstream_addr.port == 443) { if (addr_->port == 80 || addr_->port == 443) {
req += ':'; req += ':';
req += util::utos(downstream_addr.port); req += util::utos(addr_->port);
} }
req += " HTTP/1.1\r\nHost: "; req += " HTTP/1.1\r\nHost: ";
req.append(downstream_addr.host.c_str(), downstream_addr.host.size()); req += addr_->host;
req += "\r\n"; req += "\r\n";
const auto &proxy = get_config()->downstream_http_proxy; const auto &proxy = get_config()->downstream_http_proxy;
if (!proxy.userinfo.empty()) { if (!proxy.userinfo.empty()) {
@ -1761,7 +1751,7 @@ int Http2Session::tls_handshake() {
} }
if (!get_config()->conn.downstream.no_tls && !get_config()->tls.insecure && if (!get_config()->conn.downstream.no_tls && !get_config()->tls.insecure &&
check_cert() != 0) { ssl::check_cert(conn_.tls.ssl, addr_) != 0) {
return -1; 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_; } size_t Http2Session::get_group() const { return group_; }

View File

@ -62,8 +62,6 @@ public:
size_t idx); size_t idx);
~Http2Session(); ~Http2Session();
int check_cert();
// If hard is true, all pending requests are abandoned and // If hard is true, all pending requests are abandoned and
// associated ClientHandlers will be deleted. // associated ClientHandlers will be deleted.
int disconnect(bool hard = false); int disconnect(bool hard = false);
@ -147,7 +145,7 @@ public:
void submit_pending_requests(); void submit_pending_requests();
size_t get_addr_idx() const; const DownstreamAddr *get_addr() const;
size_t get_group() const; size_t get_group() const;
@ -205,11 +203,11 @@ private:
ConnectBlocker *connect_blocker_; ConnectBlocker *connect_blocker_;
// NULL if no TLS is configured // NULL if no TLS is configured
SSL_CTX *ssl_ctx_; SSL_CTX *ssl_ctx_;
// Address of remote endpoint
const DownstreamAddr *addr_;
nghttp2_session *session_; nghttp2_session *session_;
const uint8_t *data_pending_; const uint8_t *data_pending_;
size_t data_pendinglen_; size_t data_pendinglen_;
// index of get_config()->downstream_addrs this object uses
size_t addr_idx_;
size_t group_; size_t group_;
// index inside group, this is used to pin frontend to certain // index inside group, this is used to pin frontend to certain
// HTTP/2 backend for better throughput. // HTTP/2 backend for better throughput.

View File

@ -124,19 +124,16 @@ HttpDownstreamConnection::HttpDownstreamConnection(
do_write_(&HttpDownstreamConnection::noop), do_write_(&HttpDownstreamConnection::noop),
worker_(worker), worker_(worker),
ssl_ctx_(worker->get_cl_ssl_ctx()), ssl_ctx_(worker->get_cl_ssl_ctx()),
addr_(nullptr),
ioctrl_(&conn_.rlimit), ioctrl_(&conn_.rlimit),
response_htp_{0}, response_htp_{0},
group_(group), group_(group) {}
addr_idx_(0) {}
HttpDownstreamConnection::~HttpDownstreamConnection() { HttpDownstreamConnection::~HttpDownstreamConnection() {
if (conn_.tls.ssl) { if (conn_.tls.ssl) {
auto session = SSL_get1_session(conn_.tls.ssl); auto session = SSL_get1_session(conn_.tls.ssl);
if (session) { if (session) {
auto &downstreamconf = get_config()->conn.downstream; worker_->cache_downstream_tls_session(addr_, session);
auto &addr = downstreamconf.addr_groups[group_].addrs[addr_idx_];
worker_->cache_downstream_tls_session(&addr, session);
} }
} }
} }
@ -173,7 +170,7 @@ int HttpDownstreamConnection::attach_downstream(Downstream *downstream) {
auto &addrs = downstreamconf.addr_groups[group_].addrs; auto &addrs = downstreamconf.addr_groups[group_].addrs;
for (;;) { for (;;) {
auto &addr = addrs[next_downstream]; auto &addr = addrs[next_downstream];
auto i = next_downstream;
if (++next_downstream >= addrs.size()) { if (++next_downstream >= addrs.size()) {
next_downstream = 0; next_downstream = 0;
} }
@ -211,17 +208,17 @@ int HttpDownstreamConnection::attach_downstream(Downstream *downstream) {
DCLOG(INFO, this) << "Connecting to downstream server"; DCLOG(INFO, this) << "Connecting to downstream server";
} }
addr_idx_ = i; addr_ = &addr;
if (ssl_ctx_) { if (ssl_ctx_) {
auto sni_name = !get_config()->tls.backend_sni_name.empty() auto sni_name = !get_config()->tls.backend_sni_name.empty()
? StringRef(get_config()->tls.backend_sni_name) ? StringRef(get_config()->tls.backend_sni_name)
: StringRef(addrs[i].host); : StringRef(addr_->host);
if (!util::numeric_host(sni_name.c_str())) { if (!util::numeric_host(sni_name.c_str())) {
SSL_set_tlsext_host_name(conn_.tls.ssl, 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) { if (session) {
SSL_set_session(conn_.tls.ssl, session); SSL_set_session(conn_.tls.ssl, session);
SSL_SESSION_free(session); SSL_SESSION_free(session);
@ -257,10 +254,7 @@ int HttpDownstreamConnection::attach_downstream(Downstream *downstream) {
} }
int HttpDownstreamConnection::push_request_headers() { int HttpDownstreamConnection::push_request_headers() {
const auto &downstream_hostport = get_config() const auto &downstream_hostport = addr_->hostport;
->conn.downstream.addr_groups[group_]
.addrs[addr_idx_]
.hostport;
const auto &req = downstream_->request(); const auto &req = downstream_->request();
auto connect_method = req.method == HTTP_CONNECT; auto connect_method = req.method == HTTP_CONNECT;
@ -870,9 +864,7 @@ int HttpDownstreamConnection::tls_handshake() {
} }
if (!get_config()->tls.insecure && if (!get_config()->tls.insecure &&
ssl::check_cert(conn_.tls.ssl, &get_config() ssl::check_cert(conn_.tls.ssl, addr_) != 0) {
->conn.downstream.addr_groups[group_]
.addrs[addr_idx_]) != 0) {
return -1; return -1;
} }

View File

@ -81,11 +81,11 @@ private:
Worker *worker_; Worker *worker_;
// nullptr if TLS is not used. // nullptr if TLS is not used.
SSL_CTX *ssl_ctx_; SSL_CTX *ssl_ctx_;
// Address of remote endpoint
const DownstreamAddr *addr_;
IOControl ioctrl_; IOControl ioctrl_;
http_parser response_htp_; http_parser response_htp_;
size_t group_; size_t group_;
// index of get_config()->downstream_addrs this object is using
size_t addr_idx_;
}; };
} // namespace shrpx } // namespace shrpx