private static void IncomingChunkInterestReplyData(PacketHeader packetHeader, Connection connection, byte[] incomingData)
{
try
{
if (DFS.loggingEnabled) DFS._DFSLogger.Trace("IncomingChunkInterestReplyData from " + connection + " containing " + incomingData.Length + " bytes.");
if (connection.ConnectionInfo.ConnectionType != ConnectionType.TCP)
throw new Exception("IncomingChunkInterestReplyData should only be received using TCP.");
ChunkAvailabilityReply existingChunkAvailabilityReply = null;
try
{
lock (chunkDataCacheLocker)
{
if (!chunkDataCache.ContainsKey(connection.ConnectionInfo.NetworkIdentifier))
chunkDataCache.Add(connection.ConnectionInfo.NetworkIdentifier, new Dictionary<string, ChunkDataWrapper>());
if (!packetHeader.ContainsOption(PacketHeaderLongItems.PacketSequenceNumber))
throw new Exception("The dataSequenceNumber option appears to missing from the packetHeader. What has been changed?");
string packetIdentifier = packetHeader.PacketIdentifier;
if (packetIdentifier == null) throw new ArgumentException("The packetHeader.PacketIdentifier should not be null.");
//If we already have the info then we can finish this chunk off
if (chunkDataCache[connection.ConnectionInfo.NetworkIdentifier].ContainsKey(packetIdentifier))
{
if (chunkDataCache[connection.ConnectionInfo.NetworkIdentifier][packetIdentifier] == null)
throw new Exception("An entry existed for the desired dataSequenceNumber but the entry was null.");
else if (chunkDataCache[connection.ConnectionInfo.NetworkIdentifier][packetIdentifier].ChunkAvailabilityReply == null)
throw new Exception("An entry existed for the desired ChunkAvailabilityReply but the entry was null."+
" This exception can be thrown if the 'IncomingChunkInterestReplyData' packet handler has been added more than once.");
//The info beat the data so we handle it here
existingChunkAvailabilityReply = chunkDataCache[connection.ConnectionInfo.NetworkIdentifier][packetIdentifier].ChunkAvailabilityReply;
existingChunkAvailabilityReply.SetChunkData(incomingData);
chunkDataCache[connection.ConnectionInfo.NetworkIdentifier].Remove(packetIdentifier);
if (chunkDataCache[connection.ConnectionInfo.NetworkIdentifier].Count == 0)
chunkDataCache.Remove(connection.ConnectionInfo.NetworkIdentifier);
}
else
{
//If we don't have the info we just need to log the data
chunkDataCache[connection.ConnectionInfo.NetworkIdentifier].Add(packetIdentifier, new ChunkDataWrapper(packetIdentifier, incomingData));
if (DFS.loggingEnabled) DFS._DFSLogger.Trace("Added ChunkData to chunkDataCache from " + connection + ", packet identifier:" + packetIdentifier + " , containing " + incomingData.Length + " bytes.");
}
}
//Only true if we have both the data and info
if (existingChunkAvailabilityReply != null)
{
existingChunkAvailabilityReply.SetSourceConnectionInfo(connection.ConnectionInfo);
DistributedItem item = null;
lock (globalDFSLocker)
{
if (swarmedItemsDict.ContainsKey(existingChunkAvailabilityReply.ItemCheckSum))
item = swarmedItemsDict[existingChunkAvailabilityReply.ItemCheckSum];
}
if (item != null)
item.HandleIncomingChunkReply(existingChunkAvailabilityReply);
}
}
catch (Exception ex)
{
LogTools.LogException(ex, "Error_IncomingChunkInterestReplyDataInner");
}
CheckForChunkDataCacheTimeouts();
}
catch (Exception e)
{
LogTools.LogException(e, "Error_IncomingChunkInterestReplyData");
}
}