1 // 2 // 3 // Copyright 2017 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 #ifndef GRPC_SRC_CORE_LIB_IOMGR_TCP_SERVER_UTILS_POSIX_H 20 #define GRPC_SRC_CORE_LIB_IOMGR_TCP_SERVER_UTILS_POSIX_H 21 22 #include <grpc/support/port_platform.h> 23 24 #include <memory> 25 26 #include "absl/container/flat_hash_map.h" 27 28 #include "src/core/lib/event_engine/posix.h" 29 #include "src/core/lib/iomgr/ev_posix.h" 30 #include "src/core/lib/iomgr/resolve_address.h" 31 #include "src/core/lib/iomgr/socket_utils_posix.h" 32 #include "src/core/lib/iomgr/tcp_server.h" 33 #include "src/core/lib/iomgr/timer.h" 34 #include "src/core/lib/resource_quota/memory_quota.h" 35 36 // one listening port 37 typedef struct grpc_tcp_listener { 38 int fd; 39 grpc_fd* emfd; 40 grpc_tcp_server* server; 41 grpc_resolved_address addr; 42 int port; 43 unsigned port_index; 44 unsigned fd_index; 45 grpc_closure read_closure; 46 grpc_closure destroyed_closure; 47 struct grpc_tcp_listener* next; 48 // sibling is a linked list of all listeners for a given port. add_port and 49 // clone_port place all new listeners in the same sibling list. A member of 50 // the 'sibling' list is also a member of the 'next' list. The head of each 51 // sibling list has is_sibling==0, and subsequent members of sibling lists 52 // have is_sibling==1. is_sibling allows separate sibling lists to be 53 // identified while iterating through 'next'. 54 struct grpc_tcp_listener* sibling; 55 int is_sibling; 56 // If an accept4() call fails, a timer is started to drain the accept queue in 57 // case no further connection attempts reach the gRPC server. 58 grpc_closure retry_closure; 59 grpc_timer retry_timer; 60 gpr_atm retry_timer_armed; 61 } grpc_tcp_listener; 62 63 // the overall server 64 struct grpc_tcp_server { 65 gpr_refcount refs; 66 // Called whenever accept() succeeds on a server port. 67 grpc_tcp_server_cb on_accept_cb = nullptr; 68 void* on_accept_cb_arg = nullptr; 69 70 gpr_mu mu; 71 72 // active port count: how many ports are actually still listening 73 size_t active_ports = 0; 74 // destroyed port count: how many ports are completely destroyed 75 size_t destroyed_ports = 0; 76 77 // is this server shutting down? 78 bool shutdown = false; 79 // have listeners been shutdown? 80 bool shutdown_listeners = false; 81 // use SO_REUSEPORT 82 bool so_reuseport = false; 83 // expand wildcard addresses to a list of all local addresses 84 bool expand_wildcard_addrs = false; 85 86 // linked list of server ports 87 grpc_tcp_listener* head = nullptr; 88 grpc_tcp_listener* tail = nullptr; 89 unsigned nports = 0; 90 91 // List of closures passed to shutdown_starting_add(). 92 grpc_closure_list shutdown_starting{nullptr, nullptr}; 93 94 // shutdown callback 95 grpc_closure* shutdown_complete = nullptr; 96 97 // all pollsets interested in new connections. The object pointed at is not 98 // owned by this struct 99 const std::vector<grpc_pollset*>* pollsets = nullptr; 100 101 // next pollset to assign a channel to 102 gpr_atm next_pollset_to_assign = 0; 103 104 // Contains config extracted from channel args for this server 105 grpc_core::PosixTcpOptions options; 106 107 // a handler for external connections, owned 108 grpc_core::TcpServerFdHandler* fd_handler = nullptr; 109 110 // used to create slice allocators for endpoints, owned 111 grpc_core::MemoryQuotaRefPtr memory_quota; 112 113 /* used when event engine based servers are enabled */ 114 int n_bind_ports = 0; 115 absl::flat_hash_map<int, std::tuple<int, int>> listen_fd_to_index_map; 116 std::unique_ptr<grpc_event_engine::experimental::EventEngine::Listener> 117 ee_listener = nullptr; 118 /* used to store a pre-allocated FD assigned to a socket */ 119 int pre_allocated_fd; 120 }; 121 122 // If successful, add a listener to \a s for \a addr, set \a dsmode for the 123 // socket, and return the \a listener. 124 grpc_error_handle grpc_tcp_server_add_addr(grpc_tcp_server* s, 125 const grpc_resolved_address* addr, 126 unsigned port_index, 127 unsigned fd_index, 128 grpc_dualstack_mode* dsmode, 129 grpc_tcp_listener** listener); 130 131 // Get all addresses assigned to network interfaces on the machine and create a 132 // listener for each. requested_port is the port to use for every listener, or 0 133 // to select one random port that will be used for every listener. Set *out_port 134 // to the port selected. Return absl::OkStatus() only if all listeners were 135 // added. 136 grpc_error_handle grpc_tcp_server_add_all_local_addrs(grpc_tcp_server* s, 137 unsigned port_index, 138 int requested_port, 139 int* out_port); 140 141 // Prepare a recently-created socket for listening. 142 grpc_error_handle grpc_tcp_server_prepare_socket( 143 grpc_tcp_server*, int fd, const grpc_resolved_address* addr, 144 bool so_reuseport, int* port); 145 // Ruturn true if the platform supports ifaddrs 146 bool grpc_tcp_server_have_ifaddrs(void); 147 148 // Initialize (but don't start) the timer and callback to retry accept4() on a 149 // listening socket after file descriptors have been exhausted. This must be 150 // called when creating a new listener. 151 void grpc_tcp_server_listener_initialize_retry_timer( 152 grpc_tcp_listener* listener); 153 154 #endif // GRPC_SRC_CORE_LIB_IOMGR_TCP_SERVER_UTILS_POSIX_H 155