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
// 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.

View File

@ -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<sockaddr *>(&downstream_addr.addr.su.sa),
downstream_addr.addr.len);
const_cast<sockaddr *>(&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<sockaddr *>(&downstream_addr.addr.su.sa),
downstream_addr.addr.len);
rv = connect(conn_.fd, const_cast<sockaddr *>(&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_; }

View File

@ -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.

View File

@ -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;
}

View File

@ -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