ContainsOption() public method

Check if a long option has been set.
public ContainsOption ( PacketHeaderLongItems option ) : bool
option PacketHeaderLongItems The long option to be checked.
return bool
Exemplo n.º 1
0
        /// <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);
            }
        }