[+] IProtocolStack::AddEndInterceptor (optimizes away the output stage buffer, instead of preallocating a massive ring buffer, when the AddInterceptorEx variant is supplied with a uOutputBufferSize of zero)

[*] Typo iServerBadMacLimit
This commit is contained in:
Reece Wilson 2022-09-02 20:53:25 +01:00
parent 795e5f6569
commit af03c5cbf3
6 changed files with 156 additions and 10 deletions

View File

@ -15,6 +15,7 @@ namespace Aurora::IO::Net
{
NetEndpoint endpoint;
AuSPtr<ISocketDriver> pDriver;
AuUInt32 uMaxConnectTimeMs {};
};
struct NetSocketConnectMany

View File

@ -11,11 +11,39 @@ namespace Aurora::IO::Protocol
{
struct IProtocolStack : IProtocolBaseReader, IProtocolBaseWriter
{
/**
* @brief
* @param pInterceptor
* @param uOutputBufferSize When 0, a hopefully not stupid default is used.
* @return
*/
virtual bool AddInterceptor(const AuSPtr<IProtocolInterceptor> &pInterceptor, AuUInt uOutputBufferSize) = 0;
/**
* @brief
* @param pInterceptor
* @param uOutputBufferSize When 0, a hopefully not stupid default is used.
* @return
*/
virtual bool AddInterceptorEx(const AuSPtr<IProtocolInterceptorEx> &pInterceptor, AuUInt uOutputBufferSize) = 0;
/**
* @brief
* @param pInterceptor
* @return
*/
virtual bool AddEndInterceptor(const AuSPtr<IProtocolInterceptorEx> &pInterceptor) = 0;
/**
* @brief Sends one down the protocol stack, regardless of how much data is written into the
* next piece/interceptor, and regardless of if another read tick is required.
* Latterly, you are responsible for consuming all available bytes in your interceptor.
*/
virtual void DoTick() = 0;
/**
* @brief
*/
virtual void Destroy() = 0;
};

View File

@ -38,7 +38,7 @@ namespace Aurora::IO::TLS
/**
* @brief
*/
int iServerBacMacLimit { 0 };
int iServerBadMacLimit { 0 };
/**
* @brief

View File

@ -20,6 +20,11 @@ namespace Aurora::IO::Protocol
bool ProtocolStack::AddInterceptor(const AuSPtr<IProtocolInterceptor> &pInterceptor,
AuUInt uOutputBufferSize)
{
if (this->bWrittenEnd)
{
return false;
}
if (!uOutputBufferSize)
{
uOutputBufferSize = 64 * 1024;
@ -107,6 +112,11 @@ namespace Aurora::IO::Protocol
bool ProtocolStack::AddInterceptorEx(const AuSPtr<IProtocolInterceptorEx> &pInterceptor, AuUInt uOutputBufferSize)
{
if (this->bWrittenEnd)
{
return false;
}
if (!this->pSourceBufer)
{
return false;
@ -197,6 +207,93 @@ namespace Aurora::IO::Protocol
return true;
}
bool ProtocolStack::AddEndInterceptor(const AuSPtr<IProtocolInterceptorEx> &pInterceptor)
{
if (this->bWrittenEnd)
{
return false;
}
if (!this->pSourceBufer)
{
return false;
}
auto pNew = AuMakeShared<ProtocolPiece>();
if (!pNew)
{
SysPushErrorNet("Out of memory");
return false;
}
pNew->outputBuffer = {};
pNew->pOuputWriter = {};
struct StreamWrapper : IStreamWriter, IProtocolNext, AuEnableSharedFromThis<StreamWrapper>
{
ProtocolStack *pStack;
AuWPtr<IProtocolInterceptorEx> pInterceptor;
AuWPtr<ProtocolPiece> pParent;
EStreamError IsOpen() override
{
return EStreamError::eErrorNone;
}
EStreamError Write(const Memory::MemoryViewStreamRead &parameters) override
{
return pStack->DoTick(AuMakeShared<AuByteBuffer>(parameters), pParent.lock()) ?
EStreamError::eErrorNone :
EStreamError::eErrorStreamInterrupted;
}
void Close() override
{
};
void Flush() override
{
};
virtual AuSPtr<Memory::ByteBuffer> GetOutputBuffer() override
{
return {};
}
virtual AuSPtr<IStreamWriter> GetStreamWriter() override
{
return AuSharedFromThis();
}
};
auto pWrapper = AuMakeShared<StreamWrapper>();
if (!pWrapper)
{
return false;
}
pWrapper->pInterceptor = pInterceptor;
pWrapper->pStack = this;
pWrapper->pParent = pNew;
pNew->pWriteInteface = pWrapper;
pNew->pInterceptorEx = pInterceptor;
pNew->pParent = this;
this->pTopPiece = pNew;
if (!this->pBottomPiece)
{
this->pBottomPiece = pNew;
}
this->bWrittenEnd = true;
return true;
}
void ProtocolStack::Destroy()
{
if (this->bOwnsSource)
@ -246,7 +343,13 @@ namespace Aurora::IO::Protocol
AuSPtr<IStreamReader> ProtocolStack::AsStreamReader()
{
return AuMakeShared<AuIO::Buffered::BlobReader>(AsReadableByteBuffer());
auto pBuffer = AsReadableByteBuffer();
if (!pBuffer)
{
return {};
}
return AuMakeShared<AuIO::Buffered::BlobReader>(pBuffer);
}
AuSPtr<Memory::ByteBuffer> ProtocolStack::AsReadableByteBuffer()
@ -256,6 +359,11 @@ namespace Aurora::IO::Protocol
return this->pSourceBufer;
}
if (this->pTopPiece->outputBuffer.IsEmpty())
{
return {};
}
return AuSPtr<AuByteBuffer>(this->pTopPiece, &this->pTopPiece->outputBuffer);
}
@ -280,20 +388,26 @@ namespace Aurora::IO::Protocol
if (pCurrent->pInterceptorEx)
{
auto pNextStream = ((pPiece == this->pTopPiece) &&
(this->pDrainBuffer)) ?
this->pDrainBuffer :
AuSPtr<AuByteBuffer>(pCurrent, &pCurrent->outputBuffer);
auto pNextStream = ((pPiece == this->pTopPiece) && (this->pDrainBuffer)) ?
(this->pDrainBuffer) :
(!pCurrent->outputBuffer.IsEmpty() ? AuSPtr<AuByteBuffer>(pCurrent, &pCurrent->outputBuffer) : AuSPtr<AuByteBuffer> {});
auto pOldHead = pNextStream->readPtr;
auto pOldHead = pNextStream ? pNextStream->readPtr : nullptr;
if (!pCurrent->pInterceptorEx->OnDataAvailable(pRead, pNextStream))
{
pNextStream->readPtr = pOldHead;
if (pNextStream)
{
pNextStream->readPtr = pOldHead;
}
return false;
}
if (!pNextStream)
{
return true;
}
if (auto pNext = pCurrent->pNext)
{
auto pOldHead = pNextStream->readPtr;

View File

@ -20,6 +20,7 @@ namespace Aurora::IO::Protocol
bool AddInterceptor(const AuSPtr<IProtocolInterceptor> &pInterceptor, AuUInt uOutputBufferSize) override;
bool AddInterceptorEx(const AuSPtr<IProtocolInterceptorEx> &pInterceptor, AuUInt uOutputBufferSize) override;
bool AddEndInterceptor(const AuSPtr<IProtocolInterceptorEx> &pInterceptor) override;
void Destroy() override;
@ -36,5 +37,7 @@ namespace Aurora::IO::Protocol
AuSPtr<ProtocolPiece> pBottomPiece;
AuSPtr<ProtocolPiece> pTopPiece;
bool bWrittenEnd {};
};
}

View File

@ -284,7 +284,7 @@ namespace Aurora::IO::TLS
#endif
::mbedtls_ssl_conf_dtls_badmac_limit(&this->conf,
this->meta_.dtls.iServerBacMacLimit);
this->meta_.dtls.iServerBadMacLimit);
}