| 2911 | |
| 2912 | |
| 2913 | size_t SSU2Session::CreateAckBlock (uint8_t * buf, size_t len) |
| 2914 | { |
| 2915 | if (len < 8) return 0; |
| 2916 | buf[0] = eSSU2BlkAck; |
| 2917 | uint32_t ackThrough = m_OutOfSequencePackets.empty () ? m_ReceivePacketNum : *m_OutOfSequencePackets.rbegin (); |
| 2918 | htobe32buf (buf + 3, ackThrough); // Ack Through |
| 2919 | uint16_t acnt = 0; |
| 2920 | if (ackThrough) |
| 2921 | { |
| 2922 | if (m_OutOfSequencePackets.empty ()) |
| 2923 | { |
| 2924 | acnt = std::min ((int)ackThrough, SSU2_MAX_NUM_ACNT); // no gaps |
| 2925 | m_NumRanges = 0; |
| 2926 | } |
| 2927 | else |
| 2928 | { |
| 2929 | auto it = m_OutOfSequencePackets.rbegin (); it++; // prev packet num |
| 2930 | while (it != m_OutOfSequencePackets.rend () && *it == ackThrough - acnt - 1) |
| 2931 | { |
| 2932 | acnt++; |
| 2933 | if (acnt >= SSU2_MAX_NUM_ACK_PACKETS) |
| 2934 | break; |
| 2935 | else |
| 2936 | it++; |
| 2937 | } |
| 2938 | // ranges |
| 2939 | if (!m_NumRanges) |
| 2940 | { |
| 2941 | int maxNumRanges = (len - 8) >> 1; |
| 2942 | if (maxNumRanges > SSU2_MAX_NUM_ACK_RANGES) maxNumRanges = SSU2_MAX_NUM_ACK_RANGES; |
| 2943 | int numRanges = 0; |
| 2944 | uint32_t lastNum = ackThrough - acnt; |
| 2945 | if (acnt > SSU2_MAX_NUM_ACNT) |
| 2946 | { |
| 2947 | auto d = std::div (acnt - SSU2_MAX_NUM_ACNT, SSU2_MAX_NUM_ACNT); |
| 2948 | acnt = SSU2_MAX_NUM_ACNT; |
| 2949 | if (d.quot > maxNumRanges) |
| 2950 | { |
| 2951 | d.quot = maxNumRanges; |
| 2952 | d.rem = 0; |
| 2953 | } |
| 2954 | // Acks only ranges for acnt |
| 2955 | for (int i = 0; i < d.quot; i++) |
| 2956 | { |
| 2957 | m_Ranges[numRanges*2] = 0; m_Ranges[numRanges*2 + 1] = SSU2_MAX_NUM_ACNT; // NACKs 0, Acks 255 |
| 2958 | numRanges++; |
| 2959 | } |
| 2960 | if (d.rem > 0) |
| 2961 | { |
| 2962 | m_Ranges[numRanges*2] = 0; m_Ranges[numRanges*2 + 1] = d.rem; |
| 2963 | numRanges++; |
| 2964 | } |
| 2965 | } |
| 2966 | int numPackets = acnt + numRanges*SSU2_MAX_NUM_ACNT; |
| 2967 | while (it != m_OutOfSequencePackets.rend () && |
| 2968 | numRanges < maxNumRanges && numPackets < SSU2_MAX_NUM_ACK_PACKETS) |
| 2969 | { |
| 2970 | if (lastNum - (*it) > SSU2_MAX_NUM_ACNT) |
nothing calls this directly
no test coverage detected