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 #ifdef GRPC_LINUX_TCP_H
34 #include <linux/tcp.h>
35 #else
36 #include <netinet/tcp.h>
37 #endif
38 #include <stdio.h>
39 #include <string.h>
40 #include <sys/socket.h>
41 #include <sys/types.h>
42 #include <unistd.h>
43 
44 #include <string>
45 
46 #include <grpc/support/alloc.h>
47 #include <grpc/support/log.h>
48 #include <grpc/support/sync.h>
49 
50 #include "src/core/lib/channel/channel_args.h"
51 #include "src/core/lib/gpr/string.h"
52 #include "src/core/lib/iomgr/sockaddr.h"
53 #include "src/core/lib/iomgr/sockaddr_utils.h"
54 
55 /* set a socket to use zerocopy */
grpc_set_socket_zerocopy(int fd)56 grpc_error* grpc_set_socket_zerocopy(int fd) {
57 #ifdef GRPC_LINUX_ERRQUEUE
58   const int enable = 1;
59   auto err = setsockopt(fd, SOL_SOCKET, SO_ZEROCOPY, &enable, sizeof(enable));
60   if (err != 0) {
61     return GRPC_OS_ERROR(errno, "setsockopt(SO_ZEROCOPY)");
62   }
63   return GRPC_ERROR_NONE;
64 #else
65   return GRPC_OS_ERROR(ENOSYS, "setsockopt(SO_ZEROCOPY)");
66 #endif
67 }
68 
69 /* set a socket to non blocking mode */
grpc_set_socket_nonblocking(int fd,int non_blocking)70 grpc_error* grpc_set_socket_nonblocking(int fd, int non_blocking) {
71   int oldflags = fcntl(fd, F_GETFL, 0);
72   if (oldflags < 0) {
73     return GRPC_OS_ERROR(errno, "fcntl");
74   }
75 
76   if (non_blocking) {
77     oldflags |= O_NONBLOCK;
78   } else {
79     oldflags &= ~O_NONBLOCK;
80   }
81 
82   if (fcntl(fd, F_SETFL, oldflags) != 0) {
83     return GRPC_OS_ERROR(errno, "fcntl");
84   }
85 
86   return GRPC_ERROR_NONE;
87 }
88 
grpc_set_socket_no_sigpipe_if_possible(int fd)89 grpc_error* grpc_set_socket_no_sigpipe_if_possible(int fd) {
90 #ifdef GRPC_HAVE_SO_NOSIGPIPE
91   int val = 1;
92   int newval;
93   socklen_t intlen = sizeof(newval);
94   if (0 != setsockopt(fd, SOL_SOCKET, SO_NOSIGPIPE, &val, sizeof(val))) {
95     return GRPC_OS_ERROR(errno, "setsockopt(SO_NOSIGPIPE)");
96   }
97   if (0 != getsockopt(fd, SOL_SOCKET, SO_NOSIGPIPE, &newval, &intlen)) {
98     return GRPC_OS_ERROR(errno, "getsockopt(SO_NOSIGPIPE)");
99   }
100   if ((newval != 0) != (val != 0)) {
101     return GRPC_ERROR_CREATE_FROM_STATIC_STRING("Failed to set SO_NOSIGPIPE");
102   }
103 #else
104   // Avoid unused parameter warning for conditional parameter
105   (void)fd;
106 #endif
107   return GRPC_ERROR_NONE;
108 }
109 
grpc_set_socket_ip_pktinfo_if_possible(int fd)110 grpc_error* grpc_set_socket_ip_pktinfo_if_possible(int fd) {
111   // Use conditionally-important parameter to avoid warning
112   (void)fd;
113 #ifdef GRPC_HAVE_IP_PKTINFO
114   int get_local_ip = 1;
115   if (0 != setsockopt(fd, IPPROTO_IP, IP_PKTINFO, &get_local_ip,
116                       sizeof(get_local_ip))) {
117     return GRPC_OS_ERROR(errno, "setsockopt(IP_PKTINFO)");
118   }
119 #endif
120   return GRPC_ERROR_NONE;
121 }
122 
grpc_set_socket_ipv6_recvpktinfo_if_possible(int fd)123 grpc_error* grpc_set_socket_ipv6_recvpktinfo_if_possible(int fd) {
124   // Use conditionally-important parameter to avoid warning
125   (void)fd;
126 #ifdef GRPC_HAVE_IPV6_RECVPKTINFO
127   int get_local_ip = 1;
128   if (0 != setsockopt(fd, IPPROTO_IPV6, IPV6_RECVPKTINFO, &get_local_ip,
129                       sizeof(get_local_ip))) {
130     return GRPC_OS_ERROR(errno, "setsockopt(IPV6_RECVPKTINFO)");
131   }
132 #endif
133   return GRPC_ERROR_NONE;
134 }
135 
grpc_set_socket_sndbuf(int fd,int buffer_size_bytes)136 grpc_error* grpc_set_socket_sndbuf(int fd, int buffer_size_bytes) {
137   return 0 == setsockopt(fd, SOL_SOCKET, SO_SNDBUF, &buffer_size_bytes,
138                          sizeof(buffer_size_bytes))
139              ? GRPC_ERROR_NONE
140              : GRPC_OS_ERROR(errno, "setsockopt(SO_SNDBUF)");
141 }
142 
grpc_set_socket_rcvbuf(int fd,int buffer_size_bytes)143 grpc_error* grpc_set_socket_rcvbuf(int fd, int buffer_size_bytes) {
144   return 0 == setsockopt(fd, SOL_SOCKET, SO_RCVBUF, &buffer_size_bytes,
145                          sizeof(buffer_size_bytes))
146              ? GRPC_ERROR_NONE
147              : GRPC_OS_ERROR(errno, "setsockopt(SO_RCVBUF)");
148 }
149 
150 /* set a socket to close on exec */
grpc_set_socket_cloexec(int fd,int close_on_exec)151 grpc_error* grpc_set_socket_cloexec(int fd, int close_on_exec) {
152   int oldflags = fcntl(fd, F_GETFD, 0);
153   if (oldflags < 0) {
154     return GRPC_OS_ERROR(errno, "fcntl");
155   }
156 
157   if (close_on_exec) {
158     oldflags |= FD_CLOEXEC;
159   } else {
160     oldflags &= ~FD_CLOEXEC;
161   }
162 
163   if (fcntl(fd, F_SETFD, oldflags) != 0) {
164     return GRPC_OS_ERROR(errno, "fcntl");
165   }
166 
167   return GRPC_ERROR_NONE;
168 }
169 
170 /* set a socket to reuse old addresses */
grpc_set_socket_reuse_addr(int fd,int reuse)171 grpc_error* grpc_set_socket_reuse_addr(int fd, int reuse) {
172   int val = (reuse != 0);
173   int newval;
174   socklen_t intlen = sizeof(newval);
175   if (0 != setsockopt(fd, SOL_SOCKET, SO_REUSEADDR, &val, sizeof(val))) {
176     return GRPC_OS_ERROR(errno, "setsockopt(SO_REUSEADDR)");
177   }
178   if (0 != getsockopt(fd, SOL_SOCKET, SO_REUSEADDR, &newval, &intlen)) {
179     return GRPC_OS_ERROR(errno, "getsockopt(SO_REUSEADDR)");
180   }
181   if ((newval != 0) != val) {
182     return GRPC_ERROR_CREATE_FROM_STATIC_STRING("Failed to set SO_REUSEADDR");
183   }
184 
185   return GRPC_ERROR_NONE;
186 }
187 
188 /* set a socket to reuse old addresses */
grpc_set_socket_reuse_port(int fd,int reuse)189 grpc_error* grpc_set_socket_reuse_port(int fd, int reuse) {
190 #ifndef SO_REUSEPORT
191   return GRPC_ERROR_CREATE_FROM_STATIC_STRING(
192       "SO_REUSEPORT unavailable on compiling system");
193 #else
194   int val = (reuse != 0);
195   int newval;
196   socklen_t intlen = sizeof(newval);
197   if (0 != setsockopt(fd, SOL_SOCKET, SO_REUSEPORT, &val, sizeof(val))) {
198     return GRPC_OS_ERROR(errno, "setsockopt(SO_REUSEPORT)");
199   }
200   if (0 != getsockopt(fd, SOL_SOCKET, SO_REUSEPORT, &newval, &intlen)) {
201     return GRPC_OS_ERROR(errno, "getsockopt(SO_REUSEPORT)");
202   }
203   if ((newval != 0) != val) {
204     return GRPC_ERROR_CREATE_FROM_STATIC_STRING("Failed to set SO_REUSEPORT");
205   }
206 
207   return GRPC_ERROR_NONE;
208 #endif
209 }
210 
211 static gpr_once g_probe_so_reuesport_once = GPR_ONCE_INIT;
212 static int g_support_so_reuseport = false;
213 
probe_so_reuseport_once(void)214 void probe_so_reuseport_once(void) {
215   int s = socket(AF_INET, SOCK_STREAM, 0);
216   if (s < 0) {
217     /* This might be an ipv6-only environment in which case 'socket(AF_INET,..)'
218        call would fail. Try creating IPv6 socket in that case */
219     s = socket(AF_INET6, SOCK_STREAM, 0);
220   }
221   if (s >= 0) {
222     g_support_so_reuseport = GRPC_LOG_IF_ERROR(
223         "check for SO_REUSEPORT", grpc_set_socket_reuse_port(s, 1));
224     close(s);
225   }
226 }
227 
grpc_is_socket_reuse_port_supported()228 bool grpc_is_socket_reuse_port_supported() {
229   gpr_once_init(&g_probe_so_reuesport_once, probe_so_reuseport_once);
230   return g_support_so_reuseport;
231 }
232 
233 /* disable nagle */
grpc_set_socket_low_latency(int fd,int low_latency)234 grpc_error* grpc_set_socket_low_latency(int fd, int low_latency) {
235   int val = (low_latency != 0);
236   int newval;
237   socklen_t intlen = sizeof(newval);
238   if (0 != setsockopt(fd, IPPROTO_TCP, TCP_NODELAY, &val, sizeof(val))) {
239     return GRPC_OS_ERROR(errno, "setsockopt(TCP_NODELAY)");
240   }
241   if (0 != getsockopt(fd, IPPROTO_TCP, TCP_NODELAY, &newval, &intlen)) {
242     return GRPC_OS_ERROR(errno, "getsockopt(TCP_NODELAY)");
243   }
244   if ((newval != 0) != val) {
245     return GRPC_ERROR_CREATE_FROM_STATIC_STRING("Failed to set TCP_NODELAY");
246   }
247   return GRPC_ERROR_NONE;
248 }
249 
250 /* The default values for TCP_USER_TIMEOUT are currently configured to be in
251  * line with the default values of KEEPALIVE_TIMEOUT as proposed in
252  * https://github.com/grpc/proposal/blob/master/A18-tcp-user-timeout.md */
253 #define DEFAULT_CLIENT_TCP_USER_TIMEOUT_MS 20000 /* 20 seconds */
254 #define DEFAULT_SERVER_TCP_USER_TIMEOUT_MS 20000 /* 20 seconds */
255 
256 static int g_default_client_tcp_user_timeout_ms =
257     DEFAULT_CLIENT_TCP_USER_TIMEOUT_MS;
258 static int g_default_server_tcp_user_timeout_ms =
259     DEFAULT_SERVER_TCP_USER_TIMEOUT_MS;
260 static bool g_default_client_tcp_user_timeout_enabled = false;
261 static bool g_default_server_tcp_user_timeout_enabled = true;
262 
263 #if GPR_LINUX == 1
264 // For Linux, it will be detected to support TCP_USER_TIMEOUT
265 #ifndef TCP_USER_TIMEOUT
266 #define TCP_USER_TIMEOUT 18
267 #endif
268 #define SOCKET_SUPPORTS_TCP_USER_TIMEOUT_DEFAULT 0
269 #else
270 // For non-Linux, TCP_USER_TIMEOUT will be used if TCP_USER_TIMEOUT is defined.
271 #ifdef TCP_USER_TIMEOUT
272 #define SOCKET_SUPPORTS_TCP_USER_TIMEOUT_DEFAULT 0
273 #else
274 #define TCP_USER_TIMEOUT 0
275 #define SOCKET_SUPPORTS_TCP_USER_TIMEOUT_DEFAULT -1
276 #endif  // TCP_USER_TIMEOUT
277 #endif  // GPR_LINUX == 1
278 
279 // Whether the socket supports TCP_USER_TIMEOUT option.
280 // (0: don't know, 1: support, -1: not support)
281 static std::atomic<int> g_socket_supports_tcp_user_timeout(
282     SOCKET_SUPPORTS_TCP_USER_TIMEOUT_DEFAULT);
283 
config_default_tcp_user_timeout(bool enable,int timeout,bool is_client)284 void config_default_tcp_user_timeout(bool enable, int timeout, bool is_client) {
285   if (is_client) {
286     g_default_client_tcp_user_timeout_enabled = enable;
287     if (timeout > 0) {
288       g_default_client_tcp_user_timeout_ms = timeout;
289     }
290   } else {
291     g_default_server_tcp_user_timeout_enabled = enable;
292     if (timeout > 0) {
293       g_default_server_tcp_user_timeout_ms = timeout;
294     }
295   }
296 }
297 
298 /* Set TCP_USER_TIMEOUT */
grpc_set_socket_tcp_user_timeout(int fd,const grpc_channel_args * channel_args,bool is_client)299 grpc_error* grpc_set_socket_tcp_user_timeout(
300     int fd, const grpc_channel_args* channel_args, bool is_client) {
301   // Use conditionally-important parameter to avoid warning
302   (void)fd;
303   (void)channel_args;
304   (void)is_client;
305   extern grpc_core::TraceFlag grpc_tcp_trace;
306   if (g_socket_supports_tcp_user_timeout.load() >= 0) {
307     bool enable;
308     int timeout;
309     if (is_client) {
310       enable = g_default_client_tcp_user_timeout_enabled;
311       timeout = g_default_client_tcp_user_timeout_ms;
312     } else {
313       enable = g_default_server_tcp_user_timeout_enabled;
314       timeout = g_default_server_tcp_user_timeout_ms;
315     }
316     if (channel_args) {
317       for (unsigned int i = 0; i < channel_args->num_args; i++) {
318         if (0 ==
319             strcmp(channel_args->args[i].key, GRPC_ARG_KEEPALIVE_TIME_MS)) {
320           const int value = grpc_channel_arg_get_integer(
321               &channel_args->args[i], grpc_integer_options{0, 1, INT_MAX});
322           /* Continue using default if value is 0 */
323           if (value == 0) {
324             continue;
325           }
326           /* Disable if value is INT_MAX */
327           enable = value != INT_MAX;
328         } else if (0 == strcmp(channel_args->args[i].key,
329                                GRPC_ARG_KEEPALIVE_TIMEOUT_MS)) {
330           const int value = grpc_channel_arg_get_integer(
331               &channel_args->args[i], grpc_integer_options{0, 1, INT_MAX});
332           /* Continue using default if value is 0 */
333           if (value == 0) {
334             continue;
335           }
336           timeout = value;
337         }
338       }
339     }
340     if (enable) {
341       int newval;
342       socklen_t len = sizeof(newval);
343       // If this is the first time to use TCP_USER_TIMEOUT, try to check
344       // if it is available.
345       if (g_socket_supports_tcp_user_timeout.load() == 0) {
346         if (0 != getsockopt(fd, IPPROTO_TCP, TCP_USER_TIMEOUT, &newval, &len)) {
347           gpr_log(GPR_INFO,
348                   "TCP_USER_TIMEOUT is not available. TCP_USER_TIMEOUT won't "
349                   "be used thereafter");
350           g_socket_supports_tcp_user_timeout.store(-1);
351         } else {
352           gpr_log(GPR_INFO,
353                   "TCP_USER_TIMEOUT is available. TCP_USER_TIMEOUT will be "
354                   "used thereafter");
355           g_socket_supports_tcp_user_timeout.store(1);
356         }
357       }
358       if (g_socket_supports_tcp_user_timeout.load() > 0) {
359         if (GRPC_TRACE_FLAG_ENABLED(grpc_tcp_trace)) {
360           gpr_log(GPR_INFO, "Enabling TCP_USER_TIMEOUT with a timeout of %d ms",
361                   timeout);
362         }
363         if (0 != setsockopt(fd, IPPROTO_TCP, TCP_USER_TIMEOUT, &timeout,
364                             sizeof(timeout))) {
365           gpr_log(GPR_ERROR, "setsockopt(TCP_USER_TIMEOUT) %s",
366                   strerror(errno));
367           return GRPC_ERROR_NONE;
368         }
369         if (0 != getsockopt(fd, IPPROTO_TCP, TCP_USER_TIMEOUT, &newval, &len)) {
370           gpr_log(GPR_ERROR, "getsockopt(TCP_USER_TIMEOUT) %s",
371                   strerror(errno));
372           return GRPC_ERROR_NONE;
373         }
374         if (newval != timeout) {
375           /* Do not fail on failing to set TCP_USER_TIMEOUT for now. */
376           gpr_log(GPR_ERROR, "Failed to set TCP_USER_TIMEOUT");
377           return GRPC_ERROR_NONE;
378         }
379       }
380     }
381   } else {
382     if (GRPC_TRACE_FLAG_ENABLED(grpc_tcp_trace)) {
383       gpr_log(GPR_INFO, "TCP_USER_TIMEOUT not supported for this platform");
384     }
385   }
386   return GRPC_ERROR_NONE;
387 }
388 
389 /* set a socket using a grpc_socket_mutator */
grpc_set_socket_with_mutator(int fd,grpc_socket_mutator * mutator)390 grpc_error* grpc_set_socket_with_mutator(int fd, grpc_socket_mutator* mutator) {
391   GPR_ASSERT(mutator);
392   if (!grpc_socket_mutator_mutate_fd(mutator, fd)) {
393     return GRPC_ERROR_CREATE_FROM_STATIC_STRING("grpc_socket_mutator failed.");
394   }
395   return GRPC_ERROR_NONE;
396 }
397 
grpc_apply_socket_mutator_in_args(int fd,const grpc_channel_args * args)398 grpc_error* grpc_apply_socket_mutator_in_args(int fd,
399                                               const grpc_channel_args* args) {
400   const grpc_arg* socket_mutator_arg =
401       grpc_channel_args_find(args, GRPC_ARG_SOCKET_MUTATOR);
402   if (socket_mutator_arg == nullptr) {
403     return GRPC_ERROR_NONE;
404   }
405   GPR_DEBUG_ASSERT(socket_mutator_arg->type == GRPC_ARG_POINTER);
406   grpc_socket_mutator* mutator =
407       static_cast<grpc_socket_mutator*>(socket_mutator_arg->value.pointer.p);
408   return grpc_set_socket_with_mutator(fd, mutator);
409 }
410 
411 static gpr_once g_probe_ipv6_once = GPR_ONCE_INIT;
412 static int g_ipv6_loopback_available;
413 
probe_ipv6_once(void)414 static void probe_ipv6_once(void) {
415   int fd = socket(AF_INET6, SOCK_STREAM, 0);
416   g_ipv6_loopback_available = 0;
417   if (fd < 0) {
418     gpr_log(GPR_INFO, "Disabling AF_INET6 sockets because socket() failed.");
419   } else {
420     grpc_sockaddr_in6 addr;
421     memset(&addr, 0, sizeof(addr));
422     addr.sin6_family = AF_INET6;
423     addr.sin6_addr.s6_addr[15] = 1; /* [::1]:0 */
424     if (bind(fd, reinterpret_cast<grpc_sockaddr*>(&addr), sizeof(addr)) == 0) {
425       g_ipv6_loopback_available = 1;
426     } else {
427       gpr_log(GPR_INFO,
428               "Disabling AF_INET6 sockets because ::1 is not available.");
429     }
430     close(fd);
431   }
432 }
433 
grpc_ipv6_loopback_available(void)434 int grpc_ipv6_loopback_available(void) {
435   gpr_once_init(&g_probe_ipv6_once, probe_ipv6_once);
436   return g_ipv6_loopback_available;
437 }
438 
error_for_fd(int fd,const grpc_resolved_address * addr)439 static grpc_error* error_for_fd(int fd, const grpc_resolved_address* addr) {
440   if (fd >= 0) return GRPC_ERROR_NONE;
441   std::string addr_str = grpc_sockaddr_to_string(addr, false);
442   grpc_error* err = grpc_error_set_str(
443       GRPC_OS_ERROR(errno, "socket"), GRPC_ERROR_STR_TARGET_ADDRESS,
444       grpc_slice_from_copied_string(addr_str.c_str()));
445   return err;
446 }
447 
grpc_create_dualstack_socket(const grpc_resolved_address * resolved_addr,int type,int protocol,grpc_dualstack_mode * dsmode,int * newfd)448 grpc_error* grpc_create_dualstack_socket(
449     const grpc_resolved_address* resolved_addr, int type, int protocol,
450     grpc_dualstack_mode* dsmode, int* newfd) {
451   return grpc_create_dualstack_socket_using_factory(
452       nullptr, resolved_addr, type, protocol, dsmode, newfd);
453 }
454 
create_socket(grpc_socket_factory * factory,int domain,int type,int protocol)455 static int create_socket(grpc_socket_factory* factory, int domain, int type,
456                          int protocol) {
457   return (factory != nullptr)
458              ? grpc_socket_factory_socket(factory, domain, type, protocol)
459              : socket(domain, type, protocol);
460 }
461 
grpc_create_dualstack_socket_using_factory(grpc_socket_factory * factory,const grpc_resolved_address * resolved_addr,int type,int protocol,grpc_dualstack_mode * dsmode,int * newfd)462 grpc_error* grpc_create_dualstack_socket_using_factory(
463     grpc_socket_factory* factory, const grpc_resolved_address* resolved_addr,
464     int type, int protocol, grpc_dualstack_mode* dsmode, int* newfd) {
465   const grpc_sockaddr* addr =
466       reinterpret_cast<const grpc_sockaddr*>(resolved_addr->addr);
467   int family = addr->sa_family;
468   if (family == AF_INET6) {
469     if (grpc_ipv6_loopback_available()) {
470       *newfd = create_socket(factory, family, type, protocol);
471     } else {
472       *newfd = -1;
473       errno = EAFNOSUPPORT;
474     }
475     /* Check if we've got a valid dualstack socket. */
476     if (*newfd >= 0 && grpc_set_socket_dualstack(*newfd)) {
477       *dsmode = GRPC_DSMODE_DUALSTACK;
478       return GRPC_ERROR_NONE;
479     }
480     /* If this isn't an IPv4 address, then return whatever we've got. */
481     if (!grpc_sockaddr_is_v4mapped(resolved_addr, nullptr)) {
482       *dsmode = GRPC_DSMODE_IPV6;
483       return error_for_fd(*newfd, resolved_addr);
484     }
485     /* Fall back to AF_INET. */
486     if (*newfd >= 0) {
487       close(*newfd);
488     }
489     family = AF_INET;
490   }
491   *dsmode = family == AF_INET ? GRPC_DSMODE_IPV4 : GRPC_DSMODE_NONE;
492   *newfd = create_socket(factory, family, type, protocol);
493   return error_for_fd(*newfd, resolved_addr);
494 }
495 
grpc_htons(uint16_t hostshort)496 uint16_t grpc_htons(uint16_t hostshort) { return htons(hostshort); }
497 
grpc_ntohs(uint16_t netshort)498 uint16_t grpc_ntohs(uint16_t netshort) { return ntohs(netshort); }
499 
grpc_htonl(uint32_t hostlong)500 uint32_t grpc_htonl(uint32_t hostlong) { return htonl(hostlong); }
501 
grpc_ntohl(uint32_t netlong)502 uint32_t grpc_ntohl(uint32_t netlong) { return ntohl(netlong); }
503 
grpc_inet_pton(int af,const char * src,void * dst)504 int grpc_inet_pton(int af, const char* src, void* dst) {
505   return inet_pton(af, src, dst);
506 }
507 
grpc_inet_ntop(int af,const void * src,char * dst,size_t size)508 const char* grpc_inet_ntop(int af, const void* src, char* dst, size_t size) {
509   GPR_ASSERT(size <= (socklen_t)-1);
510   return inet_ntop(af, src, dst, static_cast<socklen_t>(size));
511 }
512 
513 #endif
514