Reece Wilson
67905a4192
============================================================================= Network ]==================================================================== ============================================================================= [+] Added (very) early Aurora::IO::Net implementation [+] AuNet::EHostnameType [+] AuNet::EIPProtocol [+] AuNet::ENetworkError [+] AuNet::ETransportProtocol [+] AuNet::INetInterface [+] AuNet::INetSrvDatagram [+] AuNet::INetSrvResolve [+] AuNet::INetSrvSockets [+] AuNet::INetSrvWorkers [+] AuNet::INetWorker [+] AuNet::IPAddress [+] AuNet::IResolver [+] AuNet::ISocket [+] AuNet::IResolver [+] AuNet::ISocketBase [+] AuNet::ISocketChannel [+] AuNet::ISocketDriver [+] AuNet::ISocketDriverFactory [+] AuNet::ISocketServer [+] AuNet::ISocketServerDriver [+] AuNet::NetEndpoint [+] AuNet::NetError [+] AuNet::NetHostname (+implementation) ============================================================================= Protocol ]=================================================================== ============================================================================= [+] IProtocolInterceptor [+] IProtocolInterceptorEx [+] IProtocolStack (+implementation) ============================================================================= TLS ]======================================================================== ============================================================================= [+] ITLSContext [+] TLSProtocolRecv [+] TLSProtocolSend (+implementation) ============================================================================= IO Bug Fixes ]=============================================================== ============================================================================= [*] IOProcessor::SubmitIOWorkItem should signal the CvEvent, forcing at least once future tick (wont optimize with if in tick & not yet dispatched work items) [*] Split IOPipeWork in into IOPipeProcessor header [+] IOPipeWork::GetBuffer (internal reallocation) [*] Harden against IAsyncTransactions without a loop source [*] Missing null `if (processor->listener)` in IOProcessor [*] Solved some soft-lock conditions under Linux's LoopQueue (added deferred commits) [*] Quick hack: IOProcessor::HasItems() should OR the early can-tick check function. ============================================================================= Other ]====================================================================== ============================================================================= [+] Linux: LSSignalCatcher [+] `static void AuResetMember(Aurora::Memory::ByteBuffer &ref)` for AuROXTL [*] Attempt to enforce a normalization and don't overwrite-readptr-under-istreamwriters policy in ByteBuffer_ReadWrite (circular buffers) [*] Bad ECC ctors ============================================================================= Known issues ]=============================================================== ============================================================================= > Linux net is nowhere near done > UDP socket emulation layer isn't implemented > Ciphersuite API is a stub > Private key API is a stub > ...therefore no TLS servers > Missing thread safety precautions under net > Net implementation is still beri early
294 lines
7.0 KiB
C++
294 lines
7.0 KiB
C++
/***
|
|
Copyright (C) 2022 J Reece Wilson (a/k/a "Reece"). All rights reserved.
|
|
|
|
File: AuNetStream.Linux.cpp
|
|
Date: 2022-8-26
|
|
Author: Reece
|
|
***/
|
|
#include "Networking.hpp"
|
|
#include "AuNetStream.Linux.hpp"
|
|
#include "AuNetSocket.hpp"
|
|
#include "AuNetWorker.hpp"
|
|
#include <Source/IO/Loop/LSEvent.hpp>
|
|
|
|
namespace Aurora::IO::Net
|
|
{
|
|
LinuxAsyncNetworkTransaction::LinuxAsyncNetworkTransaction(SocketBase *pSocket) :
|
|
pSocket(pSocket)
|
|
{
|
|
if (this->pSocket->GetRemoteEndpoint().transportProtocol == ETransportProtocol::eProtocolTCP)
|
|
{
|
|
//this->dwRecvFlags = MSG_PARTIAL;
|
|
}
|
|
}
|
|
|
|
LinuxAsyncNetworkTransaction::~LinuxAsyncNetworkTransaction()
|
|
{
|
|
Reset();
|
|
}
|
|
|
|
bool LinuxAsyncNetworkTransaction::StartRead(AuUInt64 offset, const AuSPtr<AuMemoryViewWrite> &memoryView)
|
|
{
|
|
if (this->bDisallowRecv)
|
|
{
|
|
SysPushErrorIO("Recv isn't allowed");
|
|
return false;
|
|
}
|
|
|
|
if (this->bIsIrredeemable)
|
|
{
|
|
SysPushErrorIO("Transaction was signaled to be destroyed to reset mid synchronizable operation. You can no longer use this stream object");
|
|
return false;
|
|
}
|
|
|
|
if (!IDontWannaUsePorts())
|
|
{
|
|
return false;
|
|
}
|
|
|
|
if (!memoryView)
|
|
{
|
|
SysPushErrorArg();
|
|
return {};
|
|
}
|
|
|
|
//if (this->pMemoryHold)
|
|
//{
|
|
// SysPushErrorIO("IO Operation in progress");
|
|
// return {};
|
|
//}
|
|
|
|
this->bLatch = false;
|
|
|
|
//this->pMemoryHold = memoryView;
|
|
this->bHasFailed = false;
|
|
|
|
this->dwLastAbstractStat = memoryView->length;
|
|
this->dwLastAbstractOffset = offset;
|
|
this->dwLastBytes = 0;
|
|
|
|
this->bIsWriting = false;
|
|
|
|
LIOS_Init(AuSharedFromThis());
|
|
SetMemory(memoryView);
|
|
|
|
if (!this->bDatagramMode)
|
|
{
|
|
if (!UNIX::LinuxOverlappedSubmitRead(this->GetSocket(), 0, this, this->pWaitable ? this->pWaitable.get() : nullptr, true))
|
|
{
|
|
LIOS_SendProcess(0, true, errno);
|
|
return true;
|
|
}
|
|
else
|
|
{
|
|
//if (gRuntimeConfig.bFIODisableBatching)
|
|
{
|
|
UNIX::SendIOBuffers();
|
|
}
|
|
|
|
return true;
|
|
}
|
|
}
|
|
else
|
|
{
|
|
return false;
|
|
}
|
|
}
|
|
|
|
bool LinuxAsyncNetworkTransaction::StartWrite(AuUInt64 offset, const AuSPtr<AuMemoryViewRead> &memoryView)
|
|
{
|
|
if (this->bDisallowSend)
|
|
{
|
|
SysPushErrorIO("Send isn't allowed");
|
|
return false;
|
|
}
|
|
|
|
if (this->bIsIrredeemable)
|
|
{
|
|
SysPushErrorIO("Transaction was signaled to be destroyed to reset mid synchronizable operation. You can no longer use this stream object");
|
|
return false;
|
|
}
|
|
|
|
if (!IDontWannaUsePorts())
|
|
{
|
|
return false;
|
|
}
|
|
|
|
if (!memoryView)
|
|
{
|
|
SysPushErrorArg();
|
|
return {};
|
|
}
|
|
|
|
//if (this->pMemoryHold)
|
|
//{
|
|
// SysPushErrorIO("IO Operation in progress");
|
|
// return {};
|
|
//}
|
|
|
|
this->bLatch = false;
|
|
|
|
//this->pMemoryHold = memoryView;
|
|
this->bHasFailed = false;
|
|
|
|
this->dwLastAbstractStat = memoryView->length;
|
|
this->dwLastAbstractOffset = offset;
|
|
this->dwLastBytes = 0;
|
|
|
|
this->bIsWriting = true;
|
|
|
|
LIOS_Init(AuSharedFromThis());
|
|
SetMemory(memoryView);
|
|
|
|
if (!this->bDatagramMode)
|
|
{
|
|
if (!UNIX::LinuxOverlappedSubmitWrite(this->GetSocket(), 0, this, this->pWaitable ? this->pWaitable.get() : nullptr))
|
|
{
|
|
LIOS_SendProcess(0, true, errno);
|
|
return false;
|
|
}
|
|
else
|
|
{
|
|
//if (gRuntimeConfig.bFIODisableBatching)
|
|
{
|
|
UNIX::SendIOBuffers();
|
|
}
|
|
|
|
return true;
|
|
}
|
|
}
|
|
else
|
|
{
|
|
return false;
|
|
}
|
|
}
|
|
|
|
void LinuxAsyncNetworkTransaction::LIOS_Process(AuUInt32 read, bool failure, int err, bool mark)
|
|
{
|
|
this->dwLastBytes = failure ? 0 : read;
|
|
this->bHasFailed |= failure;
|
|
this->dwOsErrorCode = err;
|
|
|
|
if (mark)
|
|
{
|
|
return;
|
|
}
|
|
|
|
this->DispatchCb(read);
|
|
}
|
|
|
|
bool LinuxAsyncNetworkTransaction::TranslateLastError(bool bReturnValue)
|
|
{
|
|
return false;
|
|
}
|
|
|
|
bool LinuxAsyncNetworkTransaction::Complete()
|
|
{
|
|
return this->bLatch;
|
|
}
|
|
|
|
bool LinuxAsyncNetworkTransaction::CompleteEx(AuUInt completeRoutine)
|
|
{
|
|
return false;
|
|
}
|
|
|
|
bool LinuxAsyncNetworkTransaction::Failed()
|
|
{
|
|
return this->bHasFailed;
|
|
}
|
|
|
|
AuUInt LinuxAsyncNetworkTransaction::GetOSErrorCode()
|
|
{
|
|
return this->dwOsErrorCode;
|
|
}
|
|
|
|
AuUInt32 LinuxAsyncNetworkTransaction::GetLastPacketLength()
|
|
{
|
|
return this->dwLastBytes;
|
|
}
|
|
|
|
void LinuxAsyncNetworkTransaction::SetCallback(const AuSPtr<IAsyncFinishedSubscriber> &sub)
|
|
{
|
|
this->pSub = sub;
|
|
}
|
|
|
|
bool LinuxAsyncNetworkTransaction::Wait(AuUInt32 timeout)
|
|
{
|
|
return this->bLatch;
|
|
}
|
|
|
|
AuSPtr<AuLoop::ILoopSource> LinuxAsyncNetworkTransaction::NewLoopSource()
|
|
{
|
|
return this->pWaitable;
|
|
}
|
|
|
|
void LinuxAsyncNetworkTransaction::Reset()
|
|
{
|
|
if (this->dwLastAbstractStat)
|
|
{
|
|
this->bIsIrredeemable = true;
|
|
this->bHasFailed = true;
|
|
this->dwOsErrorCode = 0;
|
|
}
|
|
else
|
|
{
|
|
this->bHasFailed = false;
|
|
}
|
|
|
|
this->dwLastBytes = 0;
|
|
this->dwLastAbstractStat = 0;
|
|
}
|
|
|
|
void LinuxAsyncNetworkTransaction::MakeSyncable()
|
|
{
|
|
this->pWaitable = AuLoop::NewLSEvent(false, true);
|
|
SysAssert(this->pWaitable);
|
|
//this->overlap.hEvent = (HANDLE)AuStaticCast<Loop::LSEvent>(this->pWaitable)->GetHandle();
|
|
}
|
|
|
|
void LinuxAsyncNetworkTransaction::ForceNextWriteWait()
|
|
{
|
|
this->bForceNextWait = true;
|
|
}
|
|
|
|
bool LinuxAsyncNetworkTransaction::IDontWannaUsePorts()
|
|
{
|
|
|
|
return true;
|
|
}
|
|
|
|
void LinuxAsyncNetworkTransaction::DispatchCb(AuUInt32 read)
|
|
{
|
|
if (this->bIsWriting)
|
|
{
|
|
if (read != this->dwLastAbstractStat)
|
|
{
|
|
this->dwOsErrorCode = 69;
|
|
this->bHasFailed = true;
|
|
}
|
|
}
|
|
|
|
this->dwLastAbstractStat = 0;
|
|
this->dwLastBytes = read;
|
|
|
|
if (AuExchange(this->bLatch, true))
|
|
{
|
|
return;
|
|
}
|
|
|
|
if (this->pSub)
|
|
{
|
|
this->pSub->OnAsyncFileOpFinished(this->dwLastAbstractOffset, read);
|
|
}
|
|
}
|
|
|
|
int LinuxAsyncNetworkTransaction::GetSocket()
|
|
{
|
|
return this->pSocket->ToPlatformHandle();
|
|
}
|
|
|
|
int LinuxAsyncNetworkTransaction::GetAlertable()
|
|
{
|
|
return (int)AuStaticCast<AuLoop::LSEvent>(this->pSocket->ToWorkerEx()->ToEvent())->GetHandle();
|
|
}
|
|
} |