From afb5d5baba43b286e238903f32498c5f3d0ca2c2 Mon Sep 17 00:00:00 2001 From: zrlw Date: Tue, 19 May 2026 12:00:30 +0800 Subject: [PATCH] Add JVM SOCKS5 proxy support to NettyConnectionClient --- .../netty4/NettyConnectionClient.java | 27 ++++++++++++++++++- 1 file changed, 26 insertions(+), 1 deletion(-) diff --git a/dubbo-remoting/dubbo-remoting-netty4/src/main/java/org/apache/dubbo/remoting/transport/netty4/NettyConnectionClient.java b/dubbo-remoting/dubbo-remoting-netty4/src/main/java/org/apache/dubbo/remoting/transport/netty4/NettyConnectionClient.java index 8fcec6ddc1df..bada55635aa6 100644 --- a/dubbo-remoting/dubbo-remoting-netty4/src/main/java/org/apache/dubbo/remoting/transport/netty4/NettyConnectionClient.java +++ b/dubbo-remoting/dubbo-remoting-netty4/src/main/java/org/apache/dubbo/remoting/transport/netty4/NettyConnectionClient.java @@ -18,7 +18,9 @@ import org.apache.dubbo.common.URL; import org.apache.dubbo.common.Version; +import org.apache.dubbo.common.config.ConfigurationUtils; import org.apache.dubbo.common.utils.NetUtils; +import org.apache.dubbo.common.utils.StringUtils; import org.apache.dubbo.remoting.ChannelHandler; import org.apache.dubbo.remoting.Constants; import org.apache.dubbo.remoting.RemotingException; @@ -28,6 +30,7 @@ import org.apache.dubbo.remoting.transport.netty4.ssl.SslContexts; import org.apache.dubbo.remoting.utils.UrlUtils; +import java.net.InetSocketAddress; import java.util.concurrent.TimeUnit; import java.util.concurrent.atomic.AtomicReference; @@ -40,6 +43,7 @@ import io.netty.channel.ChannelPipeline; import io.netty.channel.socket.SocketChannel; import io.netty.handler.codec.http2.Http2FrameCodec; +import io.netty.handler.proxy.Socks5ProxyHandler; import io.netty.handler.ssl.SslContext; import io.netty.handler.timeout.IdleStateHandler; import io.netty.util.concurrent.DefaultPromise; @@ -52,6 +56,12 @@ public final class NettyConnectionClient extends AbstractNettyConnectionClient { + private static final String SOCKS_PROXY_HOST = "socksProxyHost"; + + private static final String SOCKS_PROXY_PORT = "socksProxyPort"; + + private static final String DEFAULT_SOCKS_PROXY_PORT = "1080"; + private Bootstrap bootstrap; private AtomicReference> channelInitializedPromiseRef; @@ -70,6 +80,7 @@ protected void initConnectionClient() { super.initConnectionClient(); } + @Override protected void initBootstrap() { channelInitializedPromiseRef = new AtomicReference<>(); Bootstrap bootstrap = new Bootstrap(); @@ -124,7 +135,16 @@ protected void initChannel(SocketChannel ch) { // set null but do not close this client, it will be reconnecting in the future ch.closeFuture().addListener(channelFuture -> clearNettyChannel()); - // TODO support Socks5 + // support Socks5 + String socksProxyHost = + ConfigurationUtils.getProperty(getUrl().getOrDefaultApplicationModel(), SOCKS_PROXY_HOST); + if (socksProxyHost != null && !isFilteredAddress(getUrl().getHost())) { + int socksProxyPort = Integer.parseInt(ConfigurationUtils.getProperty( + getUrl().getOrDefaultApplicationModel(), SOCKS_PROXY_PORT, DEFAULT_SOCKS_PROXY_PORT)); + Socks5ProxyHandler socks5ProxyHandler = + new Socks5ProxyHandler(new InetSocketAddress(socksProxyHost, socksProxyPort)); + pipeline.addFirst(socks5ProxyHandler); + } // set channel initialized promise to success if necessary. Promise channelInitializedPromise = channelInitializedPromiseRef.get(); @@ -227,4 +247,9 @@ private void waitConnectionPreface(long start) throws RemotingException { throw remotingException; } } + + private boolean isFilteredAddress(String host) { + // filter local address + return StringUtils.isEquals(NetUtils.getLocalHost(), host) || NetUtils.isLocalHost(host); + } }