nghttpx: Create struct Address which holds struct sockaddr_union and length

This commit is contained in:
Tatsuhiro Tsujikawa 2015-07-27 01:41:10 +09:00
parent efcd43a367
commit cd25c6846e
11 changed files with 55 additions and 63 deletions

View File

@ -117,8 +117,8 @@ const int GRACEFUL_SHUTDOWN_SIGNAL = SIGQUIT;
#define ENV_UNIX_PATH "NGHTTP2_UNIX_PATH"
namespace {
int resolve_hostname(sockaddr_union *addr, size_t *addrlen,
const char *hostname, uint16_t port, int family) {
int resolve_hostname(Address *addr, const char *hostname, uint16_t port,
int family) {
int rv;
auto service = util::utos(port);
@ -155,8 +155,8 @@ int resolve_hostname(sockaddr_union *addr, size_t *addrlen,
<< " succeeded: " << host;
}
memcpy(addr, res->ai_addr, res->ai_addrlen);
*addrlen = res->ai_addrlen;
memcpy(&addr->su, res->ai_addr, res->ai_addrlen);
addr->len = res->ai_addrlen;
freeaddrinfo(res);
return 0;
}
@ -963,7 +963,6 @@ void fill_default_config() {
mod_config()->downstream_http_proxy_userinfo = nullptr;
mod_config()->downstream_http_proxy_host = nullptr;
mod_config()->downstream_http_proxy_port = 0;
mod_config()->downstream_http_proxy_addrlen = 0;
mod_config()->read_rate = 0;
mod_config()->read_burst = 0;
mod_config()->write_rate = 0;
@ -2347,19 +2346,19 @@ int main(int argc, char **argv) {
auto path = addr.host.get();
auto pathlen = strlen(path);
if (pathlen + 1 > sizeof(addr.addr.un.sun_path)) {
if (pathlen + 1 > sizeof(addr.addr.su.un.sun_path)) {
LOG(FATAL) << "UNIX domain socket path " << path << " is too long > "
<< sizeof(addr.addr.un.sun_path);
<< sizeof(addr.addr.su.un.sun_path);
exit(EXIT_FAILURE);
}
LOG(INFO) << "Use UNIX domain socket path " << path
<< " for backend connection";
addr.addr.un.sun_family = AF_UNIX;
addr.addr.su.un.sun_family = AF_UNIX;
// copy path including terminal NULL
std::copy_n(path, pathlen + 1, addr.addr.un.sun_path);
addr.addrlen = sizeof(addr.addr.un);
std::copy_n(path, pathlen + 1, addr.addr.su.un.sun_path);
addr.addr.len = sizeof(addr.addr.su.un);
continue;
}
@ -2367,7 +2366,7 @@ int main(int argc, char **argv) {
addr.hostport = strcopy(util::make_hostport(addr.host.get(), addr.port));
if (resolve_hostname(
&addr.addr, &addr.addrlen, addr.host.get(), addr.port,
&addr.addr, addr.host.get(), addr.port,
get_config()->backend_ipv4 ? AF_INET : (get_config()->backend_ipv6
? AF_INET6
: AF_UNSPEC)) == -1) {
@ -2381,7 +2380,6 @@ int main(int argc, char **argv) {
LOG(INFO) << "Resolving backend http proxy address";
}
if (resolve_hostname(&mod_config()->downstream_http_proxy_addr,
&mod_config()->downstream_http_proxy_addrlen,
get_config()->downstream_http_proxy_host.get(),
get_config()->downstream_http_proxy_port,
AF_UNSPEC) == -1) {
@ -2391,7 +2389,6 @@ int main(int argc, char **argv) {
if (get_config()->session_cache_memcached_host) {
if (resolve_hostname(&mod_config()->session_cache_memcached_addr,
&mod_config()->session_cache_memcached_addrlen,
get_config()->session_cache_memcached_host.get(),
get_config()->session_cache_memcached_port,
AF_UNSPEC) == -1) {

View File

@ -81,7 +81,7 @@ TicketKeys::~TicketKeys() {
DownstreamAddr::DownstreamAddr(const DownstreamAddr &other)
: addr(other.addr), host(other.host ? strcopy(other.host.get()) : nullptr),
hostport(other.hostport ? strcopy(other.hostport.get()) : nullptr),
addrlen(other.addrlen), port(other.port), host_unix(other.host_unix) {}
port(other.port), host_unix(other.host_unix) {}
DownstreamAddr &DownstreamAddr::operator=(const DownstreamAddr &other) {
if (this == &other) {
@ -91,7 +91,6 @@ DownstreamAddr &DownstreamAddr::operator=(const DownstreamAddr &other) {
addr = other.addr;
host = (other.host ? strcopy(other.host.get()) : nullptr);
hostport = (other.hostport ? strcopy(other.hostport.get()) : nullptr);
addrlen = other.addrlen;
port = other.port;
host_unix = other.host_unix;

View File

@ -184,6 +184,11 @@ union sockaddr_union {
sockaddr_un un;
};
struct Address {
size_t len;
union sockaddr_union su;
};
enum shrpx_proto { PROTO_HTTP2, PROTO_HTTP };
struct AltSvc {
@ -195,18 +200,17 @@ struct AltSvc {
};
struct DownstreamAddr {
DownstreamAddr() : addr{{0}}, addrlen(0), port(0), host_unix(false) {}
DownstreamAddr() : addr{}, port(0), host_unix(false) {}
DownstreamAddr(const DownstreamAddr &other);
DownstreamAddr(DownstreamAddr &&) = default;
DownstreamAddr &operator=(const DownstreamAddr &other);
DownstreamAddr &operator=(DownstreamAddr &&other) = default;
sockaddr_union addr;
Address addr;
// backend address. If |host_unix| is true, this is UNIX domain
// socket path.
std::unique_ptr<char[]> host;
std::unique_ptr<char[]> hostport;
size_t addrlen;
// backend port. 0 if |host_unix| is true.
uint16_t port;
// true if |host| contains UNIX domain socket path.
@ -254,8 +258,8 @@ struct Config {
// list of supported SSL/TLS protocol strings.
std::vector<std::string> tls_proto_list;
// binary form of http proxy host and port
sockaddr_union downstream_http_proxy_addr;
sockaddr_union session_cache_memcached_addr;
Address downstream_http_proxy_addr;
Address session_cache_memcached_addr;
std::chrono::seconds tls_session_timeout;
ev_tstamp http2_upstream_read_timeout;
ev_tstamp upstream_read_timeout;
@ -318,9 +322,6 @@ struct Config {
size_t http2_downstream_connections_per_worker;
size_t downstream_connections_per_host;
size_t downstream_connections_per_frontend;
// actual size of downstream_http_proxy_addr
size_t downstream_http_proxy_addrlen;
size_t session_cache_memcached_addrlen;
size_t read_rate;
size_t read_burst;
size_t write_rate;

View File

@ -276,15 +276,15 @@ int Http2Session::initiate_connection() {
}
conn_.fd = util::create_nonblock_socket(
get_config()->downstream_http_proxy_addr.storage.ss_family);
get_config()->downstream_http_proxy_addr.su.storage.ss_family);
if (conn_.fd == -1) {
connect_blocker_->on_failure();
return -1;
}
rv = connect(conn_.fd, &get_config()->downstream_http_proxy_addr.sa,
get_config()->downstream_http_proxy_addrlen);
rv = connect(conn_.fd, &get_config()->downstream_http_proxy_addr.su.sa,
get_config()->downstream_http_proxy_addr.len);
if (rv != 0 && errno != EINPROGRESS) {
SSLOG(ERROR, this) << "Failed to connect to the proxy "
<< get_config()->downstream_http_proxy_host.get()
@ -350,7 +350,7 @@ int Http2Session::initiate_connection() {
assert(conn_.fd == -1);
conn_.fd = util::create_nonblock_socket(
downstream_addr.addr.storage.ss_family);
downstream_addr.addr.su.storage.ss_family);
if (conn_.fd == -1) {
connect_blocker_->on_failure();
return -1;
@ -358,8 +358,8 @@ int Http2Session::initiate_connection() {
rv = connect(conn_.fd,
// TODO maybe not thread-safe?
const_cast<sockaddr *>(&downstream_addr.addr.sa),
downstream_addr.addrlen);
const_cast<sockaddr *>(&downstream_addr.addr.su.sa),
downstream_addr.addr.len);
if (rv != 0 && errno != EINPROGRESS) {
connect_blocker_->on_failure();
return -1;
@ -376,15 +376,16 @@ int Http2Session::initiate_connection() {
assert(conn_.fd == -1);
conn_.fd = util::create_nonblock_socket(
downstream_addr.addr.storage.ss_family);
downstream_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.sa),
downstream_addr.addrlen);
rv = connect(conn_.fd,
const_cast<sockaddr *>(&downstream_addr.addr.su.sa),
downstream_addr.addr.len);
if (rv != 0 && errno != EINPROGRESS) {
connect_blocker_->on_failure();
return -1;

View File

@ -147,7 +147,7 @@ int HttpDownstreamConnection::attach_downstream(Downstream *downstream) {
next_downstream = 0;
}
conn_.fd = util::create_nonblock_socket(addr.addr.storage.ss_family);
conn_.fd = util::create_nonblock_socket(addr.addr.su.storage.ss_family);
if (conn_.fd == -1) {
auto error = errno;
@ -159,7 +159,7 @@ int HttpDownstreamConnection::attach_downstream(Downstream *downstream) {
}
int rv;
rv = connect(conn_.fd, &addr.addr.sa, addr.addrlen);
rv = connect(conn_.fd, &addr.addr.su.sa, addr.addr.len);
if (rv != 0 && errno != EINPROGRESS) {
auto error = errno;
DCLOG(WARN, this) << "connect() failed; errno=" << error;

View File

@ -85,12 +85,11 @@ void connectcb(struct ev_loop *loop, ev_io *w, int revents) {
constexpr ev_tstamp write_timeout = 10.;
constexpr ev_tstamp read_timeout = 10.;
MemcachedConnection::MemcachedConnection(const sockaddr_union *addr,
size_t addrlen, struct ev_loop *loop)
MemcachedConnection::MemcachedConnection(const Address *addr,
struct ev_loop *loop)
: conn_(loop, -1, nullptr, write_timeout, read_timeout, 0, 0, 0, 0,
connectcb, readcb, timeoutcb, this),
parse_state_{}, addr_(addr), addrlen_(addrlen), sendsum_(0),
connected_(false) {}
parse_state_{}, addr_(addr), sendsum_(0), connected_(false) {}
MemcachedConnection::~MemcachedConnection() { disconnect(); }
@ -125,7 +124,7 @@ void MemcachedConnection::disconnect() {
int MemcachedConnection::initiate_connection() {
assert(conn_.fd == -1);
conn_.fd = util::create_nonblock_socket(addr_->storage.ss_family);
conn_.fd = util::create_nonblock_socket(addr_->su.storage.ss_family);
if (conn_.fd == -1) {
auto error = errno;
@ -135,7 +134,7 @@ int MemcachedConnection::initiate_connection() {
}
int rv;
rv = connect(conn_.fd, &addr_->sa, addrlen_);
rv = connect(conn_.fd, &addr_->su.sa, addr_->len);
if (rv != 0 && errno != EINPROGRESS) {
auto error = errno;
MCLOG(WARN, this) << "connect() failed; errno=" << error;

View File

@ -40,7 +40,7 @@ using namespace nghttp2;
namespace shrpx {
struct MemcachedRequest;
union sockaddr_union;
struct Address;
enum {
MEMCACHED_PARSE_HEADER24,
@ -93,8 +93,7 @@ constexpr uint8_t MEMCACHED_RES_MAGIC = 0x81;
// https://code.google.com/p/memcached/wiki/MemcacheBinaryProtocol
class MemcachedConnection {
public:
MemcachedConnection(const sockaddr_union *addr, size_t addrlen,
struct ev_loop *loop);
MemcachedConnection(const Address *addr, struct ev_loop *loop);
~MemcachedConnection();
void disconnect();
@ -118,8 +117,7 @@ private:
std::deque<std::unique_ptr<MemcachedRequest>> sendq_;
std::deque<MemcachedSendbuf> sendbufv_;
MemcachedParseState parse_state_;
const sockaddr_union *addr_;
size_t addrlen_;
const Address *addr_;
// Sum of the bytes to be transmitted in sendbufv_.
size_t sendsum_;
bool connected_;

View File

@ -30,10 +30,9 @@
namespace shrpx {
MemcachedDispatcher::MemcachedDispatcher(const sockaddr_union *addr,
size_t addrlen, struct ev_loop *loop)
: loop_(loop),
mconn_(make_unique<MemcachedConnection>(addr, addrlen, loop_)) {}
MemcachedDispatcher::MemcachedDispatcher(const Address *addr,
struct ev_loop *loop)
: loop_(loop), mconn_(make_unique<MemcachedConnection>(addr, loop_)) {}
MemcachedDispatcher::~MemcachedDispatcher() {}

View File

@ -35,12 +35,11 @@ namespace shrpx {
struct MemcachedRequest;
class MemcachedConnection;
union sockaddr_union;
struct Address;
class MemcachedDispatcher {
public:
MemcachedDispatcher(const sockaddr_union *addr, size_t addrlen,
struct ev_loop *loop);
MemcachedDispatcher(const Address *addr, struct ev_loop *loop);
~MemcachedDispatcher();
int add_request(std::unique_ptr<MemcachedRequest> req);

View File

@ -768,8 +768,8 @@ bool tls_hostname_match(const char *pattern, const char *hostname) {
} // namespace
namespace {
int verify_hostname(const char *hostname, const sockaddr_union *su,
size_t salen, const std::vector<std::string> &dns_names,
int verify_hostname(const char *hostname, const Address *addr,
const std::vector<std::string> &dns_names,
const std::vector<std::string> &ip_addrs,
const std::string &common_name) {
if (util::numeric_host(hostname)) {
@ -777,19 +777,19 @@ int verify_hostname(const char *hostname, const sockaddr_union *su,
return util::strieq(common_name.c_str(), hostname) ? 0 : -1;
}
const void *saddr;
switch (su->storage.ss_family) {
switch (addr->su.storage.ss_family) {
case AF_INET:
saddr = &su->in.sin_addr;
saddr = &addr->su.in.sin_addr;
break;
case AF_INET6:
saddr = &su->in6.sin6_addr;
saddr = &addr->su.in6.sin6_addr;
break;
default:
return -1;
}
for (size_t i = 0; i < ip_addrs.size(); ++i) {
if (salen == ip_addrs[i].size() &&
memcmp(saddr, ip_addrs[i].c_str(), salen) == 0) {
if (addr->len == ip_addrs[i].size() &&
memcmp(saddr, ip_addrs[i].c_str(), addr->len) == 0) {
return 0;
}
}
@ -884,8 +884,8 @@ int check_cert(SSL *ssl, const DownstreamAddr *addr) {
std::vector<std::string> dns_names;
std::vector<std::string> ip_addrs;
get_altnames(cert, dns_names, ip_addrs, common_name);
if (verify_hostname(addr->host.get(), &addr->addr, addr->addrlen, dns_names,
ip_addrs, common_name) != 0) {
if (verify_hostname(addr->host.get(), &addr->addr, dns_names, ip_addrs,
common_name) != 0) {
LOG(ERROR) << "Certificate verification failed: hostname does not match";
return -1;
}

View File

@ -78,8 +78,7 @@ Worker::Worker(struct ev_loop *loop, SSL_CTX *sv_ssl_ctx, SSL_CTX *cl_ssl_ctx,
if (get_config()->session_cache_memcached_host) {
session_cache_memcached_dispatcher_ = make_unique<MemcachedDispatcher>(
&get_config()->session_cache_memcached_addr,
get_config()->session_cache_memcached_addrlen, loop);
&get_config()->session_cache_memcached_addr, loop);
}
if (get_config()->downstream_proto == PROTO_HTTP2) {