示例#1
0
        public bool SetSectorData(long sector, byte[] data, byte[] hashCodeResult, Source source)
        {
            if (sector < 0)
                throw new ArgumentOutOfRangeException("sector");
            if (data == null)
                throw new ArgumentNullException("data");
            if (hashCodeResult == null)
                throw new ArgumentNullException("hashCodeResult");
            if (source == null)
                throw new ArgumentNullException("source");

            try
            {
                m_Sources.Lock();
                // 2007-06-14 T.Norad
                // set current time as last reception in this download
                m_LastReception = DateTime.Now;

                if ((m_SectorsMap[sector / 8] & (1 << (int)(sector % 8))) == 0)
                {
                    // Sicherer Hash-Vergleich ANFANG
                    byte[] hash = ComputeHashes.SHA512Compute(data);
                    byte[] hashCode = new byte[64];
                    for (int n = 0; n < 64; n++)
                        hashCode[n] = (byte)(hash[n] ^ m_FileHash[n]);
                    hashCode = ComputeHashes.SHA512Compute(hashCode);
                    hashCode = ComputeHashes.SHA512Compute(hashCode);
                    hashCode = ComputeHashes.SHA512Compute(hashCode);
                    hashCode = ComputeHashes.SHA512Compute(hashCode);
                    if (!Core.CompareByteArray(hashCode, hashCodeResult))
                    {
                        m_Logger.Log("A manipulated sector was received!");
                        return false;
                    }
                    // Sicherer Hash-Vergleich ENDE

                    // Sicherer Sektor-Vergleich ANFANG
                    if (sector != source.LastRequestedSector || m_IsHashing)
                    {
                        m_Logger.Log("An unrequested command was received!");
                        return false;
                    }
                    // Sicherer Sektor-Vergleich ENDE

                    // Filestream.Position setzen
                    m_FileStream.Position = sector * 32768;

                    int count;
                    if (m_FileStream.Position + 32768 <= m_FileSize)
                        count = 32768;
                    else
                        count = (int)(m_FileSize - m_FileStream.Position);
                    m_FileStream.Write(data, 0, count);
                    m_FileStream.Flush();
                    m_ReceivedSectors++;

                    //Update SectorsMap
                    m_SectorsMap[(int)(sector / 8)] |= (byte)(1 << (int)(sector % 8));
                    m_Downloaded += 32768;
                    source.Report79Received(sector);
                }
                else
                    return false;
                if (m_ReceivedSectors < m_Sectors)
                {
                    RList<long> sectorsToRequest = new RList<long>(m_SectorsMap.Length);
                    long sectorToRequest = -1;
                    if (!source.IsComplete)
                    {
                        bool sectorCanBeRequested = false;
                        for (int t = 0; t < 10 && !sectorCanBeRequested; t++)
                        {
                            for (long i = 0; i < m_SectorsMap.Length; i++)
                                if ((~m_SectorsMap[i] & source.SectorsMap[i]) != 0)
                                    sectorsToRequest.Add(i);
                            if (sectorsToRequest.Count > 0)
                            {
                                long d = sectorsToRequest[Randomizer.GenerateNumber(0, sectorsToRequest.Count)];
                                byte e = m_SectorsMap[d];
                                byte f = source.SectorsMap[d];
                                int g;
                                for (g = 0; g < 8; g++)
                                    if (((~e & f) & (1 << g)) != 0)
                                        break;
                                sectorToRequest = d * 8 + g;
                                sectorCanBeRequested = true;
                                foreach (Source activeSource in m_Sources.Values)
                                    if (activeSource.State == SourceState.Active && activeSource.LastRequestedSector == sectorToRequest)
                                    {
                                        sectorCanBeRequested = false;
                                        break;
                                    }
                            }
                            else
                                sectorCanBeRequested = false;
                        }
                        if (sectorToRequest != -1)
                        {
                            source.Report78Sent(sectorToRequest);
                            Core.SendCommand78(m_DownloadPeerID, source.PeerID, m_DownloadID, sectorToRequest);
                        }
                    }
                    else
                    {
                        bool sectorCanBeRequested = false;
                        for (int t = 0; t < 10 && !sectorCanBeRequested; t++)
                        {
                            for (long i = 0; i < m_SectorsMap.Length; i++)
                                if (m_SectorsMap[i] != 255)
                                    sectorsToRequest.Add(i);
                            if (sectorsToRequest.Count > 0)
                            {
                                long d = sectorsToRequest[Randomizer.GenerateNumber(0, sectorsToRequest.Count)];
                                byte e = m_SectorsMap[d];
                                int g;
                                for (g = 0; g < 8; g++)
                                    if ((e & (1 << g)) == 0)
                                        break;
                                sectorToRequest = d * 8 + g;
                                sectorCanBeRequested = true;
                                foreach (Source activeSource in m_Sources.Values)
                                    if (activeSource.State == SourceState.Active && activeSource.LastRequestedSector == sectorToRequest)
                                    {
                                        sectorCanBeRequested = false;
                                        break;
                                    }
                            }
                            else
                                sectorCanBeRequested = false;
                        }
                        if (sectorToRequest != -1)
                        {
                            source.Report78Sent(sectorToRequest);
                            Core.SendCommand78(m_DownloadPeerID, source.PeerID, m_DownloadID, sectorToRequest);
                        }
                    }
                }
                return true;
            }
            catch (Exception ex)
            {
                m_Logger.Log(ex, "An exception was thrown while writing in temporary file '{0}'!", m_TempFilePath);
                return false;
            }
            finally
            {
                m_Sources.Unlock();
            }
        }