mirror of https://github.com/grpc/grpc.git
Merge pull request #15130 from jiangtaoli2016/fake_handshaker
Add fake ALTS handshaker server (bazel only)pull/15145/head
commit
27fd07b12b
4 changed files with 579 additions and 0 deletions
@ -0,0 +1,47 @@ |
|||||||
|
# Copyright 2018 gRPC authors. |
||||||
|
# |
||||||
|
# Licensed under the Apache License, Version 2.0 (the "License"); |
||||||
|
# you may not use this file except in compliance with the License. |
||||||
|
# You may obtain a copy of the License at |
||||||
|
# |
||||||
|
# http://www.apache.org/licenses/LICENSE-2.0 |
||||||
|
# |
||||||
|
# Unless required by applicable law or agreed to in writing, software |
||||||
|
# distributed under the License is distributed on an "AS IS" BASIS, |
||||||
|
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
||||||
|
# See the License for the specific language governing permissions and |
||||||
|
# limitations under the License. |
||||||
|
|
||||||
|
licenses(["notice"]) # Apache v2 |
||||||
|
|
||||||
|
load("//bazel:grpc_build_system.bzl", "grpc_proto_library", "grpc_cc_binary", "grpc_package") |
||||||
|
|
||||||
|
grpc_package(name = "test/core/tsi/alts/fake_handshaker", visibility = "public") |
||||||
|
|
||||||
|
grpc_proto_library( |
||||||
|
name = "transport_security_common_proto", |
||||||
|
srcs = ["transport_security_common.proto"], |
||||||
|
has_services = False, |
||||||
|
) |
||||||
|
|
||||||
|
grpc_proto_library( |
||||||
|
name = "handshaker_proto", |
||||||
|
srcs = ["handshaker.proto"], |
||||||
|
has_services = True, |
||||||
|
deps = [ |
||||||
|
":transport_security_common_proto", |
||||||
|
], |
||||||
|
) |
||||||
|
|
||||||
|
grpc_cc_binary( |
||||||
|
name = "fake_handshaker_server", |
||||||
|
testonly = True, |
||||||
|
srcs = ["fake_handshaker_server.cc"], |
||||||
|
language = "C++", |
||||||
|
deps = [ |
||||||
|
":handshaker_proto", |
||||||
|
":transport_security_common_proto", |
||||||
|
"//:grpc++", |
||||||
|
"//test/cpp/util:test_config", |
||||||
|
], |
||||||
|
) |
@ -0,0 +1,268 @@ |
|||||||
|
/*
|
||||||
|
* |
||||||
|
* Copyright 2018 gRPC authors. |
||||||
|
* |
||||||
|
* Licensed under the Apache License, Version 2.0 (the "License"); |
||||||
|
* you may not use this file except in compliance with the License. |
||||||
|
* You may obtain a copy of the License at |
||||||
|
* |
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
* |
||||||
|
* Unless required by applicable law or agreed to in writing, software |
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS, |
||||||
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
||||||
|
* See the License for the specific language governing permissions and |
||||||
|
* limitations under the License. |
||||||
|
* |
||||||
|
*/ |
||||||
|
|
||||||
|
#include <memory> |
||||||
|
#include <sstream> |
||||||
|
#include <string> |
||||||
|
|
||||||
|
#include <gflags/gflags.h> |
||||||
|
#include <grpc/grpc.h> |
||||||
|
#include <grpc/support/log.h> |
||||||
|
#include <grpcpp/impl/codegen/async_stream.h> |
||||||
|
#include <grpcpp/security/server_credentials.h> |
||||||
|
#include <grpcpp/server.h> |
||||||
|
#include <grpcpp/server_builder.h> |
||||||
|
#include <grpcpp/server_context.h> |
||||||
|
|
||||||
|
#include "test/core/tsi/alts/fake_handshaker/handshaker.grpc.pb.h" |
||||||
|
#include "test/core/tsi/alts/fake_handshaker/handshaker.pb.h" |
||||||
|
#include "test/core/tsi/alts/fake_handshaker/transport_security_common.pb.h" |
||||||
|
#include "test/cpp/util/test_config.h" |
||||||
|
|
||||||
|
DEFINE_int32(handshaker_port, 55056, |
||||||
|
"TCP port on which the fake handshaker server listens to."); |
||||||
|
|
||||||
|
// Fake handshake messages.
|
||||||
|
constexpr char kClientInitFrame[] = "ClientInit"; |
||||||
|
constexpr char kServerFrame[] = "ServerInitAndFinished"; |
||||||
|
constexpr char kClientFinishFrame[] = "ClientFinished"; |
||||||
|
// Error messages.
|
||||||
|
constexpr char kInvalidFrameError[] = "Invalid input frame."; |
||||||
|
constexpr char kWrongStateError[] = "Wrong handshake state."; |
||||||
|
|
||||||
|
namespace grpc { |
||||||
|
namespace gcp { |
||||||
|
|
||||||
|
// FakeHandshakeService implements a fake handshaker service using a fake key
|
||||||
|
// exchange protocol. The fake key exchange protocol is a 3-message protocol:
|
||||||
|
// - Client first sends ClientInit message to Server.
|
||||||
|
// - Server then sends ServerInitAndFinished message back to Client.
|
||||||
|
// - Client finally sends ClientFinished message to Server.
|
||||||
|
// This fake handshaker service is intended for ALTS integration testing without
|
||||||
|
// relying on real ALTS handshaker service inside GCE.
|
||||||
|
// It is thread-safe.
|
||||||
|
class FakeHandshakerService : public HandshakerService::Service { |
||||||
|
public: |
||||||
|
Status DoHandshake( |
||||||
|
ServerContext* server_context, |
||||||
|
ServerReaderWriter<HandshakerResp, HandshakerReq>* stream) override { |
||||||
|
Status status; |
||||||
|
HandshakerContext context; |
||||||
|
HandshakerReq request; |
||||||
|
HandshakerResp response; |
||||||
|
gpr_log(GPR_DEBUG, "Start a new handshake."); |
||||||
|
while (stream->Read(&request)) { |
||||||
|
status = ProcessRequest(&context, request, &response); |
||||||
|
if (!status.ok()) return WriteErrorResponse(stream, status); |
||||||
|
stream->Write(response); |
||||||
|
if (context.state == COMPLETED) return Status::OK; |
||||||
|
request.Clear(); |
||||||
|
} |
||||||
|
return Status::OK; |
||||||
|
} |
||||||
|
|
||||||
|
private: |
||||||
|
// HandshakeState is used by fake handshaker server to keep track of client's
|
||||||
|
// handshake status. In the beginning of a handshake, the state is INITIAL.
|
||||||
|
// If start_client or start_server request is called, the state becomes at
|
||||||
|
// least STARTED. When the handshaker server produces the first fame, the
|
||||||
|
// state becomes SENT. After the handshaker server processes the final frame
|
||||||
|
// from the peer, the state becomes COMPLETED.
|
||||||
|
enum HandshakeState { INITIAL, STARTED, SENT, COMPLETED }; |
||||||
|
|
||||||
|
struct HandshakerContext { |
||||||
|
bool is_client = true; |
||||||
|
HandshakeState state = INITIAL; |
||||||
|
}; |
||||||
|
|
||||||
|
Status ProcessRequest(HandshakerContext* context, |
||||||
|
const HandshakerReq& request, |
||||||
|
HandshakerResp* response) { |
||||||
|
GPR_ASSERT(context != nullptr && response != nullptr); |
||||||
|
response->Clear(); |
||||||
|
if (request.has_client_start()) { |
||||||
|
gpr_log(GPR_DEBUG, "Process client start request."); |
||||||
|
return ProcessClientStart(context, request.client_start(), response); |
||||||
|
} else if (request.has_server_start()) { |
||||||
|
gpr_log(GPR_DEBUG, "Process server start request."); |
||||||
|
return ProcessServerStart(context, request.server_start(), response); |
||||||
|
} else if (request.has_next()) { |
||||||
|
gpr_log(GPR_DEBUG, "Process next request."); |
||||||
|
return ProcessNext(context, request.next(), response); |
||||||
|
} |
||||||
|
return Status(StatusCode::INVALID_ARGUMENT, "Request is empty."); |
||||||
|
} |
||||||
|
|
||||||
|
Status ProcessClientStart(HandshakerContext* context, |
||||||
|
const StartClientHandshakeReq& request, |
||||||
|
HandshakerResp* response) { |
||||||
|
GPR_ASSERT(context != nullptr && response != nullptr); |
||||||
|
// Checks request.
|
||||||
|
if (context->state != INITIAL) { |
||||||
|
return Status(StatusCode::FAILED_PRECONDITION, kWrongStateError); |
||||||
|
} |
||||||
|
if (request.application_protocols_size() == 0) { |
||||||
|
return Status(StatusCode::INVALID_ARGUMENT, |
||||||
|
"At least one application protocol needed."); |
||||||
|
} |
||||||
|
if (request.record_protocols_size() == 0) { |
||||||
|
return Status(StatusCode::INVALID_ARGUMENT, |
||||||
|
"At least one record protocol needed."); |
||||||
|
} |
||||||
|
// Sets response.
|
||||||
|
response->set_out_frames(kClientInitFrame); |
||||||
|
response->set_bytes_consumed(0); |
||||||
|
response->mutable_status()->set_code(StatusCode::OK); |
||||||
|
// Updates handshaker context.
|
||||||
|
context->is_client = true; |
||||||
|
context->state = SENT; |
||||||
|
return Status::OK; |
||||||
|
} |
||||||
|
|
||||||
|
Status ProcessServerStart(HandshakerContext* context, |
||||||
|
const StartServerHandshakeReq& request, |
||||||
|
HandshakerResp* response) { |
||||||
|
GPR_ASSERT(context != nullptr && response != nullptr); |
||||||
|
// Checks request.
|
||||||
|
if (context->state != INITIAL) { |
||||||
|
return Status(StatusCode::FAILED_PRECONDITION, kWrongStateError); |
||||||
|
} |
||||||
|
if (request.application_protocols_size() == 0) { |
||||||
|
return Status(StatusCode::INVALID_ARGUMENT, |
||||||
|
"At least one application protocol needed."); |
||||||
|
} |
||||||
|
if (request.handshake_parameters().size() == 0) { |
||||||
|
return Status(StatusCode::INVALID_ARGUMENT, |
||||||
|
"At least one set of handshake parameters needed."); |
||||||
|
} |
||||||
|
// Sets response.
|
||||||
|
if (request.in_bytes().empty()) { |
||||||
|
// start_server request does not have in_bytes.
|
||||||
|
response->set_bytes_consumed(0); |
||||||
|
context->state = STARTED; |
||||||
|
} else { |
||||||
|
// start_server request has in_bytes.
|
||||||
|
if (request.in_bytes() == kClientInitFrame) { |
||||||
|
response->set_out_frames(kServerFrame); |
||||||
|
response->set_bytes_consumed(strlen(kClientInitFrame)); |
||||||
|
context->state = SENT; |
||||||
|
} else { |
||||||
|
return Status(StatusCode::UNKNOWN, kInvalidFrameError); |
||||||
|
} |
||||||
|
} |
||||||
|
response->mutable_status()->set_code(StatusCode::OK); |
||||||
|
context->is_client = false; |
||||||
|
return Status::OK; |
||||||
|
} |
||||||
|
|
||||||
|
Status ProcessNext(HandshakerContext* context, |
||||||
|
const NextHandshakeMessageReq& request, |
||||||
|
HandshakerResp* response) { |
||||||
|
GPR_ASSERT(context != nullptr && response != nullptr); |
||||||
|
if (context->is_client) { |
||||||
|
// Processes next request on client side.
|
||||||
|
if (context->state != SENT) { |
||||||
|
return Status(StatusCode::FAILED_PRECONDITION, kWrongStateError); |
||||||
|
} |
||||||
|
if (request.in_bytes() != kServerFrame) { |
||||||
|
return Status(StatusCode::UNKNOWN, kInvalidFrameError); |
||||||
|
} |
||||||
|
response->set_out_frames(kClientFinishFrame); |
||||||
|
response->set_bytes_consumed(strlen(kServerFrame)); |
||||||
|
context->state = COMPLETED; |
||||||
|
} else { |
||||||
|
// Processes next request on server side.
|
||||||
|
HandshakeState current_state = context->state; |
||||||
|
if (current_state == STARTED) { |
||||||
|
if (request.in_bytes() != kClientInitFrame) { |
||||||
|
return Status(StatusCode::UNKNOWN, kInvalidFrameError); |
||||||
|
} |
||||||
|
response->set_out_frames(kServerFrame); |
||||||
|
response->set_bytes_consumed(strlen(kClientInitFrame)); |
||||||
|
context->state = SENT; |
||||||
|
} else if (current_state == SENT) { |
||||||
|
// Client finish frame may be sent along with the first payload from the
|
||||||
|
// client, handshaker only consumes the client finish frame.
|
||||||
|
if (request.in_bytes().substr(0, strlen(kClientFinishFrame)) != |
||||||
|
kClientFinishFrame) { |
||||||
|
return Status(StatusCode::UNKNOWN, kInvalidFrameError); |
||||||
|
} |
||||||
|
response->set_bytes_consumed(strlen(kClientFinishFrame)); |
||||||
|
context->state = COMPLETED; |
||||||
|
} else { |
||||||
|
return Status(StatusCode::FAILED_PRECONDITION, kWrongStateError); |
||||||
|
} |
||||||
|
} |
||||||
|
// At this point, processing next request succeeded.
|
||||||
|
response->mutable_status()->set_code(StatusCode::OK); |
||||||
|
if (context->state == COMPLETED) { |
||||||
|
*response->mutable_result() = GetHandshakerResult(); |
||||||
|
} |
||||||
|
return Status::OK; |
||||||
|
} |
||||||
|
|
||||||
|
Status WriteErrorResponse( |
||||||
|
ServerReaderWriter<HandshakerResp, HandshakerReq>* stream, |
||||||
|
const Status& status) { |
||||||
|
GPR_ASSERT(!status.ok()); |
||||||
|
HandshakerResp response; |
||||||
|
response.mutable_status()->set_code(status.error_code()); |
||||||
|
response.mutable_status()->set_details(status.error_message()); |
||||||
|
stream->Write(response); |
||||||
|
return status; |
||||||
|
} |
||||||
|
|
||||||
|
HandshakerResult GetHandshakerResult() { |
||||||
|
HandshakerResult result; |
||||||
|
result.set_application_protocol("grpc"); |
||||||
|
result.set_record_protocol("ALTSRP_GCM_AES128_REKEY"); |
||||||
|
result.mutable_peer_identity()->set_service_account("peer_identity"); |
||||||
|
result.mutable_local_identity()->set_service_account("local_identity"); |
||||||
|
string key(1024, '\0'); |
||||||
|
result.set_key_data(key); |
||||||
|
result.mutable_peer_rpc_versions()->mutable_max_rpc_version()->set_major(2); |
||||||
|
result.mutable_peer_rpc_versions()->mutable_max_rpc_version()->set_minor(1); |
||||||
|
result.mutable_peer_rpc_versions()->mutable_min_rpc_version()->set_major(2); |
||||||
|
result.mutable_peer_rpc_versions()->mutable_min_rpc_version()->set_minor(1); |
||||||
|
return result; |
||||||
|
} |
||||||
|
}; |
||||||
|
|
||||||
|
} // namespace gcp
|
||||||
|
} // namespace grpc
|
||||||
|
|
||||||
|
void RunServer() { |
||||||
|
GPR_ASSERT(FLAGS_handshaker_port != 0); |
||||||
|
std::ostringstream server_address; |
||||||
|
server_address << "[::1]:" << FLAGS_handshaker_port; |
||||||
|
grpc::gcp::FakeHandshakerService service; |
||||||
|
grpc::ServerBuilder builder; |
||||||
|
builder.AddListeningPort(server_address.str(), |
||||||
|
grpc::InsecureServerCredentials()); |
||||||
|
builder.RegisterService(&service); |
||||||
|
std::unique_ptr<grpc::Server> server(builder.BuildAndStart()); |
||||||
|
gpr_log(GPR_INFO, "Fake handshaker server listening on %s", |
||||||
|
server_address.str().c_str()); |
||||||
|
server->Wait(); |
||||||
|
} |
||||||
|
|
||||||
|
int main(int argc, char** argv) { |
||||||
|
grpc::testing::InitTest(&argc, &argv, true); |
||||||
|
RunServer(); |
||||||
|
return 0; |
||||||
|
} |
@ -0,0 +1,224 @@ |
|||||||
|
// Copyright 2018 gRPC authors. |
||||||
|
// |
||||||
|
// Licensed under the Apache License, Version 2.0 (the "License"); |
||||||
|
// you may not use this file except in compliance with the License. |
||||||
|
// You may obtain a copy of the License at |
||||||
|
// |
||||||
|
// http://www.apache.org/licenses/LICENSE-2.0 |
||||||
|
// |
||||||
|
// Unless required by applicable law or agreed to in writing, software |
||||||
|
// distributed under the License is distributed on an "AS IS" BASIS, |
||||||
|
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
||||||
|
// See the License for the specific language governing permissions and |
||||||
|
// limitations under the License. |
||||||
|
|
||||||
|
syntax = "proto3"; |
||||||
|
|
||||||
|
import "test/core/tsi/alts/fake_handshaker/transport_security_common.proto"; |
||||||
|
|
||||||
|
package grpc.gcp; |
||||||
|
|
||||||
|
option java_package = "io.grpc.alts.internal"; |
||||||
|
|
||||||
|
enum HandshakeProtocol { |
||||||
|
// Default value. |
||||||
|
HANDSHAKE_PROTOCOL_UNSPECIFIED = 0; |
||||||
|
|
||||||
|
// TLS handshake protocol. |
||||||
|
TLS = 1; |
||||||
|
|
||||||
|
// Application Layer Transport Security handshake protocol. |
||||||
|
ALTS = 2; |
||||||
|
} |
||||||
|
|
||||||
|
enum NetworkProtocol { |
||||||
|
NETWORK_PROTOCOL_UNSPECIFIED = 0; |
||||||
|
TCP = 1; |
||||||
|
UDP = 2; |
||||||
|
} |
||||||
|
|
||||||
|
message Endpoint { |
||||||
|
// IP address. It should contain an IPv4 or IPv6 string literal, e.g. |
||||||
|
// "192.168.0.1" or "2001:db8::1". |
||||||
|
string ip_address = 1; |
||||||
|
|
||||||
|
// Port number. |
||||||
|
int32 port = 2; |
||||||
|
|
||||||
|
// Network protocol (e.g., TCP, UDP) associated with this endpoint. |
||||||
|
NetworkProtocol protocol = 3; |
||||||
|
} |
||||||
|
|
||||||
|
message Identity { |
||||||
|
oneof identity_oneof { |
||||||
|
// Service account of a connection endpoint. |
||||||
|
string service_account = 1; |
||||||
|
|
||||||
|
// Hostname of a connection endpoint. |
||||||
|
string hostname = 2; |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
message StartClientHandshakeReq { |
||||||
|
// Handshake security protocol requested by the client. |
||||||
|
HandshakeProtocol handshake_security_protocol = 1; |
||||||
|
|
||||||
|
// The application protocols supported by the client, e.g., "h2" (for http2), |
||||||
|
// "grpc". |
||||||
|
repeated string application_protocols = 2; |
||||||
|
|
||||||
|
// The record protocols supported by the client, e.g., |
||||||
|
// "ALTSRP_GCM_AES128". |
||||||
|
repeated string record_protocols = 3; |
||||||
|
|
||||||
|
// (Optional) Describes which server identities are acceptable by the client. |
||||||
|
// If target identities are provided and none of them matches the peer |
||||||
|
// identity of the server, handshake will fail. |
||||||
|
repeated Identity target_identities = 4; |
||||||
|
|
||||||
|
// (Optional) Application may specify a local identity. Otherwise, the |
||||||
|
// handshaker chooses a default local identity. |
||||||
|
Identity local_identity = 5; |
||||||
|
|
||||||
|
// (Optional) Local endpoint information of the connection to the server, |
||||||
|
// such as local IP address, port number, and network protocol. |
||||||
|
Endpoint local_endpoint = 6; |
||||||
|
|
||||||
|
// (Optional) Endpoint information of the remote server, such as IP address, |
||||||
|
// port number, and network protocol. |
||||||
|
Endpoint remote_endpoint = 7; |
||||||
|
|
||||||
|
// (Optional) If target name is provided, a secure naming check is performed |
||||||
|
// to verify that the peer authenticated identity is indeed authorized to run |
||||||
|
// the target name. |
||||||
|
string target_name = 8; |
||||||
|
|
||||||
|
// (Optional) RPC protocol versions supported by the client. |
||||||
|
RpcProtocolVersions rpc_versions = 9; |
||||||
|
} |
||||||
|
|
||||||
|
message ServerHandshakeParameters { |
||||||
|
// The record protocols supported by the server, e.g., |
||||||
|
// "ALTSRP_GCM_AES128". |
||||||
|
repeated string record_protocols = 1; |
||||||
|
|
||||||
|
// (Optional) A list of local identities supported by the server, if |
||||||
|
// specified. Otherwise, the handshaker chooses a default local identity. |
||||||
|
repeated Identity local_identities = 2; |
||||||
|
} |
||||||
|
|
||||||
|
message StartServerHandshakeReq { |
||||||
|
// The application protocols supported by the server, e.g., "h2" (for http2), |
||||||
|
// "grpc". |
||||||
|
repeated string application_protocols = 1; |
||||||
|
|
||||||
|
// Handshake parameters (record protocols and local identities supported by |
||||||
|
// the server) mapped by the handshake protocol. Each handshake security |
||||||
|
// protocol (e.g., TLS or ALTS) has its own set of record protocols and local |
||||||
|
// identities. Since protobuf does not support enum as key to the map, the key |
||||||
|
// to handshake_parameters is the integer value of HandshakeProtocol enum. |
||||||
|
map<int32, ServerHandshakeParameters> handshake_parameters = 2; |
||||||
|
|
||||||
|
// Bytes in out_frames returned from the peer's HandshakerResp. It is possible |
||||||
|
// that the peer's out_frames are split into multiple HandshakReq messages. |
||||||
|
bytes in_bytes = 3; |
||||||
|
|
||||||
|
// (Optional) Local endpoint information of the connection to the client, |
||||||
|
// such as local IP address, port number, and network protocol. |
||||||
|
Endpoint local_endpoint = 4; |
||||||
|
|
||||||
|
// (Optional) Endpoint information of the remote client, such as IP address, |
||||||
|
// port number, and network protocol. |
||||||
|
Endpoint remote_endpoint = 5; |
||||||
|
|
||||||
|
// (Optional) RPC protocol versions supported by the server. |
||||||
|
RpcProtocolVersions rpc_versions = 6; |
||||||
|
} |
||||||
|
|
||||||
|
message NextHandshakeMessageReq { |
||||||
|
// Bytes in out_frames returned from the peer's HandshakerResp. It is possible |
||||||
|
// that the peer's out_frames are split into multiple NextHandshakerMessageReq |
||||||
|
// messages. |
||||||
|
bytes in_bytes = 1; |
||||||
|
} |
||||||
|
|
||||||
|
message HandshakerReq { |
||||||
|
oneof req_oneof { |
||||||
|
// The start client handshake request message. |
||||||
|
StartClientHandshakeReq client_start = 1; |
||||||
|
|
||||||
|
// The start server handshake request message. |
||||||
|
StartServerHandshakeReq server_start = 2; |
||||||
|
|
||||||
|
// The next handshake request message. |
||||||
|
NextHandshakeMessageReq next = 3; |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
message HandshakerResult { |
||||||
|
// The application protocol negotiated for this connection. |
||||||
|
string application_protocol = 1; |
||||||
|
|
||||||
|
// The record protocol negotiated for this connection. |
||||||
|
string record_protocol = 2; |
||||||
|
|
||||||
|
// Cryptographic key data. The key data may be more than the key length |
||||||
|
// required for the record protocol, thus the client of the handshaker |
||||||
|
// service needs to truncate the key data into the right key length. |
||||||
|
bytes key_data = 3; |
||||||
|
|
||||||
|
// The authenticated identity of the peer. |
||||||
|
Identity peer_identity = 4; |
||||||
|
|
||||||
|
// The local identity used in the handshake. |
||||||
|
Identity local_identity = 5; |
||||||
|
|
||||||
|
// Indicate whether the handshaker service client should keep the channel |
||||||
|
// between the handshaker service open, e.g., in order to handle |
||||||
|
// post-handshake messages in the future. |
||||||
|
bool keep_channel_open = 6; |
||||||
|
|
||||||
|
// The RPC protocol versions supported by the peer. |
||||||
|
RpcProtocolVersions peer_rpc_versions = 7; |
||||||
|
} |
||||||
|
|
||||||
|
message HandshakerStatus { |
||||||
|
// The status code. This could be the gRPC status code. |
||||||
|
uint32 code = 1; |
||||||
|
|
||||||
|
// The status details. |
||||||
|
string details = 2; |
||||||
|
} |
||||||
|
|
||||||
|
message HandshakerResp { |
||||||
|
// Frames to be given to the peer for the NextHandshakeMessageReq. May be |
||||||
|
// empty if no out_frames have to be sent to the peer or if in_bytes in the |
||||||
|
// HandshakerReq are incomplete. All the non-empty out frames must be sent to |
||||||
|
// the peer even if the handshaker status is not OK as these frames may |
||||||
|
// contain the alert frames. |
||||||
|
bytes out_frames = 1; |
||||||
|
|
||||||
|
// Number of bytes in the in_bytes consumed by the handshaker. It is possible |
||||||
|
// that part of in_bytes in HandshakerReq was unrelated to the handshake |
||||||
|
// process. |
||||||
|
uint32 bytes_consumed = 2; |
||||||
|
|
||||||
|
// This is set iff the handshake was successful. out_frames may still be set |
||||||
|
// to frames that needs to be forwarded to the peer. |
||||||
|
HandshakerResult result = 3; |
||||||
|
|
||||||
|
// Status of the handshaker. |
||||||
|
HandshakerStatus status = 4; |
||||||
|
} |
||||||
|
|
||||||
|
service HandshakerService { |
||||||
|
// Handshaker service accepts a stream of handshaker request, returning a |
||||||
|
// stream of handshaker response. Client is expected to send exactly one |
||||||
|
// message with either client_start or server_start followed by one or more |
||||||
|
// messages with next. Each time client sends a request, the handshaker |
||||||
|
// service expects to respond. Client does not have to wait for service's |
||||||
|
// response before sending next request. |
||||||
|
rpc DoHandshake(stream HandshakerReq) |
||||||
|
returns (stream HandshakerResp) { |
||||||
|
} |
||||||
|
} |
@ -0,0 +1,40 @@ |
|||||||
|
// Copyright 2018 gRPC authors. |
||||||
|
// |
||||||
|
// Licensed under the Apache License, Version 2.0 (the "License"); |
||||||
|
// you may not use this file except in compliance with the License. |
||||||
|
// You may obtain a copy of the License at |
||||||
|
// |
||||||
|
// http://www.apache.org/licenses/LICENSE-2.0 |
||||||
|
// |
||||||
|
// Unless required by applicable law or agreed to in writing, software |
||||||
|
// distributed under the License is distributed on an "AS IS" BASIS, |
||||||
|
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
||||||
|
// See the License for the specific language governing permissions and |
||||||
|
// limitations under the License. |
||||||
|
|
||||||
|
syntax = "proto3"; |
||||||
|
|
||||||
|
package grpc.gcp; |
||||||
|
|
||||||
|
option java_package = "io.grpc.alts.internal"; |
||||||
|
|
||||||
|
// The security level of the created channel. The list is sorted in increasing |
||||||
|
// level of security. This order must always be maintained. |
||||||
|
enum SecurityLevel { |
||||||
|
SECURITY_NONE = 0; |
||||||
|
INTEGRITY_ONLY = 1; |
||||||
|
INTEGRITY_AND_PRIVACY = 2; |
||||||
|
} |
||||||
|
|
||||||
|
// Max and min supported RPC protocol versions. |
||||||
|
message RpcProtocolVersions { |
||||||
|
// RPC version contains a major version and a minor version. |
||||||
|
message Version { |
||||||
|
uint32 major = 1; |
||||||
|
uint32 minor = 2; |
||||||
|
} |
||||||
|
// Maximum supported RPC version. |
||||||
|
Version max_rpc_version = 1; |
||||||
|
// Minimum supported RPC version. |
||||||
|
Version min_rpc_version = 2; |
||||||
|
} |
Loading…
Reference in new issue