Apache Mina和SSHD(反向SSH):无效的数据包长度0

时间:2015-11-02 08:11:53

标签: mina sshd

请分享您对如何解决此异常的想法

我们正在使用Netconf Over SSH,使用的SSH库是Apache Mina和SSHD。 Device是Netconf服务器,Application是Netconf Client。由于设备位于防火墙之后,应用程序无法连接到设备,但设备可以连接到应用程序。所以,我们正在使用设备建立的会话来进行所有通信的应用程序。

以下是以下步骤:
1.启动NioSocketAcceptor侦听/绑定到端口号
2. IoSessionConfig的useReadoperation属性设置为true
3.当接受tcp连接时,我们有一个可用的mina核心IoSession,这里我们将其称为tcpSession。
我们想用这个mina IoSession来读写netconf消息。用于将mina核心会话转换为ssdh IoSession的代码如下

new org.apache.sshd.common.io.IoSession() {         

        @Override
        public long getId() {
            return tcpSession.getId();
        }

        @Override
        public Object getAttribute(final Object key) {
            return tcpSession.getAttribute(key);
        }

        @Override
        public Object setAttribute(final Object key, final Object value) {
            return tcpSession.getAttribute(key, value);
        }

        @Override
        public SocketAddress getRemoteAddress() {
            return tcpSession.getRemoteAddress();
        }

        @Override
        public SocketAddress getLocalAddress() {
            return tcpSession.getLocalAddress();
        }

        @Override
        public IoWriteFuture write(final Buffer buffer) {
            final ChannelAsyncOutputStream.IoWriteFutureImpl ioWriteFuture = new ChannelAsyncOutputStream.IoWriteFutureImpl(buffer);
            byte[] bytes = buffer.getCompactData();   
            int capacity = bytes.length + 8;   
            IoBuffer bytebuffer = IoBuffer.allocate(capacity).setAutoExpand(true);   
            //bytebuffer.putInt(bytes.length);   
            bytebuffer.put(bytes);   
            bytebuffer.flip();              
            buffer.clear();
            final WriteFuture write = tcpSession.write(bytebuffer);
            write.addListener(new IoFutureListener<WriteFuture>() {
                @Override
                public void operationComplete(final WriteFuture future) {
                    if (future.isWritten()) {
                        ioWriteFuture.setValue(true);
                    } else {
                        // TODO check the value type expected + if exception can go there
                        ioWriteFuture.setValue(future.getException());
                    }
                }
            });

            return ioWriteFuture;
        }       

        @Override
        public CloseFuture close(final boolean immediately) {
            final DefaultCloseFuture defaultCloseFuture = new DefaultCloseFuture(null);
            tcpSession.close(immediately).addListener(new IoFutureListener<org.apache.mina.core.future.CloseFuture>() {
                @Override
                public void operationComplete(final org.apache.mina.core.future.CloseFuture future) {
                    if(future.isClosed()) {
                        defaultCloseFuture.setValue(true);
                    } else {
                        // TODO check the value type expected
                        defaultCloseFuture.setValue(false);
                    }
                }
            });
            return defaultCloseFuture;
        }

        @Override
        public IoService getService() {
            throw new UnsupportedOperationException("No service available");
        }

        @Override
        public boolean isClosed() {
            return tcpSession.getCloseFuture().isClosed();
        }

        @Override
        public boolean isClosing() {
            return tcpSession.isClosing();
        }
    });

5。用于将Apache SSHD IoSession与客户端连接的代码如下所示

final ConnectFuture connectFuture = new DefaultConnectFuture(null);
    ClientSessionImpl session = null;
    try {
        session = new ClientSessionImpl(sshClient, ioSession);
        AbstractSession.attachSession(ioSession, session);
        MyAsyncSshHandlerReader async = new MyAsyncSshHandlerReader(ioSession);
    } catch (Exception e) {
        // TODO Auto-generated catch block
        e.printStackTrace();
    }
  1. MyAsyncSshHandlerReader是用于从tcpSession读取数据的类。

    类MyAsyncSshHandlerReader实现IoFutureListener,AutoCloseable {

    private final org.apache.sshd.common.io.IoSession ioSession;
    
    public MyAsyncSshHandlerReader(org.apache.sshd.common.io.IoSession ioSession) {
        this.ioSession = ioSession;
        minaCoreIoSession.read().addListener(this);
    }
    
    @Override
    public void close() throws Exception {
        // TODO Auto-generated method stub
    
    }
    
    @Override
    public void operationComplete(ReadFuture future) {
        long msgsRead = future.getSession().getReadMessages();
        if(future.isRead() && !future.isClosed()){
    
            IoBuffer msg = (IoBuffer)future.getMessage();               
            msg.flip();
            Buffer buf = new Buffer(msg.array());           
            try {               
                if(AbstractSession.getSession(ioSession) != null){
                    AbstractSession.getSession(ioSession).messageReceived(buf);                 
                }
            } catch (Exception e) {
                e.printStackTrace();
            }
            minaCoreIoSession.read().addListener(this);
        }           
    }
    

    }

  2. 在应用程序端创建客户端会话时,将调用以下方法。

    1. sendIdentification
    2. sendKexInit()
  3. 应用程序还收到了识别消息和从设备交换的密钥 并且识别消息被正确读取但无法解码密钥交换消息,库已抛出SshException&#34;无效的数据包长度为0&#34;
  4. 2015-11-02 13:02:48,831 |信息| oupCloseable-6-2 | ClientSessionImpl | 210 - org.apache.sshd.core - 0.14.0 |错误解码包(无效长度)00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00今日00 00 00 00 00 00 00日00 00 00 00 00 00 00日00 00 00 00 00 00 00 00 00日00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00今日00 00 00 00 00 00 00日00 00 00 00 00 00 00日00 00 00 00 00 00 00 00 00日00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00今日00 00 00 00 00 00 00日00 00 00 00 00 00 00日00 00 00 00 00 00 00 00 00日00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00今日00 00 00 00 00 00 00日00 00 00 00 00 00 00日00 00 00 00 00 00 00 00 00日00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00今日00 00 00 00 00 00 00日00 00 00 00 00 00 00日00 00 00 00 00 00 00 00 00日00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 0 0 0 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00今日00 00 00 00 00 00 00 00 00今日00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00今日00 00 00 00 00 00 00日00 00 00 00 00 00 00日00 00 00 00 00 00 00 00 00日00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00今日00 00 00 00 00 00 00日00 00 00 00 00 00 00日00 00 00 00 00 00 00 00 00日00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00今日00 00 00 00 00 00 00日00 00 00 00 00 00 00日00 00 00 00 00 00 00 00 00日00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00今日00 00 00 00 00 00 00日00 00 00 00 00 00 00日00 00 00 00 00 00 00 00 00日00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00今日00 00 00 00 00 00 00日00 00 00 00 00 00 00日00 00 00 00 00 00 00 00 00日00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00今日00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00今日00 00 00 00 00 00 00日00 00 00 00 00 00 00日00 00 00 00 00 00 00 00 00日00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00今日00 00 00 00 00 00 00日00 00 00 00 00 00 00日00 00 00 00 00 00 00 00 00日00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00今日00 00 00 00 00 00 00日00 00 00 00 00 00 00日00 00 00 00 00 00 00 00 00日00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00今日00 00 00 00 00 00 00日00 00 00 00 00 00 00日00 00 00 00 00 00 00 00 00日00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00今日00 00 00 00 00 00 00日00 00 00 00 00 00 00日00 00 00 00 00 00 00 00 00日00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00今日00 00 00 00 00 00 00日00 00 00 00 00 00 00日00 00 00 00 00 00 00 00 00日00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00今日00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00今日00 00 00 00 00 00 00日00 00 00 00 00 00 00日00 00 00 00 00 00 00 00 00日00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00今日00 00 00 00 00 00 00日00 00 00 00 00 00 00日00 00 00 00 00 00 00 00 00日00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00今日00 00 00 00 00 00 00日00 00 00 00 00 00 00日00 00 00 00 00 00 00 00 00日00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00今日00 00 00 00 00 00 00日00 00 00 00 00 00 00日00 00 00 00 00 00 00 00 00日00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00今日00 00 00 00 00 00 00日00 00 00 00 00 00 00日00 00 00 00 00 00 00 00 00日00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00今日00 00 00 00 00 00 00日00 00 00 00 00 00 00日00 00 00 00 00 00 00 00 00日00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00今日00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 0 0 0 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00今日00 00 00 00 00 00 00 00 00今日00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00今日00 00 00 00 00 00 00日00 00 00 00 00 00 00日00 00 00 00 00 00 00 00 00日00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00今日00 00 00 00 00 00 00日00 00 00 00 00 00 00日00 00 00 00 00 00 00 00 00日00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00今日00 00 00 00 00 00 00日00 00 00 00 00 00 00日00 00 00 00 00 00 00 00 00日00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00今日00 00 00 00 00 00 00日00 00 00 00 00 00 00日00 00 00 00 00 00 00 00 00日00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00今日00 00 00 00 00 00 00日00 00 00 00 00 00 00日00 00 00 00 00 00 00 00 00日00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00今日00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00今日00 00 00 00 00 00 00日00 00 00 00 00 00 00日00 00 00 00 00 00 00 00 00日00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00今日00 00 00 00 00 00 00日00 00 00 00 00 00 00日00 00 00 00 00 00 00 00 00日00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00今日00 00 00 00 00 00 00日00 00 00 00 00 00 00日00 00 00 00 00 00 00 00 00日00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00今日00 00 00 00 00 00 00日00 00 00 00 00 00 00日00 00 00 00 00 00 00 00 00日00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00今日00 00 00 00 00 00 00日00 00 00 00 00 00 00日00 00 00 00 00 00 00 00 00日00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00今日00 00 00 00 00 00 00日00 00 00 00 00 00 00日00 00 00 00 00 00 00 00 00日00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00今日00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 05 fc 07 14 34 d4 4e 0e 2c 22 73 e4 7e 46 41 1b e3 55 27 ef 00 00 00 b7 65 63 64 68 2d 73 68 61 32 2d 6e 69 73 74 70 32 35 36 2c 65 63 64 68 2d 73 68 61 32 2d 6e 69 73 74 70 33 38 34 2c 65 63 64 68 2d 73 68 61 32 2d 6e 69 73 74 70 35 32 31 2c 64 69 66 66 69 65 2d 68 65 6c 6c 6d 61 6e 2d 67 72 6f 75 70 2d 65 78 63 68 61 6e 67 65 2d 73 68 61 32 35 36 2c 64 69 66 66 69 65 2d 68 65 6c 6c 6d 61 6e 2d 67 72 6f 75 70 2d 65 78 63 68 61 6e 67 65 2d 73 68 61 31 2c 64 69 66 66 69 65 2d 68 65 6c 6c 6d 61 6e 2d 67 72 6f 75 70 31 34 2d 73 68 61 31 2c 64 69 66org.apache.sshd.common.SshException:无效的数据包长度:0     在org.apache.sshd.common.session.AbstractSession.decode(AbstractSession.java:719)     在org.apache.sshd.common.session.AbstractSession.messageReceived(AbstractSession.java:308)     at org.opendaylight.controller.netconf.nettyutil.handler.ssh.client.ReversedAsyncSshHandler $ MyAsyncSshHandlerReader.operationComplete(ReversedAsyncSshHandler.java:220)

    1. 请详细说明AbstractSession.decode()方法的工作原理
    2. 从我的调试开始,rpos和limit变量保持相同的值,例如1536。我正在阅读的方式有问题吗?

      提前致谢

1 个答案:

答案 0 :(得分:0)

经过许多例子和Apache mina库后,我发现问题在于我们从mina核心IoSession中读取的方式。

正确的阅读方式::

int r=ioBuffer.remaining();
byte[] b=new byte[r];
ioBuffer.get(b,0,r);

Buffer buf = new Buffer(b);
AbstractSession.getSession(tcpSession).messageReceived(buf)