aboutsummaryrefslogtreecommitdiffhomepage
path: root/src/core/lib/iomgr/socket_utils_common_posix.cc
diff options
context:
space:
mode:
Diffstat (limited to 'src/core/lib/iomgr/socket_utils_common_posix.cc')
-rw-r--r--src/core/lib/iomgr/socket_utils_common_posix.cc42
1 files changed, 37 insertions, 5 deletions
diff --git a/src/core/lib/iomgr/socket_utils_common_posix.cc b/src/core/lib/iomgr/socket_utils_common_posix.cc
index 4fb6c7ad63..04a1767731 100644
--- a/src/core/lib/iomgr/socket_utils_common_posix.cc
+++ b/src/core/lib/iomgr/socket_utils_common_posix.cc
@@ -43,6 +43,7 @@
#include "src/core/lib/gpr/host_port.h"
#include "src/core/lib/gpr/string.h"
+#include "src/core/lib/iomgr/sockaddr.h"
#include "src/core/lib/iomgr/sockaddr_utils.h"
/* set a socket to non blocking mode */
@@ -180,6 +181,30 @@ grpc_error* grpc_set_socket_reuse_port(int fd, int reuse) {
#endif
}
+static gpr_once g_probe_so_reuesport_once = GPR_ONCE_INIT;
+static int g_support_so_reuseport = false;
+
+void probe_so_reuseport_once(void) {
+#ifndef GPR_MANYLINUX1
+ int s = socket(AF_INET, SOCK_STREAM, 0);
+ if (s < 0) {
+ /* This might be an ipv6-only environment in which case 'socket(AF_INET,..)'
+ call would fail. Try creating IPv6 socket in that case */
+ s = socket(AF_INET6, SOCK_STREAM, 0);
+ }
+ if (s >= 0) {
+ g_support_so_reuseport = GRPC_LOG_IF_ERROR(
+ "check for SO_REUSEPORT", grpc_set_socket_reuse_port(s, 1));
+ close(s);
+ }
+#endif
+}
+
+bool grpc_is_socket_reuse_port_supported() {
+ gpr_once_init(&g_probe_so_reuesport_once, probe_so_reuseport_once);
+ return g_support_so_reuseport;
+}
+
/* disable nagle */
grpc_error* grpc_set_socket_low_latency(int fd, int low_latency) {
int val = (low_latency != 0);
@@ -215,12 +240,11 @@ static void probe_ipv6_once(void) {
if (fd < 0) {
gpr_log(GPR_INFO, "Disabling AF_INET6 sockets because socket() failed.");
} else {
- struct sockaddr_in6 addr;
+ grpc_sockaddr_in6 addr;
memset(&addr, 0, sizeof(addr));
addr.sin6_family = AF_INET6;
addr.sin6_addr.s6_addr[15] = 1; /* [::1]:0 */
- if (bind(fd, reinterpret_cast<struct sockaddr*>(&addr), sizeof(addr)) ==
- 0) {
+ if (bind(fd, reinterpret_cast<grpc_sockaddr*>(&addr), sizeof(addr)) == 0) {
g_ipv6_loopback_available = 1;
} else {
gpr_log(GPR_INFO,
@@ -280,8 +304,8 @@ static int create_socket(grpc_socket_factory* factory, int domain, int type,
grpc_error* grpc_create_dualstack_socket_using_factory(
grpc_socket_factory* factory, const grpc_resolved_address* resolved_addr,
int type, int protocol, grpc_dualstack_mode* dsmode, int* newfd) {
- const struct sockaddr* addr =
- reinterpret_cast<const struct sockaddr*>(resolved_addr->addr);
+ const grpc_sockaddr* addr =
+ reinterpret_cast<const grpc_sockaddr*>(resolved_addr->addr);
int family = addr->sa_family;
if (family == AF_INET6) {
if (grpc_ipv6_loopback_available()) {
@@ -311,6 +335,14 @@ grpc_error* grpc_create_dualstack_socket_using_factory(
return error_for_fd(*newfd, resolved_addr);
}
+uint16_t grpc_htons(uint16_t hostshort) { return htons(hostshort); }
+
+uint16_t grpc_ntohs(uint16_t netshort) { return ntohs(netshort); }
+
+int grpc_inet_pton(int af, const char* src, void* dst) {
+ return inet_pton(af, src, dst);
+}
+
const char* grpc_inet_ntop(int af, const void* src, char* dst, size_t size) {
GPR_ASSERT(size <= (socklen_t)-1);
return inet_ntop(af, src, dst, static_cast<socklen_t>(size));