Class CompositeOriginalDestinationResolver
- All Implemented Interfaces:
TransparentProxyHandler.OriginalDestinationResolver
TransparentProxyHandler.OriginalDestinationResolver that tries
an ordered chain of resolution strategies and returns the first non-null result.
Each strategy is invoked in order. If a strategy returns null or throws
UnsupportedOperationException (e.g., platform not supported), the next
strategy is tried. Any other exception is caught, logged at the calling layer,
and treated as a skip (fall through to the next strategy).
Default chain (constructed via defaultChain(Configuration)):
TproxyOriginalDestinationResolver— reads the original destination fromchannel.localAddress()when TPROXY mode is active (the TPROXY iptables target preserves the original destination as the socket's local address). Returnsnullwhen TPROXY mode is not enabled in configuration.EbpfOriginalDestinationResolver— O(1) BPF hash map lookup keyed by socket cookie. An external BPF program (cgroup/connect4) records the original destination before NAT; this resolver reads and consumes the entry. Returnsnullwhen eBPF mode is not enabled or the pinned map is unavailable. Requires Linux + epoll + JNA + CAP_BPF + external BPF program.SoOriginalDstResolver— O(1)getsockopt(SO_ORIGINAL_DST)via JNA (requires Linux + Netty epoll transport; returns null on NIO channels or non-Linux)ConntrackOriginalDestinationResolver— O(n) Linux conntrack table lookup (fallback when SO_ORIGINAL_DST is unavailable)DnsIntentOriginalDestinationResolver— recovers the intended hostname from MockServer's DNS answer cache (DNS-steering mode)
Note: PROXY protocol v1/v2 resolution is handled separately by
ProxyProtocolOriginalDestinationHandler in the Netty pipeline (it requires
reading inbound bytes, not just channel metadata at channelActive time).
-
Constructor Summary
ConstructorsConstructorDescriptionCompositeOriginalDestinationResolver(List<TransparentProxyHandler.OriginalDestinationResolver> strategies) Creates a composite resolver with the given ordered strategies. -
Method Summary
Modifier and TypeMethodDescriptionReturns the default chain without TPROXY or eBPF: [SO_ORIGINAL_DST, conntrack, dns-intent].defaultChain(Configuration configuration) Returns the default chain: [TPROXY, eBPF, SO_ORIGINAL_DST, conntrack, dns-intent].resolve(io.netty.channel.Channel channel) Tries each strategy in order.intReturns the number of strategies in this chain (useful for testing).
-
Constructor Details
-
CompositeOriginalDestinationResolver
public CompositeOriginalDestinationResolver(List<TransparentProxyHandler.OriginalDestinationResolver> strategies) Creates a composite resolver with the given ordered strategies.- Parameters:
strategies- the resolution strategies to try in order; must not be null or empty- Throws:
IllegalArgumentException- if strategies is null or empty
-
-
Method Details
-
defaultChain
Returns the default chain: [TPROXY, eBPF, SO_ORIGINAL_DST, conntrack, dns-intent].TPROXY is first — when TPROXY mode is active (
transparentProxyTproxy=true), the local address IS the original destination and no further resolution is needed. When TPROXY is not enabled, the resolver returns null and the chain falls through.eBPF is second — when eBPF mode is active (
transparentProxyEbpf=true), the resolver reads a pinned BPF hash map populated by an external cgroup BPF program. The lookup is O(1) and captures the original destination before any NAT rewrite, making it more authoritative than SO_ORIGINAL_DST. When eBPF is not enabled or the pinned map is unavailable, the resolver returns null and the chain falls through.SO_ORIGINAL_DST (via JNA getsockopt) is tried third — it is an O(1) socket option read, far cheaper than the O(n) conntrack table scan. It requires Linux + Netty epoll transport; on NIO channels or non-Linux it returns null and the chain falls through to conntrack.
Conntrack is the fourth strategy because a real iptables-REDIRECT original destination is still the most authoritative source when SO_ORIGINAL_DST is unavailable. The DNS-intent resolver fills the gap when all others return null — it recovers the hostname that MockServer's DNS server mapped to the connection's destination IP.
- Parameters:
configuration- the MockServer configuration (needed by TPROXY and eBPF resolvers)
-
defaultChain
Returns the default chain without TPROXY or eBPF: [SO_ORIGINAL_DST, conntrack, dns-intent].This overload maintains backward compatibility for callers that do not have a
Configurationinstance. TPROXY and eBPF resolution are not included (both require configuration). -
resolve
Tries each strategy in order. Returns the first non-null result.If a strategy throws
UnsupportedOperationException, it is skipped (expected on unsupported platforms). Any other exception is also caught and skipped (fail-safe: the caller logs at the appropriate level).- Specified by:
resolvein interfaceTransparentProxyHandler.OriginalDestinationResolver- Parameters:
channel- the accepted Netty channel- Returns:
- the resolved original destination, or
nullif no strategy resolved it
-
strategyCount
public int strategyCount()Returns the number of strategies in this chain (useful for testing).
-