下面是解包从 sslengine 接收到的数据包的代码:
private ByteBuffer doUnwrap() throws IOException {
if (mPeerNetData.position() == 0) {
// The network input buffer is empty; read data from the channel before doing the unwrap
final int count = mSocketChannel.read(mPeerNetData);
Log.d(TAG, "bytesRead : " + count);
if (count == -1) {
handleEndOfStream(mSocketChannel, mSslEngine);
return null;
}
}
Log.d(TAG, "isReadPending :" + isReadPending);
if (!isReadPending) {
mPeerNetData.flip();
}
final SSLEngineResult result;
try {
result = mSslEngine.unwrap(mPeerNetData, mPeerAppData);
} catch (SSLException e) {
Log.d(TAG, "Exception while calling SSLEngine.unwrap()" + e);
shutdown();
return null;
}
mPeerNetData.compact();
Log.d(TAG, "Result of SSLEngine.unwrap(): {}" + result.getStatus());
final SSLEngineResult.Status status = result.getStatus();
switch (status) {
case OK:
if (mPeerNetData.position() != 0) {
isReadPending = true;
mPeerAppData = ensureRemaining(mPeerAppData, mSslEngine.getSession().getApplicationBufferSize());
doUnwrap();
}
break;
case CLOSED:
closeConnection(mSocketChannel, mSslEngine);
break;
case BUFFER_UNDERFLOW:
// The network input buffer might not have enough space, re-allocate if necessary
// (NOTE: packet buffer size as reported by the SSL session might change dynamically)
mPeerNetData = ensureRemaining(mPeerNetData, mSslEngine.getSession().getPacketBufferSize());
// Read data from the channel, retry unwrap if not end-of-stream
final int count = mSocketChannel.read(mPeerNetData);
if (count == -1) {
handleEndOfStream(mSocketChannel, mSslEngine);
return null;
}
doUnwrap();
break;
case BUFFER_OVERFLOW:
// The application input buffer does not have enough space, re-allocate and retry unwrap
// (NOTE: application buffer size as reported by the SSL session might change dynamically)
mPeerAppData = ensureRemaining(mPeerAppData, mSslEngine.getSession().getApplicationBufferSize());
doUnwrap();
break;
default:
throw new IllegalStateException("Invalid SSL status: " + status);
}
return mPeerAppData;
}
mPeerNetData 缓冲区在展开期间仍有一些数据要读取,因此我扩大了 mPeerAppData 缓冲区以保存在下一次迭代中必须从 mPeerNetData 缓冲区读取的更多数据。
我已经调试了流程,可以验证 mPeerAppData 缓冲区是否有足够的空间来保存数据,并且 mPeerNetData 缓冲区有待解包的数据。
但是在展开过程中,我收到以下错误:
javax.net.ssl.SSLException: Unable to parse TLS packet header
at org.conscrypt.ConscryptEngine.unwrap(ConscryptEngine.java:798)
at org.conscrypt.ConscryptEngine.unwrap(ConscryptEngine.java:738)
请建议我们如何避免这个错误?