AuroraRuntime/Include/Aurora/IO/Net/Net.hpp

183 lines
4.8 KiB
C++
Raw Normal View History

2021-06-27 21:25:29 +00:00
/***
Copyright (C) 2021 J Reece Wilson (a/k/a "Reece"). All rights reserved.
File: Net.hpp
Date: 2021-6-9
Author: Reece
***/
#pragma once
namespace Aurora::IO::Net
{
enum TransportProtocol
{
kProtocolUDP,
kProtocolTCP
};
enum IPProtocol
{
kIPProtocolV4,
kIPProtocolV6
};
struct IPAddress
{
IPProtocol ip;
bool hasIP;
AuString address;
union
{
AuUInt8 v4[4];
AuUInt16 v6[8];
};
AUKN_SYM AuString toString();
};
struct Endpoint
{
TransportProtocol protocol;
IPAddress address;
AuUInt16 port;
// 0 - destination is a stateless datagram server
// 1 - destination is a psuedo-stateful server
AuUInt UDPTimeout;
AUKN_SYM AuString toString();
};
class INetworkStream;
class IBasicSocket;
class IClientSocket;
using StreamHasData_cb = std::function<bool(AuSPtr<IClientSocket> socket)>; // DTLS/UDP/TCP/TLS -> TRUE = expects another frame or stream buffer, FALSE = end of socket life
using InitializeSocket_cb = std::function<bool(AuSPtr<IClientSocket> socket)>;
using ShutdownSocket_cb = std::function<void(AuSPtr<IBasicSocket> socket)>;
using Error_t = std::error_code;
class IBasicSocket
{
public:
virtual bool IsActive() = 0;
virtual Error_t GetLastError() = 0;
virtual void Shutdown() = 0;
virtual bool GetLocalEndpoint(Endpoint &out) = 0;
};
class IClientSocket : public IBasicSocket
{
public:
// called during loop pump
struct ClientCallbacks
{
StreamHasData_cb hasData; // on data available
ShutdownSocket_cb onShutdown; // Socket shutdown or otherwise dead
ShutdownSocket_cb onStreamOverSaturation; // DoS?
ShutdownSocket_cb onTLSHandshakeAbort;
};
virtual bool Initialize(const ClientCallbacks &callbacks) = 0;
virtual bool Initialize() = 0;
virtual bool GetRemoteEndpoint(Endpoint &out) = 0;
virtual bool ReadAsync(AuUInt8 *buffer, bool all, AuUInt32 &length) = 0;
virtual bool WriteAsync(const AuUInt8 *buffer, AuUInt32 length) = 0;
virtual bool WriteAsync(const AuUInt8 *buffer, AuUInt32 length, std::function<void(bool)>) = 0;
virtual AuUInt GetInternalRecvBuffer() = 0;
virtual bool SetInternalRecvBuffer(AuUInt bytes) = 0;
};
class ILocalClientSocket : public IClientSocket
{
public:
using ConnectCallback_cb = std::function<void(bool success)>;
virtual bool Connect() = 0;
virtual void ConnectAsync(ConnectCallback_cb cb) = 0;
};
struct TlsConnect
{
Aurora::Crypto::X509::Certificate serverCertificate;
AuSPtr<IBasicSocket> socket;
};
using TlsConnect_cb = std::function<bool(const TlsConnect &info)>;
struct ServerInfo
{
Endpoint listen;
};
struct TLSServerInfo : ServerInfo
{
Aurora::Crypto::RSAPair cert;
};
struct ClientInfo
{
Endpoint socket;
AuString service;
};
struct TLSClientInfo : ClientInfo
{
TlsConnect_cb pinning;
};
class IServer : public IBasicSocket
{
public:
virtual bool AddAcceptCallback(const InitializeSocket_cb &accept) = 0; // on accept*
virtual bool AddExitCallback(const ShutdownSocket_cb &accept) = 0; // server shutdown*
virtual void GetClients(AuList<AuSPtr<IClientSocket>> &soccies) = 0;
virtual bool Listen() = 0;
};
class INetworkingPool
{
public:
/**
Supported thread models:
while (true)
{
// read from sockets pre-frame
PumpSOL();
// process other async network logic here
// process writes and a few early reads before we sleep
PumpEOL();
// yield
Yield();
}
while (true)
{
// process other async network logic here
// run
Run()
}
*/
virtual void PumpSOL() = 0;
virtual void PumpEOL() = 0;
virtual void Run() = 0;
virtual bool NewServer(const ServerInfo &listen, IServer *&out) = 0;
virtual bool NewTlsServer(const TLSServerInfo &keys, IServer *&out) = 0;
virtual void DeleteServer(IServer *socket) = 0;
virtual bool NewClient(const ClientInfo &info, ILocalClientSocket *&out) = 0;
virtual bool NewTlsClient(const TLSClientInfo &info, ILocalClientSocket *&out) = 0;
virtual void DeleteClient(ILocalClientSocket *socket) = 0;
};
}