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

lgoldstein pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/mina-sshd.git

commit 23d2763f79be6067ee881c761659b85c610ae99e
Author: Lyor Goldstein <lgoldst...@apache.org>
AuthorDate: Thu Feb 27 11:21:01 2020 +0200

    [SSHD-968] Added SessionHelper#preProcessEncodeBuffer
---
 .../common/session/helpers/AbstractSession.java    | 17 ++++++-----
 .../sshd/common/session/helpers/SessionHelper.java | 33 +++++++++++++++++++++-
 2 files changed, 42 insertions(+), 8 deletions(-)

diff --git 
a/sshd-core/src/main/java/org/apache/sshd/common/session/helpers/AbstractSession.java
 
b/sshd-core/src/main/java/org/apache/sshd/common/session/helpers/AbstractSession.java
index 4468276..05e6275 100644
--- 
a/sshd-core/src/main/java/org/apache/sshd/common/session/helpers/AbstractSession.java
+++ 
b/sshd-core/src/main/java/org/apache/sshd/common/session/helpers/AbstractSession.java
@@ -1069,15 +1069,18 @@ public abstract class AbstractSession extends 
SessionHelper {
             // Check that the packet has some free space for the header
             int curPos = buffer.rpos();
             int cmd = buffer.rawByte(curPos) & 0xFF;  // usually the 1st byte 
is an SSH opcode
-            if (curPos < SshConstants.SSH_PACKET_HEADER_LEN) {
-                log.warn("encode({}) command={}[{}] performance cost: 
available buffer packet header length ({}) below min. required ({})",
-                     this, cmd, SshConstants.getCommandMessageName(cmd),
-                     curPos, SshConstants.SSH_PACKET_HEADER_LEN);
-                Buffer nb = new ByteArrayBuffer(buffer.available() + 
Long.SIZE, false);
-                nb.wpos(SshConstants.SSH_PACKET_HEADER_LEN);
-                nb.putBuffer(buffer);
+            Buffer nb = preProcessEncodeBuffer(cmd, buffer);
+            if (nb != buffer) {
                 buffer = nb;
                 curPos = buffer.rpos();
+
+                int newCmd = buffer.rawByte(curPos) & 0xFF;
+                if (cmd != newCmd) {
+                    log.warn("encode({}) - command changed from {}[{}] to 
{}[{}] by pre-processor",
+                        this, cmd, SshConstants.getCommandMessageName(cmd),
+                        newCmd, SshConstants.getCommandMessageName(newCmd));
+                    cmd = newCmd;
+                }
             }
 
             // Grab the length of the packet (excluding the 5 header bytes)
diff --git 
a/sshd-core/src/main/java/org/apache/sshd/common/session/helpers/SessionHelper.java
 
b/sshd-core/src/main/java/org/apache/sshd/common/session/helpers/SessionHelper.java
index 6003372..8fd2b44 100644
--- 
a/sshd-core/src/main/java/org/apache/sshd/common/session/helpers/SessionHelper.java
+++ 
b/sshd-core/src/main/java/org/apache/sshd/common/session/helpers/SessionHelper.java
@@ -996,9 +996,40 @@ public abstract class SessionHelper extends 
AbstractKexFactoryManager implements
         listener.sessionNegotiationEnd(this, c2sOptions, s2cOptions, 
negotiatedGuess, null);
     }
 
+    /**
+     * Invoked by the session before encoding the buffer in order to make sure 
that it is
+     * at least of size {@link SshConstants#SSH_PACKET_HEADER_LEN 
SSH_PACKET_HEADER_LEN}.
+     * This is required in order to efficiently handle the encoding. If 
necessary, it
+     * re-allocates a new buffer and returns it instead.
+     *
+     * @param cmd The command stored in the buffer
+     * @param buffer The original {@link Buffer} - assumed to be properly 
formatted
+     * and be of at least the required minimum length.
+     * @return The adjusted {@link Buffer}. <B>Note:</B> users may use this 
method to
+     * totally alter the contents of the buffer being sent but it is highly 
discouraged
+     * as it may have unexpected results.
+     * @throws IOException If failed to process the buffer
+     */
+    protected Buffer preProcessEncodeBuffer(int cmd, Buffer buffer) throws 
IOException {
+        int curPos = buffer.rpos();
+        if (curPos >= SshConstants.SSH_PACKET_HEADER_LEN) {
+            return buffer;
+        }
+
+        log.warn("preProcessEncodeBuffer({}) command={}[{}] performance cost:"
+            + " available buffer packet header length ({}) below min. required 
({})",
+            this, cmd, SshConstants.getCommandMessageName(cmd),
+            curPos, SshConstants.SSH_PACKET_HEADER_LEN);
+        Buffer nb = new ByteArrayBuffer(buffer.available() + Long.SIZE, false);
+        nb.wpos(SshConstants.SSH_PACKET_HEADER_LEN);
+        nb.putBuffer(buffer);
+        return nb;
+    }
+
     @Override
     public void disconnect(int reason, String msg) throws IOException {
-        log.info("Disconnecting({}): {} - {}", this, 
SshConstants.getDisconnectReasonName(reason), msg);
+        log.info("Disconnecting({}): {} - {}",
+            this, SshConstants.getDisconnectReasonName(reason), msg);
         String languageTag = "";    // TODO configure language...
         signalDisconnect(reason, msg, languageTag, true);
 

Reply via email to