/*** Copyright (C) 2022 J Reece Wilson (a/k/a "Reece"). All rights reserved. File: AuNetSrvSockets.cpp Date: 2022-8-16 Author: Reece ***/ #include "Networking.hpp" #include "AuNetSrvSockets.hpp" #include "AuNetInterface.hpp" #include "AuNetWorker.hpp" #include "AuNetSocket.hpp" #include "AuNetSocketServer.hpp" namespace Aurora::IO::Net { NetSrvSockets::NetSrvSockets(NetInterface *pParent) : pParent_(pParent) { } AuSPtr NetSrvSockets::Connect(const NetSocketConnect &netConnect) { if (netConnect.endpoint.transportProtocol != ETransportProtocol::eProtocolTCP) { SysPushErrorNet("Invalid transport protocol. Hint: Use ConnectManyEx for UDP."); return {}; } auto pWorker = this->pParent_->TryScheduleEx(); if (!pWorker) { SysPushErrorNet("No Worker"); return {}; } auto pSocket = AuMakeShared(this->pParent_, pWorker.get(), netConnect.pDriver, netConnect.endpoint); if (!pSocket) { SysPushErrorNet("No Memory"); return {}; } if (!pWorker->TryScheduleInternalTemplate([=](const AuSPtr> &info) { pSocket->FinishConstructAsync(); if (!pSocket->IsValid()) { pSocket->SendErrorNoStream({}); return; } if (!pSocket->Connect(pSocket->GetRemoteEndpoint())) { SysPushErrorIO("An asynchronous connect failed [root level]"); } }, AuSPtr>{})) { return {}; } return pSocket; } AuSPtr NetSrvSockets::ConnectMany(const NetSocketConnectMany &netConnectMany) { if (netConnectMany.protocol != ETransportProtocol::eProtocolTCP) { SysPushErrorNet("Invalid transport protocol. Hint: Use ConnectManyEx for UDP."); return {}; } auto pWorker = this->pParent_->TryScheduleEx(); if (!pWorker) { SysPushErrorNet("No Worker"); return {}; } auto pSocket = AuMakeShared(this->pParent_, pWorker.get(), netConnectMany.pDriver, netConnectMany); if (!pSocket) { SysPushErrorNet("No Memory"); return {}; } if (!pWorker->TryScheduleInternalTemplate([=](const AuSPtr> &info) { pSocket->FinishConstructAsync(); if (!pSocket->IsValid()) { pSocket->SendErrorNoStream({}); return; } if (!pSocket->ConnectNext()) { SysPushErrorIO("An asynchronous connect failed [root level]"); } }, AuSPtr>{})) { return {}; } return pSocket; } AuSPtr NetSrvSockets::NewServer(const NetSocketBind &netBind) { if (netBind.protocol != ETransportProtocol::eProtocolTCP) { return {}; } auto pWorker = this->pParent_->TryScheduleEx(); if (!pWorker) { SysPushErrorNet("No Worker"); return {}; } auto uMaxSockets = netBind.uMaxConnections ? netBind.uMaxConnections : 512; auto pSocket = AuMakeShared(this->pParent_, pWorker.get(), netBind.pDriver, netBind.pFactory, uMaxSockets); if (!pSocket) { SysPushErrorNet("No Memory"); return {}; } if (!pWorker->TryScheduleInternalTemplate([=](const AuSPtr> &info) { pSocket->FinishConstructAsync(); NetEndpoint endpoint; endpoint.ip = netBind.ip; endpoint.uPort = netBind.uPort; endpoint.transportProtocol = netBind.protocol; pSocket->Init(endpoint); pSocket->Listen(endpoint); pSocket->Accept(); }, AuSPtr>{})) { return {}; } return pSocket; } AuSPtr NetSrvSockets::NewServerEx(const NetSocketBindEx &netBindEx) { if (netBindEx.protocol == ETransportProtocol::eProtocolTCP) { return this->NewServer(netBindEx); } return {}; } }