From 919742772fef086e87ff683068d5c1e6d0fb26cc Mon Sep 17 00:00:00 2001 From: Kimapr Date: Wed, 28 Jan 2026 07:15:52 +0500 Subject: [PATCH] stunclient: connect() UDP socket to STUN server the purpose is so that when the socket has the Linux SO_REUSEPORT option set, and another program listens on the same port as stunclient, the kernel knows to route the STUN response to stunclient rather than the other program. stunclient currently offers no option to set SO_REUSEPORT on the socket, but if it's somehow set externally this is still useful, and doesn't break anything if it isn't. since the Filtering Test involves receiving the response from a different address, unconnected socket is used for it as usual. --- client/clientmain.cpp | 32 ++++++++++++++++++++++++++++++-- 1 file changed, 30 insertions(+), 2 deletions(-) diff --git a/client/clientmain.cpp b/client/clientmain.cpp index 2fd6b61..9be2818 100644 --- a/client/clientmain.cpp +++ b/client/clientmain.cpp @@ -457,6 +457,7 @@ HRESULT UdpClientLoop(StunClientLogicConfig& config, const ClientSocketConfig& s CSocketAddress addrRemote; // who we CSocketAddress addrLocal; int ret; + bool connected = false; fd_set set; timeval tv = {}; std::string strAddr; @@ -498,6 +499,26 @@ HRESULT UdpClientLoop(StunClientLogicConfig& config, const ClientSocketConfig& s { addrDest.ToString(&strAddr); ASSERT(spMsg->GetSize() > 0); + + if (!config.fFilteringTest) + { + std::string strAddr; + addrDest.ToString(&strAddr); + Logging::LogMsg(LL_DEBUG, "Connecting UDP socket to %s", strAddr.c_str()); + + ret = ::connect(sock, addrDest.GetSockAddr(), addrDest.GetSockAddrLength()); + + if (ret) + { + HRESULT hrRet = ERRNOHR; + Logging::LogMsg(LL_DEBUG, "ERROR. connect failed (errno = %d)", errno); + Chk(hrRet); + } + else + { + connected = true; + } + } if (Logging::GetLogLevel() >= LL_DEBUG) { @@ -506,11 +527,18 @@ HRESULT UdpClientLoop(StunClientLogicConfig& config, const ClientSocketConfig& s Logging::LogMsg(LL_DEBUG, "Sending message to %s", strAddr.c_str()); } - ret = ::sendto(sock, spMsg->GetData(), spMsg->GetSize(), 0, addrDest.GetSockAddr(), addrDest.GetSockAddrLength()); + if (connected) + { + ret = ::send(sock, spMsg->GetData(), spMsg->GetSize(), 0); + } + else + { + ret = ::sendto(sock, spMsg->GetData(), spMsg->GetSize(), 0, addrDest.GetSockAddr(), addrDest.GetSockAddrLength()); + } if (ret <= 0) { - Logging::LogMsg(LL_DEBUG, "ERROR. sendto failed (errno = %d)", errno); + Logging::LogMsg(LL_DEBUG, "ERROR. %s failed (errno = %d)", connected ? "send" : "sendto", errno); } // there's not much we can do if "sendto" fails except time out and try again }