Nicolas Noble | b7ebd3b | 2014-11-26 16:33:03 -0800 | [diff] [blame] | 1 | /* |
| 2 | * |
Craig Tiller | 6169d5f | 2016-03-31 07:46:18 -0700 | [diff] [blame] | 3 | * Copyright 2015, Google Inc. |
Nicolas Noble | b7ebd3b | 2014-11-26 16:33:03 -0800 | [diff] [blame] | 4 | * All rights reserved. |
| 5 | * |
| 6 | * Redistribution and use in source and binary forms, with or without |
| 7 | * modification, are permitted provided that the following conditions are |
| 8 | * met: |
| 9 | * |
| 10 | * * Redistributions of source code must retain the above copyright |
| 11 | * notice, this list of conditions and the following disclaimer. |
| 12 | * * Redistributions in binary form must reproduce the above |
| 13 | * copyright notice, this list of conditions and the following disclaimer |
| 14 | * in the documentation and/or other materials provided with the |
| 15 | * distribution. |
| 16 | * * Neither the name of Google Inc. nor the names of its |
| 17 | * contributors may be used to endorse or promote products derived from |
| 18 | * this software without specific prior written permission. |
| 19 | * |
| 20 | * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS |
| 21 | * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT |
| 22 | * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR |
| 23 | * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT |
| 24 | * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, |
| 25 | * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT |
| 26 | * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, |
| 27 | * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY |
| 28 | * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT |
| 29 | * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE |
| 30 | * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
| 31 | * |
| 32 | */ |
| 33 | |
Craig Tiller | 9a4dddd | 2016-03-25 17:08:13 -0700 | [diff] [blame] | 34 | #ifndef GRPC_CORE_LIB_IOMGR_SOCKET_UTILS_POSIX_H |
| 35 | #define GRPC_CORE_LIB_IOMGR_SOCKET_UTILS_POSIX_H |
Nicolas Noble | b7ebd3b | 2014-11-26 16:33:03 -0800 | [diff] [blame] | 36 | |
murgatroid99 | 7871f73 | 2016-09-23 13:49:05 -0700 | [diff] [blame] | 37 | #include "src/core/lib/iomgr/resolve_address.h" |
| 38 | |
Nicolas Noble | b7ebd3b | 2014-11-26 16:33:03 -0800 | [diff] [blame] | 39 | #include <sys/socket.h> |
Craig Tiller | f40df23 | 2016-03-25 13:38:14 -0700 | [diff] [blame] | 40 | #include <unistd.h> |
Nicolas Noble | b7ebd3b | 2014-11-26 16:33:03 -0800 | [diff] [blame] | 41 | |
Yuchen Zeng | 929f4c6 | 2016-10-10 16:02:43 -0700 | [diff] [blame] | 42 | #include <grpc/impl/codegen/grpc_types.h> |
Craig Tiller | 27f59af | 2016-04-28 14:19:48 -0700 | [diff] [blame] | 43 | #include "src/core/lib/iomgr/error.h" |
Yuchen Zeng | de3daf5 | 2016-10-13 17:26:26 -0700 | [diff] [blame] | 44 | #include "src/core/lib/iomgr/socket_mutator.h" |
Craig Tiller | 27f59af | 2016-04-28 14:19:48 -0700 | [diff] [blame] | 45 | |
Nicolas Noble | b7ebd3b | 2014-11-26 16:33:03 -0800 | [diff] [blame] | 46 | /* a wrapper for accept or accept4 */ |
murgatroid99 | dedb923 | 2016-09-26 13:54:04 -0700 | [diff] [blame] | 47 | int grpc_accept4(int sockfd, grpc_resolved_address *resolved_addr, int nonblock, |
| 48 | int cloexec); |
Nicolas Noble | b7ebd3b | 2014-11-26 16:33:03 -0800 | [diff] [blame] | 49 | |
| 50 | /* set a socket to non blocking mode */ |
Craig Tiller | 27f59af | 2016-04-28 14:19:48 -0700 | [diff] [blame] | 51 | grpc_error *grpc_set_socket_nonblocking(int fd, int non_blocking); |
Nicolas Noble | b7ebd3b | 2014-11-26 16:33:03 -0800 | [diff] [blame] | 52 | |
| 53 | /* set a socket to close on exec */ |
Craig Tiller | 27f59af | 2016-04-28 14:19:48 -0700 | [diff] [blame] | 54 | grpc_error *grpc_set_socket_cloexec(int fd, int close_on_exec); |
Nicolas Noble | b7ebd3b | 2014-11-26 16:33:03 -0800 | [diff] [blame] | 55 | |
| 56 | /* set a socket to reuse old addresses */ |
Craig Tiller | 27f59af | 2016-04-28 14:19:48 -0700 | [diff] [blame] | 57 | grpc_error *grpc_set_socket_reuse_addr(int fd, int reuse); |
Nicolas Noble | b7ebd3b | 2014-11-26 16:33:03 -0800 | [diff] [blame] | 58 | |
| 59 | /* disable nagle */ |
Craig Tiller | 27f59af | 2016-04-28 14:19:48 -0700 | [diff] [blame] | 60 | grpc_error *grpc_set_socket_low_latency(int fd, int low_latency); |
Nicolas Noble | b7ebd3b | 2014-11-26 16:33:03 -0800 | [diff] [blame] | 61 | |
Craig Tiller | ef96264 | 2016-05-18 22:57:17 -0700 | [diff] [blame] | 62 | /* set SO_REUSEPORT */ |
| 63 | grpc_error *grpc_set_socket_reuse_port(int fd, int reuse); |
| 64 | |
pmarks | b745506 | 2014-12-17 19:00:42 -0800 | [diff] [blame] | 65 | /* Returns true if this system can create AF_INET6 sockets bound to ::1. |
| 66 | The value is probed once, and cached for the life of the process. |
| 67 | |
| 68 | This is more restrictive than checking for socket(AF_INET6) to succeed, |
| 69 | because Linux with "net.ipv6.conf.all.disable_ipv6 = 1" is able to create |
| 70 | and bind IPv6 sockets, but cannot connect to a getsockname() of [::]:port |
| 71 | without a valid loopback interface. Rather than expose this half-broken |
| 72 | state to library users, we turn off IPv6 sockets. */ |
Craig Tiller | 32946d3 | 2015-01-15 11:37:30 -0800 | [diff] [blame] | 73 | int grpc_ipv6_loopback_available(void); |
pmarks | b745506 | 2014-12-17 19:00:42 -0800 | [diff] [blame] | 74 | |
Craig Tiller | 2da0296 | 2015-05-06 16:14:25 -0700 | [diff] [blame] | 75 | /* Tries to set SO_NOSIGPIPE if available on this platform. |
Craig Tiller | 2da0296 | 2015-05-06 16:14:25 -0700 | [diff] [blame] | 76 | If SO_NO_SIGPIPE is not available, returns 1. */ |
Craig Tiller | 27f59af | 2016-04-28 14:19:48 -0700 | [diff] [blame] | 77 | grpc_error *grpc_set_socket_no_sigpipe_if_possible(int fd); |
Craig Tiller | 2da0296 | 2015-05-06 16:14:25 -0700 | [diff] [blame] | 78 | |
ahedberg | 8d7cff4 | 2016-03-24 11:16:44 -0400 | [diff] [blame] | 79 | /* Tries to set IP_PKTINFO if available on this platform. |
ahedberg | 8d7cff4 | 2016-03-24 11:16:44 -0400 | [diff] [blame] | 80 | If IP_PKTINFO is not available, returns 1. */ |
Craig Tiller | 27f59af | 2016-04-28 14:19:48 -0700 | [diff] [blame] | 81 | grpc_error *grpc_set_socket_ip_pktinfo_if_possible(int fd); |
ahedberg | 8d7cff4 | 2016-03-24 11:16:44 -0400 | [diff] [blame] | 82 | |
| 83 | /* Tries to set IPV6_RECVPKTINFO if available on this platform. |
ahedberg | 8d7cff4 | 2016-03-24 11:16:44 -0400 | [diff] [blame] | 84 | If IPV6_RECVPKTINFO is not available, returns 1. */ |
Craig Tiller | 27f59af | 2016-04-28 14:19:48 -0700 | [diff] [blame] | 85 | grpc_error *grpc_set_socket_ipv6_recvpktinfo_if_possible(int fd); |
ahedberg | 8d7cff4 | 2016-03-24 11:16:44 -0400 | [diff] [blame] | 86 | |
Craig Tiller | ba94748 | 2016-06-09 08:03:49 -0700 | [diff] [blame] | 87 | /* Tries to set the socket's send buffer to given size. */ |
| 88 | grpc_error *grpc_set_socket_sndbuf(int fd, int buffer_size_bytes); |
Robbie Shade | 3f30e63 | 2016-06-08 08:40:56 -0400 | [diff] [blame] | 89 | |
Craig Tiller | ba94748 | 2016-06-09 08:03:49 -0700 | [diff] [blame] | 90 | /* Tries to set the socket's receive buffer to given size. */ |
| 91 | grpc_error *grpc_set_socket_rcvbuf(int fd, int buffer_size_bytes); |
Robbie Shade | 3f30e63 | 2016-06-08 08:40:56 -0400 | [diff] [blame] | 92 | |
Yuchen Zeng | a4f708a | 2016-10-11 18:36:24 -0700 | [diff] [blame] | 93 | /* Tries to set the socket using a grpc_socket_mutator */ |
| 94 | grpc_error *grpc_set_socket_with_mutator(int fd, grpc_socket_mutator *mutator); |
Yuchen Zeng | 929f4c6 | 2016-10-10 16:02:43 -0700 | [diff] [blame] | 95 | |
nnoble | 0c475f0 | 2014-12-05 15:37:39 -0800 | [diff] [blame] | 96 | /* An enum to keep track of IPv4/IPv6 socket modes. |
| 97 | |
| 98 | Currently, this information is only used when a socket is first created, but |
| 99 | in the future we may wish to store it alongside the fd. This would let calls |
| 100 | like sendto() know which family to use without asking the kernel first. */ |
| 101 | typedef enum grpc_dualstack_mode { |
| 102 | /* Uninitialized, or a non-IP socket. */ |
| 103 | GRPC_DSMODE_NONE, |
| 104 | /* AF_INET only. */ |
| 105 | GRPC_DSMODE_IPV4, |
| 106 | /* AF_INET6 only, because IPV6_V6ONLY could not be cleared. */ |
| 107 | GRPC_DSMODE_IPV6, |
| 108 | /* AF_INET6, which also supports ::ffff-mapped IPv4 addresses. */ |
| 109 | GRPC_DSMODE_DUALSTACK |
| 110 | } grpc_dualstack_mode; |
| 111 | |
| 112 | /* Only tests should use this flag. */ |
| 113 | extern int grpc_forbid_dualstack_sockets_for_testing; |
| 114 | |
| 115 | /* Creates a new socket for connecting to (or listening on) an address. |
| 116 | |
| 117 | If addr is AF_INET6, this creates an IPv6 socket first. If that fails, |
| 118 | and addr is within ::ffff:0.0.0.0/96, then it automatically falls back to |
| 119 | an IPv4 socket. |
| 120 | |
| 121 | If addr is AF_INET, AF_UNIX, or anything else, then this is similar to |
| 122 | calling socket() directly. |
| 123 | |
| 124 | Returns an fd on success, otherwise returns -1 with errno set to the result |
| 125 | of a failed socket() call. |
| 126 | |
| 127 | The *dsmode output indicates which address family was actually created. |
| 128 | The recommended way to use this is: |
| 129 | - First convert to IPv6 using grpc_sockaddr_to_v4mapped(). |
| 130 | - Create the socket. |
| 131 | - If *dsmode is IPV4, use grpc_sockaddr_is_v4mapped() to convert back to |
| 132 | IPv4, so that bind() or connect() see the correct family. |
| 133 | Also, it's important to distinguish between DUALSTACK and IPV6 when |
| 134 | listening on the [::] wildcard address. */ |
murgatroid99 | dedb923 | 2016-09-26 13:54:04 -0700 | [diff] [blame] | 135 | grpc_error *grpc_create_dualstack_socket(const grpc_resolved_address *addr, |
| 136 | int type, int protocol, |
Craig Tiller | 27f59af | 2016-04-28 14:19:48 -0700 | [diff] [blame] | 137 | grpc_dualstack_mode *dsmode, |
| 138 | int *newfd); |
nnoble | 0c475f0 | 2014-12-05 15:37:39 -0800 | [diff] [blame] | 139 | |
Craig Tiller | 9a4dddd | 2016-03-25 17:08:13 -0700 | [diff] [blame] | 140 | #endif /* GRPC_CORE_LIB_IOMGR_SOCKET_UTILS_POSIX_H */ |