예제 #1
0
        internal static string Bytes2StringWithLength(Stream stream)
        {
            string s = "";

            byte[] buff = HelperTools.RentBuffer(256);

            if (stream.Read(buff, 0, 4) == 4)
            {
                int length = BitConverter.ToInt32(buff, 0);
                if (stream.Read(buff, 0, length) == length)
                {
                    s = Encoding.ASCII.GetString(buff, 0, length);
                }
            }

            return(s);

            //int stringLength = BitConverter.ToInt32(_buff, _offset);
            //if (stringLength > 0 && stringLength < _buff.Length - _offset)
            //{
            //    s = Encoding.ASCII.GetString(_buff, _offset + 4, stringLength);
            //}

            //return s;
        }
예제 #2
0
        //public bool RemovePeer(string _id)
        //{
        //    if (CurrentState != State.Stoped)
        //        return false;

        //    return udpSenders.Remove(HelperTools.GetDeterministicHashCode(_id));
        //}

        /// <summary>
        /// Resets the ID Peer to its default
        /// </summary>
        /// <param name="_id">ID of the peer</param>
        /// <param name="pOriginal">Returns the default peer tha was present in the file</param>
        /// <returns></returns>
        public bool RemoveReplayAddress(string _id, out PlayPeerInfo pOriginal)
        {
            pOriginal = null;

            if (CurrentState != State.Stoped)
            {
                return(false);
            }

            int hashedID = HelperTools.GetDeterministicHashCode(_id);

            if (udpSenders.TryGetValue(hashedID, out PlayPeerInfo p))
            {
                var original = udpSendersOriginal[hashedID];

                p.IP   = original.IP;
                p.Port = original.Port;
                p.NIC  = original.NIC;

                pOriginal = original;

                return(true);
            }

            return(false);
        }
예제 #3
0
        internal static ulong IPPort2Long(string _ip, int _port)
        {
            byte[] _buffer = new byte[8];

            ushort[] ipChunks = new ushort[4];
            string[] chunks   = _ip.Split('.');
            if (chunks.Length == 4)
            {
                for (int i = 0; i < 4; i++)
                {
                    ipChunks[i] = ushort.Parse(chunks[i]);
                }
            }

            // IP 4
            for (int i = 0; i < 4; i++)
            {
                _buffer[i] = (byte)ipChunks[i];
            }

            // Port 4
            HelperTools.Int32Bytes(_buffer, 4, _port);

            return(BitConverter.ToUInt64(_buffer, 0));
        }
예제 #4
0
        /// <summary>
        /// Enables or disables a given peer by ID
        /// </summary>
        /// <param name="_id">ID of the peer</param>
        /// <param name="enabled">Enable if true, disable if false</param>
        public void SetPeerEnabled(string _id, bool enabled)
        {
            int hashedID = HelperTools.GetDeterministicHashCode(_id);

            if (udpSenders.TryGetValue(hashedID, out PlayPeerInfo p))
            {
                p.IsEnabled = enabled;
            }
        }
예제 #5
0
        private void WriteHeader(long _time, string _ID, int _size, uint _ip, int _port)
        {
            Span <byte> headerSpan = stackalloc byte[HelperTools.headerSize];

            // Time 8
            BinaryPrimitives.WriteInt64LittleEndian(headerSpan, _time);
            // Hashed ID 4
            BinaryPrimitives.WriteInt32LittleEndian(headerSpan.Slice(8), HelperTools.GetDeterministicHashCode(_ID));
            // IP 4
            BinaryPrimitives.WriteUInt32LittleEndian(headerSpan.Slice(12), _ip);
            // Port 4
            BinaryPrimitives.WriteInt32LittleEndian(headerSpan.Slice(16), _port);
            // Size 4
            BinaryPrimitives.WriteInt32LittleEndian(headerSpan.Slice(20), _size);

            // Write
            file.Write(headerSpan);
        }
예제 #6
0
        /// <summary>
        /// Retrieves information from the recording idx file
        /// </summary>
        /// <param name="_idxFilePath"></param>
        /// <returns>Peers, recording date and time, duration in secs, recording size in bytes</returns>
        public static (ICollection <PlayPeerInfo>, DateTime, int, long) GetRecordingInfo(string _idxFilePath)
        {
            int                 duration        = 0;
            int                 nPeers          = 0;
            int                 secsIdxInterval = 0;
            DateTime            date            = DateTime.MinValue;
            List <PlayPeerInfo> peers           = new List <PlayPeerInfo>();

            using (FileStream idxFile = new FileStream(_idxFilePath, FileMode.Open, FileAccess.Read))
                using (BinaryReader idxBinaryReader = new BinaryReader(idxFile))
                {
                    Span <byte> auxBuff = stackalloc byte[1024];

                    // Read DateTime, Secs Interval and Peers info
                    date            = HelperTools.fromMillis(idxBinaryReader.ReadInt64());
                    secsIdxInterval = idxBinaryReader.ReadInt32();
                    nPeers          = idxBinaryReader.ReadInt32();

                    // Read peers
                    for (int i = 0; i < nPeers; i++)
                    {
                        string ID   = HelperTools.Bytes2StringWithLength(idxFile);
                        string IP   = HelperTools.Bytes2StringWithLength(idxFile);
                        int    Port = idxBinaryReader.ReadInt32();

                        peers.Add(new PlayPeerInfo
                        {
                            ID   = ID,
                            IP   = IP,
                            Port = Port
                        });
                    }

                    // Guess duration
                    FileInfo fInfo = new FileInfo(_idxFilePath);
                    duration = ((int)((fInfo.Length - idxBinaryReader.BaseStream.Position) / HelperTools.idxIndexSize)) * secsIdxInterval;
                }

            string   rawFile = Path.Combine(Path.GetDirectoryName(_idxFilePath), Path.GetFileNameWithoutExtension(_idxFilePath)) + ".raw";
            FileInfo fRaw    = new FileInfo(rawFile);

            return(peers, date, duration, fRaw.Length);
        }
예제 #7
0
        /// <summary>
        /// Override the default destination ip of a recorded peer with a given one.
        /// </summary>
        /// <param name="_ID">ID of the peer</param>
        /// <param name="_dstIP">New destination IP</param>
        /// <param name="_dstPort">New destination Port</param>
        /// <param name="_nic">NIC to send data from</param>
        /// <returns></returns>
        public bool AddReplayAddress(string _ID, string _dstIP, int _dstPort, string _nic)
        {
            if (CurrentState != State.Stoped)
            {
                return(false);
            }

            int hashedID = HelperTools.GetDeterministicHashCode(_ID);

            if (udpSenders.TryGetValue(hashedID, out PlayPeerInfo p))
            {
                p.IP   = _dstIP;
                p.Port = _dstPort;
                p.NIC  = _nic;

                return(true);
            }

            return(false);
        }
예제 #8
0
        private void FillIDXHeader(FileStream _idxFile)
        {
            Span <byte> idxHeader = stackalloc byte[4096];

            // Time of recording
            BinaryPrimitives.WriteInt64LittleEndian(idxHeader, HelperTools.millisFromEpochNow());
            // Interval
            BinaryPrimitives.WriteInt32LittleEndian(idxHeader.Slice(8), secsIdxInterval);
            // Number of peers
            BinaryPrimitives.WriteInt32LittleEndian(idxHeader.Slice(12), socketListeners.Count);
            // Peer info
            int nBytes = 16;

            foreach (RecPeerInfo p in socketListeners.Values)
            {
                nBytes += HelperTools.StringWithLength2Bytes(idxHeader.Slice(nBytes), p.ID);
                nBytes += HelperTools.StringWithLength2Bytes(idxHeader.Slice(nBytes), p.IP);
                BinaryPrimitives.WriteInt32LittleEndian(idxHeader.Slice(nBytes), p.Port); nBytes += 4;
            }

            idxFile.Write(idxHeader.Slice(0, nBytes));
        }
예제 #9
0
        private void RunReaderSenderProcessCallback(string _filePath, string _idxFilePath, CancellationToken token)
        {
            ulong ip;
            int   n_bytes = 0, size = 0;
            int   hashedID = 0;
            long  timeoffset = 0, waitTime = 0, nowTime = 0, time = 0;
            int   lastTimeStatusS = 0, timeStatusS = 0;

            // Increase timers resolution
            WinAPI.WinAPITime.TimeBeginPeriod(1);

            // Open file
            using (FileStream file = new FileStream(filePath, FileMode.Open, FileAccess.Read))
            {
                if (has2UpdatePosition)
                {
                    file.Seek(newPosition, SeekOrigin.Begin);
                    has2UpdatePosition      = false;
                    resetTimeOffsetRequired = true;
                }

                while (!token.IsCancellationRequested)
                {
                    // Paused
                    if (CurrentState == State.Paused)
                    {
                        Thread.Sleep(500);
                    }
                    else
                    {
                        if ((n_bytes = file.Read(buffer, 0, HelperTools.headerSize)) == HelperTools.headerSize)
                        {
                            // Get fields
                            replayTime = time = BitConverter.ToInt64(buffer, 0);
                            hashedID   = BitConverter.ToInt32(buffer, 8);
                            ip         = BitConverter.ToUInt64(buffer, 12);
                            size       = BitConverter.ToInt32(buffer, 20);

                            // Update time in secs
                            timeStatusS = (int)(replayTime / 1000_000);

                            // Read Payload
                            n_bytes = file.Read(buffer, 0, size);

                            nowTime = HelperTools.GetLocalMicrosTime();

                            if (resetTimeOffsetRequired)
                            {
                                timeoffset = nowTime - time;
                                waitTime   = 0;
                                resetTimeOffsetRequired = false;
                            }
                            else
                            {
                                nowTime -= timeoffset;
                                waitTime = time - nowTime;
                                if (waitTime > 1000) // 1ms
                                {
                                    Thread.Sleep((int)(waitTime / 1000));
                                }
                            }

                            // Send
                            Send(hashedID, buffer, 0, n_bytes);

                            // Update Progress
                            if (timeStatusS != lastTimeStatusS)
                            {
                                ProgressEvent?.Invoke(timeStatusS);
                                lastTimeStatusS = timeStatusS;
                            }

                            if (has2UpdatePosition)
                            {
                                file.Seek(newPosition, SeekOrigin.Begin);
                                has2UpdatePosition      = false;
                                resetTimeOffsetRequired = true;
                            }
                        }
                        else
                        {
                            // End of File
                            cancelSource.Cancel();
                            // Update Stop Status
                            CurrentState = State.Stoped;
                            StatusEvent?.Invoke(CurrentState);
                            foreach (var k in _dataRate.Keys.ToList())
                            {
                                _dataRate[k] = 0;
                            }
                            DataRateEvent?.Invoke(_dataRate);
                            // rewind
                            Seek(0);
                            eventTimer.Dispose();
                            eventTimer = null;
                            ProgressEvent?.Invoke(0);
                        }
                    }
                }
            }
            WinAPI.WinAPITime.TimeEndPeriod(1);
        }
예제 #10
0
        /// <summary>
        /// Load a recording file
        /// </summary>
        /// <param name="_filePath">Raw file path</param>
        /// <param name="_startTime">out Start date and time</param>
        /// <param name="_lastTime">out Last time in recording</param>
        /// <returns>Collection of peers recorded in the file</returns>
        public ICollection <PlayPeerInfo> LoadFile(string _filePath, out DateTime _startTime, out int _lastTime)
        {
            if (CurrentState != State.Stoped)
            {
                throw new InvalidOperationException("Playing in progress. Must stop to load file");
            }

            filePath    = _filePath;
            idxFilePath = Path.Combine(Path.GetDirectoryName(filePath), Path.GetFileNameWithoutExtension(filePath)) + ".idx";

            // Init stuff
            _lastTime  = 0;
            _startTime = DateTime.MinValue;
            timeIndexes.Clear();
            int nPeers = 0;

            udpSendersOriginal.Clear();
            udpSenders.Clear();
            _dataRate.Clear();

            using (FileStream idxFile = new FileStream(idxFilePath, FileMode.Open, FileAccess.Read))
                using (BinaryReader idxBinaryReader = new BinaryReader(idxFile))
                {
                    int         time = 0; long position = 0;
                    Span <byte> auxBuff = stackalloc byte[4096];

                    // Read DateTime, Secs Interval and Peers info
                    RecDateTime     = _startTime = HelperTools.fromMillis(idxBinaryReader.ReadInt64());
                    secsIdxInterval = idxBinaryReader.ReadInt32();
                    nPeers          = idxBinaryReader.ReadInt32();

                    // Read peers
                    for (int i = 0; i < nPeers; i++)
                    {
                        string ID   = HelperTools.Bytes2StringWithLength(idxFile);
                        string IP   = HelperTools.Bytes2StringWithLength(idxFile);
                        int    Port = idxBinaryReader.ReadInt32();

                        udpSenders.Add(HelperTools.GetDeterministicHashCode(ID),
                                       new PlayPeerInfo
                        {
                            ID   = ID,
                            IP   = IP,
                            Port = Port
                        });

                        udpSendersOriginal.Add(HelperTools.GetDeterministicHashCode(ID),
                                               new PlayPeerInfo
                        {
                            ID   = ID,
                            IP   = IP,
                            Port = Port
                        });

                        _dataRate[ID] = 0f;
                    }

                    Span <byte> timeBuff = stackalloc byte[HelperTools.idxIndexSize];
                    // Get All times to cache
                    while (idxFile.Read(timeBuff) == HelperTools.idxIndexSize)
                    {
                        time     = BinaryPrimitives.ReadInt32LittleEndian(timeBuff);
                        position = BinaryPrimitives.ReadInt64LittleEndian(timeBuff.Slice(4));

                        try
                        {
                            timeIndexes.Add(time, position);
                        }
                        catch (Exception e)
                        {
                            logger.Error(e, "Error reading idx file. TimeIndexes");
                        }
                    }
                    _lastTime = lastTime = time;
                }
            return(udpSenders.Values);
        }