Веб-сайт самохостера Lotigara

summaryrefslogtreecommitdiff
path: root/source/core/StarUdp.cpp
diff options
context:
space:
mode:
authorKae <80987908+Novaenia@users.noreply.github.com>2023-06-20 14:33:09 +1000
committerKae <80987908+Novaenia@users.noreply.github.com>2023-06-20 14:33:09 +1000
commit6352e8e3196f78388b6c771073f9e03eaa612673 (patch)
treee23772f79a7fbc41bc9108951e9e136857484bf4 /source/core/StarUdp.cpp
parent6741a057e5639280d85d0f88ba26f000baa58f61 (diff)
everything everywhere
all at once
Diffstat (limited to 'source/core/StarUdp.cpp')
-rw-r--r--source/core/StarUdp.cpp84
1 files changed, 84 insertions, 0 deletions
diff --git a/source/core/StarUdp.cpp b/source/core/StarUdp.cpp
new file mode 100644
index 0000000..9ff7b48
--- /dev/null
+++ b/source/core/StarUdp.cpp
@@ -0,0 +1,84 @@
+#include "StarUdp.hpp"
+#include "StarLogging.hpp"
+#include "StarNetImpl.hpp"
+
+namespace Star {
+
+UdpSocket::UdpSocket(NetworkMode networkMode) : Socket(SocketType::Udp, networkMode) {}
+
+size_t UdpSocket::receive(HostAddressWithPort* address, char* data, size_t datasize) {
+ ReadLocker locker(m_mutex);
+ checkOpen("UdpSocket::receive");
+
+ int flags = 0;
+ int len;
+ struct sockaddr_storage sockAddr;
+ socklen_t sockAddrLen = sizeof(sockAddr);
+
+ len = ::recvfrom(m_impl->socketDesc, data, datasize, flags, (struct sockaddr*)&sockAddr, &sockAddrLen);
+
+ if (len < 0) {
+ if (!isActive())
+ throw SocketClosedException("Connection closed");
+ else if (netErrorInterrupt())
+ len = 0;
+ else
+ throw NetworkException(strf("udp recv error: %s", netErrorString()));
+ }
+
+ if (address)
+ setAddressFromNative(*address, m_localAddress.address().mode(), &sockAddr);
+
+ return len;
+}
+
+size_t UdpSocket::send(HostAddressWithPort const& address, char const* data, size_t size) {
+ ReadLocker locker(m_mutex);
+ checkOpen("UdpSocket::send");
+
+ struct sockaddr_storage sockAddr;
+ socklen_t sockAddrLen;
+ setNativeFromAddress(address, &sockAddr, &sockAddrLen);
+
+ int len = ::sendto(m_impl->socketDesc, data, size, 0, (struct sockaddr*)&sockAddr, sockAddrLen);
+ if (len < 0) {
+ if (!isActive())
+ throw SocketClosedException("Connection closed");
+ else if (netErrorInterrupt())
+ len = 0;
+ else
+ throw NetworkException(strf("udp send error: %s", netErrorString()));
+ }
+
+ return len;
+}
+
+UdpServer::UdpServer(HostAddressWithPort const& address)
+ : m_hostAddress(address), m_listenSocket(make_shared<UdpSocket>(m_hostAddress.address().mode())) {
+ m_listenSocket->setNonBlocking(true);
+ m_listenSocket->bind(m_hostAddress);
+ Logger::debug("UdpServer listening on: %s", m_hostAddress);
+}
+
+UdpServer::~UdpServer() {
+ close();
+}
+
+size_t UdpServer::receive(HostAddressWithPort* address, char* data, size_t bufsize, unsigned timeout) {
+ Socket::poll({{m_listenSocket, {true, false}}}, timeout);
+ return m_listenSocket->receive(address, data, bufsize);
+}
+
+size_t UdpServer::send(HostAddressWithPort const& address, char const* data, size_t len) {
+ return m_listenSocket->send(address, data, len);
+}
+
+void UdpServer::close() {
+ m_listenSocket->close();
+}
+
+bool UdpServer::isListening() const {
+ return m_listenSocket->isActive();
+}
+
+}