nghttpx: Support UNIX domain socket in backend connections
This commit is contained in:
parent
49781da8f0
commit
997f9233bc
39
src/shrpx.cc
39
src/shrpx.cc
|
@ -28,6 +28,7 @@
|
|||
#include <sys/types.h>
|
||||
#include <sys/stat.h>
|
||||
#include <sys/socket.h>
|
||||
#include <sys/un.h>
|
||||
#include <netdb.h>
|
||||
#include <signal.h>
|
||||
#include <netinet/in.h>
|
||||
|
@ -821,7 +822,9 @@ Connections:
|
|||
backend addresses are accepted by repeating this option.
|
||||
HTTP/2 backend does not support multiple backend
|
||||
addresses and the first occurrence of this option is
|
||||
used.
|
||||
used. UNIX domain socket can be specified by prefixing
|
||||
path name with "unix:" (e.g.,
|
||||
-bunix:/var/run/backend.sock)
|
||||
Default: )" << DEFAULT_DOWNSTREAM_HOST << ","
|
||||
<< DEFAULT_DOWNSTREAM_PORT << R"(
|
||||
-f, --frontend=<HOST,PORT>
|
||||
|
@ -1870,23 +1873,35 @@ int main(int argc, char **argv) {
|
|||
}
|
||||
|
||||
for (auto &addr : mod_config()->downstream_addrs) {
|
||||
auto ipv6 = util::ipv6_numeric_addr(addr.host.get());
|
||||
std::string hostport;
|
||||
|
||||
if (ipv6) {
|
||||
hostport += "[";
|
||||
if (util::istartsWith(addr.host.get(), SHRPX_UNIX_PATH_PREFIX)) {
|
||||
// for AF_UNIX socket, we use "localhost" as host for backend
|
||||
// hostport. This is used as Host header field to backend and
|
||||
// not going to be passed to any syscalls.
|
||||
addr.hostport =
|
||||
strcopy(util::make_hostport("localhost", get_config()->port));
|
||||
|
||||
auto path = addr.host.get() + str_size(SHRPX_UNIX_PATH_PREFIX);
|
||||
auto pathlen = strlen(path);
|
||||
|
||||
if (pathlen + 1 > sizeof(addr.addr.un.sun_path)) {
|
||||
LOG(FATAL) << "path unix domain socket is bound to is too long > "
|
||||
<< sizeof(addr.addr.un.sun_path);
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
|
||||
hostport += addr.host.get();
|
||||
LOG(INFO) << "Use UNIX domain socket path " << path
|
||||
<< " for backend connection";
|
||||
|
||||
if (ipv6) {
|
||||
hostport += "]";
|
||||
addr.addr.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);
|
||||
|
||||
continue;
|
||||
}
|
||||
|
||||
hostport += ":";
|
||||
hostport += util::utos(addr.port);
|
||||
|
||||
addr.hostport = strcopy(hostport);
|
||||
addr.hostport = strcopy(util::make_hostport(addr.host.get(), addr.port));
|
||||
|
||||
if (resolve_hostname(
|
||||
&addr.addr, &addr.addrlen, addr.host.get(), addr.port,
|
||||
|
|
|
@ -521,6 +521,16 @@ int parse_config(const char *opt, const char *optarg) {
|
|||
char host[NI_MAXHOST];
|
||||
uint16_t port;
|
||||
if (util::strieq(opt, SHRPX_OPT_BACKEND)) {
|
||||
if (util::istartsWith(optarg, SHRPX_UNIX_PATH_PREFIX)) {
|
||||
DownstreamAddr addr;
|
||||
addr.host = strcopy(optarg);
|
||||
addr.port = 0;
|
||||
|
||||
mod_config()->downstream_addrs.push_back(std::move(addr));
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (split_host_port(host, sizeof(host), &port, optarg) == -1) {
|
||||
return -1;
|
||||
}
|
||||
|
|
|
@ -30,6 +30,7 @@
|
|||
#include <stdint.h>
|
||||
#include <sys/types.h>
|
||||
#include <sys/socket.h>
|
||||
#include <sys/un.h>
|
||||
#include <netinet/in.h>
|
||||
#include <arpa/inet.h>
|
||||
#include <cstdio>
|
||||
|
@ -52,6 +53,8 @@ class CertLookupTree;
|
|||
|
||||
} // namespace ssl
|
||||
|
||||
#define SHRPX_UNIX_PATH_PREFIX "unix:"
|
||||
|
||||
extern const char SHRPX_OPT_PRIVATE_KEY_FILE[];
|
||||
extern const char SHRPX_OPT_PRIVATE_KEY_PASSWD_FILE[];
|
||||
extern const char SHRPX_OPT_CERTIFICATE_FILE[];
|
||||
|
@ -139,6 +142,7 @@ union sockaddr_union {
|
|||
sockaddr sa;
|
||||
sockaddr_in6 in6;
|
||||
sockaddr_in in;
|
||||
sockaddr_un un;
|
||||
};
|
||||
|
||||
enum shrpx_proto { PROTO_HTTP2, PROTO_HTTP };
|
||||
|
|
22
src/util.cc
22
src/util.cc
|
@ -847,7 +847,9 @@ int create_nonblock_socket(int family) {
|
|||
make_socket_closeonexec(fd);
|
||||
#endif // !SOCK_NONBLOCK
|
||||
|
||||
if (family == AF_INET || family == AF_INET6) {
|
||||
make_socket_nodelay(fd);
|
||||
}
|
||||
|
||||
return fd;
|
||||
}
|
||||
|
@ -1016,6 +1018,26 @@ std::string dtos(double n) {
|
|||
return utos(static_cast<int64_t>(n)) + "." + (f.size() == 1 ? "0" : "") + f;
|
||||
}
|
||||
|
||||
std::string make_hostport(const char *host, uint16_t port) {
|
||||
auto ipv6 = ipv6_numeric_addr(host);
|
||||
std::string hostport;
|
||||
|
||||
if (ipv6) {
|
||||
hostport += "[";
|
||||
}
|
||||
|
||||
hostport += host;
|
||||
|
||||
if (ipv6) {
|
||||
hostport += "]";
|
||||
}
|
||||
|
||||
hostport += ":";
|
||||
hostport += utos(port);
|
||||
|
||||
return hostport;
|
||||
}
|
||||
|
||||
} // namespace util
|
||||
|
||||
} // namespace nghttp2
|
||||
|
|
|
@ -551,6 +551,11 @@ std::string duration_str(double t);
|
|||
// fractional digits follow.
|
||||
std::string format_duration(const std::chrono::microseconds &u);
|
||||
|
||||
// Creates "host:port" string using given |host| and |port|. If
|
||||
// |host| is numeric IPv6 address (e.g., ::1), it is enclosed by "["
|
||||
// and "]".
|
||||
std::string make_hostport(const char *host, uint16_t port);
|
||||
|
||||
} // namespace util
|
||||
|
||||
} // namespace nghttp2
|
||||
|
|
Loading…
Reference in New Issue