Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 6 additions & 2 deletions node/Constants.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -739,9 +739,13 @@
#define ZT_TRUST_EXPIRATION 600000

/**
* Desired buffer size for UDP sockets (used in service and osdep but defined here)
* Desired receive and send buffer sizes for physical UDP sockets.
*
* The additional capacity absorbs short bursts before ZeroTier's receive loop
* or the operating system's transmit path drains the socket.
*/
#define ZT_UDP_DESIRED_BUF_SIZE 1048576
#define ZT_UDP_DESIRED_RCVBUF_SIZE 4194304
#define ZT_UDP_DESIRED_SNDBUF_SIZE 2097152

/**
* Desired / recommended min stack size for threads (used on some platforms to reset thread stack size)
Expand Down
6 changes: 5 additions & 1 deletion osdep/Binder.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -449,7 +449,11 @@ class Binder {
++bi;
}
if (bi == _bindingCount) {
udps = phy.udpBind(reinterpret_cast<const struct sockaddr*>(&(ii->first)), (void*)0, ZT_UDP_DESIRED_BUF_SIZE);
udps = phy.udpBind(
reinterpret_cast<const struct sockaddr*>(&(ii->first)),
(void*)0,
ZT_UDP_DESIRED_RCVBUF_SIZE,
ZT_UDP_DESIRED_SNDBUF_SIZE);
if (udps) {
#ifdef __LINUX__
// Bind Linux sockets to their device so routes that we manage do not override physical routes (wish all platforms had this!)
Expand Down
25 changes: 19 additions & 6 deletions osdep/Phy.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -324,11 +324,12 @@ template <typename HANDLER_PTR_TYPE> class Phy {
* Bind a UDP socket
*
* @param localAddress Local endpoint address and port
* @param uptr Initial value of user pointer associated with this socket (default: NULL)
* @param bufferSize Desired socket receive/send buffer size -- will set as close to this as possible (default: 0, leave alone)
* @param uptr Initial value of user pointer associated with this socket
* @param receiveBufferSize Desired socket receive buffer size -- will set as close to this as possible (0: leave alone)
* @param sendBufferSize Desired socket send buffer size -- will set as close to this as possible (0: leave alone)
* @return Socket or NULL on failure to bind
*/
inline PhySocket* udpBind(const struct sockaddr* localAddress, void* uptr = (void*)0, int bufferSize = 0)
inline PhySocket* udpBind(const struct sockaddr* localAddress, void* uptr, int receiveBufferSize, int sendBufferSize)
{
if (_socks.size() >= ZT_PHY_MAX_SOCKETS)
return (PhySocket*)0;
Expand All @@ -337,15 +338,17 @@ template <typename HANDLER_PTR_TYPE> class Phy {
if (! ZT_PHY_SOCKFD_VALID(s))
return (PhySocket*)0;

if (bufferSize > 0) {
int bs = bufferSize;
if (receiveBufferSize > 0) {
int bs = receiveBufferSize;
while (bs >= 65536) {
int tmpbs = bs;
if (setsockopt(s, SOL_SOCKET, SO_RCVBUF, (const char*)&tmpbs, sizeof(tmpbs)) == 0)
break;
bs -= 4096;
}
bs = bufferSize;
}
if (sendBufferSize > 0) {
int bs = sendBufferSize;
while (bs >= 65536) {
int tmpbs = bs;
if (setsockopt(s, SOL_SOCKET, SO_SNDBUF, (const char*)&tmpbs, sizeof(tmpbs)) == 0)
Expand Down Expand Up @@ -447,6 +450,16 @@ template <typename HANDLER_PTR_TYPE> class Phy {
return (PhySocket*)&sws;
}

/**
* Bind a UDP socket with one shared receive/send buffer size.
*
* This overload preserves the original API for existing callers.
*/
inline PhySocket* udpBind(const struct sockaddr* localAddress, void* uptr = (void*)0, int bufferSize = 0)
{
return udpBind(localAddress, uptr, bufferSize, bufferSize);
}

/**
* Set the IP TTL for the next outgoing packet (for IPv4 UDP sockets only)
*
Expand Down
2 changes: 1 addition & 1 deletion selftest.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1546,7 +1546,7 @@ static int testPhy()
testPhyInstance = new Phy<TestPhyHandlers*>(&testPhyHandlers, false, true);

std::cout << "[phy] Binding UDP listen socket to 127.0.0.1/60002... ";
PhySocket* udpListenSock = testPhyInstance->udpBind((const struct sockaddr*)&bindaddr);
PhySocket* udpListenSock = testPhyInstance->udpBind((const struct sockaddr*)&bindaddr, (void*)0, 262144, 131072);
if (! udpListenSock) {
std::cout << "FAILED." << std::endl;
return -1;
Expand Down