tcp_client_posix.cc
Go to the documentation of this file.
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 
20 
22 
23 #ifdef GRPC_POSIX_SOCKET_TCP_CLIENT
24 
25 #include <errno.h>
26 #include <netinet/in.h>
27 #include <string.h>
28 #include <unistd.h>
29 
30 #include "absl/container/flat_hash_map.h"
31 #include "absl/strings/str_cat.h"
32 
33 #include <grpc/support/alloc.h>
34 #include <grpc/support/log.h>
35 #include <grpc/support/time.h>
36 
51 
53 
54 struct async_connect {
55  gpr_mu mu;
56  grpc_fd* fd;
57  grpc_timer alarm;
58  grpc_closure on_alarm;
59  int refs;
60  grpc_closure write_closure;
61  grpc_pollset_set* interested_parties;
62  std::string addr_str;
63  grpc_endpoint** ep;
65  grpc_channel_args* channel_args;
66  int64_t connection_handle;
67  bool connect_cancelled;
68 };
69 
70 struct ConnectionShard {
74 };
75 
76 namespace {
77 
78 gpr_once g_tcp_client_posix_init = GPR_ONCE_INIT;
79 std::vector<ConnectionShard>* g_connection_shards = nullptr;
80 std::atomic<int64_t> g_connection_id{1};
81 
82 void do_tcp_client_global_init(void) {
83  size_t num_shards = std::max(2 * gpr_cpu_num_cores(), 1u);
84  g_connection_shards = new std::vector<struct ConnectionShard>(num_shards);
85 }
86 
87 } // namespace
88 
90  gpr_once_init(&g_tcp_client_posix_init, do_tcp_client_global_init);
91 }
92 
93 static grpc_error_handle prepare_socket(const grpc_resolved_address* addr,
94  int fd,
95  const grpc_channel_args* channel_args) {
97 
98  GPR_ASSERT(fd >= 0);
99 
101  if (!GRPC_ERROR_IS_NONE(err)) goto error;
102  err = grpc_set_socket_cloexec(fd, 1);
103  if (!GRPC_ERROR_IS_NONE(err)) goto error;
104  if (!grpc_is_unix_socket(addr)) {
106  if (!GRPC_ERROR_IS_NONE(err)) goto error;
108  if (!GRPC_ERROR_IS_NONE(err)) goto error;
109  err = grpc_set_socket_tcp_user_timeout(fd, channel_args,
110  true /* is_client */);
111  if (!GRPC_ERROR_IS_NONE(err)) goto error;
112  }
114  if (!GRPC_ERROR_IS_NONE(err)) goto error;
115 
117  channel_args);
118  if (!GRPC_ERROR_IS_NONE(err)) goto error;
119 
120  goto done;
121 
122 error:
123  if (fd >= 0) {
124  close(fd);
125  }
126 done:
127  return err;
128 }
129 
130 static void tc_on_alarm(void* acp, grpc_error_handle error) {
131  int done;
132  async_connect* ac = static_cast<async_connect*>(acp);
134  gpr_log(GPR_INFO, "CLIENT_CONNECT: %s: on_alarm: error=%s",
135  ac->addr_str.c_str(), grpc_error_std_string(error).c_str());
136  }
137  gpr_mu_lock(&ac->mu);
138  if (ac->fd != nullptr) {
140  ac->fd, GRPC_ERROR_CREATE_FROM_STATIC_STRING("connect() timed out"));
141  }
142  done = (--ac->refs == 0);
143  gpr_mu_unlock(&ac->mu);
144  if (done) {
145  gpr_mu_destroy(&ac->mu);
146  grpc_channel_args_destroy(ac->channel_args);
147  delete ac;
148  }
149 }
150 
152  grpc_fd* fd, const grpc_channel_args* channel_args,
153  absl::string_view addr_str) {
154  return grpc_tcp_create(fd, channel_args, addr_str);
155 }
156 
157 static void on_writable(void* acp, grpc_error_handle error) {
158  async_connect* ac = static_cast<async_connect*>(acp);
159  int so_error = 0;
160  socklen_t so_error_size;
161  int err;
162  int done;
163  grpc_endpoint** ep = ac->ep;
164  grpc_closure* closure = ac->closure;
165  std::string addr_str = ac->addr_str;
166  grpc_fd* fd;
167 
168  (void)GRPC_ERROR_REF(error);
169 
171  gpr_log(GPR_INFO, "CLIENT_CONNECT: %s: on_writable: error=%s",
172  ac->addr_str.c_str(), grpc_error_std_string(error).c_str());
173  }
174 
175  gpr_mu_lock(&ac->mu);
176  GPR_ASSERT(ac->fd);
177  fd = ac->fd;
178  ac->fd = nullptr;
179  bool connect_cancelled = ac->connect_cancelled;
180  gpr_mu_unlock(&ac->mu);
181 
182  grpc_timer_cancel(&ac->alarm);
183 
184  gpr_mu_lock(&ac->mu);
185  if (!GRPC_ERROR_IS_NONE(error)) {
186  error =
187  grpc_error_set_str(error, GRPC_ERROR_STR_OS_ERROR, "Timeout occurred");
188  goto finish;
189  }
190 
191  if (connect_cancelled) {
192  // The callback should not get scheduled in this case.
194  goto finish;
195  }
196 
197  do {
198  so_error_size = sizeof(so_error);
199  err = getsockopt(grpc_fd_wrapped_fd(fd), SOL_SOCKET, SO_ERROR, &so_error,
200  &so_error_size);
201  } while (err < 0 && errno == EINTR);
202  if (err < 0) {
203  error = GRPC_OS_ERROR(errno, "getsockopt");
204  goto finish;
205  }
206 
207  switch (so_error) {
208  case 0:
209  grpc_pollset_set_del_fd(ac->interested_parties, fd);
210  *ep = grpc_tcp_client_create_from_fd(fd, ac->channel_args, ac->addr_str);
211  fd = nullptr;
212  break;
213  case ENOBUFS:
214  /* We will get one of these errors if we have run out of
215  memory in the kernel for the data structures allocated
216  when you connect a socket. If this happens it is very
217  likely that if we wait a little bit then try again the
218  connection will work (since other programs or this
219  program will close their network connections and free up
220  memory). This does _not_ indicate that there is anything
221  wrong with the server we are connecting to, this is a
222  local problem.
223 
224  If you are looking at this code, then chances are that
225  your program or another program on the same computer
226  opened too many network connections. The "easy" fix:
227  don't do that! */
228  gpr_log(GPR_ERROR, "kernel out of buffers");
229  gpr_mu_unlock(&ac->mu);
230  grpc_fd_notify_on_write(fd, &ac->write_closure);
231  return;
232  case ECONNREFUSED:
233  /* This error shouldn't happen for anything other than connect(). */
234  error = GRPC_OS_ERROR(so_error, "connect");
235  break;
236  default:
237  /* We don't really know which syscall triggered the problem here,
238  so punt by reporting getsockopt(). */
239  error = GRPC_OS_ERROR(so_error, "getsockopt(SO_ERROR)");
240  break;
241  }
242 
243 finish:
244  if (!connect_cancelled) {
245  int shard_number = ac->connection_handle % (*g_connection_shards).size();
246  struct ConnectionShard* shard = &(*g_connection_shards)[shard_number];
247  {
248  grpc_core::MutexLock lock(&shard->mu);
249  shard->pending_connections.erase(ac->connection_handle);
250  }
251  }
252  if (fd != nullptr) {
253  grpc_pollset_set_del_fd(ac->interested_parties, fd);
254  grpc_fd_orphan(fd, nullptr, nullptr, "tcp_client_orphan");
255  fd = nullptr;
256  }
257  done = (--ac->refs == 0);
258  gpr_mu_unlock(&ac->mu);
259  if (!GRPC_ERROR_IS_NONE(error)) {
262  GPR_ASSERT(ret);
264  absl::StrCat("Failed to connect to remote host: ", str);
267  }
268  if (done) {
269  // This is safe even outside the lock, because "done", the sentinel, is
270  // populated *inside* the lock.
271  gpr_mu_destroy(&ac->mu);
272  grpc_channel_args_destroy(ac->channel_args);
273  delete ac;
274  }
275  // Push async connect closure to the executor since this may actually be
276  // called during the shutdown process, in which case a deadlock could form
277  // between the core shutdown mu and the connector mu (b/188239051)
278  if (!connect_cancelled) {
280  } else if (!GRPC_ERROR_IS_NONE(error)) {
281  // Unref the error here because it is not used.
282  (void)GRPC_ERROR_UNREF(error);
283  }
284 }
285 
287  const grpc_channel_args* channel_args, const grpc_resolved_address* addr,
288  grpc_resolved_address* mapped_addr, int* fd) {
289  grpc_dualstack_mode dsmode;
291  *fd = -1;
292  /* Use dualstack sockets where available. Set mapped to v6 or v4 mapped to
293  v6. */
294  if (!grpc_sockaddr_to_v4mapped(addr, mapped_addr)) {
295  /* addr is v4 mapped to v6 or v6. */
296  memcpy(mapped_addr, addr, sizeof(*mapped_addr));
297  }
298  error =
299  grpc_create_dualstack_socket(mapped_addr, SOCK_STREAM, 0, &dsmode, fd);
300  if (!GRPC_ERROR_IS_NONE(error)) {
301  return error;
302  }
303  if (dsmode == GRPC_DSMODE_IPV4) {
304  /* Original addr is either v4 or v4 mapped to v6. Set mapped_addr to v4. */
305  if (!grpc_sockaddr_is_v4mapped(addr, mapped_addr)) {
306  memcpy(mapped_addr, addr, sizeof(*mapped_addr));
307  }
308  }
309  if ((error = prepare_socket(mapped_addr, *fd, channel_args)) !=
310  GRPC_ERROR_NONE) {
311  return error;
312  }
313  return GRPC_ERROR_NONE;
314 }
315 
317  grpc_pollset_set* interested_parties, grpc_closure* closure, const int fd,
318  const grpc_channel_args* channel_args, const grpc_resolved_address* addr,
319  grpc_core::Timestamp deadline, grpc_endpoint** ep) {
320  int err;
321  do {
322  err = connect(fd, reinterpret_cast<const grpc_sockaddr*>(addr->addr),
323  addr->len);
324  } while (err < 0 && errno == EINTR);
325 
326  auto addr_uri = grpc_sockaddr_to_uri(addr);
327  if (!addr_uri.ok()) {
329  GRPC_ERROR_CREATE_FROM_CPP_STRING(addr_uri.status().ToString());
331  return 0;
332  }
333 
334  std::string name = absl::StrCat("tcp-client:", addr_uri.value());
335  grpc_fd* fdobj = grpc_fd_create(fd, name.c_str(), true);
336  int64_t connection_id = 0;
337  if (errno == EWOULDBLOCK || errno == EINPROGRESS) {
338  // Connection is still in progress.
339  connection_id = g_connection_id.fetch_add(1, std::memory_order_acq_rel);
340  }
341 
342  if (err >= 0) {
343  // Connection already succeded. Return 0 to discourage any cancellation
344  // attempts.
345  *ep = grpc_tcp_client_create_from_fd(fdobj, channel_args, addr_uri.value());
347  return 0;
348  }
349  if (errno != EWOULDBLOCK && errno != EINPROGRESS) {
350  // Connection already failed. Return 0 to discourage any cancellation
351  // attempts.
352  grpc_error_handle error = GRPC_OS_ERROR(errno, "connect");
354  addr_uri.value());
355  grpc_fd_orphan(fdobj, nullptr, nullptr, "tcp_client_connect_error");
357  return 0;
358  }
359 
360  grpc_pollset_set_add_fd(interested_parties, fdobj);
361 
362  async_connect* ac = new async_connect();
363  ac->closure = closure;
364  ac->ep = ep;
365  ac->fd = fdobj;
366  ac->interested_parties = interested_parties;
367  ac->addr_str = addr_uri.value();
368  ac->connection_handle = connection_id;
369  ac->connect_cancelled = false;
370  gpr_mu_init(&ac->mu);
371  ac->refs = 2;
372  GRPC_CLOSURE_INIT(&ac->write_closure, on_writable, ac,
373  grpc_schedule_on_exec_ctx);
374  ac->channel_args = grpc_channel_args_copy(channel_args);
375 
377  gpr_log(GPR_INFO, "CLIENT_CONNECT: %s: asynchronously connecting fd %p",
378  ac->addr_str.c_str(), fdobj);
379  }
380 
381  int shard_number = connection_id % (*g_connection_shards).size();
382  struct ConnectionShard* shard = &(*g_connection_shards)[shard_number];
383  {
384  grpc_core::MutexLock lock(&shard->mu);
385  shard->pending_connections.insert_or_assign(connection_id, ac);
386  }
387 
388  gpr_mu_lock(&ac->mu);
389  GRPC_CLOSURE_INIT(&ac->on_alarm, tc_on_alarm, ac, grpc_schedule_on_exec_ctx);
390  grpc_timer_init(&ac->alarm, deadline, &ac->on_alarm);
391  grpc_fd_notify_on_write(ac->fd, &ac->write_closure);
392  gpr_mu_unlock(&ac->mu);
393  return connection_id;
394 }
395 
397  grpc_pollset_set* interested_parties,
398  const grpc_channel_args* channel_args,
400  grpc_core::Timestamp deadline) {
401  grpc_resolved_address mapped_addr;
402  int fd = -1;
404  *ep = nullptr;
405  if ((error = grpc_tcp_client_prepare_fd(channel_args, addr, &mapped_addr,
406  &fd)) != GRPC_ERROR_NONE) {
408  return 0;
409  }
410  return grpc_tcp_client_create_from_prepared_fd(interested_parties, closure,
411  fd, channel_args, &mapped_addr,
412  deadline, ep);
413 }
414 
415 static bool tcp_cancel_connect(int64_t connection_handle) {
416  if (connection_handle <= 0) {
417  return false;
418  }
419  int shard_number = connection_handle % (*g_connection_shards).size();
420  struct ConnectionShard* shard = &(*g_connection_shards)[shard_number];
421  async_connect* ac = nullptr;
422  {
423  grpc_core::MutexLock lock(&shard->mu);
424  auto it = shard->pending_connections.find(connection_handle);
425  if (it != shard->pending_connections.end()) {
426  ac = it->second;
427  GPR_ASSERT(ac != nullptr);
428  // Trying to acquire ac->mu here would could cause a deadlock because
429  // the on_writable method tries to acquire the two mutexes used
430  // here in the reverse order. But we dont need to acquire ac->mu before
431  // incrementing ac->refs here. This is because the on_writable
432  // method decrements ac->refs only after deleting the connection handle
433  // from the corresponding hashmap. If the code enters here, it means that
434  // deletion hasn't happened yet. The deletion can only happen after the
435  // corresponding g_shard_mu is unlocked.
436  ++ac->refs;
437  // Remove connection from list of active connections.
438  shard->pending_connections.erase(it);
439  }
440  }
441  if (ac == nullptr) {
442  return false;
443  }
444  gpr_mu_lock(&ac->mu);
445  bool connection_cancel_success = (ac->fd != nullptr);
446  if (connection_cancel_success) {
447  // Connection is still pending. The on_writable callback hasn't executed
448  // yet because ac->fd != nullptr.
449  ac->connect_cancelled = true;
450  // Shutdown the fd. This would cause on_writable to run as soon as possible.
451  // We dont need to pass a custom error here because it wont be used since
452  // the on_connect_closure is not run if connect cancellation is successfull.
454  }
455  bool done = (--ac->refs == 0);
456  gpr_mu_unlock(&ac->mu);
457  if (done) {
458  // This is safe even outside the lock, because "done", the sentinel, is
459  // populated *inside* the lock.
460  gpr_mu_destroy(&ac->mu);
461  grpc_channel_args_destroy(ac->channel_args);
462  delete ac;
463  }
464  return connection_cancel_success;
465 }
466 
467 grpc_tcp_client_vtable grpc_posix_tcp_client_vtable = {tcp_connect,
468  tcp_cancel_connect};
469 #endif
GRPC_CLOSURE_INIT
#define GRPC_CLOSURE_INIT(closure, cb, cb_arg, scheduler)
Definition: closure.h:115
grpc_set_socket_reuse_addr
grpc_error_handle grpc_set_socket_reuse_addr(int fd, int reuse)
xds_interop_client.str
str
Definition: xds_interop_client.py:487
gpr_cpu_num_cores
GPRAPI unsigned gpr_cpu_num_cores(void)
GPR_INFO
#define GPR_INFO
Definition: include/grpc/impl/codegen/log.h:56
grpc_pollset_set_del_fd
void grpc_pollset_set_del_fd(grpc_pollset_set *pollset_set, grpc_fd *fd)
gpr_mu_unlock
GPRAPI void gpr_mu_unlock(gpr_mu *mu)
regen-readme.it
it
Definition: regen-readme.py:15
GRPC_ERROR_NONE
#define GRPC_ERROR_NONE
Definition: error.h:234
log.h
sockaddr_utils.h
absl::StrCat
std::string StrCat(const AlphaNum &a, const AlphaNum &b)
Definition: abseil-cpp/absl/strings/str_cat.cc:98
grpc_set_socket_low_latency
grpc_error_handle grpc_set_socket_low_latency(int fd, int low_latency)
finish
static int finish(struct hexdump_ctx *ctx)
Definition: hexdump.c:148
gpr_once
pthread_once_t gpr_once
Definition: impl/codegen/sync_posix.h:50
iomgr_internal.h
tcp_client_posix.h
setup.description
description
Definition: setup.py:544
grpc_fd_shutdown
void grpc_fd_shutdown(grpc_fd *fd, grpc_error_handle why)
grpc_core::MutexLock
Definition: src/core/lib/gprpp/sync.h:88
grpc_pollset_set
struct grpc_pollset_set grpc_pollset_set
Definition: iomgr_fwd.h:23
string.h
absl::string_view
Definition: abseil-cpp/absl/strings/string_view.h:167
grpc_core::Timestamp
Definition: src/core/lib/gprpp/time.h:62
grpc_set_socket_no_sigpipe_if_possible
grpc_error_handle grpc_set_socket_no_sigpipe_if_possible(int fd)
testing::internal::string
::std::string string
Definition: bloaty/third_party/protobuf/third_party/googletest/googletest/include/gtest/internal/gtest-port.h:881
error
grpc_error_handle error
Definition: retry_filter.cc:499
error_ref_leak.err
err
Definition: error_ref_leak.py:35
grpc_resolved_address
Definition: resolved_address.h:34
u
OPENSSL_EXPORT pem_password_cb void * u
Definition: pem.h:351
ABSL_GUARDED_BY
#define ABSL_GUARDED_BY(x)
Definition: abseil-cpp/absl/base/thread_annotations.h:62
GPR_ONCE_INIT
#define GPR_ONCE_INIT
Definition: impl/codegen/sync_posix.h:52
setup.name
name
Definition: setup.py:542
time.h
grpc_timer
Definition: iomgr/timer.h:33
sockaddr.h
GRPC_ERROR_STR_DESCRIPTION
@ GRPC_ERROR_STR_DESCRIPTION
top-level textual description of this error
Definition: error.h:106
grpc_channel_args
Definition: grpc_types.h:132
GRPC_TRACE_FLAG_ENABLED
#define GRPC_TRACE_FLAG_ENABLED(f)
Definition: debug/trace.h:114
grpc_core::Executor::Run
static void Run(grpc_closure *closure, grpc_error_handle error, ExecutorType executor_type=ExecutorType::DEFAULT, ExecutorJobType job_type=ExecutorJobType::SHORT)
Definition: executor.cc:398
grpc_is_unix_socket
int grpc_is_unix_socket(const grpc_resolved_address *resolved_addr)
Definition: unix_sockets_posix_noop.cc:46
grpc_tcp_client_create_from_fd
grpc_endpoint * grpc_tcp_client_create_from_fd(grpc_fd *fd, const grpc_channel_args *channel_args, absl::string_view addr_str)
grpc_error_set_str
grpc_error_handle grpc_error_set_str(grpc_error_handle src, grpc_error_strs which, absl::string_view str)
Definition: error.cc:650
gpr_once_init
GPRAPI void gpr_once_init(gpr_once *once, void(*init_function)(void))
GRPC_ERROR_STR_TARGET_ADDRESS
@ GRPC_ERROR_STR_TARGET_ADDRESS
peer that we were trying to communicate when this error occurred
Definition: error.h:117
grpc_tcp_client_create_from_prepared_fd
int64_t grpc_tcp_client_create_from_prepared_fd(grpc_pollset_set *interested_parties, grpc_closure *closure, const int fd, const grpc_channel_args *channel_args, const grpc_resolved_address *addr, grpc_core::Timestamp deadline, grpc_endpoint **ep)
gpr_mu_destroy
GPRAPI void gpr_mu_destroy(gpr_mu *mu)
grpc_tcp_trace
grpc_core::TraceFlag grpc_tcp_trace(false, "tcp")
DEBUG_LOCATION
#define DEBUG_LOCATION
Definition: debug_location.h:41
memcpy
memcpy(mem, inblock.get(), min(CONTAINING_RECORD(inblock.get(), MEMBLOCK, data) ->size, size))
refs
std::vector< CordRep * > refs
Definition: cordz_info_statistics_test.cc:81
grpc_set_socket_cloexec
grpc_error_handle grpc_set_socket_cloexec(int fd, int close_on_exec)
GRPC_OS_ERROR
#define GRPC_OS_ERROR(err, call_name)
create an error associated with errno!=0 (an 'operating system' error)
Definition: error.h:352
GPR_ASSERT
#define GPR_ASSERT(x)
Definition: include/grpc/impl/codegen/log.h:94
int64_t
signed __int64 int64_t
Definition: stdint-msvc2008.h:89
gen_stats_data.c_str
def c_str(s, encoding='ascii')
Definition: gen_stats_data.py:38
ev_posix.h
max
int max
Definition: bloaty/third_party/zlib/examples/enough.c:170
grpc_fd
struct grpc_fd grpc_fd
Definition: ev_posix.h:44
mu
Mutex mu
Definition: server_config_selector_filter.cc:74
gpr_log
GPRAPI void gpr_log(const char *file, int line, gpr_log_severity severity, const char *format,...) GPR_PRINT_FORMAT_CHECK(4
gpr_mu_init
GPRAPI void gpr_mu_init(gpr_mu *mu)
grpc_fd_create
grpc_fd * grpc_fd_create(int fd, const char *name, bool track_err)
closure
grpc_closure closure
Definition: src/core/lib/surface/server.cc:466
tcp_posix.h
grpc_tcp_create
grpc_endpoint * grpc_tcp_create(grpc_fd *fd, const grpc_channel_args *args, absl::string_view peer_string)
done
struct tab * done
Definition: bloaty/third_party/zlib/examples/enough.c:176
grpc_fd_notify_on_write
void grpc_fd_notify_on_write(grpc_fd *fd, grpc_closure *closure)
grpc_channel_args_destroy
void grpc_channel_args_destroy(grpc_channel_args *a)
Definition: channel_args.cc:360
close
#define close
Definition: test-fs.c:48
grpc_channel_args_copy
grpc_channel_args * grpc_channel_args_copy(const grpc_channel_args *src)
Definition: channel_args.cc:285
gpr_mu_lock
GPRAPI void gpr_mu_lock(gpr_mu *mu)
slice_internal.h
GPR_ERROR
#define GPR_ERROR
Definition: include/grpc/impl/codegen/log.h:57
grpc_create_dualstack_socket
grpc_error_handle grpc_create_dualstack_socket(const grpc_resolved_address *addr, int type, int protocol, grpc_dualstack_mode *dsmode, int *newfd)
grpc_sockaddr_to_v4mapped
int grpc_sockaddr_to_v4mapped(const grpc_resolved_address *resolved_addr, grpc_resolved_address *resolved_addr6_out)
Definition: sockaddr_utils.cc:111
executor.h
GRPC_ERROR_CREATE_FROM_STATIC_STRING
#define GRPC_ERROR_CREATE_FROM_STATIC_STRING(desc)
Definition: error.h:291
grpc_core::TraceFlag
Definition: debug/trace.h:63
GRPC_ERROR_STR_OS_ERROR
@ GRPC_ERROR_STR_OS_ERROR
operating system description of this error
Definition: error.h:111
unix_sockets_posix.h
grpc_tcp_client_prepare_fd
grpc_error_handle grpc_tcp_client_prepare_fd(const grpc_channel_args *channel_args, const grpc_resolved_address *addr, grpc_resolved_address *mapped_addr, int *fd)
grpc_timer_cancel
void grpc_timer_cancel(grpc_timer *timer)
Definition: iomgr/timer.cc:36
grpc_core::Mutex
Definition: src/core/lib/gprpp/sync.h:61
GRPC_ERROR_REF
#define GRPC_ERROR_REF(err)
Definition: error.h:261
gpr_mu
pthread_mutex_t gpr_mu
Definition: impl/codegen/sync_posix.h:47
GRPC_DSMODE_IPV4
@ GRPC_DSMODE_IPV4
Definition: socket_utils_posix.h:120
port.h
grpc_error_std_string
std::string grpc_error_std_string(grpc_error_handle error)
Definition: error.cc:944
ret
UniquePtr< SSL_SESSION > ret
Definition: ssl_x509.cc:1029
GRPC_ERROR_CREATE_FROM_CPP_STRING
#define GRPC_ERROR_CREATE_FROM_CPP_STRING(desc)
Definition: error.h:297
alloc.h
absl::flat_hash_map
Definition: abseil-cpp/absl/container/flat_hash_map.h:113
socket_utils_posix.h
GRPC_FD_CLIENT_CONNECTION_USAGE
@ GRPC_FD_CLIENT_CONNECTION_USAGE
Definition: socket_mutator.h:32
grpc_pollset_set_add_fd
void grpc_pollset_set_add_fd(grpc_pollset_set *pollset_set, grpc_fd *fd)
grpc_timer_init
void grpc_timer_init(grpc_timer *timer, grpc_core::Timestamp deadline, grpc_closure *closure)
Definition: iomgr/timer.cc:31
closure
Definition: proxy.cc:59
GRPC_ERROR_UNREF
#define GRPC_ERROR_UNREF(err)
Definition: error.h:262
grpc_core::ExecCtx::Run
static void Run(const DebugLocation &location, grpc_closure *closure, grpc_error_handle error)
Definition: exec_ctx.cc:98
grpc_dualstack_mode
grpc_dualstack_mode
Definition: socket_utils_posix.h:116
channel_args.h
timer.h
grpc_fd_orphan
void grpc_fd_orphan(grpc_fd *fd, grpc_closure *on_done, int *release_fd, const char *reason)
grpc_tcp_client_global_init
void grpc_tcp_client_global_init()
grpc_tcp_client_vtable
Definition: tcp_client.h:32
grpc_error_get_str
bool grpc_error_get_str(grpc_error_handle err, grpc_error_strs which, std::string *s)
Returns false if the specified string is not set.
Definition: error.cc:659
grpc_set_socket_nonblocking
grpc_error_handle grpc_set_socket_nonblocking(int fd, int non_blocking)
grpc_error
Definition: error_internal.h:42
grpc_set_socket_tcp_user_timeout
grpc_error_handle grpc_set_socket_tcp_user_timeout(int fd, const grpc_channel_args *channel_args, bool is_client)
socket_mutator.h
grpc_sockaddr_is_v4mapped
int grpc_sockaddr_is_v4mapped(const grpc_resolved_address *resolved_addr, grpc_resolved_address *resolved_addr4_out)
Definition: sockaddr_utils.cc:81
grpc_apply_socket_mutator_in_args
grpc_error_handle grpc_apply_socket_mutator_in_args(int fd, grpc_fd_usage usage, const grpc_channel_args *args)
grpc_closure
Definition: closure.h:56
grpc_sockaddr_to_uri
absl::StatusOr< std::string > grpc_sockaddr_to_uri(const grpc_resolved_address *resolved_addr)
Definition: sockaddr_utils.cc:260
grpc_endpoint
Definition: endpoint.h:105
addr
struct sockaddr_in addr
Definition: libuv/docs/code/tcp-echo-server/main.c:10
errno.h
tcp_connect
Definition: tcp_connect.py:1
grpc_fd_wrapped_fd
int grpc_fd_wrapped_fd(grpc_fd *fd)
GRPC_ERROR_IS_NONE
#define GRPC_ERROR_IS_NONE(err)
Definition: error.h:241
port_platform.h


grpc
Author(s):
autogenerated on Thu Mar 13 2025 03:01:29