| 836 | } |
| 837 | |
| 838 | size_t CConnman::SocketSendData(CNode& node) const |
| 839 | { |
| 840 | auto it = node.vSendMsg.begin(); |
| 841 | size_t nSentSize = 0; |
| 842 | |
| 843 | while (it != node.vSendMsg.end()) { |
| 844 | const auto& data = *it; |
| 845 | assert(data.size() > node.nSendOffset); |
| 846 | int nBytes = 0; |
| 847 | { |
| 848 | LOCK(node.m_sock_mutex); |
| 849 | if (!node.m_sock) { |
| 850 | break; |
| 851 | } |
| 852 | nBytes = node.m_sock->Send(reinterpret_cast<const char*>(data.data()) + node.nSendOffset, data.size() - node.nSendOffset, MSG_NOSIGNAL | MSG_DONTWAIT); |
| 853 | } |
| 854 | if (nBytes > 0) { |
| 855 | node.m_last_send = GetTime<std::chrono::seconds>(); |
| 856 | node.nSendBytes += nBytes; |
| 857 | node.nSendOffset += nBytes; |
| 858 | nSentSize += nBytes; |
| 859 | if (node.nSendOffset == data.size()) { |
| 860 | node.nSendOffset = 0; |
| 861 | node.nSendSize -= data.size(); |
| 862 | node.fPauseSend = node.nSendSize > nSendBufferMaxSize; |
| 863 | it++; |
| 864 | } else { |
| 865 | // could not send full message; stop sending more |
| 866 | break; |
| 867 | } |
| 868 | } else { |
| 869 | if (nBytes < 0) { |
| 870 | // error |
| 871 | int nErr = WSAGetLastError(); |
| 872 | if (nErr != WSAEWOULDBLOCK && nErr != WSAEMSGSIZE && nErr != WSAEINTR && nErr != WSAEINPROGRESS) { |
| 873 | LogPrint(BCLog::NET, "socket send error for peer=%d: %s\n", node.GetId(), NetworkErrorString(nErr)); |
| 874 | node.CloseSocketDisconnect(); |
| 875 | } |
| 876 | } |
| 877 | // couldn't send anything at all |
| 878 | break; |
| 879 | } |
| 880 | } |
| 881 | |
| 882 | if (it == node.vSendMsg.end()) { |
| 883 | assert(node.nSendOffset == 0); |
| 884 | assert(node.nSendSize == 0); |
| 885 | } |
| 886 | node.vSendMsg.erase(node.vSendMsg.begin(), it); |
| 887 | return nSentSize; |
| 888 | } |
| 889 | |
| 890 | static bool ReverseCompareNodeMinPingTime(const NodeEvictionCandidate &a, const NodeEvictionCandidate &b) |
| 891 | { |
nothing calls this directly
no test coverage detected