Skip to content

Commit

Permalink
Sockets: Add SetNagleBuffering()
Browse files Browse the repository at this point in the history
  • Loading branch information
stenzek committed Jul 21, 2024
1 parent f2e88ce commit cc667cd
Show file tree
Hide file tree
Showing 2 changed files with 31 additions and 0 deletions.
25 changes: 25 additions & 0 deletions src/util/sockets.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,7 @@ using nfds_t = ULONG;
#include <arpa/inet.h>
#include <errno.h>
#include <netinet/in.h>
#include <netinet/tcp.h>
#include <poll.h>
#include <sys/ioctl.h>
#include <sys/socket.h>
Expand Down Expand Up @@ -76,6 +77,12 @@ void SocketAddress::SetFromSockaddr(const void* sa, size_t length)
std::memset(m_data + m_length, 0, sizeof(m_data) - m_length);
}

bool SocketAddress::IsIPAddress() const
{
const sockaddr* addr = reinterpret_cast<const sockaddr*>(m_data);
return (addr->sa_family == AF_INET || addr->sa_family == AF_INET6);
}

std::optional<SocketAddress> SocketAddress::Parse(Type type, const char* address, u32 port, Error* error)
{
std::optional<SocketAddress> ret = SocketAddress();
Expand Down Expand Up @@ -695,6 +702,24 @@ size_t StreamSocket::WriteVector(const void** buffers, const size_t* buffer_leng
#endif
}

bool StreamSocket::SetNagleBuffering(bool enabled, Error* error /* = nullptr */)
{
if (!m_local_address.IsIPAddress())
{
Error::SetStringView(error, "Attempting to disable nagle on a non-IP socket.");
return false;
}

int disable = enabled ? 0 : 1;
if (setsockopt(m_descriptor, IPPROTO_TCP, TCP_NODELAY, reinterpret_cast<char*>(&disable), sizeof(disable)) != 0)
{
Error::SetSocket(error, "setsockopt(TCP_NODELAY) failed: ", WSAGetLastError());
return false;
}

return true;
}

void StreamSocket::Close()
{
std::unique_lock lock(m_lock);
Expand Down
6 changes: 6 additions & 0 deletions src/util/sockets.h
Original file line number Diff line number Diff line change
Expand Up @@ -56,6 +56,9 @@ struct SocketAddress final
// initializers
void SetFromSockaddr(const void* sa, size_t length);

/// Returns true if the address is IP.
bool IsIPAddress() const;

private:
u8 m_data[128] = {};
u32 m_length = 0;
Expand Down Expand Up @@ -218,6 +221,9 @@ class StreamSocket : public BaseSocket
size_t Write(const void* buffer, size_t buffer_size);
size_t WriteVector(const void** buffers, const size_t* buffer_lengths, size_t num_buffers);

/// Disables Nagle's buffering algorithm, i.e. TCP_NODELAY.
bool SetNagleBuffering(bool enabled, Error* error = nullptr);

protected:
virtual void OnConnected() = 0;
virtual void OnDisconnected(const Error& error) = 0;
Expand Down

0 comments on commit cc667cd

Please sign in to comment.