public ContainsOption ( PacketHeaderLongItems option ) : bool | ||
option | PacketHeaderLongItems | The long option to be checked. |
return | bool |
/// <summary> /// TCP - Received when a peer sends us the data portion of a chunk possibly following a request /// </summary> /// <param name="packetHeader"></param> /// <param name="connection"></param> /// <param name="incomingData"></param> 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"); } }
/// <summary> /// Returns the <see cref="SendReceiveOptions"/> to be used for the provided <see cref="PacketHeader"/>. Ensures there will not be a serializer / data processor clash for different delegate levels. /// </summary> /// <param name="header">The <see cref="PacketHeader"/> options are desired.</param> /// <returns>The requested <see cref="SendReceiveOptions"/></returns> private SendReceiveOptions IncomingPacketSendReceiveOptions(PacketHeader header) { //Are there connection specific or global packet handlers? bool connectionSpecificHandlers = false; lock (delegateLocker) connectionSpecificHandlers = incomingPacketHandlers.ContainsKey(header.PacketType); bool globalHandlers = NetworkComms.GlobalIncomingPacketHandlerExists(header.PacketType); //Get connection specific options for this packet type, if there arn't any use the connection default options SendReceiveOptions connectionSpecificOptions = PacketTypeUnwrapperOptions(header.PacketType); if (connectionSpecificOptions == null) { connectionSpecificOptions = ConnectionDefaultSendReceiveOptions; } //Get global options for this packet type, if there arn't any use the global default options SendReceiveOptions globalOptions = NetworkComms.GlobalPacketTypeUnwrapperOptions(header.PacketType); if (globalOptions == null) { globalOptions = NetworkComms.DefaultSendReceiveOptions; } if (connectionSpecificHandlers && globalHandlers) { if (!connectionSpecificOptions.OptionsCompatible(globalOptions)) { throw new PacketHandlerException("Attempted to determine correct sendReceiveOptions for packet of type '" + header.PacketType + "'. Unable to continue as connection specific and global sendReceiveOptions are not equal."); } //We need to combine options in this case using the connection specific option in preference if both are present var combinedOptions = new Dictionary <string, string>(globalOptions.Options); foreach (var pair in connectionSpecificOptions.Options) { combinedOptions[pair.Key] = pair.Value; } //If the header specifies a serializer and data processors we will autodetect those if (header.ContainsOption(PacketHeaderLongItems.SerializerProcessors)) { DataSerializer serializer; List <DataProcessor> dataProcessors; DPSManager.GetSerializerDataProcessorsFromIdentifier(header.GetOption(PacketHeaderLongItems.SerializerProcessors), out serializer, out dataProcessors); return(new SendReceiveOptions(serializer, dataProcessors, combinedOptions)); } //Otherwise we will use options that were specified return(new SendReceiveOptions(connectionSpecificOptions.DataSerializer, connectionSpecificOptions.DataProcessors, combinedOptions)); } else if (connectionSpecificHandlers) { //If the header specifies a serializer and data processors we will autodetect those if (header.ContainsOption(PacketHeaderLongItems.SerializerProcessors)) { DataSerializer serializer; List <DataProcessor> dataProcessors; DPSManager.GetSerializerDataProcessorsFromIdentifier(header.GetOption(PacketHeaderLongItems.SerializerProcessors), out serializer, out dataProcessors); return(new SendReceiveOptions(serializer, dataProcessors, connectionSpecificOptions.Options)); } return(connectionSpecificOptions); } else { //If the header specifies a serializer and data processors we will autodetect those if (header.ContainsOption(PacketHeaderLongItems.SerializerProcessors)) { DataSerializer serializer; List <DataProcessor> dataProcessors; DPSManager.GetSerializerDataProcessorsFromIdentifier(header.GetOption(PacketHeaderLongItems.SerializerProcessors), out serializer, out dataProcessors); return(new SendReceiveOptions(serializer, dataProcessors, globalOptions.Options)); } //If just globalHandlers is set (or indeed no handlers atall we just return the global options return(globalOptions); } }