This is an automated email from the ASF dual-hosted git repository.

tomaswolf pushed a commit to branch rc-3.0.0-M6
in repository https://gitbox.apache.org/repos/asf/mina-sshd.git

commit ebc3ee58643446b4bc542c5bb810e7794d17a037
Author: Thomas Wolf <[email protected]>
AuthorDate: Sat Sep 26 12:09:53 2026 +0200

    Clean up SocksProxy
    
    Minor code cleanup to avoid duplicate code and to centralize channel
    window handling.
---
 .../org/apache/sshd/common/forward/SocksProxy.java | 84 +++++++++++-----------
 1 file changed, 44 insertions(+), 40 deletions(-)

diff --git 
a/sshd-core/src/main/java/org/apache/sshd/common/forward/SocksProxy.java 
b/sshd-core/src/main/java/org/apache/sshd/common/forward/SocksProxy.java
index caf7f4974..79543f73a 100644
--- a/sshd-core/src/main/java/org/apache/sshd/common/forward/SocksProxy.java
+++ b/sshd-core/src/main/java/org/apache/sshd/common/forward/SocksProxy.java
@@ -113,6 +113,20 @@ public class SocksProxy extends AbstractCloseable 
implements IoHandler {
             }
         }
 
+        protected void openChannel(String host, int port) throws IOException {
+            SshdSocketAddress remote = new SshdSocketAddress(host, port);
+            channel = new TcpipClientChannel(TcpipClientChannel.Type.Direct, 
session, remote);
+            channel.setStreaming(Streaming.Async);
+            session.suspendRead();
+            service.registerChannel(channel);
+            // Open the channel, but don't accept input data yet!
+            LocalWindow window = channel.getLocalWindow();
+            long windowSize = window.consumeAll();
+            channel.open().addListener(f -> onChannelOpened(f, window, 
windowSize));
+        }
+
+        protected abstract void onChannelOpened(OpenFuture future, LocalWindow 
window, long windowSize);
+
         protected void sendReply(Buffer message, boolean success, Runnable 
completion, LocalWindow window, long windowSize) {
             try {
                 session.writeBuffer(message).addListener(future -> {
@@ -154,6 +168,7 @@ public class SocksProxy extends AbstractCloseable 
implements IoHandler {
      * @see <A HREF="https://en.wikipedia.org/wiki/SOCKS#SOCKS4";>SOCKS4</A>
      */
     public class Socks4 extends Proxy {
+
         public Socks4(IoSession session) {
             super(session);
         }
@@ -180,35 +195,30 @@ public class SocksProxy extends AbstractCloseable 
implements IoHandler {
                     log.debug("Received socks4 connection request for {} to 
{}:{}", userId, host, port);
                 }
 
-                SshdSocketAddress remote = new SshdSocketAddress(host, port);
-                channel = new 
TcpipClientChannel(TcpipClientChannel.Type.Direct, session, remote);
-                channel.setStreaming(Streaming.Async);
-                session.suspendRead();
-                service.registerChannel(channel);
-                // Open the channel, but don't accept input data yet!
-                LocalWindow window = channel.getLocalWindow();
-                long windowSize = window.consumeAll();
-                channel.open().addListener(f -> onChannelOpened(f, window, 
windowSize));
+                openChannel(host, port);
             } else {
                 super.onMessage(buffer);
             }
         }
 
+        @Override
         @SuppressWarnings("synthetic-access")
         protected void onChannelOpened(OpenFuture future, LocalWindow window, 
long windowSize) {
+            boolean success = future.isOpened();
+            Runnable completion = null;
             Buffer buffer = new ByteArrayBuffer(Long.SIZE, false);
             buffer.putByte((byte) 0x00);
-            Throwable t = future.getException();
-            if (t != null) {
+            if (success) {
+                buffer.putByte(SocksConstants.Socks4.REPLY_SUCCESS);
+            } else {
                 service.unregisterChannel(channel);
                 channel.close(true);
                 buffer.putByte(SocksConstants.Socks4.REPLY_FAILURE);
-            } else {
-                buffer.putByte(SocksConstants.Socks4.REPLY_SUCCESS);
+                completion = () -> session.close(false);
             }
             buffer.putInt(0);
             buffer.putShort(0);
-            sendReply(buffer, t == null, () -> session.close(false), window, 
windowSize);
+            sendReply(buffer, success, completion, window, windowSize);
         }
 
         protected String getNTString(Buffer buffer) {
@@ -245,10 +255,10 @@ public class SocksProxy extends AbstractCloseable 
implements IoHandler {
         protected synchronized void onMessage(Buffer buffer) throws 
IOException {
             if (state == Socks5State.FORWARDING && pending.available() == 0) {
                 super.onMessage(buffer);
-                return;
+            } else {
+                pending.putBuffer(buffer);
+                processPending();
             }
-            pending.putBuffer(buffer);
-            processPending();
         }
 
         protected void processPending() throws IOException {
@@ -350,42 +360,36 @@ public class SocksProxy extends AbstractCloseable 
implements IoHandler {
                 if (log.isDebugEnabled()) {
                     log.debug("Received socks5 connection request to {}:{}", 
host, port);
                 }
-                SshdSocketAddress remote = new SshdSocketAddress(host, port);
-                channel = new 
TcpipClientChannel(TcpipClientChannel.Type.Direct, session, remote);
-                channel.setStreaming(Streaming.Async);
-                session.suspendRead();
-                service.registerChannel(channel);
+
                 state = Socks5State.OPENING_CHANNEL;
-                // Open the channel, but don't accept input data yet!
-                LocalWindow window = channel.getLocalWindow();
-                long windowSize = window.consumeAll();
-                channel.open().addListener(f -> onChannelOpened(f, window, 
windowSize));
+                openChannel(host, port);
             }
         }
 
+        @Override
         @SuppressWarnings("synthetic-access")
         protected synchronized void onChannelOpened(OpenFuture future, 
LocalWindow window, long windowSize) {
-            Buffer response = new ByteArrayBuffer(10, false);
-            response.putByte(SocksConstants.Socks5.VERSION);
-            Throwable t = future.getException();
+            boolean success = future.isOpened();
             Runnable completion;
-            if (t != null) {
+            if (success) {
+                state = Socks5State.FORWARDING;
+                completion = () -> forwardPending(false);
+            } else {
                 service.unregisterChannel(channel);
                 channel.close(true);
                 pending.clear(true);
                 state = Socks5State.CLOSED;
-                response.putByte(SocksConstants.Socks5.REPLY_FAILURE);
                 completion = () -> session.close(false);
-            } else {
-                state = Socks5State.FORWARDING;
-                response.putByte(SocksConstants.Socks5.REPLY_SUCCESS);
-                completion = () -> forwardPending(false);
             }
-            response.putByte((byte) 0x00); // reserved
-            response.putByte(SocksConstants.Socks5.ADDRESS_IPV4);
-            response.putInt(0);
-            response.putShort(0);
-            sendReply(response, t == null, completion, window, windowSize);
+            byte[] answer = {
+                    SocksConstants.Socks5.VERSION,
+                    success ? SocksConstants.Socks5.REPLY_SUCCESS : 
SocksConstants.Socks5.REPLY_FAILURE,
+                    0, // reserved
+                    SocksConstants.Socks5.ADDRESS_IPV4,
+                    0, 0, 0, 0, // IP address
+                    0, 0 // port
+            };
+            sendReply(new ByteArrayBuffer(answer), success, completion, 
window, windowSize);
         }
 
         protected synchronized void forwardPending(boolean suspend) {

Reply via email to