static int handle_handshake_response (BlockTxClient *client) { BlockTxInfo *info = client->info; struct evbuffer *input = client->recv_buf; HandshakeResponse rsp; if (evbuffer_get_length (input) < sizeof(rsp)) return 0; evbuffer_remove (input, &rsp, sizeof(rsp)); rsp.status = ntohl(rsp.status); rsp.version = ntohl(rsp.version); if (rsp.status == STATUS_OK) { seaf_debug ("Handshake OK.\n"); client->version = MIN (rsp.version, BLOCK_PROTOCOL_VERSION); if (client->version == 1) blocktx_generate_encrypt_key (info->session_key, sizeof(info->session_key), client->key, client->iv); else if (client->version == 2) blocktx_generate_encrypt_key (info->session_key, sizeof(info->session_key), client->key_v2, client->iv_v2); else { seaf_warning ("Bad block protocol version %d.\n", rsp.version); info->result = BLOCK_CLIENT_FAILED; return -1; } seaf_debug ("Block protocol version %d.\n", client->version); init_frame_parser (client); if (send_authentication (client) < 0) return -1; return 0; } else if (rsp.status == STATUS_VERSION_MISMATCH) { seaf_warning ("The server refuse to accpet protocol version %d.\n" "Remote version is %d.\n", BLOCK_PROTOCOL_VERSION, rsp.version); /* this is a hard error. */ info->result = BLOCK_CLIENT_FAILED; return -1; } else if (rsp.status == STATUS_INTERNAL_SERVER_ERROR) { seaf_warning ("Internal server error.\n"); info->result = BLOCK_CLIENT_SERVER_ERROR; return -1; } seaf_warning ("Bad status code %d in handshake.\n", rsp.status); info->result = BLOCK_CLIENT_FAILED; return -1; }
static int process_session_key (BlockTxServer *server, unsigned char *enc_session_key) { char *enc_key_b64 = NULL, *key_b64 = NULL; unsigned char *session_key = NULL; gsize len; SearpcClient *client = NULL; int ret = 0; client = ccnet_create_pooled_rpc_client (seaf->client_pool, NULL, "ccnet-rpcserver"); if (!client) { seaf_warning ("Failed to create rpc client.\n"); send_handshake_response (server, STATUS_INTERNAL_SERVER_ERROR); ret = -1; goto out; } enc_key_b64 = g_base64_encode (enc_session_key, server->session_key_len); key_b64 = ccnet_privkey_decrypt (client, enc_key_b64); if (!key_b64) { seaf_warning ("Failed to decrypt session key.\n"); send_handshake_response (server, STATUS_INTERNAL_SERVER_ERROR); ret = -1; goto out; } session_key = g_base64_decode (key_b64, &len); if (server->version == 1) blocktx_generate_encrypt_key (session_key, len, server->key, server->iv); else if (server->version == 2) blocktx_generate_encrypt_key (session_key, len, server->key_v2, server->iv_v2); init_frame_parser (server); out: g_free (enc_key_b64); g_free (key_b64); g_free (session_key); ccnet_rpc_client_free (client); return ret; }
grpc_error *grpc_chttp2_perform_read(grpc_exec_ctx *exec_ctx, grpc_chttp2_transport *t, grpc_slice slice) { uint8_t *beg = GRPC_SLICE_START_PTR(slice); uint8_t *end = GRPC_SLICE_END_PTR(slice); uint8_t *cur = beg; grpc_error *err; if (cur == end) return GRPC_ERROR_NONE; switch (t->deframe_state) { case GRPC_DTS_CLIENT_PREFIX_0: case GRPC_DTS_CLIENT_PREFIX_1: case GRPC_DTS_CLIENT_PREFIX_2: case GRPC_DTS_CLIENT_PREFIX_3: case GRPC_DTS_CLIENT_PREFIX_4: case GRPC_DTS_CLIENT_PREFIX_5: case GRPC_DTS_CLIENT_PREFIX_6: case GRPC_DTS_CLIENT_PREFIX_7: case GRPC_DTS_CLIENT_PREFIX_8: case GRPC_DTS_CLIENT_PREFIX_9: case GRPC_DTS_CLIENT_PREFIX_10: case GRPC_DTS_CLIENT_PREFIX_11: case GRPC_DTS_CLIENT_PREFIX_12: case GRPC_DTS_CLIENT_PREFIX_13: case GRPC_DTS_CLIENT_PREFIX_14: case GRPC_DTS_CLIENT_PREFIX_15: case GRPC_DTS_CLIENT_PREFIX_16: case GRPC_DTS_CLIENT_PREFIX_17: case GRPC_DTS_CLIENT_PREFIX_18: case GRPC_DTS_CLIENT_PREFIX_19: case GRPC_DTS_CLIENT_PREFIX_20: case GRPC_DTS_CLIENT_PREFIX_21: case GRPC_DTS_CLIENT_PREFIX_22: case GRPC_DTS_CLIENT_PREFIX_23: while (cur != end && t->deframe_state != GRPC_DTS_FH_0) { if (*cur != GRPC_CHTTP2_CLIENT_CONNECT_STRING[t->deframe_state]) { char *msg; gpr_asprintf( &msg, "Connect string mismatch: expected '%c' (%d) got '%c' (%d) " "at byte %d", GRPC_CHTTP2_CLIENT_CONNECT_STRING[t->deframe_state], (int)(uint8_t)GRPC_CHTTP2_CLIENT_CONNECT_STRING[t->deframe_state], *cur, (int)*cur, t->deframe_state); err = GRPC_ERROR_CREATE_FROM_COPIED_STRING(msg); gpr_free(msg); return err; } ++cur; t->deframe_state = (grpc_chttp2_deframe_transport_state)(1 + (int)t->deframe_state); } if (cur == end) { return GRPC_ERROR_NONE; } /* fallthrough */ dts_fh_0: case GRPC_DTS_FH_0: GPR_ASSERT(cur < end); t->incoming_frame_size = ((uint32_t)*cur) << 16; if (++cur == end) { t->deframe_state = GRPC_DTS_FH_1; return GRPC_ERROR_NONE; } /* fallthrough */ case GRPC_DTS_FH_1: GPR_ASSERT(cur < end); t->incoming_frame_size |= ((uint32_t)*cur) << 8; if (++cur == end) { t->deframe_state = GRPC_DTS_FH_2; return GRPC_ERROR_NONE; } /* fallthrough */ case GRPC_DTS_FH_2: GPR_ASSERT(cur < end); t->incoming_frame_size |= *cur; if (++cur == end) { t->deframe_state = GRPC_DTS_FH_3; return GRPC_ERROR_NONE; } /* fallthrough */ case GRPC_DTS_FH_3: GPR_ASSERT(cur < end); t->incoming_frame_type = *cur; if (++cur == end) { t->deframe_state = GRPC_DTS_FH_4; return GRPC_ERROR_NONE; } /* fallthrough */ case GRPC_DTS_FH_4: GPR_ASSERT(cur < end); t->incoming_frame_flags = *cur; if (++cur == end) { t->deframe_state = GRPC_DTS_FH_5; return GRPC_ERROR_NONE; } /* fallthrough */ case GRPC_DTS_FH_5: GPR_ASSERT(cur < end); t->incoming_stream_id = (((uint32_t)*cur) & 0x7f) << 24; if (++cur == end) { t->deframe_state = GRPC_DTS_FH_6; return GRPC_ERROR_NONE; } /* fallthrough */ case GRPC_DTS_FH_6: GPR_ASSERT(cur < end); t->incoming_stream_id |= ((uint32_t)*cur) << 16; if (++cur == end) { t->deframe_state = GRPC_DTS_FH_7; return GRPC_ERROR_NONE; } /* fallthrough */ case GRPC_DTS_FH_7: GPR_ASSERT(cur < end); t->incoming_stream_id |= ((uint32_t)*cur) << 8; if (++cur == end) { t->deframe_state = GRPC_DTS_FH_8; return GRPC_ERROR_NONE; } /* fallthrough */ case GRPC_DTS_FH_8: GPR_ASSERT(cur < end); t->incoming_stream_id |= ((uint32_t)*cur); t->deframe_state = GRPC_DTS_FRAME; err = init_frame_parser(exec_ctx, t); if (err != GRPC_ERROR_NONE) { return err; } if (t->incoming_frame_size == 0) { err = parse_frame_slice(exec_ctx, t, grpc_empty_slice(), 1); if (err != GRPC_ERROR_NONE) { return err; } t->incoming_stream = NULL; if (++cur == end) { t->deframe_state = GRPC_DTS_FH_0; return GRPC_ERROR_NONE; } goto dts_fh_0; /* loop */ } else if (t->incoming_frame_size > t->settings[GRPC_ACKED_SETTINGS] [GRPC_CHTTP2_SETTINGS_MAX_FRAME_SIZE]) { char *msg; gpr_asprintf(&msg, "Frame size %d is larger than max frame size %d", t->incoming_frame_size, t->settings[GRPC_ACKED_SETTINGS] [GRPC_CHTTP2_SETTINGS_MAX_FRAME_SIZE]); err = GRPC_ERROR_CREATE_FROM_COPIED_STRING(msg); gpr_free(msg); return err; } if (++cur == end) { return GRPC_ERROR_NONE; } /* fallthrough */ case GRPC_DTS_FRAME: GPR_ASSERT(cur < end); if ((uint32_t)(end - cur) == t->incoming_frame_size) { err = parse_frame_slice( exec_ctx, t, grpc_slice_sub_no_ref(slice, (size_t)(cur - beg), (size_t)(end - beg)), 1); if (err != GRPC_ERROR_NONE) { return err; } t->deframe_state = GRPC_DTS_FH_0; t->incoming_stream = NULL; return GRPC_ERROR_NONE; } else if ((uint32_t)(end - cur) > t->incoming_frame_size) { size_t cur_offset = (size_t)(cur - beg); err = parse_frame_slice( exec_ctx, t, grpc_slice_sub_no_ref(slice, cur_offset, cur_offset + t->incoming_frame_size), 1); if (err != GRPC_ERROR_NONE) { return err; } cur += t->incoming_frame_size; t->incoming_stream = NULL; goto dts_fh_0; /* loop */ } else { err = parse_frame_slice( exec_ctx, t, grpc_slice_sub_no_ref(slice, (size_t)(cur - beg), (size_t)(end - beg)), 0); if (err != GRPC_ERROR_NONE) { return err; } t->incoming_frame_size -= (uint32_t)(end - cur); return GRPC_ERROR_NONE; } GPR_UNREACHABLE_CODE(return 0); } GPR_UNREACHABLE_CODE(return 0); }
int grpc_chttp2_perform_read(grpc_chttp2_transport_parsing *transport_parsing, gpr_slice slice) { gpr_uint8 *beg = GPR_SLICE_START_PTR(slice); gpr_uint8 *end = GPR_SLICE_END_PTR(slice); gpr_uint8 *cur = beg; if (cur == end) return 1; switch (transport_parsing->deframe_state) { case GRPC_DTS_CLIENT_PREFIX_0: case GRPC_DTS_CLIENT_PREFIX_1: case GRPC_DTS_CLIENT_PREFIX_2: case GRPC_DTS_CLIENT_PREFIX_3: case GRPC_DTS_CLIENT_PREFIX_4: case GRPC_DTS_CLIENT_PREFIX_5: case GRPC_DTS_CLIENT_PREFIX_6: case GRPC_DTS_CLIENT_PREFIX_7: case GRPC_DTS_CLIENT_PREFIX_8: case GRPC_DTS_CLIENT_PREFIX_9: case GRPC_DTS_CLIENT_PREFIX_10: case GRPC_DTS_CLIENT_PREFIX_11: case GRPC_DTS_CLIENT_PREFIX_12: case GRPC_DTS_CLIENT_PREFIX_13: case GRPC_DTS_CLIENT_PREFIX_14: case GRPC_DTS_CLIENT_PREFIX_15: case GRPC_DTS_CLIENT_PREFIX_16: case GRPC_DTS_CLIENT_PREFIX_17: case GRPC_DTS_CLIENT_PREFIX_18: case GRPC_DTS_CLIENT_PREFIX_19: case GRPC_DTS_CLIENT_PREFIX_20: case GRPC_DTS_CLIENT_PREFIX_21: case GRPC_DTS_CLIENT_PREFIX_22: case GRPC_DTS_CLIENT_PREFIX_23: while (cur != end && transport_parsing->deframe_state != GRPC_DTS_FH_0) { if (*cur != GRPC_CHTTP2_CLIENT_CONNECT_STRING[transport_parsing ->deframe_state]) { gpr_log(GPR_INFO, "Connect string mismatch: expected '%c' (%d) got '%c' (%d) " "at byte %d", GRPC_CHTTP2_CLIENT_CONNECT_STRING[transport_parsing ->deframe_state], (int)(gpr_uint8)GRPC_CHTTP2_CLIENT_CONNECT_STRING [transport_parsing->deframe_state], *cur, (int)*cur, transport_parsing->deframe_state); return 0; } ++cur; ++transport_parsing->deframe_state; } if (cur == end) { return 1; } /* fallthrough */ dts_fh_0: case GRPC_DTS_FH_0: GPR_ASSERT(cur < end); transport_parsing->incoming_frame_size = ((gpr_uint32)*cur) << 16; if (++cur == end) { transport_parsing->deframe_state = GRPC_DTS_FH_1; return 1; } /* fallthrough */ case GRPC_DTS_FH_1: GPR_ASSERT(cur < end); transport_parsing->incoming_frame_size |= ((gpr_uint32)*cur) << 8; if (++cur == end) { transport_parsing->deframe_state = GRPC_DTS_FH_2; return 1; } /* fallthrough */ case GRPC_DTS_FH_2: GPR_ASSERT(cur < end); transport_parsing->incoming_frame_size |= *cur; if (++cur == end) { transport_parsing->deframe_state = GRPC_DTS_FH_3; return 1; } /* fallthrough */ case GRPC_DTS_FH_3: GPR_ASSERT(cur < end); transport_parsing->incoming_frame_type = *cur; if (++cur == end) { transport_parsing->deframe_state = GRPC_DTS_FH_4; return 1; } /* fallthrough */ case GRPC_DTS_FH_4: GPR_ASSERT(cur < end); transport_parsing->incoming_frame_flags = *cur; if (++cur == end) { transport_parsing->deframe_state = GRPC_DTS_FH_5; return 1; } /* fallthrough */ case GRPC_DTS_FH_5: GPR_ASSERT(cur < end); transport_parsing->incoming_stream_id = (((gpr_uint32)*cur) & 0x7f) << 24; if (++cur == end) { transport_parsing->deframe_state = GRPC_DTS_FH_6; return 1; } /* fallthrough */ case GRPC_DTS_FH_6: GPR_ASSERT(cur < end); transport_parsing->incoming_stream_id |= ((gpr_uint32)*cur) << 16; if (++cur == end) { transport_parsing->deframe_state = GRPC_DTS_FH_7; return 1; } /* fallthrough */ case GRPC_DTS_FH_7: GPR_ASSERT(cur < end); transport_parsing->incoming_stream_id |= ((gpr_uint32)*cur) << 8; if (++cur == end) { transport_parsing->deframe_state = GRPC_DTS_FH_8; return 1; } /* fallthrough */ case GRPC_DTS_FH_8: GPR_ASSERT(cur < end); transport_parsing->incoming_stream_id |= ((gpr_uint32)*cur); transport_parsing->deframe_state = GRPC_DTS_FRAME; if (!init_frame_parser(transport_parsing)) { return 0; } if (transport_parsing->incoming_stream_id) { transport_parsing->last_incoming_stream_id = transport_parsing->incoming_stream_id; } if (transport_parsing->incoming_frame_size == 0) { if (!parse_frame_slice(transport_parsing, gpr_empty_slice(), 1)) { return 0; } transport_parsing->incoming_stream = NULL; if (++cur == end) { transport_parsing->deframe_state = GRPC_DTS_FH_0; return 1; } goto dts_fh_0; /* loop */ } if (++cur == end) { return 1; } /* fallthrough */ case GRPC_DTS_FRAME: GPR_ASSERT(cur < end); if ((gpr_uint32)(end - cur) == transport_parsing->incoming_frame_size) { if (!parse_frame_slice( transport_parsing, gpr_slice_sub_no_ref(slice, cur - beg, end - beg), 1)) { return 0; } transport_parsing->deframe_state = GRPC_DTS_FH_0; transport_parsing->incoming_stream = NULL; return 1; } else if ((gpr_uint32)(end - cur) > transport_parsing->incoming_frame_size) { if (!parse_frame_slice( transport_parsing, gpr_slice_sub_no_ref( slice, cur - beg, cur + transport_parsing->incoming_frame_size - beg), 1)) { return 0; } cur += transport_parsing->incoming_frame_size; transport_parsing->incoming_stream = NULL; goto dts_fh_0; /* loop */ } else { if (!parse_frame_slice( transport_parsing, gpr_slice_sub_no_ref(slice, cur - beg, end - beg), 0)) { return 0; } transport_parsing->incoming_frame_size -= (end - cur); return 1; } gpr_log(GPR_ERROR, "should never reach here"); abort(); } gpr_log(GPR_ERROR, "should never reach here"); abort(); return 0; }