1 /* 2 * 3 * Copyright 2015 gRPC authors. 4 * 5 * Licensed under the Apache License, Version 2.0 (the "License"); 6 * you may not use this file except in compliance with the License. 7 * You may obtain a copy of the License at 8 * 9 * http://www.apache.org/licenses/LICENSE-2.0 10 * 11 * Unless required by applicable law or agreed to in writing, software 12 * distributed under the License is distributed on an "AS IS" BASIS, 13 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 * See the License for the specific language governing permissions and 15 * limitations under the License. 16 * 17 */ 18 19 #include <grpc/support/port_platform.h> 20 21 #include "src/core/lib/iomgr/port.h" 22 23 #ifdef GRPC_POSIX_SOCKET_UTILS_COMMON 24 25 #include "src/core/lib/iomgr/socket_utils.h" 26 #include "src/core/lib/iomgr/socket_utils_posix.h" 27 28 #include <arpa/inet.h> 29 #include <errno.h> 30 #include <fcntl.h> 31 #include <limits.h> 32 #include <netinet/in.h> 33 #include <netinet/tcp.h> 34 #include <stdio.h> 35 #include <string.h> 36 #include <sys/socket.h> 37 #include <sys/types.h> 38 #include <unistd.h> 39 40 #include <grpc/support/alloc.h> 41 #include <grpc/support/log.h> 42 #include <grpc/support/sync.h> 43 44 #include "src/core/lib/channel/channel_args.h" 45 #include "src/core/lib/gpr/host_port.h" 46 #include "src/core/lib/gpr/string.h" 47 #include "src/core/lib/iomgr/sockaddr.h" 48 #include "src/core/lib/iomgr/sockaddr_utils.h" 49 50 /* set a socket to non blocking mode */ 51 grpc_error* grpc_set_socket_nonblocking(int fd, int non_blocking) { 52 int oldflags = fcntl(fd, F_GETFL, 0); 53 if (oldflags < 0) { 54 return GRPC_OS_ERROR(errno, "fcntl"); 55 } 56 57 if (non_blocking) { 58 oldflags |= O_NONBLOCK; 59 } else { 60 oldflags &= ~O_NONBLOCK; 61 } 62 63 if (fcntl(fd, F_SETFL, oldflags) != 0) { 64 return GRPC_OS_ERROR(errno, "fcntl"); 65 } 66 67 return GRPC_ERROR_NONE; 68 } 69 70 grpc_error* grpc_set_socket_no_sigpipe_if_possible(int fd) { 71 #ifdef GRPC_HAVE_SO_NOSIGPIPE 72 int val = 1; 73 int newval; 74 socklen_t intlen = sizeof(newval); 75 if (0 != setsockopt(fd, SOL_SOCKET, SO_NOSIGPIPE, &val, sizeof(val))) { 76 return GRPC_OS_ERROR(errno, "setsockopt(SO_NOSIGPIPE)"); 77 } 78 if (0 != getsockopt(fd, SOL_SOCKET, SO_NOSIGPIPE, &newval, &intlen)) { 79 return GRPC_OS_ERROR(errno, "getsockopt(SO_NOSIGPIPE)"); 80 } 81 if ((newval != 0) != (val != 0)) { 82 return GRPC_ERROR_CREATE_FROM_STATIC_STRING("Failed to set SO_NOSIGPIPE"); 83 } 84 #endif 85 return GRPC_ERROR_NONE; 86 } 87 88 grpc_error* grpc_set_socket_ip_pktinfo_if_possible(int fd) { 89 #ifdef GRPC_HAVE_IP_PKTINFO 90 int get_local_ip = 1; 91 if (0 != setsockopt(fd, IPPROTO_IP, IP_PKTINFO, &get_local_ip, 92 sizeof(get_local_ip))) { 93 return GRPC_OS_ERROR(errno, "setsockopt(IP_PKTINFO)"); 94 } 95 #endif 96 return GRPC_ERROR_NONE; 97 } 98 99 grpc_error* grpc_set_socket_ipv6_recvpktinfo_if_possible(int fd) { 100 #ifdef GRPC_HAVE_IPV6_RECVPKTINFO 101 int get_local_ip = 1; 102 if (0 != setsockopt(fd, IPPROTO_IPV6, IPV6_RECVPKTINFO, &get_local_ip, 103 sizeof(get_local_ip))) { 104 return GRPC_OS_ERROR(errno, "setsockopt(IPV6_RECVPKTINFO)"); 105 } 106 #endif 107 return GRPC_ERROR_NONE; 108 } 109 110 grpc_error* grpc_set_socket_sndbuf(int fd, int buffer_size_bytes) { 111 return 0 == setsockopt(fd, SOL_SOCKET, SO_SNDBUF, &buffer_size_bytes, 112 sizeof(buffer_size_bytes)) 113 ? GRPC_ERROR_NONE 114 : GRPC_OS_ERROR(errno, "setsockopt(SO_SNDBUF)"); 115 } 116 117 grpc_error* grpc_set_socket_rcvbuf(int fd, int buffer_size_bytes) { 118 return 0 == setsockopt(fd, SOL_SOCKET, SO_RCVBUF, &buffer_size_bytes, 119 sizeof(buffer_size_bytes)) 120 ? GRPC_ERROR_NONE 121 : GRPC_OS_ERROR(errno, "setsockopt(SO_RCVBUF)"); 122 } 123 124 /* set a socket to close on exec */ 125 grpc_error* grpc_set_socket_cloexec(int fd, int close_on_exec) { 126 int oldflags = fcntl(fd, F_GETFD, 0); 127 if (oldflags < 0) { 128 return GRPC_OS_ERROR(errno, "fcntl"); 129 } 130 131 if (close_on_exec) { 132 oldflags |= FD_CLOEXEC; 133 } else { 134 oldflags &= ~FD_CLOEXEC; 135 } 136 137 if (fcntl(fd, F_SETFD, oldflags) != 0) { 138 return GRPC_OS_ERROR(errno, "fcntl"); 139 } 140 141 return GRPC_ERROR_NONE; 142 } 143 144 /* set a socket to reuse old addresses */ 145 grpc_error* grpc_set_socket_reuse_addr(int fd, int reuse) { 146 int val = (reuse != 0); 147 int newval; 148 socklen_t intlen = sizeof(newval); 149 if (0 != setsockopt(fd, SOL_SOCKET, SO_REUSEADDR, &val, sizeof(val))) { 150 return GRPC_OS_ERROR(errno, "setsockopt(SO_REUSEADDR)"); 151 } 152 if (0 != getsockopt(fd, SOL_SOCKET, SO_REUSEADDR, &newval, &intlen)) { 153 return GRPC_OS_ERROR(errno, "getsockopt(SO_REUSEADDR)"); 154 } 155 if ((newval != 0) != val) { 156 return GRPC_ERROR_CREATE_FROM_STATIC_STRING("Failed to set SO_REUSEADDR"); 157 } 158 159 return GRPC_ERROR_NONE; 160 } 161 162 /* set a socket to reuse old addresses */ 163 grpc_error* grpc_set_socket_reuse_port(int fd, int reuse) { 164 #ifndef SO_REUSEPORT 165 return GRPC_ERROR_CREATE_FROM_STATIC_STRING( 166 "SO_REUSEPORT unavailable on compiling system"); 167 #else 168 int val = (reuse != 0); 169 int newval; 170 socklen_t intlen = sizeof(newval); 171 if (0 != setsockopt(fd, SOL_SOCKET, SO_REUSEPORT, &val, sizeof(val))) { 172 return GRPC_OS_ERROR(errno, "setsockopt(SO_REUSEPORT)"); 173 } 174 if (0 != getsockopt(fd, SOL_SOCKET, SO_REUSEPORT, &newval, &intlen)) { 175 return GRPC_OS_ERROR(errno, "getsockopt(SO_REUSEPORT)"); 176 } 177 if ((newval != 0) != val) { 178 return GRPC_ERROR_CREATE_FROM_STATIC_STRING("Failed to set SO_REUSEPORT"); 179 } 180 181 return GRPC_ERROR_NONE; 182 #endif 183 } 184 185 static gpr_once g_probe_so_reuesport_once = GPR_ONCE_INIT; 186 static int g_support_so_reuseport = false; 187 188 void probe_so_reuseport_once(void) { 189 #ifndef GPR_MANYLINUX1 190 int s = socket(AF_INET, SOCK_STREAM, 0); 191 if (s < 0) { 192 /* This might be an ipv6-only environment in which case 'socket(AF_INET,..)' 193 call would fail. Try creating IPv6 socket in that case */ 194 s = socket(AF_INET6, SOCK_STREAM, 0); 195 } 196 if (s >= 0) { 197 g_support_so_reuseport = GRPC_LOG_IF_ERROR( 198 "check for SO_REUSEPORT", grpc_set_socket_reuse_port(s, 1)); 199 close(s); 200 } 201 #endif 202 } 203 204 bool grpc_is_socket_reuse_port_supported() { 205 gpr_once_init(&g_probe_so_reuesport_once, probe_so_reuseport_once); 206 return g_support_so_reuseport; 207 } 208 209 /* disable nagle */ 210 grpc_error* grpc_set_socket_low_latency(int fd, int low_latency) { 211 int val = (low_latency != 0); 212 int newval; 213 socklen_t intlen = sizeof(newval); 214 if (0 != setsockopt(fd, IPPROTO_TCP, TCP_NODELAY, &val, sizeof(val))) { 215 return GRPC_OS_ERROR(errno, "setsockopt(TCP_NODELAY)"); 216 } 217 if (0 != getsockopt(fd, IPPROTO_TCP, TCP_NODELAY, &newval, &intlen)) { 218 return GRPC_OS_ERROR(errno, "getsockopt(TCP_NODELAY)"); 219 } 220 if ((newval != 0) != val) { 221 return GRPC_ERROR_CREATE_FROM_STATIC_STRING("Failed to set TCP_NODELAY"); 222 } 223 return GRPC_ERROR_NONE; 224 } 225 226 /* The default values for TCP_USER_TIMEOUT are currently configured to be in 227 * line with the default values of KEEPALIVE_TIMEOUT as proposed in 228 * https://github.com/grpc/proposal/blob/master/A18-tcp-user-timeout.md */ 229 #define DEFAULT_CLIENT_TCP_USER_TIMEOUT_MS 20000 /* 20 seconds */ 230 #define DEFAULT_SERVER_TCP_USER_TIMEOUT_MS 20000 /* 20 seconds */ 231 232 static int g_default_client_tcp_user_timeout_ms = 233 DEFAULT_CLIENT_TCP_USER_TIMEOUT_MS; 234 static int g_default_server_tcp_user_timeout_ms = 235 DEFAULT_SERVER_TCP_USER_TIMEOUT_MS; 236 static bool g_default_client_tcp_user_timeout_enabled = false; 237 static bool g_default_server_tcp_user_timeout_enabled = true; 238 239 void config_default_tcp_user_timeout(bool enable, int timeout, bool is_client) { 240 if (is_client) { 241 g_default_client_tcp_user_timeout_enabled = enable; 242 if (timeout > 0) { 243 g_default_client_tcp_user_timeout_ms = timeout; 244 } 245 } else { 246 g_default_server_tcp_user_timeout_enabled = enable; 247 if (timeout > 0) { 248 g_default_server_tcp_user_timeout_ms = timeout; 249 } 250 } 251 } 252 253 /* Set TCP_USER_TIMEOUT */ 254 grpc_error* grpc_set_socket_tcp_user_timeout( 255 int fd, const grpc_channel_args* channel_args, bool is_client) { 256 #ifdef GRPC_HAVE_TCP_USER_TIMEOUT 257 bool enable; 258 int timeout; 259 if (is_client) { 260 enable = g_default_client_tcp_user_timeout_enabled; 261 timeout = g_default_client_tcp_user_timeout_ms; 262 } else { 263 enable = g_default_server_tcp_user_timeout_enabled; 264 timeout = g_default_server_tcp_user_timeout_ms; 265 } 266 if (channel_args) { 267 for (unsigned int i = 0; i < channel_args->num_args; i++) { 268 if (0 == strcmp(channel_args->args[i].key, GRPC_ARG_KEEPALIVE_TIME_MS)) { 269 const int value = grpc_channel_arg_get_integer( 270 &channel_args->args[i], grpc_integer_options{0, 1, INT_MAX}); 271 /* Continue using default if value is 0 */ 272 if (value == 0) { 273 continue; 274 } 275 /* Disable if value is INT_MAX */ 276 enable = value != INT_MAX; 277 } else if (0 == strcmp(channel_args->args[i].key, 278 GRPC_ARG_KEEPALIVE_TIMEOUT_MS)) { 279 const int value = grpc_channel_arg_get_integer( 280 &channel_args->args[i], grpc_integer_options{0, 1, INT_MAX}); 281 /* Continue using default if value is 0 */ 282 if (value == 0) { 283 continue; 284 } 285 timeout = value; 286 } 287 } 288 } 289 if (enable) { 290 extern grpc_core::TraceFlag grpc_tcp_trace; 291 if (grpc_tcp_trace.enabled()) { 292 gpr_log(GPR_INFO, "Enabling TCP_USER_TIMEOUT with a timeout of %d ms", 293 timeout); 294 } 295 int newval; 296 socklen_t len = sizeof(newval); 297 if (0 != setsockopt(fd, IPPROTO_TCP, TCP_USER_TIMEOUT, &timeout, 298 sizeof(timeout))) { 299 return GRPC_OS_ERROR(errno, "setsockopt(TCP_USER_TIMEOUT)"); 300 } 301 if (0 != getsockopt(fd, IPPROTO_TCP, TCP_USER_TIMEOUT, &newval, &len)) { 302 return GRPC_OS_ERROR(errno, "getsockopt(TCP_USER_TIMEOUT)"); 303 } 304 if (newval != timeout) { 305 return GRPC_ERROR_CREATE_FROM_STATIC_STRING( 306 "Failed to set TCP_USER_TIMEOUT"); 307 } 308 } 309 #else 310 gpr_log(GPR_INFO, "TCP_USER_TIMEOUT not supported for this platform"); 311 #endif /* GRPC_HAVE_TCP_USER_TIMEOUT */ 312 return GRPC_ERROR_NONE; 313 } 314 315 /* set a socket using a grpc_socket_mutator */ 316 grpc_error* grpc_set_socket_with_mutator(int fd, grpc_socket_mutator* mutator) { 317 GPR_ASSERT(mutator); 318 if (!grpc_socket_mutator_mutate_fd(mutator, fd)) { 319 return GRPC_ERROR_CREATE_FROM_STATIC_STRING("grpc_socket_mutator failed."); 320 } 321 return GRPC_ERROR_NONE; 322 } 323 324 static gpr_once g_probe_ipv6_once = GPR_ONCE_INIT; 325 static int g_ipv6_loopback_available; 326 327 static void probe_ipv6_once(void) { 328 int fd = socket(AF_INET6, SOCK_STREAM, 0); 329 g_ipv6_loopback_available = 0; 330 if (fd < 0) { 331 gpr_log(GPR_INFO, "Disabling AF_INET6 sockets because socket() failed."); 332 } else { 333 grpc_sockaddr_in6 addr; 334 memset(&addr, 0, sizeof(addr)); 335 addr.sin6_family = AF_INET6; 336 addr.sin6_addr.s6_addr[15] = 1; /* [::1]:0 */ 337 if (bind(fd, reinterpret_cast<grpc_sockaddr*>(&addr), sizeof(addr)) == 0) { 338 g_ipv6_loopback_available = 1; 339 } else { 340 gpr_log(GPR_INFO, 341 "Disabling AF_INET6 sockets because ::1 is not available."); 342 } 343 close(fd); 344 } 345 } 346 347 int grpc_ipv6_loopback_available(void) { 348 gpr_once_init(&g_probe_ipv6_once, probe_ipv6_once); 349 return g_ipv6_loopback_available; 350 } 351 352 /* This should be 0 in production, but it may be enabled for testing or 353 debugging purposes, to simulate an environment where IPv6 sockets can't 354 also speak IPv4. */ 355 int grpc_forbid_dualstack_sockets_for_testing = 0; 356 357 static int set_socket_dualstack(int fd) { 358 if (!grpc_forbid_dualstack_sockets_for_testing) { 359 const int off = 0; 360 return 0 == setsockopt(fd, IPPROTO_IPV6, IPV6_V6ONLY, &off, sizeof(off)); 361 } else { 362 /* Force an IPv6-only socket, for testing purposes. */ 363 const int on = 1; 364 setsockopt(fd, IPPROTO_IPV6, IPV6_V6ONLY, &on, sizeof(on)); 365 return 0; 366 } 367 } 368 369 static grpc_error* error_for_fd(int fd, const grpc_resolved_address* addr) { 370 if (fd >= 0) return GRPC_ERROR_NONE; 371 char* addr_str; 372 grpc_sockaddr_to_string(&addr_str, addr, 0); 373 grpc_error* err = grpc_error_set_str(GRPC_OS_ERROR(errno, "socket"), 374 GRPC_ERROR_STR_TARGET_ADDRESS, 375 grpc_slice_from_copied_string(addr_str)); 376 gpr_free(addr_str); 377 return err; 378 } 379 380 grpc_error* grpc_create_dualstack_socket( 381 const grpc_resolved_address* resolved_addr, int type, int protocol, 382 grpc_dualstack_mode* dsmode, int* newfd) { 383 return grpc_create_dualstack_socket_using_factory( 384 nullptr, resolved_addr, type, protocol, dsmode, newfd); 385 } 386 387 static int create_socket(grpc_socket_factory* factory, int domain, int type, 388 int protocol) { 389 return (factory != nullptr) 390 ? grpc_socket_factory_socket(factory, domain, type, protocol) 391 : socket(domain, type, protocol); 392 } 393 394 grpc_error* grpc_create_dualstack_socket_using_factory( 395 grpc_socket_factory* factory, const grpc_resolved_address* resolved_addr, 396 int type, int protocol, grpc_dualstack_mode* dsmode, int* newfd) { 397 const grpc_sockaddr* addr = 398 reinterpret_cast<const grpc_sockaddr*>(resolved_addr->addr); 399 int family = addr->sa_family; 400 if (family == AF_INET6) { 401 if (grpc_ipv6_loopback_available()) { 402 *newfd = create_socket(factory, family, type, protocol); 403 } else { 404 *newfd = -1; 405 errno = EAFNOSUPPORT; 406 } 407 /* Check if we've got a valid dualstack socket. */ 408 if (*newfd >= 0 && set_socket_dualstack(*newfd)) { 409 *dsmode = GRPC_DSMODE_DUALSTACK; 410 return GRPC_ERROR_NONE; 411 } 412 /* If this isn't an IPv4 address, then return whatever we've got. */ 413 if (!grpc_sockaddr_is_v4mapped(resolved_addr, nullptr)) { 414 *dsmode = GRPC_DSMODE_IPV6; 415 return error_for_fd(*newfd, resolved_addr); 416 } 417 /* Fall back to AF_INET. */ 418 if (*newfd >= 0) { 419 close(*newfd); 420 } 421 family = AF_INET; 422 } 423 *dsmode = family == AF_INET ? GRPC_DSMODE_IPV4 : GRPC_DSMODE_NONE; 424 *newfd = create_socket(factory, family, type, protocol); 425 return error_for_fd(*newfd, resolved_addr); 426 } 427 428 uint16_t grpc_htons(uint16_t hostshort) { return htons(hostshort); } 429 430 uint16_t grpc_ntohs(uint16_t netshort) { return ntohs(netshort); } 431 432 uint32_t grpc_htonl(uint32_t hostlong) { return htonl(hostlong); } 433 434 uint32_t grpc_ntohl(uint32_t netlong) { return ntohl(netlong); } 435 436 int grpc_inet_pton(int af, const char* src, void* dst) { 437 return inet_pton(af, src, dst); 438 } 439 440 const char* grpc_inet_ntop(int af, const void* src, char* dst, size_t size) { 441 GPR_ASSERT(size <= (socklen_t)-1); 442 return inet_ntop(af, src, dst, static_cast<socklen_t>(size)); 443 } 444 445 #endif 446