| @@ -62,17 +62,25 @@ namespace SocketHelpers | |||
| #endif | |||
| } | |||
| static bool resetSocketOptions (const SocketHandle handle, const bool isDatagram, const bool allowBroadcast) noexcept | |||
| template <typename Type> | |||
| static bool setOption (const SocketHandle handle, int mode, int property, Type value) noexcept | |||
| { | |||
| return setsockopt (handle, mode, property, reinterpret_cast<const char*> (&value), sizeof (value)) == 0; | |||
| } | |||
| template <typename Type> | |||
| static bool setOption (const SocketHandle handle, int property, Type value) noexcept | |||
| { | |||
| const int sndBufSize = 65536; | |||
| const int rcvBufSize = 65536; | |||
| const int one = 1; | |||
| return setOption (handle, SOL_SOCKET, property, value); | |||
| } | |||
| static bool resetSocketOptions (const SocketHandle handle, const bool isDatagram, const bool allowBroadcast) noexcept | |||
| { | |||
| return handle > 0 | |||
| && setsockopt (handle, SOL_SOCKET, SO_RCVBUF, (const char*) &rcvBufSize, sizeof (rcvBufSize)) == 0 | |||
| && setsockopt (handle, SOL_SOCKET, SO_SNDBUF, (const char*) &sndBufSize, sizeof (sndBufSize)) == 0 | |||
| && (isDatagram ? ((! allowBroadcast) || setsockopt (handle, SOL_SOCKET, SO_BROADCAST, (const char*) &one, sizeof (one)) == 0) | |||
| : (setsockopt (handle, IPPROTO_TCP, TCP_NODELAY, (const char*) &one, sizeof (one)) == 0)); | |||
| && setOption (handle, SO_RCVBUF, (int) 65536) | |||
| && setOption (handle, SO_SNDBUF, (int) 65536) | |||
| && (isDatagram ? ((! allowBroadcast) || setOption (handle, SO_BROADCAST, (int) 1)) | |||
| : setOption (handle, IPPROTO_TCP, TCP_NODELAY, (int) 1)); | |||
| } | |||
| static void closeSocket (volatile int& handle, CriticalSection& readLock, | |||
| @@ -308,8 +316,7 @@ namespace SocketHelpers | |||
| hints.ai_flags = AI_NUMERICSERV; | |||
| struct addrinfo* info = nullptr; | |||
| if (getaddrinfo (hostName.toUTF8(), String (portNumber).toUTF8(), &hints, &info) == 0 | |||
| && info != nullptr) | |||
| if (getaddrinfo (hostName.toUTF8(), String (portNumber).toUTF8(), &hints, &info) == 0) | |||
| return info; | |||
| return nullptr; | |||
| @@ -364,8 +371,7 @@ namespace SocketHelpers | |||
| static void makeReusable (int handle) noexcept | |||
| { | |||
| const int reuse = 1; | |||
| setsockopt (handle, SOL_SOCKET, SO_REUSEADDR, (const char*) &reuse, sizeof (reuse)); | |||
| setOption (handle, SO_REUSEADDR, (int) 1); | |||
| } | |||
| static bool multicast (int handle, const String& multicastIPAddress, | |||
| @@ -380,9 +386,10 @@ namespace SocketHelpers | |||
| if (interfaceIPAddress.isNotEmpty()) | |||
| mreq.imr_interface.s_addr = inet_addr (interfaceIPAddress.toUTF8()); | |||
| int joinCmd = join ? IP_ADD_MEMBERSHIP : IP_DROP_MEMBERSHIP; | |||
| return setsockopt (handle, IPPROTO_IP, joinCmd, (const char*) &mreq, sizeof (mreq)) == 0; | |||
| return setsockopt (handle, IPPROTO_IP, | |||
| join ? IP_ADD_MEMBERSHIP | |||
| : IP_DROP_MEMBERSHIP, | |||
| (const char*) &mreq, sizeof (mreq)) == 0; | |||
| } | |||
| } | |||
| @@ -569,6 +576,7 @@ DatagramSocket::DatagramSocket (const bool canBroadcast) | |||
| SocketHelpers::initSockets(); | |||
| handle = (int) socket (AF_INET, SOCK_DGRAM, 0); | |||
| if (handle >= 0) | |||
| { | |||
| SocketHelpers::resetSocketOptions (handle, true, canBroadcast); | |||
| @@ -579,7 +587,7 @@ DatagramSocket::DatagramSocket (const bool canBroadcast) | |||
| DatagramSocket::~DatagramSocket() | |||
| { | |||
| if (lastServerAddress != nullptr) | |||
| freeaddrinfo (static_cast <struct addrinfo*> (lastServerAddress)); | |||
| freeaddrinfo (static_cast<struct addrinfo*> (lastServerAddress)); | |||
| shutdown(); | |||
| } | |||
| @@ -660,7 +668,7 @@ int DatagramSocket::write (const String& remoteHostname, int remotePortNumber, | |||
| if (handle < 0) | |||
| return -1; | |||
| struct addrinfo*& info = reinterpret_cast <struct addrinfo*&> (lastServerAddress); | |||
| struct addrinfo*& info = reinterpret_cast<struct addrinfo*&> (lastServerAddress); | |||
| // getaddrinfo can be quite slow so cache the result of the address lookup | |||
| if (info == nullptr || remoteHostname != lastServerHost || remotePortNumber != lastServerPort) | |||
| @@ -698,25 +706,18 @@ bool DatagramSocket::leaveMulticast (const String& multicastIPAddress) | |||
| bool DatagramSocket::setEnablePortReuse (bool enabled) | |||
| { | |||
| #if JUCE_ANDROID | |||
| return false; | |||
| #else | |||
| const int reuse = enabled ? 1 : 0; | |||
| #if JUCE_WINDOWS | |||
| // port re-use is implied by addr re-use on windows | |||
| const int optname = SO_REUSEADDR; | |||
| #else | |||
| const int optname = SO_REUSEPORT; | |||
| #endif | |||
| #if ! JUCE_ANDROID | |||
| if (handle >= 0) | |||
| return (setsockopt (handle, SOL_SOCKET, optname, | |||
| (const char*) &reuse, sizeof (reuse)) == 0); | |||
| return SocketHelpers::setOption (handle, | |||
| #if JUCE_WINDOWS || JUCE_LINUX | |||
| SO_REUSEADDR, // port re-use is implied by addr re-use on these platforms | |||
| #else | |||
| SO_REUSEPORT, | |||
| #endif | |||
| (int) (enabled ? 1 : 0)); | |||
| #endif | |||
| return false; | |||
| #endif | |||
| } | |||
| #if JUCE_MSVC | |||