| 768 | // |
| 769 | |
| 770 | uint32 CECSocket::WritePacket(const CECPacket *packet) |
| 771 | { |
| 772 | if (SocketRealError()) { |
| 773 | OnError(); |
| 774 | return 0; |
| 775 | } |
| 776 | // Check if output queue is empty. If not, memorize the current end. |
| 777 | std::list<CQueuedData*>::iterator outputStart = m_output_queue.begin(); |
| 778 | uint32 outputQueueSize = m_output_queue.size(); |
| 779 | for (uint32 i = 1; i < outputQueueSize; i++) { |
| 780 | ++outputStart; |
| 781 | } |
| 782 | |
| 783 | uint32_t flags = 0x20; |
| 784 | |
| 785 | // ZLIB decision is per-packet. On a local peer (loopback / RFC1918 |
| 786 | // LAN / RFC3927 link-local) the bandwidth saved by deflate is |
| 787 | // irrelevant — we'd just be paying compress/decompress CPU on both |
| 788 | // ends. Skip ZLIB for those connections up to the |
| 789 | // kLocalPeerZlibBypassMax cap; above the cap, fall back to ZLIB |
| 790 | // so the wire size stays under ReadHeader's 256 MB post-auth |
| 791 | // receiver gate. ZLIB still requires both the per-connection |
| 792 | // negotiation (`m_my_flags & EC_FLAG_ZLIB`) and a packet larger |
| 793 | // than EC_MAX_UNCOMPRESSED. |
| 794 | const uint32 packet_logical_len = packet->GetPacketLength(); |
| 795 | const bool local_bypass_zlib = m_isLocalPeer |
| 796 | && packet_logical_len <= kLocalPeerZlibBypassMax; |
| 797 | if (packet_logical_len > EC_MAX_UNCOMPRESSED |
| 798 | && ((m_my_flags & EC_FLAG_ZLIB) > 0) |
| 799 | && !local_bypass_zlib) { |
| 800 | flags |= EC_FLAG_ZLIB; |
| 801 | } else { |
| 802 | flags |= EC_FLAG_UTF8_NUMBERS; |
| 803 | } |
| 804 | |
| 805 | // Always advertise large-tag-count support per packet; the |
| 806 | // `flags &= m_my_flags` strips it back out if the peer didn't |
| 807 | // advertise EC_TAG_CAN_LARGE_TAG_COUNT in the auth handshake. |
| 808 | // Both sides must have the bit in m_my_flags (i.e. negotiated) |
| 809 | // before WriteChildren / ReadChildren take the sentinel branch. |
| 810 | flags |= EC_FLAG_LARGE_TAG_COUNT; |
| 811 | |
| 812 | flags &= m_my_flags; |
| 813 | m_tx_flags = flags; |
| 814 | |
| 815 | if (flags & EC_FLAG_ZLIB) { |
| 816 | m_z.zalloc = Z_NULL; |
| 817 | m_z.zfree = Z_NULL; |
| 818 | m_z.opaque = Z_NULL; |
| 819 | m_z.avail_in = 0; |
| 820 | m_z.next_in = &m_in_ptr[0]; |
| 821 | int zerror = deflateInit(&m_z, EC_COMPRESSION_LEVEL); |
| 822 | if (zerror != Z_OK) { |
| 823 | // don't use zlib if init failed |
| 824 | flags &= ~EC_FLAG_ZLIB; |
| 825 | ShowZError(zerror, &m_z); |
| 826 | } |
| 827 | } |
nothing calls this directly
no test coverage detected