static grpc_error *init_settings_frame_parser(grpc_exec_ctx *exec_ctx, grpc_chttp2_transport *t) { if (t->incoming_stream_id != 0) { return GRPC_ERROR_CREATE_FROM_STATIC_STRING( "Settings frame received for grpc_chttp2_stream"); } grpc_error *err = grpc_chttp2_settings_parser_begin_frame( &t->simple.settings, t->incoming_frame_size, t->incoming_frame_flags, t->settings[GRPC_PEER_SETTINGS]); if (err != GRPC_ERROR_NONE) { return err; } if (t->incoming_frame_flags & GRPC_CHTTP2_FLAG_ACK) { memcpy(t->settings[GRPC_ACKED_SETTINGS], t->settings[GRPC_SENT_SETTINGS], GRPC_CHTTP2_NUM_SETTINGS * sizeof(uint32_t)); grpc_chttp2_hptbl_set_max_bytes( exec_ctx, &t->hpack_parser.table, t->settings[GRPC_ACKED_SETTINGS] [GRPC_CHTTP2_SETTINGS_HEADER_TABLE_SIZE]); t->sent_local_settings = 0; } t->parser = grpc_chttp2_settings_parser_parse; t->parser_data = &t->simple.settings; return GRPC_ERROR_NONE; }
static grpc_error *init_frame_parser(grpc_exec_ctx *exec_ctx, grpc_chttp2_transport *t) { if (t->is_first_frame && t->incoming_frame_type != GRPC_CHTTP2_FRAME_SETTINGS) { char *msg; gpr_asprintf( &msg, "Expected SETTINGS frame as the first frame, got frame type %d", t->incoming_frame_type); grpc_error *err = GRPC_ERROR_CREATE_FROM_COPIED_STRING(msg); gpr_free(msg); return err; } t->is_first_frame = false; if (t->expect_continuation_stream_id != 0) { if (t->incoming_frame_type != GRPC_CHTTP2_FRAME_CONTINUATION) { char *msg; gpr_asprintf(&msg, "Expected CONTINUATION frame, got frame type %02x", t->incoming_frame_type); grpc_error *err = GRPC_ERROR_CREATE_FROM_COPIED_STRING(msg); gpr_free(msg); return err; } if (t->expect_continuation_stream_id != t->incoming_stream_id) { char *msg; gpr_asprintf( &msg, "Expected CONTINUATION frame for grpc_chttp2_stream %08x, got " "grpc_chttp2_stream %08x", t->expect_continuation_stream_id, t->incoming_stream_id); grpc_error *err = GRPC_ERROR_CREATE_FROM_COPIED_STRING(msg); gpr_free(msg); return err; } return init_header_frame_parser(exec_ctx, t, 1); } switch (t->incoming_frame_type) { case GRPC_CHTTP2_FRAME_DATA: return init_data_frame_parser(exec_ctx, t); case GRPC_CHTTP2_FRAME_HEADER: return init_header_frame_parser(exec_ctx, t, 0); case GRPC_CHTTP2_FRAME_CONTINUATION: return GRPC_ERROR_CREATE_FROM_STATIC_STRING( "Unexpected CONTINUATION frame"); case GRPC_CHTTP2_FRAME_RST_STREAM: return init_rst_stream_parser(exec_ctx, t); case GRPC_CHTTP2_FRAME_SETTINGS: return init_settings_frame_parser(exec_ctx, t); case GRPC_CHTTP2_FRAME_WINDOW_UPDATE: return init_window_update_frame_parser(exec_ctx, t); case GRPC_CHTTP2_FRAME_PING: return init_ping_parser(exec_ctx, t); case GRPC_CHTTP2_FRAME_GOAWAY: return init_goaway_parser(exec_ctx, t); default: if (grpc_http_trace) { gpr_log(GPR_ERROR, "Unknown frame type %02x", t->incoming_frame_type); } return init_skip_frame_parser(exec_ctx, t, 0); } }
static void add_error(grpc_error **combined, grpc_error *error) { if (error == GRPC_ERROR_NONE) return; if (*combined == GRPC_ERROR_NONE) { *combined = GRPC_ERROR_CREATE_FROM_STATIC_STRING( "Client auth metadata plugin error"); } *combined = grpc_error_add_child(*combined, error); }
static void fail_handshaker_do_handshake(grpc_exec_ctx *exec_ctx, grpc_handshaker *handshaker, grpc_tcp_server_acceptor *acceptor, grpc_closure *on_handshake_done, grpc_handshaker_args *args) { GRPC_CLOSURE_SCHED(exec_ctx, on_handshake_done, GRPC_ERROR_CREATE_FROM_STATIC_STRING( "Failed to create security handshaker")); }
void grpc_chttp2_data_parser_destroy(grpc_exec_ctx *exec_ctx, grpc_chttp2_data_parser *parser) { if (parser->parsing_frame != NULL) { GRPC_ERROR_UNREF(grpc_chttp2_incoming_byte_stream_finished( exec_ctx, parser->parsing_frame, GRPC_ERROR_CREATE_FROM_STATIC_STRING("Parser destroyed"), false)); } GRPC_ERROR_UNREF(parser->error); }
static void send_security_metadata(grpc_exec_ctx *exec_ctx, grpc_call_element *elem, grpc_transport_stream_op_batch *batch) { call_data *calld = elem->call_data; channel_data *chand = elem->channel_data; grpc_client_security_context *ctx = (grpc_client_security_context *)batch->payload ->context[GRPC_CONTEXT_SECURITY] .value; grpc_call_credentials *channel_call_creds = chand->security_connector->request_metadata_creds; int call_creds_has_md = (ctx != NULL) && (ctx->creds != NULL); if (channel_call_creds == NULL && !call_creds_has_md) { /* Skip sending metadata altogether. */ grpc_call_next_op(exec_ctx, elem, batch); return; } if (channel_call_creds != NULL && call_creds_has_md) { calld->creds = grpc_composite_call_credentials_create(channel_call_creds, ctx->creds, NULL); if (calld->creds == NULL) { grpc_transport_stream_op_batch_finish_with_failure( exec_ctx, batch, grpc_error_set_int( GRPC_ERROR_CREATE_FROM_STATIC_STRING( "Incompatible credentials set on channel and call."), GRPC_ERROR_INT_GRPC_STATUS, GRPC_STATUS_UNAUTHENTICATED)); return; } } else { calld->creds = grpc_call_credentials_ref( call_creds_has_md ? ctx->creds : channel_call_creds); } build_auth_metadata_context(&chand->security_connector->base, chand->auth_context, calld); grpc_error *cancel_error = set_cancel_func(elem, cancel_get_request_metadata); if (cancel_error != GRPC_ERROR_NONE) { grpc_transport_stream_op_batch_finish_with_failure(exec_ctx, batch, cancel_error); return; } GPR_ASSERT(calld->pollent != NULL); GRPC_CLOSURE_INIT(&calld->closure, on_credentials_metadata, batch, grpc_schedule_on_exec_ctx); grpc_error *error = GRPC_ERROR_NONE; if (grpc_call_credentials_get_request_metadata( exec_ctx, calld->creds, calld->pollent, calld->auth_md_context, &calld->md_array, &calld->closure, &error)) { // Synchronous return; invoke on_credentials_metadata() directly. on_credentials_metadata(exec_ctx, batch, error); GRPC_ERROR_UNREF(error); } }
static void on_trailing_header(grpc_exec_ctx *exec_ctx, void *tp, grpc_mdelem md) { grpc_chttp2_transport *t = (grpc_chttp2_transport *)tp; grpc_chttp2_stream *s = t->incoming_stream; GPR_TIMER_BEGIN("on_trailing_header", 0); GPR_ASSERT(s != NULL); if (GRPC_TRACER_ON(grpc_http_trace)) { char *key = grpc_slice_to_c_string(GRPC_MDKEY(md)); char *value = grpc_dump_slice(GRPC_MDVALUE(md), GPR_DUMP_HEX | GPR_DUMP_ASCII); gpr_log(GPR_INFO, "HTTP:%d:TRL:%s: %s: %s", s->id, t->is_client ? "CLI" : "SVR", key, value); gpr_free(key); gpr_free(value); } if (grpc_slice_eq(GRPC_MDKEY(md), GRPC_MDSTR_GRPC_STATUS) && !grpc_mdelem_eq(md, GRPC_MDELEM_GRPC_STATUS_0)) { /* TODO(ctiller): check for a status like " 0" */ s->seen_error = true; } const size_t new_size = s->metadata_buffer[1].size + GRPC_MDELEM_LENGTH(md); const size_t metadata_size_limit = t->settings[GRPC_ACKED_SETTINGS] [GRPC_CHTTP2_SETTINGS_MAX_HEADER_LIST_SIZE]; if (new_size > metadata_size_limit) { gpr_log(GPR_DEBUG, "received trailing metadata size exceeds limit (%" PRIuPTR " vs. %" PRIuPTR ")", new_size, metadata_size_limit); grpc_chttp2_cancel_stream( exec_ctx, t, s, grpc_error_set_int(GRPC_ERROR_CREATE_FROM_STATIC_STRING( "received trailing metadata size exceeds limit"), GRPC_ERROR_INT_GRPC_STATUS, GRPC_STATUS_RESOURCE_EXHAUSTED)); grpc_chttp2_parsing_become_skip_parser(exec_ctx, t); s->seen_error = true; GRPC_MDELEM_UNREF(exec_ctx, md); } else { grpc_error *error = grpc_chttp2_incoming_metadata_buffer_add( exec_ctx, &s->metadata_buffer[1], md); if (error != GRPC_ERROR_NONE) { grpc_chttp2_cancel_stream(exec_ctx, t, s, error); grpc_chttp2_parsing_become_skip_parser(exec_ctx, t); s->seen_error = true; GRPC_MDELEM_UNREF(exec_ctx, md); } } GPR_TIMER_END("on_trailing_header", 0); }
/* Called when an upload session can be safely shutdown. Close session FD and start to shutdown listen FD. */ static void session_shutdown_cb(grpc_exec_ctx *exec_ctx, void *arg, /*session */ bool success) { session *se = arg; server *sv = se->sv; grpc_fd_orphan(exec_ctx, se->em_fd, NULL, NULL, "a"); gpr_free(se); /* Start to shutdown listen fd. */ grpc_fd_shutdown(exec_ctx, sv->em_fd, GRPC_ERROR_CREATE_FROM_STATIC_STRING("session_shutdown_cb")); }
static void partly_done(grpc_exec_ctx *exec_ctx, state_watcher *w, bool due_to_completion, grpc_error *error) { if (due_to_completion) { grpc_timer_cancel(exec_ctx, &w->alarm); } else { grpc_channel_element *client_channel_elem = grpc_channel_stack_last_element( grpc_channel_get_channel_stack(w->channel)); grpc_client_channel_watch_connectivity_state( exec_ctx, client_channel_elem, grpc_polling_entity_create_from_pollset(grpc_cq_pollset(w->cq)), NULL, &w->on_complete, NULL); } gpr_mu_lock(&w->mu); if (due_to_completion) { if (GRPC_TRACER_ON(grpc_trace_operation_failures)) { GRPC_LOG_IF_ERROR("watch_completion_error", GRPC_ERROR_REF(error)); } GRPC_ERROR_UNREF(error); error = GRPC_ERROR_NONE; } else { if (error == GRPC_ERROR_NONE) { error = GRPC_ERROR_CREATE_FROM_STATIC_STRING( "Timed out waiting for connection state change"); } else if (error == GRPC_ERROR_CANCELLED) { error = GRPC_ERROR_NONE; } } switch (w->phase) { case WAITING: GRPC_ERROR_REF(error); w->error = error; w->phase = READY_TO_CALL_BACK; break; case READY_TO_CALL_BACK: if (error != GRPC_ERROR_NONE) { GPR_ASSERT(!due_to_completion); GRPC_ERROR_UNREF(w->error); GRPC_ERROR_REF(error); w->error = error; } w->phase = CALLING_BACK_AND_FINISHED; grpc_cq_end_op(exec_ctx, w->cq, w->tag, w->error, finished_completion, w, &w->completion_storage); break; case CALLING_BACK_AND_FINISHED: GPR_UNREACHABLE_CODE(return ); break; } gpr_mu_unlock(&w->mu); GRPC_ERROR_UNREF(error); }
static grpc_error *tcp_connect(grpc_exec_ctx *exec_ctx, const test_addr *remote, on_connect_result *result) { gpr_timespec deadline = grpc_timeout_seconds_to_deadline(10); int clifd; int nconnects_before; const struct sockaddr *remote_addr = (const struct sockaddr *)remote->addr.addr; gpr_log(GPR_INFO, "Connecting to %s", remote->str); gpr_mu_lock(g_mu); nconnects_before = g_nconnects; on_connect_result_init(&g_result); clifd = socket(remote_addr->sa_family, SOCK_STREAM, 0); if (clifd < 0) { gpr_mu_unlock(g_mu); return GRPC_OS_ERROR(errno, "Failed to create socket"); } gpr_log(GPR_DEBUG, "start connect to %s", remote->str); if (connect(clifd, remote_addr, (socklen_t)remote->addr.len) != 0) { gpr_mu_unlock(g_mu); close(clifd); return GRPC_OS_ERROR(errno, "connect"); } gpr_log(GPR_DEBUG, "wait"); while (g_nconnects == nconnects_before && gpr_time_cmp(deadline, gpr_now(deadline.clock_type)) > 0) { grpc_pollset_worker *worker = NULL; grpc_error *err; if ((err = grpc_pollset_work(exec_ctx, g_pollset, &worker, gpr_now(GPR_CLOCK_MONOTONIC), deadline)) != GRPC_ERROR_NONE) { gpr_mu_unlock(g_mu); close(clifd); return err; } gpr_mu_unlock(g_mu); grpc_exec_ctx_finish(exec_ctx); gpr_mu_lock(g_mu); } gpr_log(GPR_DEBUG, "wait done"); if (g_nconnects != nconnects_before + 1) { gpr_mu_unlock(g_mu); close(clifd); return GRPC_ERROR_CREATE_FROM_STATIC_STRING("Didn't connect"); } close(clifd); *result = g_result; gpr_mu_unlock(g_mu); gpr_log(GPR_INFO, "Result (%d, %d) fd %d", result->port_index, result->fd_index, result->server_fd); grpc_tcp_server_unref(exec_ctx, result->server); return GRPC_ERROR_NONE; }
static void on_peer_checked(grpc_exec_ctx *exec_ctx, void *arg, grpc_error *error) { security_handshaker *h = arg; gpr_mu_lock(&h->mu); if (error != GRPC_ERROR_NONE || h->shutdown) { security_handshake_failed_locked(exec_ctx, h, GRPC_ERROR_REF(error)); goto done; } // Create frame protector. tsi_frame_protector *protector; tsi_result result = tsi_handshaker_result_create_frame_protector( h->handshaker_result, NULL, &protector); if (result != TSI_OK) { error = grpc_set_tsi_error_result( GRPC_ERROR_CREATE_FROM_STATIC_STRING("Frame protector creation failed"), result); security_handshake_failed_locked(exec_ctx, h, error); goto done; } // Get unused bytes. unsigned char *unused_bytes = NULL; size_t unused_bytes_size = 0; result = tsi_handshaker_result_get_unused_bytes( h->handshaker_result, &unused_bytes, &unused_bytes_size); // Create secure endpoint. if (unused_bytes_size > 0) { grpc_slice slice = grpc_slice_from_copied_buffer((char *)unused_bytes, unused_bytes_size); h->args->endpoint = grpc_secure_endpoint_create(protector, h->args->endpoint, &slice, 1); grpc_slice_unref_internal(exec_ctx, slice); } else { h->args->endpoint = grpc_secure_endpoint_create(protector, h->args->endpoint, NULL, 0); } tsi_handshaker_result_destroy(h->handshaker_result); h->handshaker_result = NULL; // Clear out the read buffer before it gets passed to the transport. grpc_slice_buffer_reset_and_unref_internal(exec_ctx, h->args->read_buffer); // Add auth context to channel args. grpc_arg auth_context_arg = grpc_auth_context_to_arg(h->auth_context); grpc_channel_args *tmp_args = h->args->args; h->args->args = grpc_channel_args_copy_and_add(tmp_args, &auth_context_arg, 1); grpc_channel_args_destroy(exec_ctx, tmp_args); // Invoke callback. GRPC_CLOSURE_SCHED(exec_ctx, h->on_handshake_done, GRPC_ERROR_NONE); // Set shutdown to true so that subsequent calls to // security_handshaker_shutdown() do nothing. h->shutdown = true; done: gpr_mu_unlock(&h->mu); security_handshaker_unref(exec_ctx, h); }
static void must_succeed(grpc_exec_ctx *exec_ctx, void *arg, grpc_error *error) { GPR_ASSERT(g_connecting != NULL); GPR_ASSERT(error == GRPC_ERROR_NONE); grpc_endpoint_shutdown( exec_ctx, g_connecting, GRPC_ERROR_CREATE_FROM_STATIC_STRING("must_succeed called")); grpc_endpoint_destroy(exec_ctx, g_connecting); g_connecting = NULL; finish_connection(exec_ctx); }
static void close_transport_locked(grpc_exec_ctx *exec_ctx, inproc_transport *t) { INPROC_LOG(GPR_DEBUG, "close_transport %p %d", t, t->is_closed); grpc_connectivity_state_set( exec_ctx, &t->connectivity, GRPC_CHANNEL_SHUTDOWN, GRPC_ERROR_CREATE_FROM_STATIC_STRING("Closing transport."), "close transport"); if (!t->is_closed) { t->is_closed = true; /* Also end all streams on this transport */ while (t->stream_list != NULL) { // cancel_stream_locked also adjusts stream list cancel_stream_locked( exec_ctx, t->stream_list, grpc_error_set_int( GRPC_ERROR_CREATE_FROM_STATIC_STRING("Transport closed"), GRPC_ERROR_INT_GRPC_STATUS, GRPC_STATUS_UNAVAILABLE)); } } }
static void fake_resolver_shutdown_locked(grpc_exec_ctx* exec_ctx, grpc_resolver* resolver) { fake_resolver* r = (fake_resolver*)resolver; if (r->next_completion != NULL) { *r->target_result = NULL; GRPC_CLOSURE_SCHED( exec_ctx, r->next_completion, GRPC_ERROR_CREATE_FROM_STATIC_STRING("Resolver Shutdown")); r->next_completion = NULL; } }
/* set a socket to reuse old addresses */ grpc_error *grpc_set_socket_reuse_port(int fd, int reuse) { #ifndef SO_REUSEPORT return GRPC_ERROR_CREATE_FROM_STATIC_STRING( "SO_REUSEPORT unavailable on compiling system"); #else int val = (reuse != 0); int newval; socklen_t intlen = sizeof(newval); if (0 != setsockopt(fd, SOL_SOCKET, SO_REUSEPORT, &val, sizeof(val))) { return GRPC_OS_ERROR(errno, "setsockopt(SO_REUSEPORT)"); } if (0 != getsockopt(fd, SOL_SOCKET, SO_REUSEPORT, &newval, &intlen)) { return GRPC_OS_ERROR(errno, "getsockopt(SO_REUSEPORT)"); } if ((newval != 0) != val) { return GRPC_ERROR_CREATE_FROM_STATIC_STRING("Failed to set SO_REUSEPORT"); } return GRPC_ERROR_NONE; #endif }
static void on_connect(grpc_exec_ctx *exec_ctx, void *vargs, grpc_endpoint *tcp, grpc_pollset *accepting_pollset, grpc_tcp_server_acceptor *acceptor) { gpr_free(acceptor); struct server_thread_args *args = (struct server_thread_args *)vargs; grpc_endpoint_shutdown(exec_ctx, tcp, GRPC_ERROR_CREATE_FROM_STATIC_STRING("Connected")); grpc_endpoint_destroy(exec_ctx, tcp); gpr_mu_lock(args->mu); GRPC_LOG_IF_ERROR("pollset_kick", grpc_pollset_kick(args->pollset, NULL)); gpr_mu_unlock(args->mu); }
static grpc_error *check_peer_locked(grpc_exec_ctx *exec_ctx, security_handshaker *h) { tsi_peer peer; tsi_result result = tsi_handshaker_result_extract_peer(h->handshaker_result, &peer); if (result != TSI_OK) { return grpc_set_tsi_error_result( GRPC_ERROR_CREATE_FROM_STATIC_STRING("Peer extraction failed"), result); } grpc_security_connector_check_peer(exec_ctx, h->connector, peer, &h->auth_context, &h->on_peer_checked); return GRPC_ERROR_NONE; }
static void resolve_address_impl(grpc_exec_ctx *exec_ctx, const char *name, const char *default_port, grpc_pollset_set *interested_parties, grpc_closure *on_done, grpc_resolved_addresses **addrs) { uv_getaddrinfo_t *req; request *r; struct addrinfo *hints; char *host; char *port; grpc_error *err; int s; err = try_split_host_port(name, default_port, &host, &port); if (err != GRPC_ERROR_NONE) { grpc_closure_sched(exec_ctx, on_done, err); return; } r = gpr_malloc(sizeof(request)); r->on_done = on_done; r->addresses = addrs; r->host = host; r->port = port; req = gpr_malloc(sizeof(uv_getaddrinfo_t)); req->data = r; /* Call getaddrinfo */ hints = gpr_malloc(sizeof(struct addrinfo)); memset(hints, 0, sizeof(struct addrinfo)); hints->ai_family = AF_UNSPEC; /* ipv4 or ipv6 */ hints->ai_socktype = SOCK_STREAM; /* stream socket */ hints->ai_flags = AI_PASSIVE; /* for wildcard IP address */ r->hints = hints; s = uv_getaddrinfo(uv_default_loop(), req, getaddrinfo_callback, host, port, hints); if (s != 0) { *addrs = NULL; err = GRPC_ERROR_CREATE_FROM_STATIC_STRING("getaddrinfo failed"); err = grpc_error_set_str(err, GRPC_ERROR_STR_OS_ERROR, grpc_slice_from_static_string(uv_strerror(s))); grpc_closure_sched(exec_ctx, on_done, err); gpr_free(r); gpr_free(req); gpr_free(hints); gpr_free(host); gpr_free(port); } }
static void multiple_shutdown_test(grpc_endpoint_test_config config) { grpc_endpoint_test_fixture f = begin_test(config, "multiple_shutdown_test", 128); int fail_count = 0; grpc_slice_buffer slice_buffer; grpc_slice_buffer_init(&slice_buffer); grpc_exec_ctx exec_ctx = GRPC_EXEC_CTX_INIT; grpc_endpoint_add_to_pollset(&exec_ctx, f.client_ep, g_pollset); grpc_endpoint_read(&exec_ctx, f.client_ep, &slice_buffer, GRPC_CLOSURE_CREATE(inc_on_failure, &fail_count, grpc_schedule_on_exec_ctx)); wait_for_fail_count(&exec_ctx, &fail_count, 0); grpc_endpoint_shutdown(&exec_ctx, f.client_ep, GRPC_ERROR_CREATE_FROM_STATIC_STRING("Test Shutdown")); wait_for_fail_count(&exec_ctx, &fail_count, 1); grpc_endpoint_read(&exec_ctx, f.client_ep, &slice_buffer, GRPC_CLOSURE_CREATE(inc_on_failure, &fail_count, grpc_schedule_on_exec_ctx)); wait_for_fail_count(&exec_ctx, &fail_count, 2); grpc_slice_buffer_add(&slice_buffer, grpc_slice_from_copied_string("a")); grpc_endpoint_write(&exec_ctx, f.client_ep, &slice_buffer, GRPC_CLOSURE_CREATE(inc_on_failure, &fail_count, grpc_schedule_on_exec_ctx)); wait_for_fail_count(&exec_ctx, &fail_count, 3); grpc_endpoint_shutdown(&exec_ctx, f.client_ep, GRPC_ERROR_CREATE_FROM_STATIC_STRING("Test Shutdown")); wait_for_fail_count(&exec_ctx, &fail_count, 3); grpc_slice_buffer_destroy_internal(&exec_ctx, &slice_buffer); grpc_endpoint_destroy(&exec_ctx, f.client_ep); grpc_endpoint_destroy(&exec_ctx, f.server_ep); grpc_exec_ctx_finish(&exec_ctx); }
/* disable nagle */ grpc_error *grpc_set_socket_low_latency(int fd, int low_latency) { int val = (low_latency != 0); int newval; socklen_t intlen = sizeof(newval); if (0 != setsockopt(fd, IPPROTO_TCP, TCP_NODELAY, &val, sizeof(val))) { return GRPC_OS_ERROR(errno, "setsockopt(TCP_NODELAY)"); } if (0 != getsockopt(fd, IPPROTO_TCP, TCP_NODELAY, &newval, &intlen)) { return GRPC_OS_ERROR(errno, "getsockopt(TCP_NODELAY)"); } if ((newval != 0) != val) { return GRPC_ERROR_CREATE_FROM_STATIC_STRING("Failed to set TCP_NODELAY"); } return GRPC_ERROR_NONE; }
static void me_read(grpc_exec_ctx *exec_ctx, grpc_endpoint *ep, grpc_slice_buffer *slices, grpc_closure *cb) { half *m = (half *)ep; gpr_mu_lock(&m->parent->mu); if (m->parent->shutdown) { GRPC_CLOSURE_SCHED( exec_ctx, cb, GRPC_ERROR_CREATE_FROM_STATIC_STRING("Already shutdown")); } else if (m->read_buffer.count > 0) { grpc_slice_buffer_swap(&m->read_buffer, slices); GRPC_CLOSURE_SCHED(exec_ctx, cb, GRPC_ERROR_NONE); } else { m->on_read = cb; m->on_read_out = slices; } gpr_mu_unlock(&m->parent->mu); }
/* set a socket to reuse old addresses */ grpc_error *grpc_set_socket_reuse_addr(int fd, int reuse) { int val = (reuse != 0); int newval; socklen_t intlen = sizeof(newval); if (0 != setsockopt(fd, SOL_SOCKET, SO_REUSEADDR, &val, sizeof(val))) { return GRPC_OS_ERROR(errno, "setsockopt(SO_REUSEADDR)"); } if (0 != getsockopt(fd, SOL_SOCKET, SO_REUSEADDR, &newval, &intlen)) { return GRPC_OS_ERROR(errno, "getsockopt(SO_REUSEADDR)"); } if ((newval != 0) != val) { return GRPC_ERROR_CREATE_FROM_STATIC_STRING("Failed to set SO_REUSEADDR"); } return GRPC_ERROR_NONE; }
grpc_error *grpc_set_socket_no_sigpipe_if_possible(int fd) { #ifdef GRPC_HAVE_SO_NOSIGPIPE int val = 1; int newval; socklen_t intlen = sizeof(newval); if (0 != setsockopt(fd, SOL_SOCKET, SO_NOSIGPIPE, &val, sizeof(val))) { return GRPC_OS_ERROR(errno, "setsockopt(SO_NOSIGPIPE)"); } if (0 != getsockopt(fd, SOL_SOCKET, SO_NOSIGPIPE, &newval, &intlen)) { return GRPC_OS_ERROR(errno, "getsockopt(SO_NOSIGPIPE)"); } if ((newval != 0) != (val != 0)) { return GRPC_ERROR_CREATE_FROM_STATIC_STRING("Failed to set SO_NOSIGPIPE"); } #endif return GRPC_ERROR_NONE; }
static void on_connect(grpc_exec_ctx *exec_ctx, void *arg, grpc_endpoint *tcp, grpc_pollset *pollset, grpc_tcp_server_acceptor *acceptor) { grpc_endpoint_shutdown(exec_ctx, tcp, GRPC_ERROR_CREATE_FROM_STATIC_STRING("Connected")); grpc_endpoint_destroy(exec_ctx, tcp); on_connect_result temp_result; on_connect_result_set(&temp_result, acceptor); gpr_free(acceptor); gpr_mu_lock(g_mu); g_result = temp_result; g_nconnects++; GPR_ASSERT(GRPC_LOG_IF_ERROR("pollset_kick", grpc_pollset_kick(exec_ctx, g_pollset, NULL))); gpr_mu_unlock(g_mu); }
static void test_fd_cleanup(grpc_exec_ctx *exec_ctx, test_fd *tfds, int num_fds) { int release_fd; int i; for (i = 0; i < num_fds; i++) { grpc_fd_shutdown(exec_ctx, tfds[i].fd, GRPC_ERROR_CREATE_FROM_STATIC_STRING("test_fd_cleanup")); grpc_exec_ctx_flush(exec_ctx); grpc_fd_orphan(exec_ctx, tfds[i].fd, NULL, &release_fd, false /* already_closed */, "test_fd_cleanup"); grpc_exec_ctx_flush(exec_ctx); GPR_ASSERT(release_fd == tfds[i].inner_fd); close(tfds[i].inner_fd); } }
static grpc_ares_request *my_dns_lookup_ares( grpc_exec_ctx *exec_ctx, const char *dns_server, const char *addr, const char *default_port, grpc_pollset_set *interested_parties, grpc_closure *on_done, grpc_lb_addresses **lb_addrs, bool check_grpclb, char **service_config_json) { gpr_mu_lock(&g_mu); GPR_ASSERT(0 == strcmp("test", addr)); grpc_error *error = GRPC_ERROR_NONE; if (g_fail_resolution) { g_fail_resolution = false; gpr_mu_unlock(&g_mu); error = GRPC_ERROR_CREATE_FROM_STATIC_STRING("Forced Failure"); } else { gpr_mu_unlock(&g_mu); *lb_addrs = grpc_lb_addresses_create(1, NULL); grpc_lb_addresses_set_address(*lb_addrs, 0, NULL, 0, false, NULL, NULL); } GRPC_CLOSURE_SCHED(exec_ctx, on_done, error); return NULL; }
void grpc_connectivity_state_destroy(grpc_exec_ctx *exec_ctx, grpc_connectivity_state_tracker *tracker) { grpc_error *error; grpc_connectivity_state_watcher *w; while ((w = tracker->watchers)) { tracker->watchers = w->next; if (GRPC_CHANNEL_SHUTDOWN != *w->current) { *w->current = GRPC_CHANNEL_SHUTDOWN; error = GRPC_ERROR_NONE; } else { error = GRPC_ERROR_CREATE_FROM_STATIC_STRING("Shutdown connectivity owner"); } GRPC_CLOSURE_SCHED(exec_ctx, w->notify, error); gpr_free(w); } GRPC_ERROR_UNREF(tracker->current_error); gpr_free(tracker->name); }
static void my_resolve_address(grpc_exec_ctx *exec_ctx, const char *addr, const char *default_port, grpc_pollset_set *interested_parties, grpc_closure *on_done, grpc_resolved_addresses **addrs) { gpr_mu_lock(&g_mu); GPR_ASSERT(0 == strcmp("test", addr)); grpc_error *error = GRPC_ERROR_NONE; if (g_fail_resolution) { g_fail_resolution = false; gpr_mu_unlock(&g_mu); error = GRPC_ERROR_CREATE_FROM_STATIC_STRING("Forced Failure"); } else { gpr_mu_unlock(&g_mu); *addrs = gpr_malloc(sizeof(**addrs)); (*addrs)->naddrs = 1; (*addrs)->addrs = gpr_malloc(sizeof(*(*addrs)->addrs)); (*addrs)->addrs[0].len = 123; } GRPC_CLOSURE_SCHED(exec_ctx, on_done, error); }
static void cleanup_test_fds(grpc_exec_ctx *exec_ctx, test_fd *tfds, const int num_fds) { int release_fd; for (int i = 0; i < num_fds; i++) { grpc_fd_shutdown(exec_ctx, tfds[i].fd, GRPC_ERROR_CREATE_FROM_STATIC_STRING("fd cleanup")); grpc_exec_ctx_flush(exec_ctx); /* grpc_fd_orphan frees the memory allocated for grpc_fd. Normally it also * calls close() on the underlying fd. In our case, we are using * grpc_wakeup_fd and we would like to destroy it ourselves (by calling * grpc_wakeup_fd_destroy). To prevent grpc_fd from calling close() on the * underlying fd, call it with a non-NULL 'release_fd' parameter */ grpc_fd_orphan(exec_ctx, tfds[i].fd, NULL, &release_fd, false /* already_closed */, "test_fd_cleanup"); grpc_exec_ctx_flush(exec_ctx); grpc_wakeup_fd_destroy(&tfds[i].wakeup_fd); } }
static grpc_error *on_handshake_next_done_locked( grpc_exec_ctx *exec_ctx, security_handshaker *h, tsi_result result, const unsigned char *bytes_to_send, size_t bytes_to_send_size, tsi_handshaker_result *handshaker_result) { grpc_error *error = GRPC_ERROR_NONE; // Read more if we need to. if (result == TSI_INCOMPLETE_DATA) { GPR_ASSERT(bytes_to_send_size == 0); grpc_endpoint_read(exec_ctx, h->args->endpoint, h->args->read_buffer, &h->on_handshake_data_received_from_peer); return error; } if (result != TSI_OK) { return grpc_set_tsi_error_result( GRPC_ERROR_CREATE_FROM_STATIC_STRING("Handshake failed"), result); } // Update handshaker result. if (handshaker_result != NULL) { GPR_ASSERT(h->handshaker_result == NULL); h->handshaker_result = handshaker_result; } if (bytes_to_send_size > 0) { // Send data to peer, if needed. grpc_slice to_send = grpc_slice_from_copied_buffer( (const char *)bytes_to_send, bytes_to_send_size); grpc_slice_buffer_reset_and_unref_internal(exec_ctx, &h->outgoing); grpc_slice_buffer_add(&h->outgoing, to_send); grpc_endpoint_write(exec_ctx, h->args->endpoint, &h->outgoing, &h->on_handshake_data_sent_to_peer); } else if (handshaker_result == NULL) { // There is nothing to send, but need to read from peer. grpc_endpoint_read(exec_ctx, h->args->endpoint, h->args->read_buffer, &h->on_handshake_data_received_from_peer); } else { // Handshake has finished, check peer and so on. error = check_peer_locked(exec_ctx, h); } return error; }