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/types.h>
|
||||||
#include <sys/stat.h>
|
#include <sys/stat.h>
|
||||||
#include <sys/socket.h>
|
#include <sys/socket.h>
|
||||||
|
#include <sys/un.h>
|
||||||
#include <netdb.h>
|
#include <netdb.h>
|
||||||
#include <signal.h>
|
#include <signal.h>
|
||||||
#include <netinet/in.h>
|
#include <netinet/in.h>
|
||||||
|
@ -821,7 +822,9 @@ Connections:
|
||||||
backend addresses are accepted by repeating this option.
|
backend addresses are accepted by repeating this option.
|
||||||
HTTP/2 backend does not support multiple backend
|
HTTP/2 backend does not support multiple backend
|
||||||
addresses and the first occurrence of this option is
|
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: )" << DEFAULT_DOWNSTREAM_HOST << ","
|
||||||
<< DEFAULT_DOWNSTREAM_PORT << R"(
|
<< DEFAULT_DOWNSTREAM_PORT << R"(
|
||||||
-f, --frontend=<HOST,PORT>
|
-f, --frontend=<HOST,PORT>
|
||||||
|
@ -1870,23 +1873,35 @@ int main(int argc, char **argv) {
|
||||||
}
|
}
|
||||||
|
|
||||||
for (auto &addr : mod_config()->downstream_addrs) {
|
for (auto &addr : mod_config()->downstream_addrs) {
|
||||||
auto ipv6 = util::ipv6_numeric_addr(addr.host.get());
|
|
||||||
std::string hostport;
|
|
||||||
|
|
||||||
if (ipv6) {
|
if (util::istartsWith(addr.host.get(), SHRPX_UNIX_PATH_PREFIX)) {
|
||||||
hostport += "[";
|
// 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) {
|
addr.addr.un.sun_family = AF_UNIX;
|
||||||
hostport += "]";
|
// copy path including terminal NULL
|
||||||
|
std::copy_n(path, pathlen + 1, addr.addr.un.sun_path);
|
||||||
|
addr.addrlen = sizeof(addr.addr.un);
|
||||||
|
|
||||||
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
hostport += ":";
|
addr.hostport = strcopy(util::make_hostport(addr.host.get(), addr.port));
|
||||||
hostport += util::utos(addr.port);
|
|
||||||
|
|
||||||
addr.hostport = strcopy(hostport);
|
|
||||||
|
|
||||||
if (resolve_hostname(
|
if (resolve_hostname(
|
||||||
&addr.addr, &addr.addrlen, addr.host.get(), addr.port,
|
&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];
|
char host[NI_MAXHOST];
|
||||||
uint16_t port;
|
uint16_t port;
|
||||||
if (util::strieq(opt, SHRPX_OPT_BACKEND)) {
|
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) {
|
if (split_host_port(host, sizeof(host), &port, optarg) == -1) {
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
|
@ -30,6 +30,7 @@
|
||||||
#include <stdint.h>
|
#include <stdint.h>
|
||||||
#include <sys/types.h>
|
#include <sys/types.h>
|
||||||
#include <sys/socket.h>
|
#include <sys/socket.h>
|
||||||
|
#include <sys/un.h>
|
||||||
#include <netinet/in.h>
|
#include <netinet/in.h>
|
||||||
#include <arpa/inet.h>
|
#include <arpa/inet.h>
|
||||||
#include <cstdio>
|
#include <cstdio>
|
||||||
|
@ -52,6 +53,8 @@ class CertLookupTree;
|
||||||
|
|
||||||
} // namespace ssl
|
} // namespace ssl
|
||||||
|
|
||||||
|
#define SHRPX_UNIX_PATH_PREFIX "unix:"
|
||||||
|
|
||||||
extern const char SHRPX_OPT_PRIVATE_KEY_FILE[];
|
extern const char SHRPX_OPT_PRIVATE_KEY_FILE[];
|
||||||
extern const char SHRPX_OPT_PRIVATE_KEY_PASSWD_FILE[];
|
extern const char SHRPX_OPT_PRIVATE_KEY_PASSWD_FILE[];
|
||||||
extern const char SHRPX_OPT_CERTIFICATE_FILE[];
|
extern const char SHRPX_OPT_CERTIFICATE_FILE[];
|
||||||
|
@ -139,6 +142,7 @@ union sockaddr_union {
|
||||||
sockaddr sa;
|
sockaddr sa;
|
||||||
sockaddr_in6 in6;
|
sockaddr_in6 in6;
|
||||||
sockaddr_in in;
|
sockaddr_in in;
|
||||||
|
sockaddr_un un;
|
||||||
};
|
};
|
||||||
|
|
||||||
enum shrpx_proto { PROTO_HTTP2, PROTO_HTTP };
|
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);
|
make_socket_closeonexec(fd);
|
||||||
#endif // !SOCK_NONBLOCK
|
#endif // !SOCK_NONBLOCK
|
||||||
|
|
||||||
|
if (family == AF_INET || family == AF_INET6) {
|
||||||
make_socket_nodelay(fd);
|
make_socket_nodelay(fd);
|
||||||
|
}
|
||||||
|
|
||||||
return fd;
|
return fd;
|
||||||
}
|
}
|
||||||
|
@ -1016,6 +1018,26 @@ std::string dtos(double n) {
|
||||||
return utos(static_cast<int64_t>(n)) + "." + (f.size() == 1 ? "0" : "") + f;
|
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 util
|
||||||
|
|
||||||
} // namespace nghttp2
|
} // namespace nghttp2
|
||||||
|
|
|
@ -551,6 +551,11 @@ std::string duration_str(double t);
|
||||||
// fractional digits follow.
|
// fractional digits follow.
|
||||||
std::string format_duration(const std::chrono::microseconds &u);
|
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 util
|
||||||
|
|
||||||
} // namespace nghttp2
|
} // namespace nghttp2
|
||||||
|
|
Loading…
Reference in New Issue