void TransportLayerASIO::ASIOSourceTicket::_headerCallback(const std::error_code& ec, size_t size) { if (ec) { finishFill(errorCodeToStatus(ec)); return; } auto session = getSession(); if (!session) return; MSGHEADER::View headerView(_buffer.get()); auto msgLen = static_cast<size_t>(headerView.getMessageLength()); if (msgLen < kHeaderSize || msgLen > MaxMessageSizeBytes) { LOG(0) << "recv(): message msgLen " << msgLen << " is invalid. " << "Min " << kHeaderSize << " Max: " << MaxMessageSizeBytes; finishFill(errorCodeToStatus(ec)); return; } if (msgLen == size) { finishFill(Status::OK()); return; } _buffer.realloc(msgLen); MsgData::View msgView(_buffer.get()); session->read(isSync(), asio::buffer(msgView.data(), msgView.dataLen()), [this](const std::error_code& ec, size_t size) { _bodyCallback(ec, size); }); }
void TransportLayerASIO::ASIOSourceTicket::_bodyCallback(const std::error_code& ec, size_t size) { if (ec) { finishFill(errorCodeToStatus(ec)); return; } _target->setData(std::move(_buffer)); networkCounter.hitPhysicalIn(_target->size()); finishFill(Status::OK()); }
void TransportLayerASIO::ASIOSinkTicket::_sinkCallback(const std::error_code& ec, size_t size) { networkCounter.hitPhysicalOut(_msgToSend.size()); finishFill(ec ? errorCodeToStatus(ec) : Status::OK()); }
Status TransportLayerASIO::setup() { std::vector<std::string> listenAddrs; if (_listenerOptions.ipList.empty()) { listenAddrs = {"127.0.0.1"}; if (_listenerOptions.enableIPv6) { listenAddrs.emplace_back("::1"); } } else { boost::split( listenAddrs, _listenerOptions.ipList, boost::is_any_of(","), boost::token_compress_on); } #ifndef _WIN32 if (_listenerOptions.useUnixSockets) { listenAddrs.emplace_back(makeUnixSockPath(_listenerOptions.port)); } #endif for (auto& ip : listenAddrs) { std::error_code ec; if (ip.empty()) { warning() << "Skipping empty bind address"; continue; } SockAddr addr(StringData(ip), _listenerOptions.port, _listenerOptions.enableIPv6 ? AF_UNSPEC : AF_INET); asio::generic::stream_protocol::endpoint endpoint(addr.raw(), addr.addressSize); #ifndef _WIN32 if (addr.getType() == AF_UNIX) { if (::unlink(ip.c_str()) == -1 && errno != ENOENT) { error() << "Failed to unlink socket file " << ip << " " << errnoWithDescription(errno); fassertFailedNoTrace(40486); } } #endif if (addr.getType() == AF_INET6 && !_listenerOptions.enableIPv6) { error() << "Specified ipv6 bind address, but ipv6 is disabled"; fassertFailedNoTrace(40488); } GenericAcceptor acceptor(*_ioContext); acceptor.open(endpoint.protocol()); acceptor.set_option(GenericAcceptor::reuse_address(true)); acceptor.bind(endpoint, ec); if (ec) { return errorCodeToStatus(ec); } #ifndef _WIN32 if (addr.getType() == AF_UNIX) { if (::chmod(ip.c_str(), serverGlobalParams.unixSocketPermissions) == -1) { error() << "Failed to chmod socket file " << ip << " " << errnoWithDescription(errno); fassertFailedNoTrace(40487); } } #endif _acceptors.emplace_back(std::move(acceptor)); } invariant(!_acceptors.empty()); #ifdef MONGO_CONFIG_SSL const auto& sslParams = getSSLGlobalParams(); _sslMode = static_cast<SSLParams::SSLModes>(sslParams.sslMode.load()); if (_sslMode != SSLParams::SSLMode_disabled) { _sslContext = stdx::make_unique<asio::ssl::context>(asio::ssl::context::sslv23); const auto sslManager = getSSLManager(); sslManager ->initSSLContext(_sslContext->native_handle(), sslParams, SSLManagerInterface::ConnectionDirection::kOutgoing) .transitional_ignore(); } #endif return Status::OK(); }