private void ReadCallback(IAsyncResult asyncResult)
{
AsyncReceiveRecordsResult asyncReadResult = (AsyncReceiveRecordsResult)asyncResult.AsyncState;
try {
int readBytes = _innerStream.EndRead(asyncResult);
if (readBytes == 0)
{
throw new EndOfStreamException("Connection closed while reading TLS record");
}
_inputBufferCount += readBytes;
// We require at least 5 bytes of header
if (_inputBufferCount < 5)
{
_innerStream.BeginRead(_inputBuffer,
_inputBufferCount,
5 - _inputBufferCount,
new AsyncCallback(ReadCallback),
asyncReadResult);
return;
}
// We require the fragment bytes
int fragmentLength = (_inputBuffer[3] << 8) | _inputBuffer[4];
if (5 + fragmentLength > _inputBuffer.Length)
{
throw new RecordTooLargeException("Received TLS record fragment size too large");
}
else if (_inputBufferCount < 5 + fragmentLength)
{
_innerStream.BeginRead(_inputBuffer,
_inputBufferCount,
5 + fragmentLength - _inputBufferCount,
new AsyncCallback(ReadCallback),
asyncReadResult);
return;
}
// Construct the TLSRecord returned as result
Record record = new Record(_inputBuffer);
Buffer.BlockCopy(_inputBuffer, 5, record.Fragment, 0, fragmentLength);
_inputBufferCount = 0;
// Complete the asynchronous read
FinishReceive(true);
asyncReadResult.AddRecord(record);
asyncReadResult.SetComplete();
} catch (Exception e) {
FinishReceive(false);
asyncReadResult.SetComplete(e);
}
}