int long_test() { grpc_error_t ret; long a[N], b[N]; int success = 1; int i; int handleInitialized = 0; ret = grpc_function_handle_default(&handles, MODULE_NAME "/long_test"); if (ret != GRPC_NO_ERROR) { fprintf(stderr, "grpc_function_handle_default() error. (%s)\n", grpc_error_string(ret)); success = 0; goto finalize; } handleInitialized = 1; for (i = 0; i < N; i++) { a[i] = i; b[i] = 0; } ret = grpc_call(&handles, (long)N, a, b); if (ret != GRPC_NO_ERROR) { fprintf(stderr, "grpc_call() error. (%s)\n", grpc_error_string(ret)); success = 0; goto finalize; } for (i = 0; i < N; i++) { if (a[i] != b[i]) { success = 0; if (verbose) { printf("long_test: a[%d](%ld) != b[%d](%ld)\n", i, a[i], i, b[i]); } } } finalize: if (handleInitialized != 0) { ret = grpc_function_handle_destruct(&handles); if (ret != GRPC_NO_ERROR) { fprintf(stderr, "grpc_function_handle_destruct() error. (%s)\n", grpc_error_string(ret)); success = 0; } handleInitialized = 0; } return success; }
int string_test() { grpc_error_t ret; char *buffer = NULL; char teststring[TEST_STR_LENGTH]; int i; int success = 1; int handleInitialized = 0; ret = grpc_function_handle_default(&handles, MODULE_NAME "/string_test"); if (ret != GRPC_NO_ERROR) { fprintf(stderr, "grpc_function_handle_default() error. (%s)\n", grpc_error_string(ret)); success = 0; goto finalize; } handleInitialized = 1; for (i = 0; i < TEST_STR_LENGTH -1; i++) { *(teststring + i) = (i % 10) + '0'; } *(teststring + i) = '\0'; ret = grpc_call(&handles, teststring, &buffer); if (ret != GRPC_NO_ERROR) { fprintf(stderr, "grpc_call() error. (%s)\n", grpc_error_string(ret)); success = 0; goto finalize; } if (strcmp(teststring, buffer) != 0) { if (verbose) { printf("%s != %s\n", teststring, buffer); } success = 0; } finalize: if (handleInitialized != 0) { ret = grpc_function_handle_destruct(&handles); if (ret != GRPC_NO_ERROR) { fprintf(stderr, "grpc_function_handle_destruct() error. (%s)\n", grpc_error_string(ret)); success = 0; } handleInitialized = 0; } /* buffer was allocated in grpc_call() by malloc() */ free(buffer); return success; }
int callback_multi_test() { grpc_error_t ret; double a[N][N], b[N][N]; int i, j; int rVal = 1; for (i = 0; i < N; i++) { for (j = 0; j < N; j++) { a[i][j] = i * N + j; b[i][j] = 0.0; } } ret = grpc_function_handle_default(&handles, MODULE_NAME "/callback_multi_test"); if (ret != GRPC_NO_ERROR) { fprintf(stderr, "grpc_function_handle_default() error. (%s)\n", grpc_error_string(ret)); rVal = 0; goto end; } ret = grpc_call(&handles, N, a, b, callback_return_func, callback_return_func); if (ret != GRPC_NO_ERROR) { fprintf(stderr, "grpc_call() error. (%s)\n", grpc_error_string(ret)); rVal = 0; } ret = grpc_function_handle_destruct(&handles); if (ret != GRPC_NO_ERROR) { fprintf(stderr, "grpc_function_handle_destruct() error. (%s)\n", grpc_error_string(ret)); rVal = 0; } if (rVal != 0) { for (i = 0; i < N; i++) { for (j = 0; j < N; j++) { if (a[i][j] != b[i][j]) { rVal = 0; goto end; } } } } end: return rVal; }
int callback_string_test() { grpc_error_t ret; char *strings[] = {"caller0","caller1","caller2","caller3","caller4"}; char string[64]= ""; int i; int rVal = 1; for (i = 0; i < 5; i++) { strcat(string, strings[i]); } ret = grpc_function_handle_default(&handles, MODULE_NAME "/callbackstr"); if (ret != GRPC_NO_ERROR) { fprintf(stderr, "grpc_function_handle_default() error. (%s)\n", grpc_error_string(ret)); rVal = 0; goto end; } ret = grpc_call(&handles, strings, callbackstring_func); if (ret != GRPC_NO_ERROR) { fprintf(stderr, "grpc_call() error. (%s)\n", grpc_error_string(ret)); rVal = 0; } ret = grpc_function_handle_destruct(&handles); if (ret != GRPC_NO_ERROR) { fprintf(stderr, "grpc_function_handle_destruct() error. (%s)\n", grpc_error_string(ret)); rVal = 0; } if (verbose) { printf("\ncallbacked = '%s'", callbacked); } if (verbose) { printf("\nfrontend = '%s'\n", string); } if (rVal != 0) { if (strcmp(callbacked, string) != 0) { rVal = 0; } } end: return rVal; }
int callback_test() { grpc_error_t ret; double initial = 100.0, lsum = 0.0; int times = 1; int rVal = 1; sum = 0.0; ret = grpc_function_handle_default(&handles, MODULE_NAME "/callback_test"); if (ret != GRPC_NO_ERROR) { fprintf(stderr, "grpc_function_handle_default() error. (%s)\n", grpc_error_string(ret)); rVal = 0; goto end; } ret = grpc_call(&handles, initial, times, callback_func); if (ret != GRPC_NO_ERROR) { fprintf(stderr, "grpc_call() error. (%s)\n", grpc_error_string(ret)); rVal = 0; } ret = grpc_function_handle_destruct(&handles); if (ret != GRPC_NO_ERROR) { fprintf(stderr, "grpc_function_handle_destruct() error. (%s)\n", grpc_error_string(ret)); rVal = 0; } if (rVal != 0) { int i; double d = 0.0; for (i = 0; i < times; i++) { d += initial; lsum += d; } if (sum != lsum) { if (verbose) { printf("sum = %f(should be %f)\n", sum, lsum); } rVal = 0; } } end: return rVal; }
/* * Copy from inout-file to out-file and from in-file to inout-file. */ int main(int argc, char *argv[]) { grpc_error_t ret; if (argc < 5) { fprintf(stderr, "Usage: %s config in-file inout-file out-file\n", argv[0]); exit(2); } ret = grpc_initialize(argv[1]); if (ret != GRPC_NO_ERROR) { fprintf(stderr, "grpc_initialize() error. (%s)\n", grpc_error_string(ret)); exit(2); } ret = grpc_function_handle_default(&handles, MODULE_NAME "/filename_test"); if (ret != GRPC_NO_ERROR) { fprintf(stderr, "grpc_function_handle_default() error. (%s)\n", grpc_error_string(ret)); exit(2); } ret = grpc_call(&handles, argv[2], argv[3], argv[4]); if (ret != GRPC_NO_ERROR) { fprintf(stderr, "grpc_call() error. (%s)\n", grpc_error_string(ret)); exit(2); } ret = grpc_function_handle_destruct(&handles); if (ret != GRPC_NO_ERROR) { fprintf(stderr, "grpc_function_handle_destruct() error. (%s)\n", grpc_error_string(ret)); exit(2); } ret = grpc_finalize(); if (ret != GRPC_NO_ERROR) { fprintf(stderr, "grpc_finalize() error. (%s)\n", grpc_error_string(ret)); exit(2); } return 0; }
static void tcp_handle_write(grpc_exec_ctx *exec_ctx, void *arg /* grpc_tcp */, grpc_error *error) { grpc_tcp *tcp = (grpc_tcp *)arg; grpc_closure *cb; if (error != GRPC_ERROR_NONE) { cb = tcp->write_cb; tcp->write_cb = NULL; cb->cb(exec_ctx, cb->cb_arg, error); TCP_UNREF(exec_ctx, tcp, "write"); return; } if (!tcp_flush(tcp, &error)) { if (grpc_tcp_trace) { gpr_log(GPR_DEBUG, "write: delayed"); } grpc_fd_notify_on_write(exec_ctx, tcp->em_fd, &tcp->write_closure); } else { cb = tcp->write_cb; tcp->write_cb = NULL; if (grpc_tcp_trace) { const char *str = grpc_error_string(error); gpr_log(GPR_DEBUG, "write: %s", str); grpc_error_free_string(str); } grpc_closure_run(exec_ctx, cb, error); TCP_UNREF(exec_ctx, tcp, "write"); } }
static void on_handshake_done(grpc_exec_ctx *exec_ctx, grpc_endpoint *endpoint, grpc_channel_args *args, gpr_slice_buffer *read_buffer, void *user_data, grpc_error *error) { server_secure_connect *state = user_data; if (error != GRPC_ERROR_NONE) { const char *error_str = grpc_error_string(error); gpr_log(GPR_ERROR, "Handshaking failed: %s", error_str); grpc_error_free_string(error_str); GRPC_ERROR_UNREF(error); grpc_channel_args_destroy(args); gpr_free(read_buffer); grpc_handshake_manager_shutdown(exec_ctx, state->handshake_mgr); grpc_handshake_manager_destroy(exec_ctx, state->handshake_mgr); state_unref(state->state); gpr_free(state); return; } grpc_handshake_manager_destroy(exec_ctx, state->handshake_mgr); state->handshake_mgr = NULL; // TODO(roth, jboeuf): Convert security connector handshaking to use new // handshake API, and then move the code from on_secure_handshake_done() // into this function. state->args = args; grpc_server_security_connector_do_handshake( exec_ctx, state->state->sc, state->acceptor, endpoint, read_buffer, state->deadline, on_secure_handshake_done, state); }
static grpc_error *parse_frame_slice(grpc_exec_ctx *exec_ctx, grpc_chttp2_transport *t, grpc_slice slice, int is_last) { grpc_chttp2_stream *s = t->incoming_stream; grpc_error *err = t->parser(exec_ctx, t->parser_data, t, s, slice, is_last); if (err == GRPC_ERROR_NONE) { return err; } else if (grpc_error_get_int(err, GRPC_ERROR_INT_STREAM_ID, NULL)) { if (GRPC_TRACER_ON(grpc_http_trace)) { const char *msg = grpc_error_string(err); gpr_log(GPR_ERROR, "%s", msg); } grpc_chttp2_parsing_become_skip_parser(exec_ctx, t); if (s) { s->forced_close_error = err; grpc_slice_buffer_add( &t->qbuf, grpc_chttp2_rst_stream_create(t->incoming_stream_id, GRPC_HTTP2_PROTOCOL_ERROR, &s->stats.outgoing)); } else { GRPC_ERROR_UNREF(err); } } return err; }
static grpc_error *parse_frame_slice( grpc_exec_ctx *exec_ctx, grpc_chttp2_transport_parsing *transport_parsing, gpr_slice slice, int is_last) { grpc_chttp2_stream_parsing *stream_parsing = transport_parsing->incoming_stream; grpc_error *err = transport_parsing->parser( exec_ctx, transport_parsing->parser_data, transport_parsing, stream_parsing, slice, is_last); if (err == GRPC_ERROR_NONE) { if (stream_parsing) { grpc_chttp2_list_add_parsing_seen_stream(transport_parsing, stream_parsing); } return GRPC_ERROR_NONE; } else if (grpc_error_get_int(err, GRPC_ERROR_INT_STREAM_ID, NULL)) { if (grpc_http_trace) { const char *msg = grpc_error_string(err); gpr_log(GPR_ERROR, "%s", msg); grpc_error_free_string(msg); } grpc_chttp2_parsing_become_skip_parser(exec_ctx, transport_parsing); if (stream_parsing) { stream_parsing->forced_close_error = err; gpr_slice_buffer_add( &transport_parsing->qbuf, grpc_chttp2_rst_stream_create(transport_parsing->incoming_stream_id, GRPC_CHTTP2_PROTOCOL_ERROR, &stream_parsing->stats.outgoing)); } else { GRPC_ERROR_UNREF(err); } } return err; }
// If the handshake failed or we're shutting down, clean up and invoke the // callback with the error. static void security_handshake_failed_locked(grpc_exec_ctx *exec_ctx, security_handshaker *h, grpc_error *error) { if (error == GRPC_ERROR_NONE) { // If we were shut down after the handshake succeeded but before an // endpoint callback was invoked, we need to generate our own error. error = GRPC_ERROR_CREATE_FROM_STATIC_STRING("Handshaker shutdown"); } const char *msg = grpc_error_string(error); gpr_log(GPR_DEBUG, "Security handshake failed: %s", msg); if (!h->shutdown) { // TODO(ctiller): It is currently necessary to shutdown endpoints // before destroying them, even if we know that there are no // pending read/write callbacks. This should be fixed, at which // point this can be removed. grpc_endpoint_shutdown(exec_ctx, h->args->endpoint, GRPC_ERROR_REF(error)); // Not shutting down, so the write failed. Clean up before // invoking the callback. cleanup_args_for_failure_locked(exec_ctx, h); // Set shutdown to true so that subsequent calls to // security_handshaker_shutdown() do nothing. h->shutdown = true; } // Invoke callback. GRPC_CLOSURE_SCHED(exec_ctx, h->on_handshake_done, error); }
static void security_handshake_done(grpc_exec_ctx *exec_ctx, grpc_security_handshake *h, grpc_error *error) { grpc_timer_cancel(exec_ctx, &h->timer); if (!h->is_client_side) { security_connector_remove_handshake(h); } if (error == GRPC_ERROR_NONE) { h->cb(exec_ctx, h->user_data, GRPC_SECURITY_OK, h->secure_endpoint, h->auth_context); } else { const char *msg = grpc_error_string(error); gpr_log(GPR_ERROR, "Security handshake failed: %s", msg); grpc_error_free_string(msg); if (h->secure_endpoint != NULL) { grpc_endpoint_shutdown(exec_ctx, h->secure_endpoint); grpc_endpoint_destroy(exec_ctx, h->secure_endpoint); } else { grpc_endpoint_destroy(exec_ctx, h->wrapped_endpoint); } h->cb(exec_ctx, h->user_data, GRPC_SECURITY_ERROR, NULL, NULL); } unref_handshake(h); GRPC_ERROR_UNREF(error); }
char *grpc_transport_stream_op_string(grpc_transport_stream_op *op) { char *tmp; char *out; gpr_strvec b; gpr_strvec_init(&b); gpr_strvec_add( &b, gpr_strdup(op->covered_by_poller ? "[COVERED]" : "[UNCOVERED]")); if (op->send_initial_metadata != NULL) { gpr_strvec_add(&b, gpr_strdup(" ")); gpr_strvec_add(&b, gpr_strdup("SEND_INITIAL_METADATA{")); put_metadata_list(&b, *op->send_initial_metadata); gpr_strvec_add(&b, gpr_strdup("}")); } if (op->send_message != NULL) { gpr_strvec_add(&b, gpr_strdup(" ")); gpr_asprintf(&tmp, "SEND_MESSAGE:flags=0x%08x:len=%d", op->send_message->flags, op->send_message->length); gpr_strvec_add(&b, tmp); } if (op->send_trailing_metadata != NULL) { gpr_strvec_add(&b, gpr_strdup(" ")); gpr_strvec_add(&b, gpr_strdup("SEND_TRAILING_METADATA{")); put_metadata_list(&b, *op->send_trailing_metadata); gpr_strvec_add(&b, gpr_strdup("}")); } if (op->recv_initial_metadata != NULL) { gpr_strvec_add(&b, gpr_strdup(" ")); gpr_strvec_add(&b, gpr_strdup("RECV_INITIAL_METADATA")); } if (op->recv_message != NULL) { gpr_strvec_add(&b, gpr_strdup(" ")); gpr_strvec_add(&b, gpr_strdup("RECV_MESSAGE")); } if (op->recv_trailing_metadata != NULL) { gpr_strvec_add(&b, gpr_strdup(" ")); gpr_strvec_add(&b, gpr_strdup("RECV_TRAILING_METADATA")); } if (op->cancel_error != GRPC_ERROR_NONE) { gpr_strvec_add(&b, gpr_strdup(" ")); const char *msg = grpc_error_string(op->cancel_error); gpr_asprintf(&tmp, "CANCEL:%s", msg); gpr_strvec_add(&b, tmp); } out = gpr_strvec_flatten(&b, NULL); gpr_strvec_destroy(&b); return out; }
static void got_port_from_server(grpc_exec_ctx *exec_ctx, void *arg, grpc_error *error) { size_t i; int port = 0; portreq *pr = arg; int failed = 0; grpc_httpcli_response *response = &pr->response; if (error != GRPC_ERROR_NONE) { failed = 1; const char *msg = grpc_error_string(error); gpr_log(GPR_DEBUG, "failed port pick from server: retrying [%s]", msg); grpc_error_free_string(msg); } else if (response->status != 200) { failed = 1; gpr_log(GPR_DEBUG, "failed port pick from server: status=%d", response->status); } if (failed) { grpc_httpcli_request req; memset(&req, 0, sizeof(req)); GPR_ASSERT(pr->retries < 10); gpr_sleep_until(gpr_time_add( gpr_now(GPR_CLOCK_REALTIME), gpr_time_from_millis( (int64_t)(1000.0 * (1 + pow(1.3, pr->retries) * rand() / RAND_MAX)), GPR_TIMESPAN))); pr->retries++; req.host = pr->server; req.http.path = "/get"; grpc_http_response_destroy(&pr->response); memset(&pr->response, 0, sizeof(pr->response)); grpc_resource_quota *resource_quota = grpc_resource_quota_create("port_server_client/pick_retry"); grpc_httpcli_get(exec_ctx, pr->ctx, &pr->pops, resource_quota, &req, GRPC_TIMEOUT_SECONDS_TO_DEADLINE(10), grpc_closure_create(got_port_from_server, pr), &pr->response); grpc_resource_quota_internal_unref(exec_ctx, resource_quota); return; } GPR_ASSERT(response); GPR_ASSERT(response->status == 200); for (i = 0; i < response->body_length; i++) { GPR_ASSERT(response->body[i] >= '0' && response->body[i] <= '9'); port = port * 10 + response->body[i] - '0'; } GPR_ASSERT(port > 1024); gpr_mu_lock(pr->mu); pr->port = port; GRPC_LOG_IF_ERROR( "pollset_kick", grpc_pollset_kick(grpc_polling_entity_pollset(&pr->pops), NULL)); gpr_mu_unlock(pr->mu); }
// Helper function to shut down the proxy connection. // Does NOT take ownership of a reference to error. static void proxy_connection_failed(grpc_exec_ctx* exec_ctx, proxy_connection* conn, bool is_client, const char* prefix, grpc_error* error) { const char* msg = grpc_error_string(error); gpr_log(GPR_INFO, "%s: %s", prefix, msg); grpc_error_free_string(msg); grpc_endpoint_shutdown(exec_ctx, conn->client_endpoint); if (conn->server_endpoint != NULL) grpc_endpoint_shutdown(exec_ctx, conn->server_endpoint); proxy_connection_unref(exec_ctx, conn); }
static void hs_on_recv(grpc_exec_ctx *exec_ctx, void *user_data, grpc_error *err) { grpc_call_element *elem = user_data; call_data *calld = elem->call_data; if (err == GRPC_ERROR_NONE) { server_filter_args a; a.elem = elem; a.exec_ctx = exec_ctx; grpc_metadata_batch_filter(calld->recv_initial_metadata, server_filter, &a); /* Have we seen the required http2 transport headers? (:method, :scheme, content-type, with :path and :authority covered at the channel level right now) */ if (calld->seen_method && calld->seen_scheme && calld->seen_te_trailers && calld->seen_path && calld->seen_authority) { /* do nothing */ } else { err = GRPC_ERROR_CREATE("Bad incoming HTTP headers"); if (!calld->seen_path) { err = grpc_error_add_child(err, GRPC_ERROR_CREATE("Missing :path header")); } if (!calld->seen_authority) { err = grpc_error_add_child( err, GRPC_ERROR_CREATE("Missing :authority header")); } if (!calld->seen_method) { err = grpc_error_add_child(err, GRPC_ERROR_CREATE("Missing :method header")); } if (!calld->seen_scheme) { err = grpc_error_add_child(err, GRPC_ERROR_CREATE("Missing :scheme header")); } if (!calld->seen_te_trailers) { err = grpc_error_add_child( err, GRPC_ERROR_CREATE("Missing te: trailers header")); } /* Error this call out */ if (grpc_http_trace) { const char *error_str = grpc_error_string(err); gpr_log(GPR_ERROR, "Invalid http2 headers: %s", error_str); grpc_error_free_string(error_str); } grpc_call_element_send_cancel(exec_ctx, elem); } } else { GRPC_ERROR_REF(err); } calld->on_done_recv->cb(exec_ctx, calld->on_done_recv->cb_arg, err); GRPC_ERROR_UNREF(err); }
int grpc_server_add_secure_http2_port(grpc_server *server, const char *addr, grpc_server_credentials *creds) { grpc_exec_ctx exec_ctx = GRPC_EXEC_CTX_INIT; grpc_error *err = GRPC_ERROR_NONE; grpc_server_security_connector *sc = NULL; int port_num = 0; GRPC_API_TRACE( "grpc_server_add_secure_http2_port(" "server=%p, addr=%s, creds=%p)", 3, (server, addr, creds)); // Create security context. if (creds == NULL) { err = GRPC_ERROR_CREATE( "No credentials specified for secure server port (creds==NULL)"); goto done; } grpc_security_status status = grpc_server_credentials_create_security_connector(&exec_ctx, creds, &sc); if (status != GRPC_SECURITY_OK) { char *msg; gpr_asprintf(&msg, "Unable to create secure server with credentials of type %s.", creds->type); err = grpc_error_set_int(GRPC_ERROR_CREATE(msg), GRPC_ERROR_INT_SECURITY_STATUS, status); gpr_free(msg); goto done; } // Create channel args. grpc_arg args_to_add[2]; args_to_add[0] = grpc_server_credentials_to_arg(creds); args_to_add[1] = grpc_security_connector_to_arg(&sc->base); grpc_channel_args *args = grpc_channel_args_copy_and_add(grpc_server_get_channel_args(server), args_to_add, GPR_ARRAY_SIZE(args_to_add)); // Add server port. err = grpc_chttp2_server_add_port(&exec_ctx, server, addr, args, &port_num); done: if (sc != NULL) { GRPC_SECURITY_CONNECTOR_UNREF(&exec_ctx, &sc->base, "server"); } grpc_exec_ctx_finish(&exec_ctx); if (err != GRPC_ERROR_NONE) { const char *msg = grpc_error_string(err); gpr_log(GPR_ERROR, "%s", msg); grpc_error_free_string(msg); GRPC_ERROR_UNREF(err); } return port_num; }
static void tcp_write(grpc_exec_ctx *exec_ctx, grpc_endpoint *ep, grpc_slice_buffer *buf, grpc_closure *cb) { grpc_tcp *tcp = (grpc_tcp *)ep; grpc_error *error = GRPC_ERROR_NONE; if (grpc_tcp_trace) { size_t i; for (i = 0; i < buf->count; i++) { char *data = grpc_dump_slice(buf->slices[i], GPR_DUMP_HEX | GPR_DUMP_ASCII); gpr_log(GPR_DEBUG, "WRITE %p (peer=%s): %s", tcp, tcp->peer_string, data); gpr_free(data); } } GPR_TIMER_BEGIN("tcp_write", 0); GPR_ASSERT(tcp->write_cb == NULL); if (buf->length == 0) { GPR_TIMER_END("tcp_write", 0); grpc_exec_ctx_sched(exec_ctx, cb, grpc_fd_is_shutdown(tcp->em_fd) ? tcp_annotate_error(GRPC_ERROR_CREATE("EOF"), tcp) : GRPC_ERROR_NONE, NULL); return; } tcp->outgoing_buffer = buf; tcp->outgoing_slice_idx = 0; tcp->outgoing_byte_idx = 0; if (!tcp_flush(tcp, &error)) { TCP_REF(tcp, "write"); tcp->write_cb = cb; if (grpc_tcp_trace) { gpr_log(GPR_DEBUG, "write: delayed"); } grpc_fd_notify_on_write(exec_ctx, tcp->em_fd, &tcp->write_closure); } else { if (grpc_tcp_trace) { const char *str = grpc_error_string(error); gpr_log(GPR_DEBUG, "write: %s", str); grpc_error_free_string(str); } grpc_exec_ctx_sched(exec_ctx, cb, error, NULL); } GPR_TIMER_END("tcp_write", 0); }
static void dns_on_resolved(grpc_exec_ctx *exec_ctx, void *arg, grpc_error *error) { dns_resolver *r = arg; grpc_channel_args *result = NULL; gpr_mu_lock(&r->mu); GPR_ASSERT(r->resolving); r->resolving = false; if (r->addresses != NULL) { grpc_lb_addresses *addresses = grpc_lb_addresses_create( r->addresses->naddrs, NULL /* user_data_vtable */); for (size_t i = 0; i < r->addresses->naddrs; ++i) { grpc_lb_addresses_set_address( addresses, i, &r->addresses->addrs[i].addr, r->addresses->addrs[i].len, false /* is_balancer */, NULL /* balancer_name */, NULL /* user_data */); } grpc_arg new_arg = grpc_lb_addresses_create_channel_arg(addresses); result = grpc_channel_args_copy_and_add(r->channel_args, &new_arg, 1); grpc_resolved_addresses_destroy(r->addresses); grpc_lb_addresses_destroy(addresses); } else { gpr_timespec now = gpr_now(GPR_CLOCK_MONOTONIC); gpr_timespec next_try = gpr_backoff_step(&r->backoff_state, now); gpr_timespec timeout = gpr_time_sub(next_try, now); const char *msg = grpc_error_string(error); gpr_log(GPR_DEBUG, "dns resolution failed: %s", msg); grpc_error_free_string(msg); GPR_ASSERT(!r->have_retry_timer); r->have_retry_timer = true; GRPC_RESOLVER_REF(&r->base, "retry-timer"); if (gpr_time_cmp(timeout, gpr_time_0(timeout.clock_type)) > 0) { gpr_log(GPR_DEBUG, "retrying in %" PRId64 ".%09d seconds", timeout.tv_sec, timeout.tv_nsec); } else { gpr_log(GPR_DEBUG, "retrying immediately"); } grpc_timer_init(exec_ctx, &r->retry_timer, next_try, dns_on_retry_timer, r, now); } if (r->resolved_result != NULL) { grpc_channel_args_destroy(r->resolved_result); } r->resolved_result = result; r->resolved_version++; dns_maybe_finish_next_locked(exec_ctx, r); gpr_mu_unlock(&r->mu); GRPC_RESOLVER_UNREF(exec_ctx, &r->base, "dns-resolving"); }
static void on_handshake_done(grpc_exec_ctx *exec_ctx, void *arg, grpc_error *error) { grpc_handshaker_args *args = arg; server_connection_state *connection_state = args->user_data; gpr_mu_lock(&connection_state->server_state->mu); if (error != GRPC_ERROR_NONE || connection_state->server_state->shutdown) { const char *error_str = grpc_error_string(error); gpr_log(GPR_DEBUG, "Handshaking failed: %s", error_str); if (error == GRPC_ERROR_NONE && args->endpoint != NULL) { // We were shut down after handshaking completed successfully, so // destroy the endpoint here. // TODO(ctiller): It is currently necessary to shutdown endpoints // before destroying them, even if we know that there are no // pending read/write callbacks. This should be fixed, at which // point this can be removed. grpc_endpoint_shutdown(exec_ctx, args->endpoint, GRPC_ERROR_NONE); grpc_endpoint_destroy(exec_ctx, args->endpoint); grpc_channel_args_destroy(exec_ctx, args->args); grpc_slice_buffer_destroy_internal(exec_ctx, args->read_buffer); gpr_free(args->read_buffer); } } else { // If the handshaking succeeded but there is no endpoint, then the // handshaker may have handed off the connection to some external // code, so we can just clean up here without creating a transport. if (args->endpoint != NULL) { grpc_transport *transport = grpc_create_chttp2_transport(exec_ctx, args->args, args->endpoint, 0); grpc_server_setup_transport( exec_ctx, connection_state->server_state->server, transport, connection_state->accepting_pollset, args->args); grpc_chttp2_transport_start_reading(exec_ctx, transport, args->read_buffer); grpc_channel_args_destroy(exec_ctx, args->args); } } grpc_handshake_manager_pending_list_remove( &connection_state->server_state->pending_handshake_mgrs, connection_state->handshake_mgr); gpr_mu_unlock(&connection_state->server_state->mu); grpc_handshake_manager_destroy(exec_ctx, connection_state->handshake_mgr); grpc_tcp_server_unref(exec_ctx, connection_state->server_state->tcp_server); gpr_free(connection_state->acceptor); gpr_free(connection_state); }
void grpc_connectivity_state_set(grpc_exec_ctx *exec_ctx, grpc_connectivity_state_tracker *tracker, grpc_connectivity_state state, grpc_error *error, const char *reason) { grpc_connectivity_state cur = (grpc_connectivity_state)gpr_atm_no_barrier_load( &tracker->current_state_atm); grpc_connectivity_state_watcher *w; if (GRPC_TRACER_ON(grpc_connectivity_state_trace)) { const char *error_string = grpc_error_string(error); gpr_log(GPR_DEBUG, "SET: %p %s: %s --> %s [%s] error=%p %s", tracker, tracker->name, grpc_connectivity_state_name(cur), grpc_connectivity_state_name(state), reason, error, error_string); } switch (state) { case GRPC_CHANNEL_INIT: case GRPC_CHANNEL_CONNECTING: case GRPC_CHANNEL_IDLE: case GRPC_CHANNEL_READY: GPR_ASSERT(error == GRPC_ERROR_NONE); break; case GRPC_CHANNEL_SHUTDOWN: case GRPC_CHANNEL_TRANSIENT_FAILURE: GPR_ASSERT(error != GRPC_ERROR_NONE); break; } GRPC_ERROR_UNREF(tracker->current_error); tracker->current_error = error; if (cur == state) { return; } GPR_ASSERT(cur != GRPC_CHANNEL_SHUTDOWN); gpr_atm_no_barrier_store(&tracker->current_state_atm, state); while ((w = tracker->watchers) != NULL) { *w->current = state; tracker->watchers = w->next; if (GRPC_TRACER_ON(grpc_connectivity_state_trace)) { gpr_log(GPR_DEBUG, "NOTIFY: %p %s: %p", tracker, tracker->name, w->notify); } GRPC_CLOSURE_SCHED(exec_ctx, w->notify, GRPC_ERROR_REF(tracker->current_error)); gpr_free(w); } }
static void on_handshake_done(grpc_exec_ctx *exec_ctx, void *arg, grpc_error *error) { grpc_handshaker_args *args = arg; on_done_closure *c = args->user_data; if (error != GRPC_ERROR_NONE) { const char *msg = grpc_error_string(error); gpr_log(GPR_ERROR, "Secure transport setup failed: %s", msg); grpc_error_free_string(msg); c->func(exec_ctx, c->arg, NULL); } else { grpc_channel_args_destroy(args->args); grpc_slice_buffer_destroy(args->read_buffer); gpr_free(args->read_buffer); c->func(exec_ctx, c->arg, args->endpoint); } grpc_handshake_manager_destroy(exec_ctx, c->handshake_mgr); gpr_free(c); }
/* Queue a GRPC_OP_COMPLETED operation */ void grpc_cq_end_op(grpc_exec_ctx *exec_ctx, grpc_completion_queue *cc, void *tag, grpc_error *error, void (*done)(grpc_exec_ctx *exec_ctx, void *done_arg, grpc_cq_completion *storage), void *done_arg, grpc_cq_completion *storage) { int shutdown; int i; grpc_pollset_worker *pluck_worker; #ifndef NDEBUG int found = 0; #endif GPR_TIMER_BEGIN("grpc_cq_end_op", 0); if (grpc_api_trace || (grpc_trace_operation_failures && error != GRPC_ERROR_NONE)) { const char *errmsg = grpc_error_string(error); GRPC_API_TRACE( "grpc_cq_end_op(exec_ctx=%p, cc=%p, tag=%p, error=%s, done=%p, " "done_arg=%p, storage=%p)", 7, (exec_ctx, cc, tag, errmsg, done, done_arg, storage)); if (grpc_trace_operation_failures) { gpr_log(GPR_ERROR, "Operation failed: tag=%p, error=%s", tag, errmsg); } grpc_error_free_string(errmsg); } storage->tag = tag; storage->done = done; storage->done_arg = done_arg; storage->next = ((uintptr_t)&cc->completed_head) | ((uintptr_t)(error == GRPC_ERROR_NONE)); gpr_mu_lock(cc->mu); #ifndef NDEBUG for (i = 0; i < (int)cc->outstanding_tag_count; i++) { if (cc->outstanding_tags[i] == tag) { cc->outstanding_tag_count--; GPR_SWAP(void *, cc->outstanding_tags[i], cc->outstanding_tags[cc->outstanding_tag_count]); found = 1; break; } }
static void read_callback(uv_stream_t *stream, ssize_t nread, const uv_buf_t *buf) { grpc_slice sub; grpc_error *error; grpc_exec_ctx exec_ctx = GRPC_EXEC_CTX_INIT; grpc_tcp *tcp = stream->data; grpc_closure *cb = tcp->read_cb; if (nread == 0) { // Nothing happened. Wait for the next callback return; } TCP_UNREF(&exec_ctx, tcp, "read"); tcp->read_cb = NULL; // TODO(murgatroid99): figure out what the return value here means uv_read_stop(stream); if (nread == UV_EOF) { error = GRPC_ERROR_CREATE("EOF"); } else if (nread > 0) { // Successful read sub = grpc_slice_sub_no_ref(tcp->read_slice, 0, (size_t)nread); grpc_slice_buffer_add(tcp->read_slices, sub); error = GRPC_ERROR_NONE; if (grpc_tcp_trace) { size_t i; const char *str = grpc_error_string(error); gpr_log(GPR_DEBUG, "read: error=%s", str); for (i = 0; i < tcp->read_slices->count; i++) { char *dump = grpc_dump_slice(tcp->read_slices->slices[i], GPR_DUMP_HEX | GPR_DUMP_ASCII); gpr_log(GPR_DEBUG, "READ %p (peer=%s): %s", tcp, tcp->peer_string, dump); gpr_free(dump); } } } else { // nread < 0: Error error = GRPC_ERROR_CREATE("TCP Read failed"); } grpc_closure_sched(&exec_ctx, cb, error); grpc_exec_ctx_finish(&exec_ctx); }
static void call_read_cb(grpc_exec_ctx *exec_ctx, grpc_tcp *tcp, grpc_error *error) { grpc_closure *cb = tcp->read_cb; if (grpc_tcp_trace) { size_t i; const char *str = grpc_error_string(error); gpr_log(GPR_DEBUG, "read: error=%s", str); grpc_error_free_string(str); for (i = 0; i < tcp->incoming_buffer->count; i++) { char *dump = grpc_dump_slice(tcp->incoming_buffer->slices[i], GPR_DUMP_HEX | GPR_DUMP_ASCII); gpr_log(GPR_DEBUG, "READ %p (peer=%s): %s", tcp, tcp->peer_string, dump); gpr_free(dump); } } tcp->read_cb = NULL; tcp->incoming_buffer = NULL; grpc_closure_run(exec_ctx, cb, error); }
static void tc_on_alarm(grpc_exec_ctx *exec_ctx, void *acp, grpc_error *error) { int done; async_connect *ac = acp; if (grpc_tcp_trace) { const char *str = grpc_error_string(error); gpr_log(GPR_DEBUG, "CLIENT_CONNECT: %s: on_alarm: error=%s", ac->addr_str, str); } gpr_mu_lock(&ac->mu); if (ac->fd != NULL) { grpc_fd_shutdown(exec_ctx, ac->fd, GRPC_ERROR_CREATE_FROM_STATIC_STRING( "connect() timed out")); } done = (--ac->refs == 0); gpr_mu_unlock(&ac->mu); if (done) { gpr_mu_destroy(&ac->mu); gpr_free(ac->addr_str); grpc_channel_args_destroy(exec_ctx, ac->channel_args); gpr_free(ac); } }
static void write_callback(uv_write_t *req, int status) { grpc_tcp *tcp = req->data; grpc_error *error; grpc_exec_ctx exec_ctx = GRPC_EXEC_CTX_INIT; grpc_closure *cb = tcp->write_cb; tcp->write_cb = NULL; TCP_UNREF(&exec_ctx, tcp, "write"); if (status == 0) { error = GRPC_ERROR_NONE; } else { error = GRPC_ERROR_CREATE("TCP Write failed"); } if (grpc_tcp_trace) { const char *str = grpc_error_string(error); gpr_log(GPR_DEBUG, "write complete on %p: error=%s", tcp, str); } gpr_free(tcp->write_buffers); grpc_resource_user_free(&exec_ctx, tcp->resource_user, sizeof(uv_buf_t) * tcp->write_slices->count); grpc_closure_sched(&exec_ctx, cb, error); grpc_exec_ctx_finish(&exec_ctx); }
void grpc_connectivity_state_set(grpc_exec_ctx *exec_ctx, grpc_connectivity_state_tracker *tracker, grpc_connectivity_state state, grpc_error *error, const char *reason) { grpc_connectivity_state_watcher *w; if (grpc_connectivity_state_trace) { const char *error_string = grpc_error_string(error); gpr_log(GPR_DEBUG, "SET: %p %s: %s --> %s [%s] error=%p %s", tracker, tracker->name, grpc_connectivity_state_name(tracker->current_state), grpc_connectivity_state_name(state), reason, error, error_string); grpc_error_free_string(error_string); } switch (state) { case GRPC_CHANNEL_CONNECTING: case GRPC_CHANNEL_IDLE: case GRPC_CHANNEL_READY: GPR_ASSERT(error == GRPC_ERROR_NONE); break; case GRPC_CHANNEL_SHUTDOWN: case GRPC_CHANNEL_TRANSIENT_FAILURE: GPR_ASSERT(error != GRPC_ERROR_NONE); break; } GRPC_ERROR_UNREF(tracker->current_error); tracker->current_error = error; if (tracker->current_state == state) { return; } GPR_ASSERT(tracker->current_state != GRPC_CHANNEL_SHUTDOWN); tracker->current_state = state; while ((w = tracker->watchers) != NULL) { *w->current = tracker->current_state; tracker->watchers = w->next; grpc_exec_ctx_sched(exec_ctx, w->notify, GRPC_ERROR_REF(tracker->current_error), NULL); gpr_free(w); } }
static void uv_endpoint_read(grpc_exec_ctx *exec_ctx, grpc_endpoint *ep, grpc_slice_buffer *read_slices, grpc_closure *cb) { grpc_tcp *tcp = (grpc_tcp *)ep; int status; grpc_error *error = GRPC_ERROR_NONE; GPR_ASSERT(tcp->read_cb == NULL); tcp->read_cb = cb; tcp->read_slices = read_slices; grpc_slice_buffer_reset_and_unref_internal(exec_ctx, read_slices); TCP_REF(tcp, "read"); // TODO(murgatroid99): figure out what the return value here means status = uv_read_start((uv_stream_t *)tcp->handle, alloc_uv_buf, read_callback); if (status != 0) { error = GRPC_ERROR_CREATE("TCP Read failed at start"); error = grpc_error_set_str(error, GRPC_ERROR_STR_OS_ERROR, uv_strerror(status)); grpc_closure_sched(exec_ctx, cb, error); } if (grpc_tcp_trace) { const char *str = grpc_error_string(error); gpr_log(GPR_DEBUG, "Initiating read on %p: error=%s", tcp, str); } }
char *grpc_transport_op_string(grpc_transport_op *op) { char *tmp; char *out; bool first = true; gpr_strvec b; gpr_strvec_init(&b); if (op->on_connectivity_state_change != NULL) { if (!first) gpr_strvec_add(&b, gpr_strdup(" ")); first = false; if (op->connectivity_state != NULL) { gpr_asprintf(&tmp, "ON_CONNECTIVITY_STATE_CHANGE:p=%p:from=%s", op->on_connectivity_state_change, grpc_connectivity_state_name(*op->connectivity_state)); gpr_strvec_add(&b, tmp); } else { gpr_asprintf(&tmp, "ON_CONNECTIVITY_STATE_CHANGE:p=%p:unsubscribe", op->on_connectivity_state_change); gpr_strvec_add(&b, tmp); } } if (op->disconnect_with_error != GRPC_ERROR_NONE) { if (!first) gpr_strvec_add(&b, gpr_strdup(" ")); first = false; const char *err = grpc_error_string(op->disconnect_with_error); gpr_asprintf(&tmp, "DISCONNECT:%s", err); gpr_strvec_add(&b, tmp); grpc_error_free_string(err); } if (op->send_goaway) { if (!first) gpr_strvec_add(&b, gpr_strdup(" ")); first = false; char *msg = op->goaway_message == NULL ? "null" : grpc_dump_slice(*op->goaway_message, GPR_DUMP_ASCII | GPR_DUMP_HEX); gpr_asprintf(&tmp, "SEND_GOAWAY:status=%d:msg=%s", op->goaway_status, msg); if (op->goaway_message != NULL) gpr_free(msg); gpr_strvec_add(&b, tmp); } if (op->set_accept_stream) { if (!first) gpr_strvec_add(&b, gpr_strdup(" ")); first = false; gpr_asprintf(&tmp, "SET_ACCEPT_STREAM:%p(%p,...)", op->set_accept_stream_fn, op->set_accept_stream_user_data); gpr_strvec_add(&b, tmp); } if (op->bind_pollset != NULL) { if (!first) gpr_strvec_add(&b, gpr_strdup(" ")); first = false; gpr_strvec_add(&b, gpr_strdup("BIND_POLLSET")); } if (op->bind_pollset_set != NULL) { if (!first) gpr_strvec_add(&b, gpr_strdup(" ")); first = false; gpr_strvec_add(&b, gpr_strdup("BIND_POLLSET_SET")); } if (op->send_ping != NULL) { if (!first) gpr_strvec_add(&b, gpr_strdup(" ")); first = false; gpr_strvec_add(&b, gpr_strdup("SEND_PING")); } out = gpr_strvec_flatten(&b, NULL); gpr_strvec_destroy(&b); return out; }