Skip to content

Commit df18000

Browse files
committed
updated to support SO_BINDTODEVICE and bind client_host.
1 parent 8650f00 commit df18000

File tree

9 files changed

+60
-8
lines changed

9 files changed

+60
-8
lines changed

src/brpc/channel.cpp

Lines changed: 22 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -77,6 +77,7 @@ ChannelSSLOptions* ChannelOptions::mutable_ssl_options() {
7777
static ChannelSignature ComputeChannelSignature(const ChannelOptions& opt) {
7878
if (opt.auth == NULL &&
7979
!opt.has_ssl_options() &&
80+
opt.client_host.empty() &&
8081
opt.device_name.empty() &&
8182
opt.connection_group.empty() &&
8283
opt.hc_option.health_check_path.empty()) {
@@ -95,6 +96,10 @@ static ChannelSignature ComputeChannelSignature(const ChannelOptions& opt) {
9596
buf.append("|conng=");
9697
buf.append(opt.connection_group);
9798
}
99+
if (!opt.client_host.empty()) {
100+
buf.append("|clih=");
101+
buf.append(opt.client_host);
102+
}
98103
if (!opt.device_name.empty()) {
99104
buf.append("|devn=");
100105
buf.append(opt.device_name);
@@ -367,6 +372,13 @@ int Channel::InitSingle(const butil::EndPoint& server_addr_and_port,
367372
LOG(ERROR) << "Invalid port=" << port;
368373
return -1;
369374
}
375+
butil::EndPoint client_endpoint;
376+
if (!_options.client_host.empty() &&
377+
butil::str2ip(_options.client_host.c_str(), &client_endpoint.ip) != 0 &&
378+
butil::hostname2ip(_options.client_host.c_str(), &client_endpoint.ip) != 0) {
379+
LOG(ERROR) << "Invalid client host=`" << _options.client_host << '\'';
380+
return -1;
381+
}
370382
_server_address = server_addr_and_port;
371383
const ChannelSignature sig = ComputeChannelSignature(_options);
372384
std::shared_ptr<SocketSSLContext> ssl_ctx;
@@ -375,7 +387,8 @@ int Channel::InitSingle(const butil::EndPoint& server_addr_and_port,
375387
}
376388
if (SocketMapInsert(SocketMapKey(server_addr_and_port, sig),
377389
&_server_id, ssl_ctx, _options.use_rdma,
378-
_options.hc_option, _options.device_name) != 0) {
390+
_options.hc_option, client_endpoint,
391+
_options.device_name) != 0) {
379392
LOG(ERROR) << "Fail to insert into SocketMap";
380393
return -1;
381394
}
@@ -403,6 +416,13 @@ int Channel::Init(const char* ns_url,
403416
_options.mutable_ssl_options()->sni_name = _service_name;
404417
}
405418
}
419+
butil::EndPoint client_endpoint;
420+
if (!_options.client_host.empty() &&
421+
butil::str2ip(_options.client_host.c_str(), &client_endpoint.ip) != 0 &&
422+
butil::hostname2ip(_options.client_host.c_str(), &client_endpoint.ip) != 0) {
423+
LOG(ERROR) << "Invalid client host=`" << _options.client_host << '\'';
424+
return -1;
425+
}
406426
std::unique_ptr<LoadBalancerWithNaming> lb(new (std::nothrow)
407427
LoadBalancerWithNaming);
408428
if (NULL == lb) {
@@ -415,6 +435,7 @@ int Channel::Init(const char* ns_url,
415435
ns_opt.use_rdma = _options.use_rdma;
416436
ns_opt.channel_signature = ComputeChannelSignature(_options);
417437
ns_opt.hc_option = _options.hc_option;
438+
ns_opt.client_endpoint = client_endpoint;
418439
ns_opt.device_name = _options.device_name;
419440
if (CreateSocketSSLContext(_options, &ns_opt.ssl_ctx) != 0) {
420441
return -1;

src/brpc/channel.h

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -149,6 +149,11 @@ struct ChannelOptions {
149149
// When it is not set, FLAGS_health_check_path and FLAGS_health_check_timeout_ms will take effect.
150150
HealthCheckOption hc_option;
151151

152+
// IP address or host name of the client.
153+
// if the client_host is "", the client IP address is determined by the OS.
154+
// Default: ""
155+
std::string client_host;
156+
152157
// The device name of the client's network adapter.
153158
// if the device_name is "", the flow control is determined by the OS.
154159
// Default: ""

src/brpc/details/naming_service_thread.cpp

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -127,6 +127,7 @@ void NamingServiceThread::Actions::ResetServers(
127127
const SocketMapKey key(_added[i], _owner->_options.channel_signature);
128128
CHECK_EQ(0, SocketMapInsert(key, &tagged_id.id, _owner->_options.ssl_ctx,
129129
_owner->_options.use_rdma, _owner->_options.hc_option,
130+
_owner->_options.client_endpoint,
130131
_owner->_options.device_name));
131132
_added_sockets.push_back(tagged_id);
132133
}

src/brpc/details/naming_service_thread.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -53,6 +53,7 @@ struct GetNamingServiceThreadOptions {
5353
HealthCheckOption hc_option;
5454
ChannelSignature channel_signature;
5555
std::shared_ptr<SocketSSLContext> ssl_ctx;
56+
butil::EndPoint client_endpoint;
5657
std::string device_name;
5758
};
5859

src/brpc/socket.cpp

Lines changed: 14 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -728,7 +728,7 @@ int Socket::OnCreated(const SocketOptions& options) {
728728
_keytable_pool = options.keytable_pool;
729729
_tos = 0;
730730
_remote_side = options.remote_side;
731-
_local_side = butil::EndPoint();
731+
_local_side = options.local_side;
732732
_device_name = options.device_name;
733733
_on_edge_triggered_events = options.on_edge_triggered_events;
734734
_user = options.user;
@@ -1305,6 +1305,17 @@ int Socket::Connect(const timespec* abstime,
13051305
return -1;
13061306
}
13071307
}
1308+
if (local_side().ip != butil::IP_ANY) {
1309+
struct sockaddr_storage cli_addr;
1310+
if (butil::endpoint2sockaddr(local_side(), &cli_addr, &addr_size) != 0) {
1311+
PLOG(ERROR) << "Fail to get client sockaddr";
1312+
return -1;
1313+
}
1314+
if (::bind(sockfd, (struct sockaddr*)&cli_addr, addr_size) != 0) {
1315+
PLOG(ERROR) << "Fail to bind client socket, errno=" << strerror(errno);
1316+
return -1;
1317+
}
1318+
}
13081319
const int rc = ::connect(
13091320
sockfd, (struct sockaddr*)&serv_addr, addr_size);
13101321
if (rc != 0 && errno != EINPROGRESS) {
@@ -2819,6 +2830,7 @@ int Socket::GetPooledSocket(SocketUniquePtr* pooled_socket) {
28192830
if (socket_pool == NULL) {
28202831
SocketOptions opt;
28212832
opt.remote_side = remote_side();
2833+
opt.local_side = butil::EndPoint(local_side().ip, 0);
28222834
opt.user = user();
28232835
opt.on_edge_triggered_events = _on_edge_triggered_events;
28242836
opt.initial_ssl_ctx = _ssl_ctx;
@@ -2920,6 +2932,7 @@ int Socket::GetShortSocket(SocketUniquePtr* short_socket) {
29202932
SocketId id;
29212933
SocketOptions opt;
29222934
opt.remote_side = remote_side();
2935+
opt.local_side = butil::EndPoint(local_side().ip, 0);
29232936
opt.user = user();
29242937
opt.on_edge_triggered_events = _on_edge_triggered_events;
29252938
opt.initial_ssl_ctx = _ssl_ctx;

src/brpc/socket.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -250,6 +250,7 @@ struct SocketOptions {
250250
// user->BeforeRecycle() before recycling.
251251
int fd{-1};
252252
butil::EndPoint remote_side;
253+
butil::EndPoint local_side;
253254
std::string device_name;
254255
// If `connect_on_create' is true and `fd' is less than 0,
255256
// a client connection will be established to remote_side()

src/brpc/socket_map.cpp

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -93,8 +93,9 @@ int SocketMapInsert(const SocketMapKey& key, SocketId* id,
9393
const std::shared_ptr<SocketSSLContext>& ssl_ctx,
9494
bool use_rdma,
9595
const HealthCheckOption& hc_option,
96+
const butil::EndPoint& client_endpoint,
9697
const std::string& device_name) {
97-
return get_or_new_client_side_socket_map()->Insert(key, id, ssl_ctx, use_rdma, hc_option, device_name);
98+
return get_or_new_client_side_socket_map()->Insert(key, id, ssl_ctx, use_rdma, hc_option, client_endpoint, device_name);
9899
}
99100

100101
int SocketMapFind(const SocketMapKey& key, SocketId* id) {
@@ -231,6 +232,7 @@ int SocketMap::Insert(const SocketMapKey& key, SocketId* id,
231232
const std::shared_ptr<SocketSSLContext>& ssl_ctx,
232233
bool use_rdma,
233234
const HealthCheckOption& hc_option,
235+
const butil::EndPoint& client_endpoint,
234236
const std::string& device_name) {
235237
ShowSocketMapInBvarIfNeed();
236238

@@ -253,6 +255,7 @@ int SocketMap::Insert(const SocketMapKey& key, SocketId* id,
253255
SocketId tmp_id;
254256
SocketOptions opt;
255257
opt.remote_side = key.peer.addr;
258+
opt.local_side = client_endpoint;
256259
opt.device_name = device_name;
257260
opt.initial_ssl_ctx = ssl_ctx;
258261
opt.use_rdma = use_rdma;

src/brpc/socket_map.h

Lines changed: 10 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -83,18 +83,21 @@ int SocketMapInsert(const SocketMapKey& key, SocketId* id,
8383
const std::shared_ptr<SocketSSLContext>& ssl_ctx,
8484
bool use_rdma,
8585
const HealthCheckOption& hc_option,
86+
const butil::EndPoint& client_endpoint,
8687
const std::string& device_name);
8788

8889
inline int SocketMapInsert(const SocketMapKey& key, SocketId* id,
8990
const std::shared_ptr<SocketSSLContext>& ssl_ctx) {
9091
HealthCheckOption hc_option;
91-
return SocketMapInsert(key, id, ssl_ctx, false, hc_option, "");
92+
butil::EndPoint endpoint;
93+
return SocketMapInsert(key, id, ssl_ctx, false, hc_option, endpoint, "");
9294
}
9395

9496
inline int SocketMapInsert(const SocketMapKey& key, SocketId* id) {
9597
std::shared_ptr<SocketSSLContext> empty_ptr;
9698
HealthCheckOption hc_option;
97-
return SocketMapInsert(key, id, empty_ptr, false, hc_option, "");
99+
butil::EndPoint endpoint;
100+
return SocketMapInsert(key, id, empty_ptr, false, hc_option, endpoint, "");
98101
}
99102

100103
// Find the SocketId associated with `key'.
@@ -157,17 +160,20 @@ class SocketMap {
157160
const std::shared_ptr<SocketSSLContext>& ssl_ctx,
158161
bool use_rdma,
159162
const HealthCheckOption& hc_option,
163+
const butil::EndPoint& client_endpoint,
160164
const std::string& device_name);
161165

162166
int Insert(const SocketMapKey& key, SocketId* id,
163167
const std::shared_ptr<SocketSSLContext>& ssl_ctx) {
164168
HealthCheckOption hc_option;
165-
return Insert(key, id, ssl_ctx, false, hc_option, "");
169+
butil::EndPoint endpoint;
170+
return Insert(key, id, ssl_ctx, false, hc_option, endpoint, "");
166171
}
167172
int Insert(const SocketMapKey& key, SocketId* id) {
168173
std::shared_ptr<SocketSSLContext> empty_ptr;
169174
HealthCheckOption hc_option;
170-
return Insert(key, id, empty_ptr, false, hc_option, "");
175+
butil::EndPoint endpoint;
176+
return Insert(key, id, empty_ptr, false, hc_option, endpoint, "");
171177
}
172178

173179
void Remove(const SocketMapKey& key, SocketId expected_id);

test/brpc_server_unittest.cpp

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2087,7 +2087,7 @@ void TestClientHost(const butil::EndPoint& ep,
20872087
ASSERT_EQ(cntl.ErrorCode(), error_code);
20882088
}
20892089

2090-
TEST_F(ServerTest, network_device_name) {
2090+
TEST_F(ServerTest, bind_client_host_and_network_device) {
20912091
butil::EndPoint ep;
20922092
ASSERT_EQ(0, str2endpoint("127.0.0.1:8613", &ep));
20932093
brpc::Server server;
@@ -2098,6 +2098,7 @@ TEST_F(ServerTest, network_device_name) {
20982098

20992099
brpc::Controller cntl;
21002100
brpc::ChannelOptions copt;
2101+
copt.client_host = "localhost";
21012102
copt.device_name = "lo";
21022103
std::vector<brpc::ConnectionType> connection_types = {
21032104
brpc::CONNECTION_TYPE_SINGLE,

0 commit comments

Comments
 (0)