hjwsm1989 opened a new issue, #3260:
URL: https://github.com/apache/brpc/issues/3260
**Is your feature request related to a problem?**
Yes.
`brpc` currently has partial support for binding a client connection to a
specific local IP/device (see PR #3179), but that only covers the case where
one `Channel` uses one fixed local bind target.
This is not sufficient for multi-homed applications where:
- the server side has multiple addresses (for example private/public or
multiple private planes), and
- one client `Channel` may talk to different peers/endpoints selected from
naming service / load balancer, and
- different remote peers must use different local `IP + device` bindings.
A concrete failure mode is:
- private NICs are down,
- the OS still routes packets to another node's private IP via another
available NIC,
- heartbeats can still reach the peer's private endpoint,
- upper-layer health logic does not detect the private-network failure
correctly.
In this case, failing fast is preferred. We do **not** want the OS to
silently reroute traffic through another interface.
**Describe the solution you'd like**
Support **per-peer client bind policy** instead of only one fixed bind
target per `Channel`.
In other words, `brpc` should be able to choose the local bind target
**before creating the socket for a selected peer**, and then apply:
- local source IP binding (`bind(local_ip, 0)`), and
- device binding (`SO_BINDTODEVICE` on Linux)
for that specific peer.
From a design perspective, the key requirement is:
- the bind decision should happen at the `Channel` / naming-service /
socket-creation layer,
- not by late ad-hoc inference inside `Socket::Connect()`.
A rule-based model would likely fit best, for example:
- `peer selector -> local_ip@device`
where peer selector could be something like:
- exact peer endpoint,
- CIDR,
- or a default/fallback rule.
Important expectations:
- works for `single` / `pooled` / `short` connection types consistently,
- works for channels backed by naming service / multiple server addresses,
- derived sockets (pooled/short) inherit the same bind policy,
- different bind policies do not accidentally share the same underlying
socket,
- when the configured local path is unavailable, connection should fail
instead of being rerouted by the OS.
**Describe alternatives you've considered**
1. **One fixed local bind target per Channel**
- This is what the current single-bind approach enables.
- It does not work when one `Channel` can reach multiple peers that
require different egress interfaces.
2. **Split traffic into multiple Channels at application level**
- This works around the problem, but is cumbersome and pushes
topology-specific policy to every application.
- It is also awkward when server addresses are dynamic and come from
naming service.
3. **Infer device dynamically inside `Socket::Connect()`**
- This is too late in the stack and not very stable.
- It also makes pooled/derived socket behavior harder to reason about.
4. **Encode local device into server endpoint strings (for example
`ip:port@device`)**
- This mixes remote server attributes with local client attributes and is
hard to extend cleanly.
**Additional context/screenshots**
The motivation comes from a real multi-homed deployment where server private
addresses and client egress interfaces must be matched explicitly.
PR #3179 is a very useful foundation, but for multi-address /
naming-service-based channels we still need a way to express and enforce
**per-peer local bind selection**.
--
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.
To unsubscribe, e-mail: [email protected]
For queries about this service, please contact Infrastructure at:
[email protected]
---------------------------------------------------------------------
To unsubscribe, e-mail: [email protected]
For additional commands, e-mail: [email protected]