aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorYash Tibrewal <yashkt@google.com>2018-09-06 15:26:36 -0700
committerYash Tibrewal <yashkt@google.com>2018-09-06 15:26:36 -0700
commitb91da3f4bf4ab30428e50a0c6734fcb931e3d85e (patch)
tree616e901996ff635ff44e47481a457d23b343320a
parent39e53c13bf1f62fdfe7e05fbfe5427f5ad3b1a90 (diff)
downloadgrpc-grpc-b91da3f4bf4ab30428e50a0c6734fcb931e3d85e.tar.gz
Add support for reading channel args
-rw-r--r--src/core/lib/iomgr/port.h1
-rw-r--r--src/core/lib/iomgr/socket_utils_common_posix.cc87
-rw-r--r--src/core/lib/iomgr/socket_utils_posix.h8
-rw-r--r--src/core/lib/iomgr/tcp_client_posix.cc3
-rw-r--r--src/core/lib/iomgr/tcp_server_utils_posix_common.cc3
5 files changed, 83 insertions, 19 deletions
diff --git a/src/core/lib/iomgr/port.h b/src/core/lib/iomgr/port.h
index bc58ed13c0..807b9bf85a 100644
--- a/src/core/lib/iomgr/port.h
+++ b/src/core/lib/iomgr/port.h
@@ -77,7 +77,6 @@
#define GRPC_LINUX_SOCKETUTILS 1
#endif
#endif
-#include <linux/version.h>
#ifdef LINUX_VERSION_CODE
#if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 37)
#define GRPC_HAVE_TCP_USER_TIMEOUT
diff --git a/src/core/lib/iomgr/socket_utils_common_posix.cc b/src/core/lib/iomgr/socket_utils_common_posix.cc
index b7fc833608..4ef3d8319f 100644
--- a/src/core/lib/iomgr/socket_utils_common_posix.cc
+++ b/src/core/lib/iomgr/socket_utils_common_posix.cc
@@ -41,6 +41,7 @@
#include <grpc/support/log.h>
#include <grpc/support/sync.h>
+#include "src/core/lib/channel/channel_args.h"
#include "src/core/lib/gpr/host_port.h"
#include "src/core/lib/gpr/string.h"
#include "src/core/lib/iomgr/sockaddr.h"
@@ -222,25 +223,83 @@ grpc_error* grpc_set_socket_low_latency(int fd, int low_latency) {
return GRPC_ERROR_NONE;
}
-#define DEFAULT_TCP_USER_TIMEOUT 20000 /* 20 seconds */
+/* The default values for TCP_USER_TIMEOUT are currently configured to be in
+ * line with the default values of KEEPALIVE_TIMEOUT as proposed in
+ * https://github.com/grpc/proposal/blob/master/A18-tcp-user-timeout.md */
+#define DEFAULT_CLIENT_TCP_USER_TIMEOUT_MS 20000 /* 20 seconds */
+#define DEFAULT_SERVER_TCP_USER_TIMEOUT_MS 20000 /* 20 seconds */
+
+static int g_default_client_tcp_user_timeout_ms =
+ DEFAULT_CLIENT_TCP_USER_TIMEOUT_MS;
+static int g_default_server_tcp_user_timeout_ms =
+ DEFAULT_SERVER_TCP_USER_TIMEOUT_MS;
+static bool g_default_client_tcp_user_timeout_enabled = false;
+static bool g_default_server_tcp_user_timeout_enabled = true;
+
+void config_default_tcp_user_timeout(bool enable, int timeout, bool is_client) {
+ if (is_client) {
+ g_default_client_tcp_user_timeout_enabled = enable;
+ if (timeout > 0) {
+ g_default_client_tcp_user_timeout_ms = timeout;
+ }
+ } else {
+ g_default_server_tcp_user_timeout_enabled = enable;
+ if (timeout > 0) {
+ g_default_server_tcp_user_timeout_ms = timeout;
+ }
+ }
+}
/* Set TCP_USER_TIMEOUT */
-grpc_error* grpc_set_socket_tcp_user_timeout(int fd, int val) {
+grpc_error* grpc_set_socket_tcp_user_timeout(
+ int fd, const grpc_channel_args* channel_args, bool is_client) {
#ifdef GRPC_HAVE_TCP_USER_TIMEOUT
- int newval;
- socklen_t len = sizeof(newval);
- if (val == 0) {
- val = DEFAULT_TCP_USER_TIMEOUT;
- }
- if (0 != setsockopt(fd, IPPROTO_TCP, TCP_USER_TIMEOUT, &val, sizeof(val))) {
- return GRPC_OS_ERROR(errno, "setsockopt(TCP_USER_TIMEOUT)");
+ bool enable;
+ int timeout;
+ if (is_client) {
+ enable = g_default_client_tcp_user_timeout_enabled;
+ timeout = g_default_client_tcp_user_timeout_ms;
+ } else {
+ enable = g_default_server_tcp_user_timeout_enabled;
+ timeout = g_default_server_tcp_user_timeout_ms;
}
- if (0 != getsockopt(fd, IPPROTO_TCP, TCP_USER_TIMEOUT, &newval, &len)) {
- return GRPC_OS_ERROR(errno, "getsockopt(TCP_USER_TIMEOUT)");
+ if (channel_args) {
+ for (unsigned int i = 0; i < channel_args->num_args; i++) {
+ if (0 == strcmp(channel_args->args[i].key, GRPC_ARG_KEEPALIVE_TIME_MS)) {
+ const int value = grpc_channel_arg_get_integer(
+ &channel_args->args[i], grpc_integer_options{0, 1, INT_MAX});
+ /* Continue using default if value is 0 */
+ if (value == 0) {
+ continue;
+ }
+ /* Disable if value is INT_MAX */
+ enable = value != INT_MAX;
+ } else if (0 == strcmp(channel_args->args[i].key,
+ GRPC_ARG_KEEPALIVE_TIMEOUT_MS)) {
+ const int value = grpc_channel_arg_get_integer(
+ &channel_args->args[i], grpc_integer_options{0, 1, INT_MAX});
+ /* Continue using default if value is 0 */
+ if (value == 0) {
+ continue;
+ }
+ timeout = value;
+ }
+ }
}
- if (newval != val) {
- return GRPC_ERROR_CREATE_FROM_STATIC_STRING(
- "Failed to set TCP_USER_TIMEOUT");
+ if (enable) {
+ int newval;
+ socklen_t len = sizeof(newval);
+ if (0 != setsockopt(fd, IPPROTO_TCP, TCP_USER_TIMEOUT, &timeout,
+ sizeof(timeout))) {
+ return GRPC_OS_ERROR(errno, "setsockopt(TCP_USER_TIMEOUT)");
+ }
+ if (0 != getsockopt(fd, IPPROTO_TCP, TCP_USER_TIMEOUT, &newval, &len)) {
+ return GRPC_OS_ERROR(errno, "getsockopt(TCP_USER_TIMEOUT)");
+ }
+ if (newval != timeout) {
+ return GRPC_ERROR_CREATE_FROM_STATIC_STRING(
+ "Failed to set TCP_USER_TIMEOUT");
+ }
}
#else
gpr_log(GPR_INFO, "TCP_USER_TIMEOUT not supported for this platform");
diff --git a/src/core/lib/iomgr/socket_utils_posix.h b/src/core/lib/iomgr/socket_utils_posix.h
index 8550bd1324..71a304dc4e 100644
--- a/src/core/lib/iomgr/socket_utils_posix.h
+++ b/src/core/lib/iomgr/socket_utils_posix.h
@@ -53,8 +53,12 @@ grpc_error* grpc_set_socket_low_latency(int fd, int low_latency);
/* set SO_REUSEPORT */
grpc_error* grpc_set_socket_reuse_port(int fd, int reuse);
-/* Set TCP_USER_TIMEOUT to val, or the default value if val is 0. */
-grpc_error* grpc_set_socket_tcp_user_timeout(int fd, int val);
+/* Configure the default values for TCP_USER_TIMEOUT */
+void config_default_tcp_user_timeout(bool enable, int timeout, bool is_client);
+
+/* Set TCP_USER_TIMEOUT */
+grpc_error* grpc_set_socket_tcp_user_timeout(
+ int fd, const grpc_channel_args* channel_args, bool is_client);
/* Returns true if this system can create AF_INET6 sockets bound to ::1.
The value is probed once, and cached for the life of the process.
diff --git a/src/core/lib/iomgr/tcp_client_posix.cc b/src/core/lib/iomgr/tcp_client_posix.cc
index c2a0892211..b71f557094 100644
--- a/src/core/lib/iomgr/tcp_client_posix.cc
+++ b/src/core/lib/iomgr/tcp_client_posix.cc
@@ -76,7 +76,8 @@ static grpc_error* prepare_socket(const grpc_resolved_address* addr, int fd,
if (!grpc_is_unix_socket(addr)) {
err = grpc_set_socket_low_latency(fd, 1);
if (err != GRPC_ERROR_NONE) goto error;
- err = grpc_set_socket_tcp_user_timeout(fd, 0 /* set to gRPC default */);
+ err = grpc_set_socket_tcp_user_timeout(fd, channel_args,
+ true /* is_client */);
if (err != GRPC_ERROR_NONE) goto error;
}
err = grpc_set_socket_no_sigpipe_if_possible(fd);
diff --git a/src/core/lib/iomgr/tcp_server_utils_posix_common.cc b/src/core/lib/iomgr/tcp_server_utils_posix_common.cc
index 20b9037c68..6cebc84024 100644
--- a/src/core/lib/iomgr/tcp_server_utils_posix_common.cc
+++ b/src/core/lib/iomgr/tcp_server_utils_posix_common.cc
@@ -166,7 +166,8 @@ grpc_error* grpc_tcp_server_prepare_socket(grpc_tcp_server* s, int fd,
if (err != GRPC_ERROR_NONE) goto error;
err = grpc_set_socket_reuse_addr(fd, 1);
if (err != GRPC_ERROR_NONE) goto error;
- err = grpc_set_socket_tcp_user_timeout(fd, 0 /* set to gRPC default */);
+ err = grpc_set_socket_tcp_user_timeout(fd, s->channel_args,
+ false /* is_client */);
if (err != GRPC_ERROR_NONE) goto error;
}
err = grpc_set_socket_no_sigpipe_if_possible(fd);