Skip to content

Commit 2578b05

Browse files
committed
bind_client_ip
1 parent c7ae57a commit 2578b05

8 files changed

Lines changed: 57 additions & 13 deletions

File tree

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.connection_group.empty() &&
8182
opt.hc_option.health_check_path.empty()) {
8283
// Returning zeroized result by default is more intuitive for users.
@@ -94,6 +95,10 @@ static ChannelSignature ComputeChannelSignature(const ChannelOptions& opt) {
9495
buf.append("|conng=");
9596
buf.append(opt.connection_group);
9697
}
98+
if (!opt.client_host.empty()) {
99+
buf.append("|clih=");
100+
buf.append(opt.client_host);
101+
}
97102
if (opt.auth) {
98103
buf.append("|auth=");
99104
buf.append((char*)&opt.auth, sizeof(opt.auth));
@@ -362,14 +367,22 @@ int Channel::InitSingle(const butil::EndPoint& server_addr_and_port,
362367
LOG(ERROR) << "Invalid port=" << port;
363368
return -1;
364369
}
370+
butil::EndPoint client_end_point;
371+
if (!_options.client_host.empty() &&
372+
butil::str2ip(_options.client_host.c_str(), &client_end_point.ip) != 0 &&
373+
butil::hostname2ip(_options.client_host.c_str(), &client_end_point.ip) != 0) {
374+
LOG(ERROR) << "Invalid client host=`" << _options.client_host << '\'';
375+
return -1;
376+
}
365377
_server_address = server_addr_and_port;
366378
const ChannelSignature sig = ComputeChannelSignature(_options);
367379
std::shared_ptr<SocketSSLContext> ssl_ctx;
368380
if (CreateSocketSSLContext(_options, &ssl_ctx) != 0) {
369381
return -1;
370382
}
371383
if (SocketMapInsert(SocketMapKey(server_addr_and_port, sig),
372-
&_server_id, ssl_ctx, _options.use_rdma, _options.hc_option) != 0) {
384+
&_server_id, ssl_ctx, _options.use_rdma,
385+
_options.hc_option, client_end_point) != 0) {
373386
LOG(ERROR) << "Fail to insert into SocketMap";
374387
return -1;
375388
}
@@ -397,6 +410,13 @@ int Channel::Init(const char* ns_url,
397410
_options.mutable_ssl_options()->sni_name = _service_name;
398411
}
399412
}
413+
butil::EndPoint client_end_point;
414+
if (!_options.client_host.empty() &&
415+
butil::str2ip(_options.client_host.c_str(), &client_end_point.ip) != 0 &&
416+
butil::hostname2ip(_options.client_host.c_str(), &client_end_point.ip) != 0) {
417+
LOG(ERROR) << "Invalid client host=`" << _options.client_host << '\'';
418+
return -1;
419+
}
400420
std::unique_ptr<LoadBalancerWithNaming> lb(new (std::nothrow)
401421
LoadBalancerWithNaming);
402422
if (NULL == lb) {
@@ -409,6 +429,7 @@ int Channel::Init(const char* ns_url,
409429
ns_opt.use_rdma = _options.use_rdma;
410430
ns_opt.channel_signature = ComputeChannelSignature(_options);
411431
ns_opt.hc_option = _options.hc_option;
432+
ns_opt.client_end_point = client_end_point;
412433
if (CreateSocketSSLContext(_options, &ns_opt.ssl_ctx) != 0) {
413434
return -1;
414435
}

src/brpc/channel.h

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -148,6 +148,10 @@ struct ChannelOptions {
148148
// Its priority is higher than FLAGS_health_check_path and FLAGS_health_check_timeout_ms.
149149
// When it is not set, FLAGS_health_check_path and FLAGS_health_check_timeout_ms will take effect.
150150
HealthCheckOption hc_option;
151+
152+
// IP address or host name of the client
153+
// Default: ""
154+
std::string client_host;
151155
private:
152156
// SSLOptions is large and not often used, allocate it on heap to
153157
// prevent ChannelOptions from being bloated in most cases.

src/brpc/details/naming_service_thread.cpp

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -126,7 +126,8 @@ void NamingServiceThread::Actions::ResetServers(
126126
// to pick those Sockets with the right settings during OnAddedServers
127127
const SocketMapKey key(_added[i], _owner->_options.channel_signature);
128128
CHECK_EQ(0, SocketMapInsert(key, &tagged_id.id, _owner->_options.ssl_ctx,
129-
_owner->_options.use_rdma, _owner->_options.hc_option));
129+
_owner->_options.use_rdma, _owner->_options.hc_option,
130+
_owner->_options.client_end_point));
130131
_added_sockets.push_back(tagged_id);
131132
}
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_end_point;
5657
};
5758

5859
// A dedicated thread to map a name to ServerIds

src/brpc/socket.cpp

Lines changed: 9 additions & 2 deletions
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
_on_edge_triggered_events = options.on_edge_triggered_events;
733733
_user = options.user;
734734
_conn = options.conn;
@@ -1283,8 +1283,10 @@ int Socket::Connect(const timespec* abstime,
12831283
_ssl_state = SSL_OFF;
12841284
}
12851285
struct sockaddr_storage serv_addr;
1286+
struct sockaddr_storage cli_addr;
12861287
socklen_t addr_size = 0;
1287-
if (butil::endpoint2sockaddr(remote_side(), &serv_addr, &addr_size) != 0) {
1288+
if (butil::endpoint2sockaddr(remote_side(), &serv_addr, &addr_size) != 0 ||
1289+
butil::endpoint2sockaddr(local_side(), &cli_addr, &addr_size) != 0) {
12881290
PLOG(ERROR) << "Fail to get sockaddr";
12891291
return -1;
12901292
}
@@ -1297,6 +1299,10 @@ int Socket::Connect(const timespec* abstime,
12971299
// We need to do async connect (to manage the timeout by ourselves).
12981300
CHECK_EQ(0, butil::make_non_blocking(sockfd));
12991301

1302+
if (::bind(sockfd, (struct sockaddr*)& cli_addr, addr_size) != 0) {
1303+
LOG(FATAL) << "Fail to bind socket, errno=" << strerror(errno);
1304+
return -1;
1305+
}
13001306
const int rc = ::connect(
13011307
sockfd, (struct sockaddr*)&serv_addr, addr_size);
13021308
if (rc != 0 && errno != EINPROGRESS) {
@@ -2811,6 +2817,7 @@ int Socket::GetPooledSocket(SocketUniquePtr* pooled_socket) {
28112817
if (socket_pool == NULL) {
28122818
SocketOptions opt;
28132819
opt.remote_side = remote_side();
2820+
opt.local_side = local_side();
28142821
opt.user = user();
28152822
opt.on_edge_triggered_events = _on_edge_triggered_events;
28162823
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
// If `connect_on_create' is true and `fd' is less than 0,
254255
// a client connection will be established to remote_side()
255256
// regarding deadline `connect_abstime' when Socket is being created.

src/brpc/socket_map.cpp

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -92,8 +92,9 @@ SocketMap* get_or_new_client_side_socket_map() {
9292
int SocketMapInsert(const SocketMapKey& key, SocketId* id,
9393
const std::shared_ptr<SocketSSLContext>& ssl_ctx,
9494
bool use_rdma,
95-
const HealthCheckOption& hc_option) {
96-
return get_or_new_client_side_socket_map()->Insert(key, id, ssl_ctx, use_rdma, hc_option);
95+
const HealthCheckOption& hc_option,
96+
butil::EndPoint& client_end_point) {
97+
return get_or_new_client_side_socket_map()->Insert(key, id, ssl_ctx, use_rdma, hc_option, client_end_point);
9798
}
9899

99100
int SocketMapFind(const SocketMapKey& key, SocketId* id) {
@@ -229,7 +230,8 @@ void SocketMap::ShowSocketMapInBvarIfNeed() {
229230
int SocketMap::Insert(const SocketMapKey& key, SocketId* id,
230231
const std::shared_ptr<SocketSSLContext>& ssl_ctx,
231232
bool use_rdma,
232-
const HealthCheckOption& hc_option) {
233+
const HealthCheckOption& hc_option,
234+
butil::EndPoint& client_end_point) {
233235
ShowSocketMapInBvarIfNeed();
234236

235237
std::unique_lock<butil::Mutex> mu(_mutex);
@@ -251,6 +253,7 @@ int SocketMap::Insert(const SocketMapKey& key, SocketId* id,
251253
SocketId tmp_id;
252254
SocketOptions opt;
253255
opt.remote_side = key.peer.addr;
256+
opt.local_side = client_end_point;
254257
opt.initial_ssl_ctx = ssl_ctx;
255258
opt.use_rdma = use_rdma;
256259
opt.hc_option = hc_option;

src/brpc/socket_map.h

Lines changed: 12 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -82,18 +82,21 @@ struct SocketMapKeyHasher {
8282
int SocketMapInsert(const SocketMapKey& key, SocketId* id,
8383
const std::shared_ptr<SocketSSLContext>& ssl_ctx,
8484
bool use_rdma,
85-
const HealthCheckOption& hc_option);
85+
const HealthCheckOption& hc_option,
86+
butil::EndPoint& client_end_point);
8687

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

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

99102
// Find the SocketId associated with `key'.
@@ -155,17 +158,20 @@ class SocketMap {
155158
int Insert(const SocketMapKey& key, SocketId* id,
156159
const std::shared_ptr<SocketSSLContext>& ssl_ctx,
157160
bool use_rdma,
158-
const HealthCheckOption& hc_option);
161+
const HealthCheckOption& hc_option,
162+
butil::EndPoint& client_end_point);
159163

160164
int Insert(const SocketMapKey& key, SocketId* id,
161165
const std::shared_ptr<SocketSSLContext>& ssl_ctx) {
162166
HealthCheckOption hc_option;
163-
return Insert(key, id, ssl_ctx, false, hc_option);
167+
butil::EndPoint endpoint;
168+
return Insert(key, id, ssl_ctx, false, hc_option, endpoint);
164169
}
165170
int Insert(const SocketMapKey& key, SocketId* id) {
166171
std::shared_ptr<SocketSSLContext> empty_ptr;
167172
HealthCheckOption hc_option;
168-
return Insert(key, id, empty_ptr, false, hc_option);
173+
butil::EndPoint endpoint;
174+
return Insert(key, id, empty_ptr, false, hc_option, endpoint);
169175
}
170176

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

0 commit comments

Comments
 (0)