in folly/net/TcpInfo.cpp [484:568]
void TcpInfo::initCcInfoFromFd(
const NetworkSocket& fd,
TcpInfo& wrappedInfo,
netops::Dispatcher& netopsDispatcher) {
#ifndef FOLLY_HAVE_TCP_CC_INFO
return; // platform not supported
#elif defined(__linux__)
if (NetworkSocket() == fd) {
return;
}
// identification strings returned by Linux Kernel for TCP_CONGESTION
static constexpr auto kLinuxCcNameStrReno = "reno";
static constexpr auto kLinuxCcNameStrCubic = "cubic";
static constexpr auto kLinuxCcNameStrBic = "bic";
static constexpr auto kLinuxCcNameStrBbr = "bbr";
static constexpr auto kLinuxCcNameStrVegas = "vegas";
static constexpr auto kLinuxCcNameStrDctcp = "dctcp";
static constexpr auto kLinuxCcNameStrDctcpReno = "dctcp_reno";
static constexpr auto kLinuxCcNameStrDctcpCubic = "dctcp_cubic";
std::array<char, (unsigned int)kLinuxTcpCaNameMax> tcpCongestion{{0}};
socklen_t optlen = tcpCongestion.size();
if (netopsDispatcher.getsockopt(
fd, IPPROTO_TCP, TCP_CONGESTION, tcpCongestion.data(), &optlen) < 0) {
VLOG(4) << "Error calling getsockopt(): " << folly::errnoStr(errno);
return;
}
{
auto ccStr = std::string(tcpCongestion.data());
if (ccStr == kLinuxCcNameStrReno) {
wrappedInfo.maybeCcEnum = CongestionControlName::RENO;
} else if (ccStr == kLinuxCcNameStrCubic) {
wrappedInfo.maybeCcEnum = CongestionControlName::CUBIC;
} else if (ccStr == kLinuxCcNameStrBic) {
wrappedInfo.maybeCcEnum = CongestionControlName::BIC;
} else if (ccStr == kLinuxCcNameStrBbr) {
wrappedInfo.maybeCcEnum = CongestionControlName::BBR;
} else if (ccStr == kLinuxCcNameStrVegas) {
wrappedInfo.maybeCcEnum = CongestionControlName::VEGAS;
} else if (ccStr == kLinuxCcNameStrDctcp) {
wrappedInfo.maybeCcEnum = CongestionControlName::DCTCP;
} else if (ccStr == kLinuxCcNameStrDctcpReno) {
wrappedInfo.maybeCcEnum = CongestionControlName::DCTCP_RENO;
} else if (ccStr == kLinuxCcNameStrDctcpCubic) {
wrappedInfo.maybeCcEnum = CongestionControlName::DCTCP_CUBIC;
} else {
wrappedInfo.maybeCcEnum = CongestionControlName::UNKNOWN;
}
wrappedInfo.maybeCcNameRaw.emplace(std::move(ccStr));
}
// get TCP_CC_INFO if supported for the congestion control algorithm
switch (wrappedInfo.maybeCcEnum.value_or(CongestionControlName::UNKNOWN)) {
case CongestionControlName::UNKNOWN:
case CongestionControlName::RENO:
case CongestionControlName::CUBIC:
case CongestionControlName::BIC:
return; // no TCP_CC_INFO for these congestion controls, exit out
case CongestionControlName::BBR:
case CongestionControlName::VEGAS:
case CongestionControlName::DCTCP:
case CongestionControlName::DCTCP_RENO:
case CongestionControlName::DCTCP_CUBIC:
break; // supported, proceed
case CongestionControlName::NumCcTypes:
LOG(FATAL) << "CongestionControlName::NumCcTypes is not a valid CC type";
}
tcp_cc_info ccInfo = {};
socklen_t len = sizeof(tcp_cc_info);
const int ret = netopsDispatcher.getsockopt(
fd, IPPROTO_TCP, TCP_CC_INFO, (void*)&ccInfo, &len);
if (ret < 0) {
int errnoCopy = errno;
VLOG(4) << "Error calling getsockopt(): " << folly::errnoStr(errnoCopy);
return;
}
wrappedInfo.maybeCcInfo = ccInfo;
wrappedInfo.tcpCcInfoBytesRead = len;
#else
return;
#endif
}