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); } }