首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >Android SSLEngine BUFFER_UNDERFLOW在阅读时打开包装

Android SSLEngine BUFFER_UNDERFLOW在阅读时打开包装
EN

Stack Overflow用户
提问于 2013-12-06 20:56:55
回答 1查看 1.3K关注 0票数 0

我不知道为什么,但是有一半通过ssl的站点在我的阅读过程中得到了buffer_underflow。

当我的程序被链接起来连续调用不同的ssl站点时,它不能在一半的链接上工作,但是如果我一个接一个地调用它们,它们就会工作。例如,我使用Chrome的开发工具在我的nexus 7平板电脑上调用https://www.facebook.com。当我看到请求时,调用的链接是:

如果我将它们链接在一起(以模拟浏览器对https://www.facebook.com的调用),就会得到一半的链接会受到缓冲区的影响,直到最终不得不关闭它们的连接(读取0字节)。然而,如果我一个接一个地给他们打电话,他们总是很好。以下是我的阅读代码:

代码语言:javascript
复制
public int readSSLFrom(SelectionKey key, SecureIO session) throws IOException{
    int result = 0;
    String TAG = "readSSLFrom";
    Log.i(TAG,"Hanshake status: "+session.sslEngine.getHandshakeStatus().toString());
    synchronized (buffer){
        ByteBuffer sslIn = ByteBuffer.allocate(session.getApplicationSizeBuffer());
        ByteBuffer tmp = ByteBuffer.allocate(session.getApplicationSizeBuffer());
        ReadableByteChannel channel = (ReadableByteChannel) key.channel();
        if (buffer.remaining() < session.getPacketBufferSize()){
            increaseSize(session.getPacketBufferSize());
        }
        int read = 0;
        while (((read = channel.read(sslIn)) > 0) &&
                buffer.remaining() >= session.getApplicationSizeBuffer()){
            if (read < 0){
                session.sslEngine.closeInbound();
                return -1;
            }
            inner: while (sslIn.position() > 0){ 
                sslIn.flip();
                tmp.clear();
                SSLEngineResult res = session.sslEngine.unwrap(sslIn, tmp);
                result = result + res.bytesProduced();
                sslIn.compact();
                tmp.flip();
                if (tmp.hasRemaining()){
                    buffer.put(tmp);
                }
                switch (res.getStatus()){
                case BUFFER_OVERFLOW:
                    Log.i(TAG,"Buffer overflow");
                    throw new Error();
                case BUFFER_UNDERFLOW:
                    Log.i(TAG,"Buffer underflow");
                    if (session.getPacketBufferSize() > tmp.capacity()){
                        Log.i(TAG,"increasing capacity");
                        ByteBuffer b = ByteBuffer.allocate(session.getPacketBufferSize());
                        sslIn.flip();
                        b.put(sslIn);
                        sslIn = b;
                    }
                    break inner;
                case CLOSED:
                    Log.i(TAG,"Closed");
                    if (sslIn.position() == 0){
                        break inner;
                    } else{
                        return -1;
                    }
                case OK:
                    Log.i(TAG,"OK");
                    session.checkHandshake(key);
                    break;
                default:
                    break;
                }
            }
        }
        if (read < 0){
            //session.sslEngine.closeInbound();
            return -1;
        }
    }
    dataEnd = buffer.position();
    return result;
}

谢谢。

EN

回答 1

Stack Overflow用户

发布于 2014-01-03 06:49:29

缓冲层在展开过程中是可以接受的,并且经常发生。当您有部分TLS记录(<16 TLS)时,就会发生这种情况。这种情况可能发生在两种情况下,1)当您有不到16 it,所以您没有结果当您打开-只是缓存所有这些数据,并等待其余的到达打开它。2)当您有超过16‘t但最后的TLS数据包还没有完成时,例如20’t或36‘t。在本例中,第一个16 4KB /32 4KB将在展开过程中给出一个结果,您需要缓存剩余的4KB,只需等待完成此TLS数据包的12 4KB中的其余部分--然后才能展开。

我希望这能帮上忙,试试我的代码,看看它是否适合你。

对不起,这不适合在评论,所以我回答说,而不是。

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/20433442

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档