in mcrouter/lib/network/AsyncMcServer.cpp [495:637]
void startAccepting() {
CHECK(accepting_);
auto& opts = server_.opts_;
if (!opts.existingSocketFds.empty()) {
checkLogic(
opts.ports.empty() && opts.sslPorts.empty(),
"Can't use ports if using existing socket");
checkLogic(
!reusePort_,
"Can't use multiple listening sockets option if using existing socket");
// Don't enable tcpZeroCopy here as it will be inherited. It has to be
// enabled when the socket is in a TCP_CLOSE state, afterwards its too
// late.
if (opts.worker.tcpZeroCopyThresholdBytes > 0) {
for (auto fd : opts.existingSocketFds) {
int val = 0;
socklen_t optlen = sizeof(val);
int ret = getsockopt(fd, SOL_SOCKET, SO_ZEROCOPY, &val, &optlen);
checkLogic(!ret, "Failed to getsockopt existing FD");
checkLogic(val, "SO_ZEROCOPY must be enabled on existing socket.");
}
}
if (!opts.pemCertPath.empty() || !opts.pemKeyPath.empty() ||
!opts.pemCaPath.empty()) {
checkLogic(
!opts.pemCertPath.empty() && !opts.pemKeyPath.empty() &&
!opts.pemCaPath.empty(),
"All of pemCertPath, pemKeyPath and pemCaPath are required "
"if at least one of them set");
sslSocket_.reset(new folly::AsyncServerSocket());
std::vector<folly::NetworkSocket> sockets;
for (auto fd : opts.existingSocketFds) {
sockets.push_back(folly::NetworkSocket::fromFd(fd));
}
sslSocket_->useExistingSockets(sockets);
} else {
socket_.reset(new folly::AsyncServerSocket());
std::vector<folly::NetworkSocket> sockets;
for (auto fd : opts.existingSocketFds) {
sockets.push_back(folly::NetworkSocket::fromFd(fd));
}
socket_->useExistingSockets(sockets);
}
} else if (!opts.unixDomainSockPath.empty()) {
checkLogic(
opts.ports.empty() && opts.sslPorts.empty() &&
opts.existingSocketFds.empty(),
"Can't listen on port and unix domain socket at the same time");
checkLogic(
!reusePort_,
"Can't use multiple listening sockets option with unix domain sockets.");
checkLogic(
!opts.worker.tcpZeroCopyThresholdBytes,
"Can't use tcp zero copy with unix domain sockets.");
std::remove(opts.unixDomainSockPath.c_str());
socket_.reset(new folly::AsyncServerSocket());
folly::SocketAddress serverAddress;
serverAddress.setFromPath(opts.unixDomainSockPath);
socket_->bind(serverAddress);
} else {
checkLogic(
!server_.opts_.ports.empty() || !server_.opts_.sslPorts.empty(),
"At least one port (plain or SSL) must be speicified");
if (!server_.opts_.ports.empty()) {
socket_.reset(new folly::AsyncServerSocket());
socket_->setReusePortEnabled(reusePort_);
for (auto port : server_.opts_.ports) {
if (server_.opts_.listenAddresses.empty()) {
socket_->bind(port);
} else {
std::vector<folly::IPAddress> ipAddresses;
for (auto& listenAddress : server_.opts_.listenAddresses) {
auto maybeIp = folly::IPAddress::tryFromString(listenAddress);
checkLogic(
maybeIp.hasValue(),
"Invalid listen address: {}",
listenAddress);
auto ip = std::move(maybeIp).value();
ipAddresses.push_back(std::move(ip));
}
socket_->bind(ipAddresses, port);
}
}
if (opts.worker.tcpZeroCopyThresholdBytes > 0) {
bool zeroCopyApplied = socket_->setZeroCopy(true);
checkLogic(zeroCopyApplied, "Failed to set TCP zero copy on socket");
}
socket_->setTosReflect(server_.opts_.worker.tosReflection);
}
if (!server_.opts_.sslPorts.empty()) {
checkLogic(
!server_.opts_.pemCertPath.empty() &&
!server_.opts_.pemKeyPath.empty() &&
!server_.opts_.pemCaPath.empty(),
"All of pemCertPath, pemKeyPath, pemCaPath required"
" with sslPorts");
sslSocket_.reset(new folly::AsyncServerSocket());
sslSocket_->setReusePortEnabled(reusePort_);
for (auto sslPort : server_.opts_.sslPorts) {
sslSocket_->bind(sslPort);
}
if (opts.worker.tcpZeroCopyThresholdBytes > 0) {
bool zeroCopyApplied = sslSocket_->setZeroCopy(true);
checkLogic(
zeroCopyApplied, "Failed to set TCP zero copy on ssl socket");
}
sslSocket_->setTosReflect(server_.opts_.worker.tosReflection);
}
}
if (socket_) {
socket_->listen(server_.opts_.tcpListenBacklog);
socket_->startAccepting();
socket_->attachEventBase(&eventBase());
}
if (sslSocket_) {
if (server_.opts_.tfoEnabledForSsl) {
sslSocket_->setTFOEnabled(true, server_.opts_.tfoQueueSize);
} else {
sslSocket_->setTFOEnabled(false, 0);
}
sslSocket_->listen(server_.opts_.tcpListenBacklog);
sslSocket_->startAccepting();
sslSocket_->attachEventBase(&eventBase());
}
for (auto& t : server_.threads_) {
if (socket_ != nullptr) {
socket_->addAcceptCallback(&t->acceptCallback_, &t->eventBase());
}
if (sslSocket_ != nullptr) {
sslSocket_->addAcceptCallback(&t->sslAcceptCallback_, &t->eventBase());
}
if (socket_ != nullptr || sslSocket_ != nullptr || t.get() != this) {
acceptorsKeepAlive_.emplace_back(getKeepAliveToken(&t->eventBase()));
}
}
}