nghttpx: Create struct Address which holds struct sockaddr_union and length
This commit is contained in:
parent
efcd43a367
commit
cd25c6846e
23
src/shrpx.cc
23
src/shrpx.cc
|
@ -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) {
|
||||
|
|
|
@ -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;
|
||||
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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_;
|
||||
|
|
|
@ -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() {}
|
||||
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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) {
|
||||
|
|
Loading…
Reference in New Issue