Skip to content

Commit 6aff650

Browse files
committed
Support RDMA handshake protocol
1 parent cbb4ccd commit 6aff650

20 files changed

Lines changed: 1008 additions & 547 deletions

src/brpc/global.cpp

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -69,6 +69,7 @@
6969

7070
// Protocols
7171
#include "brpc/protocol.h"
72+
#include "brpc/policy/rdma_handshake_protocol.h"
7273
#include "brpc/policy/baidu_rpc_protocol.h"
7374
#include "brpc/policy/http_rpc_protocol.h"
7475
#include "brpc/policy/http2_rpc_protocol.h"
@@ -437,6 +438,15 @@ static void GlobalInitializeOrDieImpl() {
437438
}
438439

439440
// Protocols
441+
Protocol rdma_handshake_protocol = {
442+
ParseRdmaHandshake, NULL, NULL,
443+
ProcessRdmaHandshake, NULL,
444+
NULL, NULL, NULL,
445+
CONNECTION_TYPE_ALL, "rdma_handshake" };
446+
if (RegisterProtocol(PROTOCOL_RDMA_HANDSHAKE, rdma_handshake_protocol) != 0) {
447+
exit(1);
448+
}
449+
440450
Protocol baidu_protocol = { ParseRpcMessage,
441451
SerializeRpcRequest, PackRpcRequest,
442452
ProcessRpcRequest, ProcessRpcResponse,

src/brpc/input_messenger.cpp

Lines changed: 0 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -79,7 +79,6 @@ DECLARE_uint64(max_body_size);
7979
const size_t MSG_SIZE_WINDOW = 10; // Take last so many message into stat.
8080
const size_t MIN_ONCE_READ = 4096;
8181
const size_t MAX_ONCE_READ = 524288;
82-
const size_t PROTO_DUMMY_LEN = 4;
8382

8483
ParseResult InputMessenger::CutInputMessage(
8584
Socket* m, size_t* index, bool read_eof) {
@@ -107,16 +106,6 @@ ParseResult InputMessenger::CutInputMessage(
107106
<< " bytes, the connection will be closed."
108107
" Set max_body_size to allow bigger messages";
109108
return result;
110-
} else {
111-
if (m->_read_buf.size() >= 4) {
112-
// The length of `data' must be PROTO_DUMMY_LEN + 1 to store extra ending char '\0'
113-
char data[PROTO_DUMMY_LEN + 1];
114-
m->_read_buf.copy_to_cstr(data, PROTO_DUMMY_LEN);
115-
if (strncmp(data, "RDMA", PROTO_DUMMY_LEN) == 0) {
116-
// To avoid timeout when client uses RDMA but server uses TCP
117-
return MakeParseError(PARSE_ERROR_TRY_OTHERS);
118-
}
119-
}
120109
}
121110

122111
if (m->CreatedByConnect()) {

src/brpc/input_messenger.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,7 @@ namespace rdma {
3030
class RdmaEndpoint;
3131
}
3232
class TcpTransport;
33+
class RdmaTransport;
3334
struct InputMessageHandler {
3435
// The callback to cut a message from `source'.
3536
// Returned message will be passed to process_request or process_response
@@ -92,6 +93,7 @@ class InputMessageClosure {
9293
class InputMessenger : public SocketUser {
9394
friend class Socket;
9495
friend class TcpTransport;
96+
friend class RdmaTransport;
9597
friend class rdma::RdmaEndpoint;
9698
public:
9799
explicit InputMessenger(size_t capacity = 128);

src/brpc/options.proto

Lines changed: 29 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -37,35 +37,36 @@ enum ConnectionType {
3737

3838
enum ProtocolType {
3939
PROTOCOL_UNKNOWN = 0;
40-
PROTOCOL_BAIDU_STD = 1;
41-
PROTOCOL_STREAMING_RPC = 2;
42-
PROTOCOL_HULU_PBRPC = 3;
43-
PROTOCOL_SOFA_PBRPC = 4;
44-
PROTOCOL_RTMP = 5;
45-
PROTOCOL_THRIFT = 6;
46-
PROTOCOL_HTTP = 7;
47-
PROTOCOL_PUBLIC_PBRPC = 8;
48-
PROTOCOL_NOVA_PBRPC = 9;
49-
PROTOCOL_REDIS = 10;
50-
PROTOCOL_NSHEAD_CLIENT = 11; // implemented in baidu-rpc-ub
51-
PROTOCOL_NSHEAD = 12;
52-
PROTOCOL_HADOOP_RPC = 13;
53-
PROTOCOL_HADOOP_SERVER_RPC = 14;
54-
PROTOCOL_MONGO = 15; // server side only
55-
PROTOCOL_UBRPC_COMPACK = 16;
56-
PROTOCOL_DIDX_CLIENT = 17; // Client side only
57-
PROTOCOL_MEMCACHE = 18; // Client side only
58-
PROTOCOL_ITP = 19;
59-
PROTOCOL_NSHEAD_MCPACK = 20;
60-
PROTOCOL_DISP_IDL = 21; // Client side only
61-
PROTOCOL_ERSDA_CLIENT = 22; // Client side only
62-
PROTOCOL_UBRPC_MCPACK2 = 23; // Client side only
40+
PROTOCOL_RDMA_HANDSHAKE = 1;
41+
PROTOCOL_BAIDU_STD = 2;
42+
PROTOCOL_STREAMING_RPC = 3;
43+
PROTOCOL_HULU_PBRPC = 4;
44+
PROTOCOL_SOFA_PBRPC = 5;
45+
PROTOCOL_RTMP = 6;
46+
PROTOCOL_THRIFT = 7;
47+
PROTOCOL_HTTP = 8;
48+
PROTOCOL_PUBLIC_PBRPC = 9;
49+
PROTOCOL_NOVA_PBRPC = 10;
50+
PROTOCOL_REDIS = 11;
51+
PROTOCOL_NSHEAD_CLIENT = 12; // implemented in baidu-rpc-ub
52+
PROTOCOL_NSHEAD = 13;
53+
PROTOCOL_HADOOP_RPC = 14;
54+
PROTOCOL_HADOOP_SERVER_RPC = 15;
55+
PROTOCOL_MONGO = 16; // server side only
56+
PROTOCOL_UBRPC_COMPACK = 17;
57+
PROTOCOL_DIDX_CLIENT = 18; // Client side only
58+
PROTOCOL_MEMCACHE = 19; // Client side only
59+
PROTOCOL_ITP = 20;
60+
PROTOCOL_NSHEAD_MCPACK = 21;
61+
PROTOCOL_DISP_IDL = 22; // Client side only
62+
PROTOCOL_ERSDA_CLIENT = 23; // Client side only
63+
PROTOCOL_UBRPC_MCPACK2 = 24; // Client side only
6364
// Reserve special protocol for cds-agent, which depends on FIFO right now
64-
PROTOCOL_CDS_AGENT = 24; // Client side only
65-
PROTOCOL_ESP = 25; // Client side only
66-
PROTOCOL_H2 = 26;
67-
PROTOCOL_COUCHBASE = 27;
68-
PROTOCOL_MYSQL = 28; // Client side only
65+
PROTOCOL_CDS_AGENT = 25; // Client side only
66+
PROTOCOL_ESP = 26; // Client side only
67+
PROTOCOL_H2 = 27;
68+
PROTOCOL_COUCHBASE = 28;
69+
PROTOCOL_MYSQL = 29; // Client side only
6970
}
7071

7172
enum CompressType {

src/brpc/parse_result.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@
1919
#ifndef BRPC_PARSE_RESULT_H
2020
#define BRPC_PARSE_RESULT_H
2121

22+
#include <stddef.h>
2223

2324
namespace brpc {
2425

Lines changed: 41 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,41 @@
1+
// Licensed to the Apache Software Foundation (ASF) under one
2+
// or more contributor license agreements. See the NOTICE file
3+
// distributed with this work for additional information
4+
// regarding copyright ownership. The ASF licenses this file
5+
// to you under the Apache License, Version 2.0 (the
6+
// "License"); you may not use this file except in compliance
7+
// with the License. You may obtain a copy of the License at
8+
//
9+
// http://www.apache.org/licenses/LICENSE-2.0
10+
//
11+
// Unless required by applicable law or agreed to in writing,
12+
// software distributed under the License is distributed on an
13+
// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
14+
// KIND, either express or implied. See the License for the
15+
// specific language governing permissions and limitations
16+
// under the License.
17+
18+
#include "brpc/policy/rdma_handshake_protocol.h"
19+
20+
#include "butil/logging.h"
21+
#include "brpc/destroyable.h"
22+
#include "brpc/rdma/rdma_handshake_server.h"
23+
24+
namespace brpc {
25+
namespace policy {
26+
27+
ParseResult ParseRdmaHandshake(butil::IOBuf* source, Socket* socket,
28+
bool /*read_eof*/, const void* /*arg*/) {
29+
return rdma::ExecuteServerHandshake(source, socket);
30+
}
31+
32+
void ProcessRdmaHandshake(InputMessageBase* msg) {
33+
// ParseRdmaHandshake replies inline and only ever returns
34+
// NOT_ENOUGH_DATA / TRY_OTHERS / hard errors, never a real message, so this
35+
// must never run. Keep a placeholder (required for server registration).
36+
DestroyingPtr<InputMessageBase> destroying_msg(msg);
37+
CHECK(false) << "ProcessRdmaHandshake should never be called";
38+
}
39+
40+
} // namespace policy
41+
} // namespace brpc
Lines changed: 56 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,56 @@
1+
// Licensed to the Apache Software Foundation (ASF) under one
2+
// or more contributor license agreements. See the NOTICE file
3+
// distributed with this work for additional information
4+
// regarding copyright ownership. The ASF licenses this file
5+
// to you under the Apache License, Version 2.0 (the
6+
// "License"); you may not use this file except in compliance
7+
// with the License. You may obtain a copy of the License at
8+
//
9+
// http://www.apache.org/licenses/LICENSE-2.0
10+
//
11+
// Unless required by applicable law or agreed to in writing,
12+
// software distributed under the License is distributed on an
13+
// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
14+
// KIND, either express or implied. See the License for the
15+
// specific language governing permissions and limitations
16+
// under the License.
17+
18+
#ifndef BRPC_POLICY_RDMA_HANDSHAKE_PROTOCOL_H
19+
#define BRPC_POLICY_RDMA_HANDSHAKE_PROTOCOL_H
20+
21+
// NOTE: This file is intentionally INDEPENDENT of BRPC_WITH_RDMA. A server may
22+
// run in TCP mode either because it was built without RDMA, or because RDMA was
23+
// not enabled at runtime. In both cases an RDMA client that connects to it will
24+
// send an RDMA handshake magic ("RDMA" for v2, "RDM3" for v3) first. Without
25+
// special handling the server treats those bytes as an unknown protocol and
26+
// closes the connection, so the client (blocked reading the server hello) only
27+
// sees EOF and cannot fall back to TCP.
28+
//
29+
// To let the client fall back on the SAME connection, the server recognizes the
30+
// RDMA handshake as a "first-class" protocol (magic in the first 4 bytes,
31+
// PROTOCOL_RDMA_HANDSHAKE is ordered before PROTOCOL_HTTP), replies a hello with
32+
// an incompatible version so the client rejects it and downgrades to TCP, then
33+
// drains the client's subsequent ACK and lets normal RPC parsing continue.
34+
35+
#include "butil/iobuf.h"
36+
#include "brpc/input_message_base.h"
37+
#include "brpc/parse_result.h"
38+
#include "brpc/socket.h"
39+
40+
namespace brpc {
41+
namespace policy {
42+
43+
// Parse binary format of rdma handshake.
44+
ParseResult ParseRdmaHandshake(butil::IOBuf* source, Socket* socket,
45+
bool read_eof, const void* arg);
46+
47+
// Actions to a rdma handshake request, which is left unimplemented.
48+
// All requests are processed in the parsing process. This function
49+
// must be declared since server only enables redis as a server-side
50+
// protocol when this function is declared.
51+
void ProcessRdmaHandshake(InputMessageBase* msg);
52+
53+
} // namespace policy
54+
} // namespace brpc
55+
56+
#endif // BRPC_POLICY_RDMA_HANDSHAKE_PROTOCOL_H

0 commit comments

Comments
 (0)