MCPcopy Create free account
hub / github.com/bitcoin/bitcoin / SocketSendData

Method SocketSendData

src/net.cpp:1607–1684  ·  view source on GitHub ↗

Source from the content-addressed store, hash-verified

1605}
1606
1607std::pair<size_t, bool> CConnman::SocketSendData(CNode& node) const
1608{
1609 auto it = node.vSendMsg.begin();
1610 size_t nSentSize = 0;
1611 bool data_left{false}; //!< second return value (whether unsent data remains)
1612 std::optional<bool> expected_more;
1613
1614 while (true) {
1615 if (it != node.vSendMsg.end()) {
1616 // If possible, move one message from the send queue to the transport. This fails when
1617 // there is an existing message still being sent, or (for v2 transports) when the
1618 // handshake has not yet completed.
1619 size_t memusage = it->GetMemoryUsage();
1620 if (node.m_transport->SetMessageToSend(*it)) {
1621 // Update memory usage of send buffer (as *it will be deleted).
1622 node.m_send_memusage -= memusage;
1623 ++it;
1624 }
1625 }
1626 const auto& [data, more, msg_type] = node.m_transport->GetBytesToSend(it != node.vSendMsg.end());
1627 // We rely on the 'more' value returned by GetBytesToSend to correctly predict whether more
1628 // bytes are still to be sent, to correctly set the MSG_MORE flag. As a sanity check,
1629 // verify that the previously returned 'more' was correct.
1630 if (expected_more.has_value()) Assume(!data.empty() == *expected_more);
1631 expected_more = more;
1632 data_left = !data.empty(); // will be overwritten on next loop if all of data gets sent
1633 int nBytes = 0;
1634 if (!data.empty()) {
1635 LOCK(node.m_sock_mutex);
1636 // There is no socket in case we've already disconnected, or in test cases without
1637 // real connections. In these cases, we bail out immediately and just leave things
1638 // in the send queue and transport.
1639 if (!node.m_sock) {
1640 break;
1641 }
1642 int flags = MSG_NOSIGNAL | MSG_DONTWAIT;
1643#ifdef MSG_MORE
1644 if (more) {
1645 flags |= MSG_MORE;
1646 }
1647#endif
1648 nBytes = node.m_sock->Send(data.data(), data.size(), flags);
1649 }
1650 if (nBytes > 0) {
1651 node.m_last_send = NodeClock::now();
1652 node.nSendBytes += nBytes;
1653 // Notify transport that bytes have been processed.
1654 node.m_transport->MarkBytesSent(nBytes);
1655 // Update statistics per message type.
1656 if (!msg_type.empty()) { // don't report v2 handshake bytes for now
1657 node.AccountForSentBytes(msg_type, nBytes);
1658 }
1659 nSentSize += nBytes;
1660 if ((size_t)nBytes != data.size()) {
1661 // could not send full message; stop sending more
1662 break;
1663 }
1664 } else {

Callers

nothing calls this directly

Calls 15

NetworkErrorStringFunction · 0.85
SetMessageToSendMethod · 0.80
GetBytesToSendMethod · 0.80
MarkBytesSentMethod · 0.80
DisconnectMsgMethod · 0.80
CloseSocketDisconnectMethod · 0.80
GetSendMemoryUsageMethod · 0.80
beginMethod · 0.45
endMethod · 0.45
GetMemoryUsageMethod · 0.45
has_valueMethod · 0.45
emptyMethod · 0.45

Tested by

no test coverage detected