⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 opensslconnector.cpp

📁 强大易用的邮件收发客户端
💻 CPP
字号:
#include "stdafx.h"
#include "OpenSSLConnector.h"

#include <openssl/err.h>

///////////////////////////////////////////////////////////////////////////////
// CAsyncConnector
///////////////////////////////////////////////////////////////////////////////

CAsyncConnector::CAsyncConnector(
   SSL_CTX *pContext,
   IConnectorCallback &sink)
   :  COpenSSLConnectorBase(pContext), 
      m_sink(sink)
{ 
}
      
CAsyncConnector::~CAsyncConnector()
{
}

void CAsyncConnector::Write(
   BYTE *pData,
   size_t dataLen)
{
   // could try and put the data in the buffer we have on the front of the list?

   Buffer *pBuffer = new Buffer(pData, dataLen);

   AppendBuffer(m_pendingWriteList, pBuffer);

   RunSSL();
}

void CAsyncConnector::ReadCompleted(
   BYTE *pData,
   size_t dataLen)
{
   // could try and put the data in the buffer we have on the front of the list?

   Buffer *pBuffer = new Buffer(pData, dataLen);

   AppendBuffer(m_pendingReadList, pBuffer);

   RunSSL();
}

void CAsyncConnector::GetPendingOperations(
   bool &dataToRead, 
   bool &dataToWrite)
{
   dataToRead = !m_pendingReadList.Empty();

   dataToWrite = !m_pendingWriteList.Empty();
}

void CAsyncConnector::PerformRead()
{
   OutputDebugString("PerformRead\n");

   Buffer *pBuffer = GetNextBuffer(m_pendingReadList);

   if (pBuffer)
   {
      size_t bufferUsed = DataToRead(pBuffer->data, pBuffer->used);

      // we're pushed bufferUsed bytes into the ssl engine...

      UseData(m_pendingReadList, pBuffer, bufferUsed);
   }
}

void CAsyncConnector::PerformWrite()
{
   OutputDebugString("PerformWrite\n");

   Buffer *pBuffer = GetNextBuffer(m_pendingWriteList);
   
   if (pBuffer)
   {
      size_t bufferUsed = DataToWrite(pBuffer->data, pBuffer->used);

      // may not be able to push all data into the BIO in one go

      UseData(m_pendingWriteList, pBuffer, bufferUsed);
   }
}

void CAsyncConnector::OnDataToWrite(
   BYTE *pData,
   size_t dataLength)
{
   m_sink.WriteData(pData, dataLength);
}

void CAsyncConnector::OnDataToRead(
   BYTE *pData,
   size_t dataLength)
{
   m_bytesAvailable = dataLength;

   while (m_bytesAvailable > 0)
   {
      m_sink.OnDataAvailable();
      
      // Sink should call receive until all data is gone
   }
}

void CAsyncConnector::GetNextReadDataBuffer(
   BYTE **ppBuffer,
   size_t &bufferSize)
{
   *ppBuffer = m_buffer;
   bufferSize = sizeof(m_buffer);
}

void CAsyncConnector::GetNextWriteDataBuffer(
   BYTE **ppBuffer,
   size_t &bufferSize)
{
   *ppBuffer = m_buffer;
   bufferSize = sizeof(m_buffer);
}


size_t CAsyncConnector::Receive(
   BYTE *pData,
   size_t dataLength)
{
   size_t bytesRead = min(m_bytesAvailable, dataLength);

   memcpy(pData, m_buffer, bytesRead);

   if (bytesRead != m_bytesAvailable)
   {
      memmove(m_buffer, m_buffer + bytesRead, m_bytesAvailable - bytesRead);
   }

   m_bytesAvailable -= bytesRead;     

   return bytesRead;
}

void CAsyncConnector::UseData(
   BufferList &list,
   Buffer *pBuffer,
   size_t result)
{
   if (result == 0)
   {
      PutbackBuffer(list, pBuffer);

      OutputDebugString("No data used\n");
   }
   else if (result < pBuffer->used)
   {
      pBuffer->ConsumeAndRemove(result);

      PutbackBuffer(list, pBuffer);

      OutputDebugString("partial data used\n");
   }
   else if (result == pBuffer->used)
   {
      // we've used all of the data in this buffer so we can reuse it for
      // sending any data out...
      
      delete pBuffer;

      OutputDebugString("all data used\n");
   }
}

void CAsyncConnector::AppendBuffer(
   BufferList &list,
   Buffer *pBuffer)
{
   pBuffer->pNext = 0;
   
   if (list.pTail)
   {
      list.pTail->pNext = pBuffer;
   }

   list.pTail = pBuffer;

   if (!list.pHead)
   {
      list.pHead = pBuffer;
   }
}

CAsyncConnector::Buffer *CAsyncConnector::GetNextBuffer(
   BufferList &list) 
{
   Buffer *pBuffer = 0;

   if (list.pHead)
   {
      pBuffer = list.pHead;
      list.pHead = pBuffer->pNext;
      pBuffer->pNext = 0;

      if (list.pTail == pBuffer)
      {
         list.pTail = 0;
      }
   }

   return pBuffer;
}

void CAsyncConnector::PutbackBuffer(
   BufferList &list, 
   Buffer *pBuffer)
{
   pBuffer->pNext = list.pHead;

   list.pHead = pBuffer;

   if (!list.pTail)
   {
      list.pTail = pBuffer;
   }
}

CAsyncConnector::Buffer::Buffer(
   BYTE *pData, 
   size_t dataLength)
{
   ASSERT(dataLength <= BUFFER_SIZE);

   CopyMemory(data, pData, dataLength);

   used = dataLength;

   pNext = 0;
}

void CAsyncConnector::Buffer::ConsumeAndRemove(
   size_t bytesUsed)
{
   ASSERT(bytesUsed >= used);

   MoveMemory(data, data + bytesUsed, used - bytesUsed);

   used -= bytesUsed;
}


⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -