Exemple #1
0
 private async Task Publish(EventHubClient client, QuickBlockTransferSegment segment)
 {
     try
     {
         await client.SendAsync(new EventData(segment.Content)
         {
             PartitionKey = segment.GetKey(),
             Properties =
             {
                 {nameof(segment.Header), segment.Header},
                 {nameof(segment.ReceivedAt), segment.ReceivedAt},
                 {nameof(segment.Filename), segment.Filename},
                 {nameof(segment.TimeStamp), segment.TimeStamp},
                 {nameof(segment.Checksum), segment.Checksum},
                 {nameof(segment.BlockNumber), segment.BlockNumber},
                 {nameof(segment.TotalBlocks), segment.TotalBlocks},
                 {nameof(segment.Version), segment.Version},
                 {nameof(segment.Source), segment.Source}
             }
         });
     }
     catch (Exception ex)
     {
         _log.Error(ex.ToString());
     }
 }
Exemple #2
0
        /// <summary>
        /// Parses the Quick Block Transfer V2 header.
        /// </summary>
        /// <param name="groups">The match from the regular expression parser.</param>
        /// <param name="packet">The packet to be populated.</param>
        private void ParseHeaderV2(GroupCollection groups, QuickBlockTransferSegment packet)
        {
            if (!groups["DL"].Success)
            {
                return;
            }

            packet.Version = 2;
            packet.Length  = int.Parse(groups["DL"].Value);

            if (packet.Length <= 0 || packet.Length > 1024)
            {
                throw new IndexOutOfRangeException("DL (length) value " + packet.Length + " is out of range (1-1024).");
            }
        }
Exemple #3
0
        /// <summary>
        /// Parses the Quick Block Transfer V1 header.
        /// </summary>
        /// <param name="groups">The match from the regular expression parser.</param>
        /// <param name="packet">The packet to be populated.</param>
        private static void ParseHeaderV1(GroupCollection groups, QuickBlockTransferSegment packet)
        {
            packet.Version     = 1;
            packet.Length      = QuickBlockV1BodySize;
            packet.Filename    = groups["PF"].Value;
            packet.BlockNumber = int.Parse(groups["PN"].Value);
            packet.TotalBlocks = int.Parse(groups["PT"].Value);
            packet.Checksum    = int.Parse(groups["CS"].Value);

            DateTimeOffset ts;
            var            dateText = groups["FD"].Value;

            if (DateTimeOffset.TryParseExact(dateText, HeaderDateTimeFormat, CultureInfo.InvariantCulture,
                                             DateTimeStyles.AssumeUniversal, out ts))
            {
                packet.TimeStamp = ts;
            }
            else
            {
                ByteBlasterEventSource.Log.ParserWarning("Unable to parse header date", dateText);
            }
        }
Exemple #4
0
        /// <summary>
        /// Reads and parses the packet header.
        /// </summary>
        /// <param name="input">The input.</param>
        /// <returns>QuickBlockTransferPacket.</returns>
        private QuickBlockTransferSegment ParsePacketHeader(IByteBuffer input)
        {
            var header = ReadString(input, QuickBlockHeaderSize);

            ByteBlasterEventSource.Log.HeaderReceived(header);
            var match = HeaderRegex.Match(header);

            if (match.Success)
            {
                var packet = new QuickBlockTransferSegment
                {
                    Header = header,
                    Source = _remoteAddress
                };

                ParseHeaderV1(match.Groups, packet);
                ParseHeaderV2(match.Groups, packet);

                return(packet);
            }

            throw new InvalidDataException("QuickBlockPacketDecoder Unknown header: " + header);
        }
Exemple #5
0
        /// <summary>
        /// Decodes the byte buffer and builds QuickBlockTransfer packets.
        /// </summary>
        /// <param name="context">The handler context.</param>
        /// <param name="input">The input byte buffer from the socket.</param>
        /// <param name="output">The output packets.</param>
        protected override void Decode(IChannelHandlerContext context, IByteBuffer input, List <object> output)
        {
            switch (State)
            {
            case DecoderState.ReSync:
                if (!input.IsReadable(QuickBlockV1BodySize + FrameSyncBytes))
                {
                    break;
                }
                PerformanceCounters.FrameSyncTotal.Increment();
                if (!SynchronizeFrame(input))
                {
                    break;
                }
                State = DecoderState.StartFrame;
                goto case DecoderState.StartFrame;

            case DecoderState.StartFrame:
                if (!SkipNullBytes(input))
                {
                    break;
                }
                State = DecoderState.FrameType;
                goto case DecoderState.FrameType;

            case DecoderState.FrameType:
                if (!input.IsReadable(QuickBlockHeaderSize))
                {
                    break;
                }
                if (IsDataBlockHeader(input))
                {
                    State = DecoderState.BlockHeader;
                    goto case DecoderState.BlockHeader;
                }
                if (IsServerList(input))
                {
                    PerformanceCounters.ServerListReceivedTotal.Increment();
                    State = DecoderState.ServerList;
                    goto case DecoderState.ServerList;
                }
                throw new InvalidOperationException("Unknown frame type");

            case DecoderState.ServerList:
                var content = ReadString(input);
                if (content.Length == 0)
                {
                    break;
                }
                context.FireUserEventTriggered(ParseServerList(content));
                State = DecoderState.StartFrame;
                goto case DecoderState.StartFrame;

            case DecoderState.BlockHeader:
                Packet = ParsePacketHeader(input);
                PerformanceCounters.BlocksReceivedTotal.Increment();
                if (Packet.Version == 2)
                {
                    PerformanceCounters.CompressedBlocksReceivedTotal.Increment();
                }
                State = DecoderState.BlockBody;
                goto case DecoderState.BlockBody;

            case DecoderState.BlockBody:
                if (!input.IsReadable(Packet.Length))
                {
                    break;
                }
                Packet.Content = ReadPacketBody(input, Packet.Length, Packet.Version);
                PerformanceCounters.BlocksProcessedPerSecond.Increment();
                State = DecoderState.Validate;
                goto case DecoderState.Validate;

            case DecoderState.Validate:
                if (Packet.TotalBlocks <= 0 || Packet.BlockNumber <= 0)
                {
                    PerformanceCounters.ChecksumErrorsTotal.Increment();
                    throw new InvalidDataException("Header block values out of range. " + Packet);
                }

                if (VerifyChecksum(Packet.Content, Packet.Checksum))
                {
                    ByteBlasterEventSource.Log.PacketCreated(Packet.ToString());
                    context.FireUserEventTriggered(Packet);
                }
                else
                {
                    PerformanceCounters.ChecksumErrorsTotal.Increment();
                    throw new InvalidDataException("Block Checksum failed. " + Packet);
                }

                State = DecoderState.StartFrame;
                goto case DecoderState.StartFrame;

            default:
                throw new InvalidOperationException("Unknown Decoder State: " + State);
            }
        }
        /// <summary>
        /// Reads and parses the packet header.
        /// </summary>
        /// <param name="input">The input.</param>
        /// <returns>QuickBlockTransferPacket.</returns>
        private QuickBlockTransferSegment ParsePacketHeader(IByteBuffer input)
        {
            var header = ReadString(input, QuickBlockHeaderSize);

            ByteBlasterEventSource.Log.HeaderReceived(header);
            var match = HeaderRegex.Match(header);
            if (match.Success)
            {
                var packet = new QuickBlockTransferSegment
                {
                    Header = header,
                    Source = _remoteAddress
                };

                ParseHeaderV1(match.Groups, packet);
                ParseHeaderV2(match.Groups, packet);

                return packet;
            }

            throw new InvalidDataException("QuickBlockPacketDecoder Unknown header: " + header);
        }
        /// <summary>
        /// Parses the Quick Block Transfer V2 header.
        /// </summary>
        /// <param name="groups">The match from the regular expression parser.</param>
        /// <param name="packet">The packet to be populated.</param>
        private void ParseHeaderV2(GroupCollection groups, QuickBlockTransferSegment packet)
        {
            if (!groups["DL"].Success) return;
            
            packet.Version = 2;
            packet.Length = int.Parse(groups["DL"].Value);

            if (packet.Length <= 0 || packet.Length > 1024)
                throw new IndexOutOfRangeException("DL (length) value " + packet.Length + " is out of range (1-1024).");
        }
        /// <summary>
        /// Parses the Quick Block Transfer V1 header.
        /// </summary>
        /// <param name="groups">The match from the regular expression parser.</param>
        /// <param name="packet">The packet to be populated.</param>
        private static void ParseHeaderV1(GroupCollection groups, QuickBlockTransferSegment packet)
        {
            packet.Version = 1;
            packet.Length = QuickBlockV1BodySize;
            packet.Filename = groups["PF"].Value;
            packet.BlockNumber = int.Parse(groups["PN"].Value);
            packet.TotalBlocks = int.Parse(groups["PT"].Value);
            packet.Checksum = int.Parse(groups["CS"].Value);

            DateTimeOffset ts;
            var dateText = groups["FD"].Value;
            if (DateTimeOffset.TryParseExact(dateText, HeaderDateTimeFormat, CultureInfo.InvariantCulture,
                DateTimeStyles.AssumeUniversal, out ts))
            {
                packet.TimeStamp = ts;
            }
            else
            {
                ByteBlasterEventSource.Log.ParserWarning("Unable to parse header date", dateText);
            }
        }
        /// <summary>
        /// Decodes the byte buffer and builds QuickBlockTransfer packets.
        /// </summary>
        /// <param name="context">The handler context.</param>
        /// <param name="input">The input byte buffer from the socket.</param>
        /// <param name="output">The output packets.</param>
        protected override void Decode(IChannelHandlerContext context, IByteBuffer input, List<object> output)
        {
            switch (State)
            {
                case DecoderState.ReSync:
                    if (!input.IsReadable(QuickBlockV1BodySize + FrameSyncBytes)) break;
                    PerformanceCounters.FrameSyncTotal.Increment();
                    if (!SynchronizeFrame(input)) break;
                    State = DecoderState.StartFrame;
                    goto case DecoderState.StartFrame;

                case DecoderState.StartFrame:
                    if (!SkipNullBytes(input)) break;
                    State = DecoderState.FrameType;
                    goto case DecoderState.FrameType;

                case DecoderState.FrameType:
                    if (!input.IsReadable(QuickBlockHeaderSize)) break;
                    if (IsDataBlockHeader(input))
                    {
                        State = DecoderState.BlockHeader;
                        goto case DecoderState.BlockHeader;
                    }
                    if (IsServerList(input))
                    {
                        PerformanceCounters.ServerListReceivedTotal.Increment();
                        State = DecoderState.ServerList;
                        goto case DecoderState.ServerList;
                    }
                    throw new InvalidOperationException("Unknown frame type");

                case DecoderState.ServerList:
                    var content = ReadString(input);
                    if (content.Length == 0) break;
                    context.FireUserEventTriggered(ParseServerList(content));
                    State = DecoderState.StartFrame;
                    goto case DecoderState.StartFrame;

                case DecoderState.BlockHeader:
                    Packet = ParsePacketHeader(input);
                    PerformanceCounters.BlocksReceivedTotal.Increment();
                    if (Packet.Version == 2)
                        PerformanceCounters.CompressedBlocksReceivedTotal.Increment();
                    State = DecoderState.BlockBody;
                    goto case DecoderState.BlockBody;

                case DecoderState.BlockBody:
                    if (!input.IsReadable(Packet.Length)) break;
                    Packet.Content = ReadPacketBody(input, Packet.Length, Packet.Version);
                    PerformanceCounters.BlocksProcessedPerSecond.Increment();
                    State = DecoderState.Validate;
                    goto case DecoderState.Validate;

                case DecoderState.Validate:
                    if (Packet.TotalBlocks <= 0 || Packet.BlockNumber <= 0)
                    {
                        PerformanceCounters.ChecksumErrorsTotal.Increment();
                        throw new InvalidDataException("Header block values out of range. " + Packet);
                    }

                    if (VerifyChecksum(Packet.Content, Packet.Checksum))
                    {
                        ByteBlasterEventSource.Log.PacketCreated(Packet.ToString());
                        context.FireUserEventTriggered(Packet);
                    }
                    else
                    {
                        PerformanceCounters.ChecksumErrorsTotal.Increment();
                        throw new InvalidDataException("Block Checksum failed. " + Packet);
                    }

                    State = DecoderState.StartFrame;
                    goto case DecoderState.StartFrame;

                default:
                    throw new InvalidOperationException("Unknown Decoder State: " + State);
            }
        }