| 4138 | } |
| 4139 | |
| 4140 | void CConnman::PushMessage(CNode* pnode, CSerializedNetMsg&& msg) |
| 4141 | { |
| 4142 | AssertLockNotHeld(m_total_bytes_sent_mutex); |
| 4143 | |
| 4144 | if (pnode->IsPrivateBroadcastConn() && !IsOutboundMessageAllowedInPrivateBroadcast(msg.m_type)) { |
| 4145 | LogDebug(BCLog::PRIVBROADCAST, "Omitting send of message '%s', %s", msg.m_type, pnode->LogPeer()); |
| 4146 | return; |
| 4147 | } |
| 4148 | |
| 4149 | if (!m_private_broadcast.m_outbound_tor_ok_at_least_once.load() && !pnode->IsInboundConn() && |
| 4150 | pnode->addr.IsTor() && msg.m_type == NetMsgType::VERACK) { |
| 4151 | // If we are sending the peer VERACK that means we successfully sent |
| 4152 | // and received another message to/from that peer (VERSION). |
| 4153 | m_private_broadcast.m_outbound_tor_ok_at_least_once.store(true); |
| 4154 | } |
| 4155 | |
| 4156 | size_t nMessageSize = msg.data.size(); |
| 4157 | LogDebug(BCLog::NET, "sending %s (%d bytes) peer=%d\n", msg.m_type, nMessageSize, pnode->GetId()); |
| 4158 | if (m_capture_messages) { |
| 4159 | CaptureMessage(pnode->addr, msg.m_type, msg.data, /*is_incoming=*/false); |
| 4160 | } |
| 4161 | |
| 4162 | TRACEPOINT(net, outbound_message, |
| 4163 | pnode->GetId(), |
| 4164 | pnode->m_addr_name.c_str(), |
| 4165 | pnode->ConnectionTypeAsString().c_str(), |
| 4166 | msg.m_type.c_str(), |
| 4167 | msg.data.size(), |
| 4168 | msg.data.data() |
| 4169 | ); |
| 4170 | |
| 4171 | size_t nBytesSent = 0; |
| 4172 | { |
| 4173 | LOCK(pnode->cs_vSend); |
| 4174 | // Check if the transport still has unsent bytes, and indicate to it that we're about to |
| 4175 | // give it a message to send. |
| 4176 | const auto& [to_send, more, _msg_type] = |
| 4177 | pnode->m_transport->GetBytesToSend(/*have_next_message=*/true); |
| 4178 | const bool queue_was_empty{to_send.empty() && pnode->vSendMsg.empty()}; |
| 4179 | |
| 4180 | // Update memory usage of send buffer. |
| 4181 | pnode->m_send_memusage += msg.GetMemoryUsage(); |
| 4182 | if (pnode->m_send_memusage + pnode->m_transport->GetSendMemoryUsage() > nSendBufferMaxSize) pnode->fPauseSend = true; |
| 4183 | // Move message to vSendMsg queue. |
| 4184 | pnode->vSendMsg.push_back(std::move(msg)); |
| 4185 | |
| 4186 | // If there was nothing to send before, and there is now (predicted by the "more" value |
| 4187 | // returned by the GetBytesToSend call above), attempt "optimistic write": |
| 4188 | // because the poll/select loop may pause for SELECT_TIMEOUT_MILLISECONDS before actually |
| 4189 | // doing a send, try sending from the calling thread if the queue was empty before. |
| 4190 | // With a V1Transport, more will always be true here, because adding a message always |
| 4191 | // results in sendable bytes there, but with V2Transport this is not the case (it may |
| 4192 | // still be in the handshake). |
| 4193 | if (queue_was_empty && more) { |
| 4194 | std::tie(nBytesSent, std::ignore) = SocketSendData(*pnode); |
| 4195 | } |
| 4196 | } |
| 4197 | if (nBytesSent) RecordBytesSent(nBytesSent); |
no test coverage detected