/* grpc_run_batch_stack_cleanup ensures the run_batch_stack is properly * cleaned up */ static void grpc_run_batch_stack_cleanup(run_batch_stack *st) { size_t i = 0; grpc_metadata_array_destroy(&st->send_metadata); grpc_metadata_array_destroy(&st->send_trailing_metadata); grpc_metadata_array_destroy(&st->recv_metadata); grpc_metadata_array_destroy(&st->recv_trailing_metadata); if (GRPC_SLICE_START_PTR(st->send_status_details) != NULL) { grpc_slice_unref(st->send_status_details); } if (GRPC_SLICE_START_PTR(st->recv_status_details) != NULL) { grpc_slice_unref(st->recv_status_details); } if (st->recv_message != NULL) { grpc_byte_buffer_destroy(st->recv_message); } for (i = 0; i < st->op_num; i++) { if (st->ops[i].op == GRPC_OP_SEND_MESSAGE) { grpc_byte_buffer_destroy(st->ops[i].data.send_message.send_message); } } }
static int verify_jwt_signature(EVP_PKEY *key, const char *alg, grpc_slice signature, grpc_slice signed_data) { EVP_MD_CTX *md_ctx = EVP_MD_CTX_create(); const EVP_MD *md = evp_md_from_alg(alg); int result = 0; GPR_ASSERT(md != NULL); /* Checked before. */ if (md_ctx == NULL) { gpr_log(GPR_ERROR, "Could not create EVP_MD_CTX."); goto end; } if (EVP_DigestVerifyInit(md_ctx, NULL, md, NULL, key) != 1) { gpr_log(GPR_ERROR, "EVP_DigestVerifyInit failed."); goto end; } if (EVP_DigestVerifyUpdate(md_ctx, GRPC_SLICE_START_PTR(signed_data), GRPC_SLICE_LENGTH(signed_data)) != 1) { gpr_log(GPR_ERROR, "EVP_DigestVerifyUpdate failed."); goto end; } if (EVP_DigestVerifyFinal(md_ctx, GRPC_SLICE_START_PTR(signature), GRPC_SLICE_LENGTH(signature)) != 1) { gpr_log(GPR_ERROR, "JWT signature verification failed."); goto end; } result = 1; end: if (md_ctx != NULL) EVP_MD_CTX_destroy(md_ctx); return result; }
static void test_load_small_file(void) { FILE *tmp = NULL; grpc_slice slice; grpc_slice slice_with_null_term; grpc_error *error; char *tmp_name; const char *blah = "blah"; LOG_TEST_NAME("test_load_small_file"); tmp = gpr_tmpfile(prefix, &tmp_name); GPR_ASSERT(tmp_name != NULL); GPR_ASSERT(tmp != NULL); GPR_ASSERT(fwrite(blah, 1, strlen(blah), tmp) == strlen(blah)); fclose(tmp); error = grpc_load_file(tmp_name, 0, &slice); GPR_ASSERT(error == GRPC_ERROR_NONE); GPR_ASSERT(GRPC_SLICE_LENGTH(slice) == strlen(blah)); GPR_ASSERT(!memcmp(GRPC_SLICE_START_PTR(slice), blah, strlen(blah))); error = grpc_load_file(tmp_name, 1, &slice_with_null_term); GPR_ASSERT(error == GRPC_ERROR_NONE); GPR_ASSERT(GRPC_SLICE_LENGTH(slice_with_null_term) == (strlen(blah) + 1)); GPR_ASSERT(strcmp((const char *)GRPC_SLICE_START_PTR(slice_with_null_term), blah) == 0); remove(tmp_name); gpr_free(tmp_name); grpc_slice_unref(slice); grpc_slice_unref(slice_with_null_term); }
void grpc_split_slices(grpc_slice_split_mode mode, grpc_slice *src_slices, size_t src_slice_count, grpc_slice **dst_slices, size_t *dst_slice_count) { size_t i, j; size_t length; switch (mode) { case GRPC_SLICE_SPLIT_IDENTITY: *dst_slice_count = src_slice_count; *dst_slices = gpr_malloc(sizeof(grpc_slice) * src_slice_count); for (i = 0; i < src_slice_count; i++) { (*dst_slices)[i] = src_slices[i]; grpc_slice_ref((*dst_slices)[i]); } break; case GRPC_SLICE_SPLIT_MERGE_ALL: *dst_slice_count = 1; length = 0; for (i = 0; i < src_slice_count; i++) { length += GRPC_SLICE_LENGTH(src_slices[i]); } *dst_slices = gpr_malloc(sizeof(grpc_slice)); **dst_slices = grpc_slice_malloc(length); length = 0; for (i = 0; i < src_slice_count; i++) { memcpy(GRPC_SLICE_START_PTR(**dst_slices) + length, GRPC_SLICE_START_PTR(src_slices[i]), GRPC_SLICE_LENGTH(src_slices[i])); length += GRPC_SLICE_LENGTH(src_slices[i]); } break; case GRPC_SLICE_SPLIT_ONE_BYTE: length = 0; for (i = 0; i < src_slice_count; i++) { length += GRPC_SLICE_LENGTH(src_slices[i]); } *dst_slice_count = length; *dst_slices = gpr_malloc(sizeof(grpc_slice) * length); length = 0; for (i = 0; i < src_slice_count; i++) { for (j = 0; j < GRPC_SLICE_LENGTH(src_slices[i]); j++) { (*dst_slices)[length] = grpc_slice_sub(src_slices[i], j, j + 1); length++; } } break; } }
static int zlib_body(z_stream* zs, grpc_slice_buffer* input, grpc_slice_buffer* output, int (*flate)(z_stream* zs, int flush)) { int r; int flush; size_t i; grpc_slice outbuf = grpc_slice_malloc(OUTPUT_BLOCK_SIZE); const uInt uint_max = ~(uInt)0; GPR_ASSERT(GRPC_SLICE_LENGTH(outbuf) <= uint_max); zs->avail_out = (uInt)GRPC_SLICE_LENGTH(outbuf); zs->next_out = GRPC_SLICE_START_PTR(outbuf); flush = Z_NO_FLUSH; for (i = 0; i < input->count; i++) { if (i == input->count - 1) flush = Z_FINISH; GPR_ASSERT(GRPC_SLICE_LENGTH(input->slices[i]) <= uint_max); zs->avail_in = (uInt)GRPC_SLICE_LENGTH(input->slices[i]); zs->next_in = GRPC_SLICE_START_PTR(input->slices[i]); do { if (zs->avail_out == 0) { grpc_slice_buffer_add_indexed(output, outbuf); outbuf = grpc_slice_malloc(OUTPUT_BLOCK_SIZE); GPR_ASSERT(GRPC_SLICE_LENGTH(outbuf) <= uint_max); zs->avail_out = (uInt)GRPC_SLICE_LENGTH(outbuf); zs->next_out = GRPC_SLICE_START_PTR(outbuf); } r = flate(zs, flush); if (r < 0 && r != Z_BUF_ERROR /* not fatal */) { gpr_log(GPR_INFO, "zlib error (%d)", r); goto error; } } while (zs->avail_out == 0); if (zs->avail_in) { gpr_log(GPR_INFO, "zlib: not all input consumed"); goto error; } } GPR_ASSERT(outbuf.refcount); outbuf.data.refcounted.length -= zs->avail_out; grpc_slice_buffer_add_indexed(output, outbuf); return 1; error: grpc_slice_unref(outbuf); return 0; }
grpc_slice grpc_chttp2_window_update_create( uint32_t id, uint32_t window_update, grpc_transport_one_way_stats *stats) { static const size_t frame_size = 13; grpc_slice slice = GRPC_SLICE_MALLOC(frame_size); stats->header_bytes += frame_size; uint8_t *p = GRPC_SLICE_START_PTR(slice); GPR_ASSERT(window_update); *p++ = 0; *p++ = 0; *p++ = 4; *p++ = GRPC_CHTTP2_FRAME_WINDOW_UPDATE; *p++ = 0; *p++ = (uint8_t)(id >> 24); *p++ = (uint8_t)(id >> 16); *p++ = (uint8_t)(id >> 8); *p++ = (uint8_t)(id); *p++ = (uint8_t)(window_update >> 24); *p++ = (uint8_t)(window_update >> 16); *p++ = (uint8_t)(window_update >> 8); *p++ = (uint8_t)(window_update); return slice; }
grpc_error *grpc_chttp2_ping_parser_parse(grpc_exec_ctx *exec_ctx, void *parser, grpc_chttp2_transport *t, grpc_chttp2_stream *s, grpc_slice slice, int is_last) { uint8_t *const beg = GRPC_SLICE_START_PTR(slice); uint8_t *const end = GRPC_SLICE_END_PTR(slice); uint8_t *cur = beg; grpc_chttp2_ping_parser *p = parser; while (p->byte != 8 && cur != end) { p->opaque_8bytes[p->byte] = *cur; cur++; p->byte++; } if (p->byte == 8) { GPR_ASSERT(is_last); if (p->is_ack) { grpc_chttp2_ack_ping(exec_ctx, t, p->opaque_8bytes); } else { grpc_slice_buffer_add(&t->qbuf, grpc_chttp2_ping_create(1, p->opaque_8bytes)); grpc_chttp2_initiate_write(exec_ctx, t, false, "ping response"); } } return GRPC_ERROR_NONE; }
/* Takes ownership of creds_path if not NULL. */ static grpc_error *create_default_creds_from_path( grpc_exec_ctx *exec_ctx, char *creds_path, grpc_call_credentials **creds) { grpc_json *json = NULL; grpc_auth_json_key key; grpc_auth_refresh_token token; grpc_call_credentials *result = NULL; grpc_slice creds_data = grpc_empty_slice(); grpc_error *error = GRPC_ERROR_NONE; if (creds_path == NULL) { error = GRPC_ERROR_CREATE_FROM_STATIC_STRING("creds_path unset"); goto end; } error = grpc_load_file(creds_path, 0, &creds_data); if (error != GRPC_ERROR_NONE) { goto end; } json = grpc_json_parse_string_with_len( (char *)GRPC_SLICE_START_PTR(creds_data), GRPC_SLICE_LENGTH(creds_data)); if (json == NULL) { error = grpc_error_set_str( GRPC_ERROR_CREATE_FROM_STATIC_STRING("Failed to parse JSON"), GRPC_ERROR_STR_RAW_BYTES, grpc_slice_ref_internal(creds_data)); goto end; } /* First, try an auth json key. */ key = grpc_auth_json_key_create_from_json(json); if (grpc_auth_json_key_is_valid(&key)) { result = grpc_service_account_jwt_access_credentials_create_from_auth_json_key( exec_ctx, key, grpc_max_auth_token_lifetime()); if (result == NULL) { error = GRPC_ERROR_CREATE_FROM_STATIC_STRING( "grpc_service_account_jwt_access_credentials_create_from_auth_json_" "key failed"); } goto end; } /* Then try a refresh token if the auth json key was invalid. */ token = grpc_auth_refresh_token_create_from_json(json); if (grpc_auth_refresh_token_is_valid(&token)) { result = grpc_refresh_token_credentials_create_from_auth_refresh_token(token); if (result == NULL) { error = GRPC_ERROR_CREATE_FROM_STATIC_STRING( "grpc_refresh_token_credentials_create_from_auth_refresh_token " "failed"); } goto end; } end: GPR_ASSERT((result == NULL) + (error == GRPC_ERROR_NONE) == 1); if (creds_path != NULL) gpr_free(creds_path); grpc_slice_unref_internal(exec_ctx, creds_data); if (json != NULL) grpc_json_destroy(json); *creds = result; return error; }
static void test_load_big_file(void) { FILE *tmp = NULL; grpc_slice slice; grpc_error *error; char *tmp_name; static const size_t buffer_size = 124631; unsigned char *buffer = gpr_malloc(buffer_size); unsigned char *current; size_t i; LOG_TEST_NAME("test_load_big_file"); memset(buffer, 42, buffer_size); tmp = gpr_tmpfile(prefix, &tmp_name); GPR_ASSERT(tmp != NULL); GPR_ASSERT(tmp_name != NULL); GPR_ASSERT(fwrite(buffer, 1, buffer_size, tmp) == buffer_size); fclose(tmp); error = grpc_load_file(tmp_name, 0, &slice); GPR_ASSERT(error == GRPC_ERROR_NONE); GPR_ASSERT(GRPC_SLICE_LENGTH(slice) == buffer_size); current = GRPC_SLICE_START_PTR(slice); for (i = 0; i < buffer_size; i++) { GPR_ASSERT(current[i] == 42); } remove(tmp_name); gpr_free(tmp_name); grpc_slice_unref(slice); gpr_free(buffer); }
static void flush_write_staging_buffer(secure_endpoint *ep, uint8_t **cur, uint8_t **end) { grpc_slice_buffer_add(&ep->output_buffer, ep->write_staging_buffer); ep->write_staging_buffer = grpc_slice_malloc(STAGING_BUFFER_SIZE); *cur = GRPC_SLICE_START_PTR(ep->write_staging_buffer); *end = GRPC_SLICE_END_PTR(ep->write_staging_buffer); }
GPR_EXPORT const char* GPR_CALLTYPE grpcsharp_batch_context_recv_status_on_client_details( const grpcsharp_batch_context* ctx, size_t* details_length) { *details_length = GRPC_SLICE_LENGTH(ctx->recv_status_on_client.status_details); return (char*)GRPC_SLICE_START_PTR(ctx->recv_status_on_client.status_details); }
void create_jwt(const char *json_key_file_path, const char *service_url, const char *scope) { grpc_auth_json_key key; char *jwt; grpc_slice json_key_data; GPR_ASSERT(GRPC_LOG_IF_ERROR( "load_file", grpc_load_file(json_key_file_path, 1, &json_key_data))); key = grpc_auth_json_key_create_from_string( (const char *)GRPC_SLICE_START_PTR(json_key_data)); grpc_slice_unref(json_key_data); if (!grpc_auth_json_key_is_valid(&key)) { fprintf(stderr, "Could not parse json key.\n"); exit(1); } jwt = grpc_jwt_encode_and_sign( &key, service_url == NULL ? GRPC_JWT_OAUTH2_AUDIENCE : service_url, grpc_max_auth_token_lifetime(), scope); grpc_auth_json_key_destruct(&key); if (jwt == NULL) { fprintf(stderr, "Could not create JWT.\n"); exit(1); } fprintf(stdout, "%s\n", jwt); gpr_free(jwt); }
int grpc_slice_rchr(grpc_slice s, char c) { const char *b = (const char *)GRPC_SLICE_START_PTR(s); int i; for (i = (int)GRPC_SLICE_LENGTH(s) - 1; i != -1 && b[i] != c; i--) ; return i; }
/* * Gets the next slice from recv_message byte buffer. * Returns 1 if a slice was get successfully, 0 if there are no more slices to * read. Set slice_len to the length of the slice and the slice_data_ptr to * point to slice's data. Caller must ensure that the byte buffer being read * from stays alive as long as the data of the slice are being accessed * (grpc_byte_buffer_reader_peek method is used internally) * * Remarks: * Slices can only be iterated once. * Initializes recv_message_buffer_reader if it was not initialized yet. */ GPR_EXPORT int GPR_CALLTYPE grpcsharp_batch_context_recv_message_next_slice_peek( grpcsharp_batch_context* ctx, size_t* slice_len, uint8_t** slice_data_ptr) { *slice_len = 0; *slice_data_ptr = NULL; if (!ctx->recv_message) { return 0; } if (!ctx->recv_message_reader) { ctx->recv_message_reader = &ctx->reserved_recv_message_reader; GPR_ASSERT(grpc_byte_buffer_reader_init(ctx->recv_message_reader, ctx->recv_message)); } grpc_slice* slice_ptr; if (!grpc_byte_buffer_reader_peek(ctx->recv_message_reader, &slice_ptr)) { return 0; } /* recv_message buffer must not be deleted before all the data is read */ *slice_len = GRPC_SLICE_LENGTH(*slice_ptr); *slice_data_ptr = GRPC_SLICE_START_PTR(*slice_ptr); return 1; }
static void flush_read_staging_buffer(secure_endpoint *ep, uint8_t **cur, uint8_t **end) { grpc_slice_buffer_add(ep->read_buffer, ep->read_staging_buffer); ep->read_staging_buffer = GRPC_SLICE_MALLOC(STAGING_BUFFER_SIZE); *cur = GRPC_SLICE_START_PTR(ep->read_staging_buffer); *end = GRPC_SLICE_END_PTR(ep->read_staging_buffer); }
void grpc_chttp2_encode_data(uint32_t id, grpc_slice_buffer *inbuf, uint32_t write_bytes, int is_eof, grpc_transport_one_way_stats *stats, grpc_slice_buffer *outbuf) { grpc_slice hdr; uint8_t *p; static const size_t header_size = 9; hdr = grpc_slice_malloc(header_size); p = GRPC_SLICE_START_PTR(hdr); GPR_ASSERT(write_bytes < (1 << 24)); *p++ = (uint8_t)(write_bytes >> 16); *p++ = (uint8_t)(write_bytes >> 8); *p++ = (uint8_t)(write_bytes); *p++ = GRPC_CHTTP2_FRAME_DATA; *p++ = is_eof ? GRPC_CHTTP2_DATA_FLAG_END_STREAM : 0; *p++ = (uint8_t)(id >> 24); *p++ = (uint8_t)(id >> 16); *p++ = (uint8_t)(id >> 8); *p++ = (uint8_t)(id); grpc_slice_buffer_add(outbuf, hdr); grpc_slice_buffer_move_first(inbuf, write_bytes, outbuf); stats->framing_bytes += header_size; stats->data_bytes += write_bytes; }
static void test_load_empty_file(void) { FILE *tmp = NULL; grpc_slice slice; grpc_slice slice_with_null_term; grpc_error *error; char *tmp_name; LOG_TEST_NAME("test_load_empty_file"); tmp = gpr_tmpfile(prefix, &tmp_name); GPR_ASSERT(tmp_name != NULL); GPR_ASSERT(tmp != NULL); fclose(tmp); error = grpc_load_file(tmp_name, 0, &slice); GPR_ASSERT(error == GRPC_ERROR_NONE); GPR_ASSERT(GRPC_SLICE_LENGTH(slice) == 0); error = grpc_load_file(tmp_name, 1, &slice_with_null_term); GPR_ASSERT(error == GRPC_ERROR_NONE); GPR_ASSERT(GRPC_SLICE_LENGTH(slice_with_null_term) == 1); GPR_ASSERT(GRPC_SLICE_START_PTR(slice_with_null_term)[0] == 0); remove(tmp_name); gpr_free(tmp_name); grpc_slice_unref(slice); grpc_slice_unref(slice_with_null_term); }
grpc_slice grpc_byte_buffer_reader_readall(grpc_byte_buffer_reader *reader) { grpc_slice in_slice; size_t bytes_read = 0; const size_t input_size = grpc_byte_buffer_length(reader->buffer_out); grpc_slice out_slice = grpc_slice_malloc(input_size); uint8_t *const outbuf = GRPC_SLICE_START_PTR(out_slice); /* just an alias */ while (grpc_byte_buffer_reader_next(reader, &in_slice) != 0) { const size_t slice_length = GRPC_SLICE_LENGTH(in_slice); memcpy(&(outbuf[bytes_read]), GRPC_SLICE_START_PTR(in_slice), slice_length); bytes_read += slice_length; grpc_slice_unref(in_slice); GPR_ASSERT(bytes_read <= input_size); } return out_slice; }
static void win_read(grpc_exec_ctx *exec_ctx, grpc_endpoint *ep, grpc_slice_buffer *read_slices, grpc_closure *cb) { grpc_tcp *tcp = (grpc_tcp *)ep; grpc_winsocket *handle = tcp->socket; grpc_winsocket_callback_info *info = &handle->read_info; int status; DWORD bytes_read = 0; DWORD flags = 0; WSABUF buffer; if (tcp->shutting_down) { GRPC_CLOSURE_SCHED( exec_ctx, cb, GRPC_ERROR_CREATE_REFERENCING_FROM_STATIC_STRING( "TCP socket is shutting down", &tcp->shutdown_error, 1)); return; } tcp->read_cb = cb; tcp->read_slices = read_slices; grpc_slice_buffer_reset_and_unref_internal(exec_ctx, read_slices); tcp->read_slice = GRPC_SLICE_MALLOC(8192); buffer.len = (ULONG)GRPC_SLICE_LENGTH( tcp->read_slice); // we know slice size fits in 32bit. buffer.buf = (char *)GRPC_SLICE_START_PTR(tcp->read_slice); TCP_REF(tcp, "read"); /* First let's try a synchronous, non-blocking read. */ status = WSARecv(tcp->socket->socket, &buffer, 1, &bytes_read, &flags, NULL, NULL); info->wsa_error = status == 0 ? 0 : WSAGetLastError(); /* Did we get data immediately ? Yay. */ if (info->wsa_error != WSAEWOULDBLOCK) { info->bytes_transfered = bytes_read; GRPC_CLOSURE_SCHED(exec_ctx, &tcp->on_read, GRPC_ERROR_NONE); return; } /* Otherwise, let's retry, by queuing a read. */ memset(&tcp->socket->read_info.overlapped, 0, sizeof(OVERLAPPED)); status = WSARecv(tcp->socket->socket, &buffer, 1, &bytes_read, &flags, &info->overlapped, NULL); if (status != 0) { int wsa_error = WSAGetLastError(); if (wsa_error != WSA_IO_PENDING) { info->wsa_error = wsa_error; GRPC_CLOSURE_SCHED(exec_ctx, &tcp->on_read, GRPC_WSA_ERROR(info->wsa_error, "WSARecv")); return; } } grpc_socket_notify_on_read(exec_ctx, tcp->socket, &tcp->on_read); }
static grpc_call_credentials *create_refresh_token_creds( const char *json_refresh_token_file_path) { grpc_slice refresh_token; GPR_ASSERT(GRPC_LOG_IF_ERROR( "load_file", grpc_load_file(json_refresh_token_file_path, 1, &refresh_token))); return grpc_google_refresh_token_credentials_create( (const char *)GRPC_SLICE_START_PTR(refresh_token), NULL); }
static void uv_endpoint_write(grpc_exec_ctx *exec_ctx, grpc_endpoint *ep, grpc_slice_buffer *write_slices, grpc_closure *cb) { grpc_tcp *tcp = (grpc_tcp *)ep; uv_buf_t *buffers; unsigned int buffer_count; unsigned int i; grpc_slice *slice; uv_write_t *write_req; if (grpc_tcp_trace) { size_t j; for (j = 0; j < write_slices->count; j++) { char *data = grpc_dump_slice(write_slices->slices[j], GPR_DUMP_HEX | GPR_DUMP_ASCII); gpr_log(GPR_DEBUG, "WRITE %p (peer=%s): %s", tcp, tcp->peer_string, data); gpr_free(data); } } if (tcp->shutting_down) { grpc_closure_sched(exec_ctx, cb, GRPC_ERROR_CREATE("TCP socket is shutting down")); return; } GPR_ASSERT(tcp->write_cb == NULL); tcp->write_slices = write_slices; GPR_ASSERT(tcp->write_slices->count <= UINT_MAX); if (tcp->write_slices->count == 0) { // No slices means we don't have to do anything, // and libuv doesn't like empty writes grpc_closure_sched(exec_ctx, cb, GRPC_ERROR_NONE); return; } tcp->write_cb = cb; buffer_count = (unsigned int)tcp->write_slices->count; buffers = gpr_malloc(sizeof(uv_buf_t) * buffer_count); grpc_resource_user_alloc(exec_ctx, tcp->resource_user, sizeof(uv_buf_t) * buffer_count, NULL); for (i = 0; i < buffer_count; i++) { slice = &tcp->write_slices->slices[i]; buffers[i].base = (char *)GRPC_SLICE_START_PTR(*slice); buffers[i].len = GRPC_SLICE_LENGTH(*slice); } tcp->write_buffers = buffers; write_req = &tcp->write_req; write_req->data = tcp; TCP_REF(tcp, "write"); // TODO(murgatroid99): figure out what the return value here means uv_write(write_req, (uv_stream_t *)tcp->handle, buffers, buffer_count, write_callback); }
static void alloc_uv_buf(uv_handle_t *handle, size_t suggested_size, uv_buf_t *buf) { grpc_exec_ctx exec_ctx = GRPC_EXEC_CTX_INIT; grpc_tcp *tcp = handle->data; (void)suggested_size; tcp->read_slice = grpc_resource_user_slice_malloc( &exec_ctx, tcp->resource_user, GRPC_TCP_DEFAULT_READ_SLICE_SIZE); buf->base = (char *)GRPC_SLICE_START_PTR(tcp->read_slice); buf->len = GRPC_SLICE_LENGTH(tcp->read_slice); grpc_exec_ctx_finish(&exec_ctx); }
int grpc_slice_slice(grpc_slice haystack, grpc_slice needle) { size_t haystack_len = GRPC_SLICE_LENGTH(haystack); const uint8_t *haystack_bytes = GRPC_SLICE_START_PTR(haystack); size_t needle_len = GRPC_SLICE_LENGTH(needle); const uint8_t *needle_bytes = GRPC_SLICE_START_PTR(needle); if (haystack_len == 0 || needle_len == 0) return -1; if (haystack_len < needle_len) return -1; if (haystack_len == needle_len) return grpc_slice_eq(haystack, needle) ? 0 : -1; if (needle_len == 1) return grpc_slice_chr(haystack, (char)*needle_bytes); const uint8_t *last = haystack_bytes + haystack_len - needle_len; for (const uint8_t *cur = haystack_bytes; cur != last; ++cur) { if (0 == memcmp(cur, needle_bytes, needle_len)) { return (int)(cur - haystack_bytes); } } return -1; }
static grpc_error *conforms_to(grpc_slice slice, const uint8_t *legal_bits, const char *err_desc) { const uint8_t *p = GRPC_SLICE_START_PTR(slice); const uint8_t *e = GRPC_SLICE_END_PTR(slice); for (; p != e; p++) { int idx = *p; int byte = idx / 8; int bit = idx % 8; if ((legal_bits[byte] & (1 << bit)) == 0) { char *dump = grpc_dump_slice(slice, GPR_DUMP_HEX | GPR_DUMP_ASCII); grpc_error *error = grpc_error_set_str( grpc_error_set_int(GRPC_ERROR_CREATE_FROM_COPIED_STRING(err_desc), GRPC_ERROR_INT_OFFSET, p - GRPC_SLICE_START_PTR(slice)), GRPC_ERROR_STR_RAW_BYTES, grpc_slice_from_copied_string(dump)); gpr_free(dump); return error; } } return GRPC_ERROR_NONE; }
grpc_error *grpc_chttp2_window_update_parser_parse( grpc_exec_ctx *exec_ctx, void *parser, grpc_chttp2_transport *t, grpc_chttp2_stream *s, grpc_slice slice, int is_last) { uint8_t *const beg = GRPC_SLICE_START_PTR(slice); uint8_t *const end = GRPC_SLICE_END_PTR(slice); uint8_t *cur = beg; grpc_chttp2_window_update_parser *p = parser; while (p->byte != 4 && cur != end) { p->amount |= ((uint32_t)*cur) << (8 * (3 - p->byte)); cur++; p->byte++; } if (s != NULL) { s->stats.incoming.framing_bytes += (uint32_t)(end - cur); } if (p->byte == 4) { uint32_t received_update = p->amount; if (received_update == 0 || (received_update & 0x80000000u)) { char *msg; gpr_asprintf(&msg, "invalid window update bytes: %d", p->amount); grpc_error *err = GRPC_ERROR_CREATE_FROM_COPIED_STRING(msg); gpr_free(msg); return err; } GPR_ASSERT(is_last); if (t->incoming_stream_id != 0) { if (s != NULL) { GRPC_CHTTP2_FLOW_CREDIT_STREAM("parse", t, s, outgoing_window_delta, received_update); if (grpc_chttp2_list_remove_stalled_by_stream(t, s)) { grpc_chttp2_become_writable( exec_ctx, t, s, GRPC_CHTTP2_STREAM_WRITE_INITIATE_UNCOVERED, "stream.read_flow_control"); } } } else { bool was_zero = t->outgoing_window <= 0; GRPC_CHTTP2_FLOW_CREDIT_TRANSPORT("parse", t, outgoing_window, received_update); bool is_zero = t->outgoing_window <= 0; if (was_zero && !is_zero) { grpc_chttp2_initiate_write(exec_ctx, t, "new_global_flow_control"); } } } return GRPC_ERROR_NONE; }
/* finish a frame - fill in the previously reserved header */ static void finish_frame(framer_state *st, int is_header_boundary, int is_last_in_stream) { uint8_t type = 0xff; type = st->is_first_frame ? GRPC_CHTTP2_FRAME_HEADER : GRPC_CHTTP2_FRAME_CONTINUATION; fill_header( GRPC_SLICE_START_PTR(st->output->slices[st->header_idx]), type, st->stream_id, st->output->length - st->output_length_at_start_of_frame, (uint8_t)((is_last_in_stream ? GRPC_CHTTP2_DATA_FLAG_END_STREAM : 0) | (is_header_boundary ? GRPC_CHTTP2_DATA_FLAG_END_HEADERS : 0))); st->stats->framing_bytes += 9; st->is_first_frame = 0; }
grpc_slice grpc_slice_sub(grpc_slice source, size_t begin, size_t end) { grpc_slice subset; if (end - begin <= sizeof(subset.data.inlined.bytes)) { subset.refcount = NULL; subset.data.inlined.length = (uint8_t)(end - begin); memcpy(subset.data.inlined.bytes, GRPC_SLICE_START_PTR(source) + begin, end - begin); } else { subset = grpc_slice_sub_no_ref(source, begin, end); /* Bump the refcount */ subset.refcount->ref(subset.refcount); } return subset; }
static BIGNUM *bignum_from_base64(const char *b64) { BIGNUM *result = NULL; grpc_slice bin; if (b64 == NULL) return NULL; bin = grpc_base64_decode(b64, 1); if (GRPC_SLICE_IS_EMPTY(bin)) { gpr_log(GPR_ERROR, "Invalid base64 for big num."); return NULL; } result = BN_bin2bn(GRPC_SLICE_START_PTR(bin), TSI_SIZE_AS_SIZE(GRPC_SLICE_LENGTH(bin)), NULL); grpc_slice_unref(bin); return result; }
static size_t count_slices(grpc_slice *slices, size_t nslices, int *current_data) { size_t num_bytes = 0; unsigned i, j; unsigned char *buf; for (i = 0; i < nslices; ++i) { buf = GRPC_SLICE_START_PTR(slices[i]); for (j = 0; j < GRPC_SLICE_LENGTH(slices[i]); ++j) { GPR_ASSERT(buf[j] == *current_data); *current_data = (*current_data + 1) % 256; } num_bytes += GRPC_SLICE_LENGTH(slices[i]); } return num_bytes; }
grpc_error *grpc_validate_header_key_is_legal(grpc_slice slice) { static const uint8_t legal_header_bits[256 / 8] = { 0x00, 0x00, 0x00, 0x00, 0x00, 0x60, 0xff, 0x03, 0x00, 0x00, 0x00, 0x80, 0xfe, 0xff, 0xff, 0x07, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}; if (GRPC_SLICE_LENGTH(slice) == 0) { return GRPC_ERROR_CREATE_FROM_STATIC_STRING( "Metadata keys cannot be zero length"); } if (GRPC_SLICE_START_PTR(slice)[0] == ':') { return GRPC_ERROR_CREATE_FROM_STATIC_STRING( "Metadata keys cannot start with :"); } return conforms_to(slice, legal_header_bits, "Illegal header key"); }