From 74c5967448ab9d087977784020c84e920fc291ea Mon Sep 17 00:00:00 2001 From: Jiri Danek Date: Fri, 9 Jul 2021 11:41:19 +0200 Subject: [PATCH] udp --- tests/c_benchmarks/UDPSocket.cpp | 100 +++++++++++++++++++++++++++++++ tests/c_benchmarks/UDPSocket.h | 28 +++++++++ 2 files changed, 128 insertions(+) create mode 100644 tests/c_benchmarks/UDPSocket.cpp create mode 100644 tests/c_benchmarks/UDPSocket.h diff --git a/tests/c_benchmarks/UDPSocket.cpp b/tests/c_benchmarks/UDPSocket.cpp new file mode 100644 index 0000000000..a4152c0b32 --- /dev/null +++ b/tests/c_benchmarks/UDPSocket.cpp @@ -0,0 +1,100 @@ +#include "UDPSocket.h" + +#include "SocketException.h" +#include "socket_utils.h" + +#include +#include +#include + +#include + +UDPSocket::UDPSocket() : Socket(SOCK_DGRAM, IPPROTO_UDP) +{ + setBroadcast(); +} + +UDPSocket::UDPSocket(unsigned short localPort) : Socket(SOCK_DGRAM, IPPROTO_UDP) +{ + setLocalPort(localPort); + setBroadcast(); +} + +UDPSocket::UDPSocket(const std::string &localAddress, unsigned short localPort) : Socket(SOCK_DGRAM, IPPROTO_UDP) +{ + setLocalAddressAndPort(localAddress, localPort); + setBroadcast(); +} + +void UDPSocket::setBroadcast() +{ + int broadcastPermission = 1; + setsockopt(mFileDescriptor, SOL_SOCKET, SO_BROADCAST, &broadcastPermission, sizeof(broadcastPermission)); +} + +void UDPSocket::disconnect() +{ + sockaddr_in nullAddr = {}; + nullAddr.sin_family = AF_UNSPEC; + + // Try to disconnect + if (::connect(mFileDescriptor, reinterpret_cast(&nullAddr), sizeof(nullAddr)) < 0) { + if (errno != EAFNOSUPPORT) { + throw SocketException("Disconnect failed (connect())", true); + } + } +} + +void UDPSocket::sendTo(const void *buffer, int bufferLen, const std::string &remoteAddress, unsigned short remotePort) +{ + sockaddr_in destAddr; + fillSockAddr(remoteAddress, remotePort, destAddr); + + // Write out the whole buffer as a single message. + if (sendto(mFileDescriptor, buffer, bufferLen, 0, reinterpret_cast(&destAddr), sizeof(destAddr)) != bufferLen) { + throw SocketException("Send failed (sendto())", true); + } +} + +int UDPSocket::recvFrom(void *buffer, int bufferLen, std::string &sourceAddress, unsigned short &sourcePort) +{ + sockaddr_in clntAddr; + socklen_t addrLen = sizeof(clntAddr); + int rtn = recvfrom(mFileDescriptor, buffer, bufferLen, 0, reinterpret_cast(&clntAddr), &addrLen); + if (rtn < 0) { + throw SocketException("Receive failed (recvfrom())", true); + } + sourceAddress = inet_ntoa(clntAddr.sin_addr); + sourcePort = ntohs(clntAddr.sin_port); + + return rtn; +} + +void UDPSocket::setMulticastTTL(unsigned char multicastTTL) +{ + if (setsockopt(mFileDescriptor, IPPROTO_IP, IP_MULTICAST_TTL, (void *) &multicastTTL, sizeof(multicastTTL)) < 0) { + throw SocketException("Multicast TTL set failed (setsockopt())", true); + } +} + +void UDPSocket::joinGroup(const std::string &multicastGroup) +{ + struct ip_mreq multicastRequest; + + multicastRequest.imr_multiaddr.s_addr = inet_addr(multicastGroup.c_str()); + multicastRequest.imr_interface.s_addr = htonl(INADDR_ANY); + if (setsockopt(mFileDescriptor, IPPROTO_IP, IP_ADD_MEMBERSHIP, &multicastRequest, sizeof(multicastRequest)) < 0) { + throw SocketException("Multicast group join failed (setsockopt())", true); + } +} + +void UDPSocket::leaveGroup(const std::string &multicastGroup) +{ + struct ip_mreq multicastRequest; + + multicastRequest.imr_multiaddr.s_addr = inet_addr(multicastGroup.c_str()); + multicastRequest.imr_interface.s_addr = htonl(INADDR_ANY); + if (setsockopt(mFileDescriptor, IPPROTO_IP, IP_DROP_MEMBERSHIP, &multicastRequest, sizeof(multicastRequest)) < 0) { + throw SocketException("Multicast group leave failed (setsockopt())", true); + } +} \ No newline at end of file diff --git a/tests/c_benchmarks/UDPSocket.h b/tests/c_benchmarks/UDPSocket.h new file mode 100644 index 0000000000..d9d24b1717 --- /dev/null +++ b/tests/c_benchmarks/UDPSocket.h @@ -0,0 +1,28 @@ +// +// Created by jdanek on 7/8/21. +// + +#ifndef QPID_DISPATCH_UDPSOCKET_H +#define QPID_DISPATCH_UDPSOCKET_H + +#include "Socket.h" + +#include +class UDPSocket : public Socket +{ + public: + UDPSocket(); + UDPSocket(unsigned short localPort); + UDPSocket(const std::string &localAddress, unsigned short localPort); + void disconnect(); + void sendTo(const void *buffer, int bufferLen, const std::string &remoteAddress, unsigned short remotePort); + int recvFrom(void *buffer, int bufferLen, std::string &sourceAddress, unsigned short &sourcePort); + void setMulticastTTL(unsigned char multicastTTL); + void joinGroup(const std::string &multicastGroup); + void leaveGroup(const std::string &multicastGroup); + + private: + void setBroadcast(); +}; + +#endif // QPID_DISPATCH_UDPSOCKET_H