| 2913 | } |
| 2914 | |
| 2915 | void CPartFile::AddClientSources(CMemFile* sources, unsigned nSourceFrom, uint8 uClientSXVersion, bool bSourceExchange2, const CUpDownClient* /*pClient*/) |
| 2916 | { |
| 2917 | // Kad reviewed |
| 2918 | |
| 2919 | if (m_stopped) { |
| 2920 | return; |
| 2921 | } |
| 2922 | |
| 2923 | uint32 nCount = 0; |
| 2924 | uint8 uPacketSXVersion = 0; |
| 2925 | if (!bSourceExchange2) { |
| 2926 | nCount = sources->ReadUInt16(); |
| 2927 | |
| 2928 | // Check if the data size matches the 'nCount' for v1 or v2 and eventually correct the source |
| 2929 | // exchange version while reading the packet data. Otherwise we could experience a higher |
| 2930 | // chance in dealing with wrong source data, userhashs and finally duplicate sources. |
| 2931 | uint32 uDataSize = sources->GetLength() - sources->GetPosition(); |
| 2932 | |
| 2933 | if ((uint32)(nCount*(4+2+4+2)) == uDataSize) { //Checks if version 1 packet is correct size |
| 2934 | if(uClientSXVersion != 1) { |
| 2935 | return; |
| 2936 | } |
| 2937 | uPacketSXVersion = 1; |
| 2938 | } else if ((uint32)(nCount*(4+2+4+2+16)) == uDataSize) { // Checks if version 2&3 packet is correct size |
| 2939 | if (uClientSXVersion == 2) { |
| 2940 | uPacketSXVersion = 2; |
| 2941 | } else if (uClientSXVersion > 2) { |
| 2942 | uPacketSXVersion = 3; |
| 2943 | } else { |
| 2944 | return; |
| 2945 | } |
| 2946 | } else if (nCount*(4+2+4+2+16+1) == uDataSize) { |
| 2947 | if (uClientSXVersion != 4 ) { |
| 2948 | return; |
| 2949 | } |
| 2950 | uPacketSXVersion = 4; |
| 2951 | } else { |
| 2952 | // If v5 inserts additional data (like v2), the above code will correctly filter those packets. |
| 2953 | // If v5 appends additional data after <count>(<Sources>)[count], we are in trouble with the |
| 2954 | // above code. Though a client which does not understand v5+ should never receive such a packet. |
| 2955 | AddDebugLogLineN(logClient, CFormat("Received invalid source exchange packet (v%u) of data size %u for %s") % uClientSXVersion % uDataSize % GetFileName()); |
| 2956 | return; |
| 2957 | } |
| 2958 | } else { |
| 2959 | // for SX2: |
| 2960 | // We only check if the version is known by us and do a quick sanitize check on known version |
| 2961 | // other then SX1, the packet will be ignored if any error appears, since it can't be a "misunderstanding" anymore |
| 2962 | if (uClientSXVersion > SOURCEEXCHANGE2_VERSION || uClientSXVersion == 0 ){ |
| 2963 | AddDebugLogLineN(logPartFile, CFormat("Invalid source exchange type version: %i") % uClientSXVersion); |
| 2964 | return; |
| 2965 | } |
| 2966 | |
| 2967 | // all known versions use the first 2 bytes as count and unknown version are already filtered above |
| 2968 | nCount = sources->ReadUInt16(); |
| 2969 | uint32 uDataSize = (uint32)(sources->GetLength() - sources->GetPosition()); |
| 2970 | bool bError = false; |
| 2971 | switch (uClientSXVersion){ |
| 2972 | case 1: |
no test coverage detected