void NetworkInterfaceASIO::_beginCommunication(AsyncOp* op) { if (op->canceled()) { return _completeOperation(op, kCanceledStatus); } auto negotiatedProtocol = rpc::negotiate(op->connection()->serverProtocols(), op->connection()->clientProtocols()); if (!negotiatedProtocol.isOK()) { return _completeOperation(op, negotiatedProtocol.getStatus()); } op->setOperationProtocol(negotiatedProtocol.getValue()); op->setToSend(std::move(*_messageFromRequest(op->request(), negotiatedProtocol.getValue()))); // TODO: Is this logic actually necessary (SERVER-19320)? if (op->toSend()->empty()) return _completedWriteCallback(op); // TODO: Some day we may need to support vector messages. fassert(28708, op->toSend()->buf() != 0); asio::const_buffer buf(op->toSend()->buf(), op->toSend()->size()); return _asyncSendSimpleMessage(op, buf); }
void NetworkInterfaceASIO::_recvMessageBody(AsyncOp* op) { // TODO: This error code should be more meaningful. std::error_code ec; // validate message length int len = op->header()->constView().getMessageLength(); if (len == 542393671) { LOG(3) << "attempt to access MongoDB over HTTP on the native driver port."; return _networkErrorCallback(op, ec); } else if (len == -1) { // TODO: An endian check is run after the client connects, we should // set that we've received the client's handshake LOG(3) << "Endian check received from client"; return _networkErrorCallback(op, ec); } else if (static_cast<size_t>(len) < sizeof(MSGHEADER::Value) || static_cast<size_t>(len) > MaxMessageSizeBytes) { warning() << "recv(): message len " << len << " is invalid. " << "Min " << sizeof(MSGHEADER::Value) << " Max: " << MaxMessageSizeBytes; return _networkErrorCallback(op, ec); } // validate response id uint32_t expectedId = op->toSend()->header().getId(); uint32_t actualId = op->header()->constView().getResponseTo(); if (actualId != expectedId) { LOG(3) << "got wrong response:" << " expected response id: " << expectedId << ", got response id: " << actualId; return _networkErrorCallback(op, ec); } int z = (len + 1023) & 0xfffffc00; invariant(z >= len); op->toRecv()->setData(reinterpret_cast<char*>(mongoMalloc(z)), true); MsgData::View mdView = op->toRecv()->buf(); // copy header data into master buffer int headerLen = sizeof(MSGHEADER::Value); memcpy(mdView.view2ptr(), op->header(), headerLen); int bodyLength = len - headerLen; invariant(bodyLength >= 0); // receive remaining data into md->data asio::async_read(op->connection()->sock(), asio::buffer(mdView.data(), bodyLength), [this, op, mdView](asio::error_code ec, size_t bytes) { if (op->canceled()) { return _completeOperation(op, kCanceledStatus); } if (ec) { LOG(3) << "error receiving message body"; return _networkErrorCallback(op, ec); } return _completedWriteCallback(op); }); }
void NetworkInterfaceASIO::_beginCommunication(AsyncOp* op) { if (op->canceled()) { return _completeOperation(op, kCanceledStatus); } Message* toSend = op->toSend(); _messageFromRequest(op->request(), toSend); if (toSend->empty()) return _completedWriteCallback(op); // TODO: Some day we may need to support vector messages. fassert(28708, toSend->buf() != 0); asio::const_buffer buf(toSend->buf(), toSend->size()); return _asyncSendSimpleMessage(op, buf); }