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_CORE_LIB_IOMGR_TCP_SERVER_UTILS_POSIX_H
20 #define GRPC_CORE_LIB_IOMGR_TCP_SERVER_UTILS_POSIX_H
21 
22 #include <grpc/support/port_platform.h>
23 
24 #include "src/core/lib/iomgr/ev_posix.h"
25 #include "src/core/lib/iomgr/resolve_address.h"
26 #include "src/core/lib/iomgr/socket_utils_posix.h"
27 #include "src/core/lib/iomgr/tcp_server.h"
28 
29 /* one listening port */
30 typedef struct grpc_tcp_listener {
31   int fd;
32   grpc_fd* emfd;
33   grpc_tcp_server* server;
34   grpc_resolved_address addr;
35   int port;
36   unsigned port_index;
37   unsigned fd_index;
38   grpc_closure read_closure;
39   grpc_closure destroyed_closure;
40   struct grpc_tcp_listener* next;
41   /* sibling is a linked list of all listeners for a given port. add_port and
42      clone_port place all new listeners in the same sibling list. A member of
43      the 'sibling' list is also a member of the 'next' list. The head of each
44      sibling list has is_sibling==0, and subsequent members of sibling lists
45      have is_sibling==1. is_sibling allows separate sibling lists to be
46      identified while iterating through 'next'. */
47   struct grpc_tcp_listener* sibling;
48   int is_sibling;
49 } grpc_tcp_listener;
50 
51 /* the overall server */
52 struct grpc_tcp_server {
53   gpr_refcount refs;
54   /* Called whenever accept() succeeds on a server port. */
55   grpc_tcp_server_cb on_accept_cb;
56   void* on_accept_cb_arg;
57 
58   gpr_mu mu;
59 
60   /* active port count: how many ports are actually still listening */
61   size_t active_ports;
62   /* destroyed port count: how many ports are completely destroyed */
63   size_t destroyed_ports;
64 
65   /* is this server shutting down? */
66   bool shutdown;
67   /* have listeners been shutdown? */
68   bool shutdown_listeners;
69   /* use SO_REUSEPORT */
70   bool so_reuseport;
71   /* expand wildcard addresses to a list of all local addresses */
72   bool expand_wildcard_addrs;
73 
74   /* linked list of server ports */
75   grpc_tcp_listener* head;
76   grpc_tcp_listener* tail;
77   unsigned nports;
78 
79   /* List of closures passed to shutdown_starting_add(). */
80   grpc_closure_list shutdown_starting;
81 
82   /* shutdown callback */
83   grpc_closure* shutdown_complete;
84 
85   /* all pollsets interested in new connections */
86   grpc_pollset** pollsets;
87   /* number of pollsets in the pollsets array */
88   size_t pollset_count;
89 
90   /* next pollset to assign a channel to */
91   gpr_atm next_pollset_to_assign;
92 
93   /* channel args for this server */
94   grpc_channel_args* channel_args;
95 
96   /* a handler for external connections, owned */
97   grpc_core::TcpServerFdHandler* fd_handler;
98 };
99 
100 /* If successful, add a listener to \a s for \a addr, set \a dsmode for the
101    socket, and return the \a listener. */
102 grpc_error* grpc_tcp_server_add_addr(grpc_tcp_server* s,
103                                      const grpc_resolved_address* addr,
104                                      unsigned port_index, unsigned fd_index,
105                                      grpc_dualstack_mode* dsmode,
106                                      grpc_tcp_listener** listener);
107 
108 /* Get all addresses assigned to network interfaces on the machine and create a
109    listener for each. requested_port is the port to use for every listener, or 0
110    to select one random port that will be used for every listener. Set *out_port
111    to the port selected. Return GRPC_ERROR_NONE only if all listeners were
112    added. */
113 grpc_error* grpc_tcp_server_add_all_local_addrs(grpc_tcp_server* s,
114                                                 unsigned port_index,
115                                                 int requested_port,
116                                                 int* out_port);
117 
118 /* Prepare a recently-created socket for listening. */
119 grpc_error* grpc_tcp_server_prepare_socket(grpc_tcp_server*, int fd,
120                                            const grpc_resolved_address* addr,
121                                            bool so_reuseport, int* port);
122 /* Ruturn true if the platform supports ifaddrs */
123 bool grpc_tcp_server_have_ifaddrs(void);
124 
125 #endif /* GRPC_CORE_LIB_IOMGR_TCP_SERVER_UTILS_POSIX_H */
126