in ctsTraffic/ctsConfig.cpp [3993:4222]
int SetPreBindOptions(SOCKET socket, const ctSockaddr& localAddress) noexcept
{
ctsConfigInitOnce();
if (g_configSettings->OutgoingIfIndex > 0)
{
constexpr int optlen{sizeof g_configSettings->OutgoingIfIndex};
if (localAddress.family() == AF_INET)
{
// Interface index is in network byte order for IPPROTO_IP.
const DWORD optionValue = htonl(g_configSettings->OutgoingIfIndex);
if (::setsockopt(
socket,
IPPROTO_IP, // level
IP_UNICAST_IF, // optname
reinterpret_cast<const char*>(&optionValue),
optlen) != 0)
{
const auto gle = WSAGetLastError();
PrintErrorIfFailed("setsockopt(IP_UNICAST_IF)", gle);
return gle;
}
}
else
{
// Interface index is in host byte order for IPPROTO_IPV6.
if (::setsockopt(
socket,
IPPROTO_IPV6, // level
IPV6_UNICAST_IF, // optname
reinterpret_cast<const char*>(&g_configSettings->OutgoingIfIndex),
optlen) != 0)
{
const auto gle = WSAGetLastError();
PrintErrorIfFailed("setsockopt(IPV6_UNICAST_IF)", gle);
return gle;
}
}
}
//
// if the user specified bind addresses, enable SO_PORT_SCALABILITY
// - this will allow each unique IP address the full range of ephemeral ports
// this option is not available when just binding to INET_ANY (making an ephemeral bind)
// this option is also not used if the user is binding to an explicit port #
// - since the port scalability rules no longer apply
//
// these only are applicable for outgoing connections
//
if (ProtocolType::TCP == g_configSettings->Protocol && !IsListening())
{
if (g_configSettings->Options & ReuseUnicastPort)
{
// the admin configured the system to use this socket option
// it is not compatible with SO_PORT_SCALABILITY
constexpr DWORD optval{1}; // BOOL
constexpr int optlen{sizeof optval};
#ifndef SO_REUSE_UNICASTPORT
#define SO_REUSE_UNICASTPORT (SO_PORT_SCALABILITY + 1)
#endif
if (::setsockopt(
socket,
SOL_SOCKET, // level
SO_REUSE_UNICASTPORT, // optname
reinterpret_cast<const char*>(&optval),
optlen) != 0)
{
const auto gle = WSAGetLastError();
PrintErrorIfFailed("setsockopt(SO_REUSE_UNICASTPORT)", gle);
return gle;
}
}
else if (!localAddress.IsAddressAny() && localAddress.port() == 0)
{
constexpr DWORD optval{1}; // BOOL
// ReSharper disable once CppTooWideScopeInitStatement
constexpr int optlen{sizeof optval};
if (::setsockopt(
socket,
SOL_SOCKET, // level
SO_PORT_SCALABILITY, // optname
reinterpret_cast<const char*>(&optval),
optlen) != 0)
{
const auto gle = WSAGetLastError();
PrintErrorIfFailed("setsockopt(SO_PORT_SCALABILITY)", gle);
return gle;
}
}
}
if (g_configSettings->Options & LoopbackFastPath)
{
DWORD inValue{1};
DWORD bytesReturned{};
if (::WSAIoctl(
socket,
SIO_LOOPBACK_FAST_PATH,
&inValue, sizeof inValue,
nullptr, 0,
&bytesReturned,
nullptr,
nullptr) != 0)
{
const auto gle = WSAGetLastError();
PrintErrorIfFailed("WSAIoctl(SIO_LOOPBACK_FAST_PATH)", gle);
return gle;
}
}
if (g_configSettings->KeepAliveValue > 0)
{
tcp_keepalive keepaliveValues{};
keepaliveValues.onoff = 1;
keepaliveValues.keepalivetime = g_configSettings->KeepAliveValue;
keepaliveValues.keepaliveinterval = 1000; // continue to default to 1 second
DWORD bytesReturned{};
if (::WSAIoctl(
socket,
SIO_KEEPALIVE_VALS, // control code
&keepaliveValues, sizeof keepaliveValues, // in params
nullptr, 0, // out params
&bytesReturned,
nullptr,
nullptr
) != 0)
{
const auto gle = WSAGetLastError();
PrintErrorIfFailed("WSAIoctl(SIO_KEEPALIVE_VALS)", gle);
return gle;
}
}
else if (g_configSettings->Options & Keepalive)
{
constexpr DWORD optval{1};
// ReSharper disable once CppTooWideScopeInitStatement
constexpr int optlen{sizeof optval};
if (::setsockopt(
socket,
SOL_SOCKET, // level
SO_KEEPALIVE, // optname
reinterpret_cast<const char*>(&optval),
optlen) != 0)
{
const auto gle = WSAGetLastError();
PrintErrorIfFailed("setsockopt(SO_KEEPALIVE)", gle);
return gle;
}
}
if (g_configSettings->Options & SetRecvBuf)
{
const auto recvBuff = g_configSettings->RecvBufValue;
if (::setsockopt(
socket,
SOL_SOCKET,
SO_RCVBUF,
reinterpret_cast<const char*>(&recvBuff),
static_cast<int>(sizeof recvBuff)) != 0)
{
const auto gle = WSAGetLastError();
PrintErrorIfFailed("setsockopt(SO_RCVBUF)", gle);
return gle;
}
}
if (g_configSettings->Options & SetSendBuf)
{
const auto sendBuff = g_configSettings->SendBufValue;
if (::setsockopt(
socket,
SOL_SOCKET,
SO_SNDBUF,
reinterpret_cast<const char*>(&sendBuff),
static_cast<int>(sizeof sendBuff)) != 0)
{
const auto gle = WSAGetLastError();
PrintErrorIfFailed("setsockopt(SO_SNDBUF)", gle);
return gle;
}
}
if (g_configSettings->Options & NonBlockingIo)
{
u_long enableNonBlocking = 1;
if (::ioctlsocket(socket, FIONBIO, &enableNonBlocking) != 0)
{
const auto gle = WSAGetLastError();
PrintErrorIfFailed("ioctlsocket(FIONBIO)", gle);
return gle;
}
}
if (g_configSettings->Options & EnableCircularQueueing)
{
DWORD bytesReturned{};
// ReSharper disable once CppTooWideScopeInitStatement
const auto error = ::WSAIoctl(
socket,
SIO_ENABLE_CIRCULAR_QUEUEING,
nullptr, 0, // in buffer
nullptr, 0, // out buffer
&bytesReturned,
nullptr,
nullptr);
if (error != 0)
{
const auto gle = WSAGetLastError();
PrintErrorIfFailed("WSAIoctl(SIO_ENABLE_CIRCULAR_QUEUEING)", gle);
return gle;
}
}
if (g_configSettings->Options & HandleInlineIocp)
{
if (!::SetFileCompletionNotificationModes(reinterpret_cast<HANDLE>(socket), FILE_SKIP_COMPLETION_PORT_ON_SUCCESS)) // NOLINT(performance-no-int-to-ptr)
{
const auto gle = GetLastError();
PrintErrorIfFailed("SetFileCompletionNotificationModes(FILE_SKIP_COMPLETION_PORT_ON_SUCCESS)", gle);
return static_cast<int>(gle);
}
}
return NO_ERROR;
}