예제 #1
0
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;
}
예제 #2
0
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;
}
예제 #3
0
파일: parsing.c 프로젝트: endobson/grpc
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);
}
예제 #4
0
파일: parsing.c 프로젝트: xincun/grpc
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;
}