Пример #1
0
        /// <summary>
        /// Handles the deletion of a chunk of the file
        /// </summary>
        /// <param name="currentFileChunk">The P2PChunk to be deleted</param>
        /// <param name="currentFile">The P2PFile to wich the chunk belongs</param>
        /// <returns></returns>
        public bool ChunkDeleter(P2PChunk currentFileChunk, P2PFile currentFile){
            Listener listener = new Listener(this._port);

            int lastIndex = currentFileChunk.peers.Count - 1;
            //Sends a delete message to every peer with the chunk
            for (int i = lastIndex; i >= 0; i--) {
                if (_peers.TryGetValue(currentFileChunk.peers[i], out Peer currentReceiver)) {
                    if (!currentReceiver.IsOnline()){
                        return false;
                    }
                    var deletionMessage = new FileDeletionMessage(currentReceiver) {
                        type = TypeCode.REQUEST,
                        statusCode = StatusCode.OK,
                        port = _port,
                        fileHash = currentFileChunk.hash,
                        fullFileHash = currentFile.hash
                    };

                    //Sends the message and waits for a response,
                    //which will then overwrite the original sent message
                    if (listener.SendAndAwaitResponse(ref deletionMessage, 2000)) {
                        if (deletionMessage.type.Equals(TypeCode.RESPONSE)) {
                            currentFileChunk.RemovePeer(deletionMessage.fromUuid);
                            if (currentFileChunk.peers.Count == 0) {
                                currentFile.RemoveChunk(currentFileChunk.hash);
                            }
                            if (deletionMessage.statusCode.Equals(StatusCode.FILE_NOT_FOUND)) {
                                DiskHelper.ConsoleWrite("File not found at peer");
                            }
                        }
                    }
                }
            }
            return true;
        }
Пример #2
0
        /// <summary>
        /// Function to receive a deletion request of files on the receiver's computer
        /// </summary>
        /// <param name="message">The message with the chunks which has to be deleted</param>
        private void ReceivedDeletionRequest(FileDeletionMessage message)
        {
            DiskHelper.ConsoleWrite("Deletion Message Received.");
            if (!message.type.Equals(TypeCode.REQUEST))
            {
                return;
            }
            if (!message.statusCode.Equals(StatusCode.OK))
            {
                return;
            }
            string path = _path + @".hidden\" + message.fromUuid + @"\" + message.fullFileHash + @"\" +
                          message.fileHash;

            DiskHelper.ConsoleWrite(path);
            if (File.Exists(path))
            {
                File.Delete(path);
                message.statusCode = StatusCode.ACCEPTED;
                message.CreateReply();
                message.Send(message.port);
            }
            else
            {
                message.statusCode = StatusCode.FILE_NOT_FOUND;
                message.CreateReply();
                message.Send(message.port);
            }
        }
Пример #3
0
 /// <summary>
 /// Function to receive download message
 /// </summary>
 /// <param name="downloadMessage">The message which has to be received</param>
 private void ReceivedDownloadMessage(DownloadMessage downloadMessage)
 {
     if (downloadMessage.type.Equals(TypeCode.REQUEST))
     {
         string path = _path + @".hidden\" + downloadMessage.fromUuid + @"\" +
                       downloadMessage.fullFileName + @"\" + downloadMessage.filehash;
         if (downloadMessage.statusCode == StatusCode.OK)
         {
             if (File.Exists(path))
             {
                 downloadMessage.CreateReply();
                 downloadMessage.statusCode = StatusCode.ACCEPTED;
                 downloadMessage.Send(downloadMessage.port);
                 Console.WriteLine("Response send");
             }
             else
             {
                 Console.WriteLine("File not found");
                 downloadMessage.CreateReply();
                 downloadMessage.statusCode = StatusCode.FILE_NOT_FOUND;
                 downloadMessage.Send(downloadMessage.port);
             }
         }
         else if (downloadMessage.statusCode.Equals(StatusCode.ACCEPTED))
         {
             var sender = new ChunkSender(downloadMessage.fromIp, downloadMessage.port);
             sender.Send(path);
             DiskHelper.ConsoleWrite("File send " + downloadMessage.filehash);
         }
     }
 }
Пример #4
0
        /// <summary>
        /// This is a helper function for the fetching function, this is responsible for downloading the chunk.
        /// </summary>
        /// <param name="fullFileName">Full name of the file.</param>
        /// <param name="port">Port for which to download from.</param>
        private bool Downloader(string fullFileName, int port)
        {
            int timeout        = 3000;
            int timeoutCounter = 0;
            var server         = new TcpListener(this._ip, port);

            try{
                server.AllowNatTraversal(true);
                server.Server.ReceiveTimeout = 1000;
                server.Server.SendTimeout    = 1000;
                server.Start();
            }catch (Exception e) {
                Logger.Error(e);
                return(false);
            }

            while (!server.Pending())
            {
                if (timeoutCounter >= timeout)
                {
                    server.Stop();
                    return(false);
                }
                timeoutCounter++;
                Thread.Sleep(5);
            }

            try
            {
                var client = server.AcceptTcpClient();
                client.ReceiveTimeout        = 1000;
                client.Client.ReceiveTimeout = 1000;

                using (NetworkStream stream = client.GetStream()){
                    using (var fileStream = File.Open(_path + fullFileName + @"\" + _hash,
                                                      FileMode.OpenOrCreate, FileAccess.Write)){
                        DiskHelper.ConsoleWrite("Creating file: " + this._hash);

                        int i;
                        while ((i = stream.Read(_buffer, 0, _buffer.Length)) > 0)
                        {
                            fileStream.Write(_buffer, 0, (i < _buffer.Length) ? i : _buffer.Length);
                        }


                        fileStream.Close();
                    }

                    stream.Close();
                    _ports.Release(port);
                    return(true);
                }
            }
            catch (Exception e) {
                DiskHelper.ConsoleWrite("The peer requested went offline in Downloader." + e);
                return(false);
            }
        }
Пример #5
0
        /// <summary>
        /// Function to receive peers from one or your peers peer list
        /// </summary>
        /// <param name="message">It is the message which is sent to the receiver</param>
        private void ReceivedPeerFetch(PeerFetcherMessage message)
        {
            if (message.type.Equals(TypeCode.REQUEST))
            {
                var outgoing = new List <Peer>();
                var incoming = message.peers;
                // Adding sender to list
                if (!InPeerList(message.fromUuid, _peers))
                {
                    _peers.TryAdd(message.fromUuid, new Peer(message.fromUuid, message.fromIp));
                }

                //Checks whether a incomming peer exists in the peerlist.
                foreach (var incomingPeer in incoming)
                {
                    if (InPeerList(incomingPeer.GetUuid(), _peers))
                    {
                        break;
                    }
                    _peers.TryAdd(incomingPeer.GetUuid(), incomingPeer);
                    DiskHelper.ConsoleWrite("Peer added: " + incomingPeer.GetUuid());
                }

                foreach (var outGoingPeer in _peers)
                {
                    if (InPeerList(outGoingPeer.Value.GetUuid(), incoming))
                    {
                        break;
                    }
                    if (outGoingPeer.Value.GetUuid() == message.fromUuid)
                    {
                        break;
                    }
                    outgoing.Add(outGoingPeer.Value);
                }

                message.CreateReply();
                message.peers = outgoing;
                message.Send();
            }
            else
            {
                // Rechieved response
                foreach (Peer incomingPeer in message.peers)
                {
                    if (InPeerList(incomingPeer.GetUuid(), _peers))
                    {
                        break;
                    }
                    if ((IdHandler.GetUuid().Equals(incomingPeer.GetUuid())))
                    {
                        break;
                    }
                    _peers.TryAdd(incomingPeer.GetUuid(), incomingPeer);
                    Console.WriteLine("Peer added: " + incomingPeer.GetUuid());
                }
            }
        }
Пример #6
0
        private void RestoreOriginalFile(string path, P2PFile fileInformation)
        {
            DiskHelper.ConsoleWrite("File exist");

            string pathWithoutExtension = (_path + @".hidden\incoming\" + fileInformation.hash);

            //Merge files
            var splitterLibrary = new SplitterLibrary();


            if (!splitterLibrary.MergeFiles(_path + @".hidden\incoming\" + fileInformation.hash + @"\",
                                            pathWithoutExtension + ".aes",
                                            fileInformation.GetChunksAsString()))
            {
                _queue.Enqueue(fileInformation);
                return;
            }

            // Decrypt file
            var decryption = new FileEncryption(pathWithoutExtension, ".lzma");

            if (!decryption.DoDecrypt(IdHandler.GetKeyMold()))
            {
                _queue.Enqueue(fileInformation);
                return;
            }

            DiskHelper.ConsoleWrite("File decrypted");

            File.Delete(path);

            // Decompress file
            string pathToFileForCopying =
                Compressor.DecompressFile(pathWithoutExtension + ".lzma", pathWithoutExtension);


            DiskHelper.ConsoleWrite("File decompressed");

            foreach (string filePath in _index.GetEntry(_fileHash).paths)
            {
                if (!Directory.Exists(Path.GetDirectoryName(filePath)))
                {
                    Directory.CreateDirectory(Path.GetDirectoryName(filePath) ?? throw new NullReferenceException());
                }

                try{
                    if (!File.Exists(filePath))
                    {
                        File.Copy(pathToFileForCopying, filePath);
                        DiskHelper.ConsoleWrite($"File saved to: {filePath}");
                    }
                }
                catch (Exception e) {
                    logger.Error(e);
                }
            }
        }
Пример #7
0
        /// <summary>
        /// Pushes the inputted chunk to the network, sending it the required amount of peers.
        /// </summary>
        /// <param name="chunk">The chunk to push to the network</param>
        /// <param name="chunkPath">String path to the chunks</param>
        /// <param name="numberOfRecevingPeers">The number of peers to send the file to,
        /// this will be the amount of receivers, unless the network is smaller than the given input.</param>
        /// <param name="receiverOffset">The offset for whom to send the files to, this determines the spacing of the chunks on the peerlist.</param>
        /// <returns>Boolean of whether the push was a success.</returns>
        public bool Push(P2PChunk chunk, string chunkPath, int numberOfRecevingPeers = 10, int receiverOffset = 0)
        {
            this._port = _ports.GetAvailablePort();
            List <Peer> peers      = this.GetPeers();
            FileInfo    fileInfo   = new FileInfo(chunkPath);
            Listener    listener   = new Listener(this._port);
            bool        sendToAll  = true;
            int         listLength = peers.Count;
            int         peerCount;
            int         numberOfReceivers = Math.Min(numberOfRecevingPeers, listLength);

            for (peerCount = 0; peerCount < numberOfReceivers; peerCount++)
            {
                Peer currentPeer = peers[(peerCount + receiverOffset) % listLength];
                var  upload      = new UploadMessage(currentPeer)
                {
                    filesize     = fileInfo.Length,
                    fullFilename = chunk.originalHash,
                    chunkHash    = chunk.hash,
                    path         = chunkPath,
                    port         = this._port
                };

                if (listener.SendAndAwaitResponse(ref upload, 2000))
                {
                    if (upload.statusCode == StatusCode.ACCEPTED)
                    {
                        ChunkSender sender = new ChunkSender(currentPeer.StringIp, upload.port);

                        if (sender.Send(chunkPath))
                        {
                            DiskHelper.ConsoleWrite($"The chunk {chunk.hash} was sent to {currentPeer.GetUuid()}");
                            chunk.AddPeer(currentPeer.GetUuid());
                        }
                        else
                        {
                            sendToAll = false;
                        }
                        _ports.Release(upload.port);
                    }
                }
            }

            _ports.Release(this._port);
            return(sendToAll);
        }
Пример #8
0
 /// <summary>
 /// Toggles whether a peer is online.
 /// </summary>
 /// <param name="online">Boolean of whether the peer got online, or offline.</param>
 public void SetOnline(bool online)
 {
     if (online != this._online)
     {
         if (online)
         {
             DiskHelper.ConsoleWrite(this._ip + " - is now online!");
             rankHandler.UpdateUptime(this);
             PeerSwitchedOnline?.Invoke();
         }
         else
         {
             DiskHelper.ConsoleWrite(this._ip + " - is now offline!");
             rankHandler.UpdateUptime(this);
         }
     }
     this._online = online;
     this._pingsWithoutResponse = 0;
 }
Пример #9
0
        /// <summary>
        /// Handles the connection, creates and downloads the file.
        /// </summary>
        private void ConnectionHandler()
        {
            string path = this._path + this._filename;

            try{
                var client = _server.AcceptTcpClient();
                client.ReceiveTimeout = 5000;

                using (NetworkStream stream = client.GetStream()){
                    DiskHelper.ConsoleWrite(@"Receiving file");

                    using (var fileStream = File.Open(path, FileMode.OpenOrCreate, FileAccess.Write)){
                        DiskHelper.ConsoleWrite("Creating file: " + this._filename);
                        int i;

                        while ((i = stream.Read(_buffer, 0, _buffer.Length)) > 0)
                        {
                            fileStream.Write(_buffer, 0, (i < _buffer.Length) ? i : _buffer.Length);
                        }

                        DiskHelper.ConsoleWrite(@"File done downloading");
                        fileStream.Close();
                    }

                    stream.Close();
                }

                client.Close();
            }
            catch (InvalidOperationException e) {
                logger.Fatal(e);
            }
            catch (Exception e) {
                logger.Error(e);
            }
            finally{
                Stop();
            }
        }
Пример #10
0
        /// <summary>
        /// Fetching function, this fetches the given chunk from the network, returns true if the chunk is fetched.
        /// </summary>
        /// <param name="chunk">The chunk wanted to download.</param>
        /// <param name="fullFileName">The name of the full file.</param>
        /// <returns>Rather the chunk has been fetched.</returns>
        public bool Fetch(P2PChunk chunk, string fullFileName)
        {
            _port       = _ports.GetAvailablePort();
            _hash       = chunk.hash;
            _peersToAsk = chunk.peers;
            Listener listener = new Listener(this._port);

            foreach (var peer in _peersToAsk)
            {
                if (!_peers.TryGetValue(peer, out Peer currentPeer))
                {
                    break;
                }

                if (currentPeer.IsOnline())
                {
                    var download = new DownloadMessage(currentPeer)
                    {
                        port         = this._port,
                        fullFileName = chunk.originalHash,
                        filehash     = _hash
                    };

                    // Sends the download message and waits for a
                    // "response" download message to be received.
                    // Then changed 'download' to this message and
                    // returns true. If a response is not received
                    // within time, it returns false.
                    if (listener.SendAndAwaitResponse(ref download, 3000))
                    {
                        // If the download is accepted, a receiver is
                        // started and the port of the receiver is
                        // sent to the peer.
                        if (download.statusCode == StatusCode.ACCEPTED)
                        {
                            int receiverPort = _ports.GetAvailablePort();
                            download.CreateReply();
                            download.type       = Messages.TypeCode.REQUEST;
                            download.statusCode = StatusCode.ACCEPTED;
                            download.port       = receiverPort;

                            if (!Directory.Exists(_path + fullFileName + @"\"))
                            {
                                Directory.CreateDirectory(_path + fullFileName + @"\");
                            }

                            download.Send();

                            if (!currentPeer.IsOnline())
                            {
                                DiskHelper.ConsoleWrite("The peer requested went offline.");
                                continue;
                            }
                            DiskHelper.ConsoleWrite("FileReceiver opened");
                            if (!Downloader(fullFileName, receiverPort))
                            {
                                return(false);
                            }

                            _ports.Release(download.port);
                            break;
                        }
                        else if (download.statusCode == StatusCode.FILE_NOT_FOUND)
                        {
                            Console.WriteLine("File not found at peer.");
                            chunk.peers.Remove(download.fromUuid);
                        }
                    }
                }
            }

            if (File.Exists(_path + fullFileName + @"\" + _hash))
            {
                if (CheckDownloadHash(_path + fullFileName + @"\" + _hash, _hash))
                {
                    DiskHelper.ConsoleWrite(@"Chunk done downloading");
                    return(true);
                }
            }

            return(false);
        }
Пример #11
0
        /// <summary>
        /// Main running function for UploadManager, needs to be called for it to run.
        /// </summary>
        public void Run()
        {
            _isStopped = false;
            this._waitHandle.Set();

            while (_isRunning)
            {
                this._waitHandle.WaitOne();

                if (!_isRunning)
                {
                    break;
                }

                while (this._queue.TryDequeue(out P2PFile file))
                {
                    bool uploaded = true;

                    if (!_peers.Any(p => p.Value.IsOnline()))
                    {
                        this._queue.Enqueue(file);
                        break;
                    }



                    if (!_isRunning)
                    {
                        this._queue.Enqueue(file);
                        break;
                    }

                    string filePath           = file.paths[0];
                    string compressedFilePath = this._path + @".hidden\" + file.hash;

                    // Compress file
                    bool compressionCompleted = Compressor.CompressFile(filePath, compressedFilePath);

                    if (!compressionCompleted)
                    {
                        this._queue.Enqueue(file);
                        continue;
                    }

                    // Encrypt file
                    var encryption = new FileEncryption(compressedFilePath, ".lzma");

                    bool encryptionCompleted = encryption.DoEncrypt(IdHandler.GetKeyMold());

                    if (!encryptionCompleted)
                    {
                        this._queue.Enqueue(file);
                        continue;
                    }

                    _hiddenFolder.Remove(compressedFilePath + ".lzma");

                    string encryptedFilePath = compressedFilePath + ".aes";

                    // Initialize splitter
                    var splitter = new SplitterLibrary();

                    List <string> chunks =
                        splitter.SplitFile(encryptedFilePath, file.hash, _path + @".hidden\splitter\");
                    file.AddChunk(chunks);

                    FileUploader uploader = new FileUploader(_ports, _peers);

                    int i = 0;
                    foreach (var chunk in file.chunks)
                    {
                        string path = _path + @".hidden\splitter\" + chunk.hash;

                        //3 is used, because the network is relatively small. 10 is the default.
                        if (!uploader.Push(chunk, path, 3, i))
                        {
                            uploaded = false;
                        }
                        i++;
                    }

                    if (!uploaded)
                    {
                        this._queue.Enqueue(file);
                    }

                    if (uploaded)
                    {
                        Console.WriteLine();
                        DiskHelper.ConsoleWrite($"The file {file.hash} was successfully sent to all \n");
                    }
                }

                this._waitHandle.Reset();
            }

            _isStopped = true;
        }
Пример #12
0
        static void Main()
        {
            bool   running  = true;
            bool   firstRun = true;
            MyForm torPdos  = new MyForm();

            //If the ''Path'' variable is not set, the GUI is run to set this up.
            if (string.IsNullOrEmpty(DiskHelper.GetRegistryValue("Path")))
            {
                Application.Run(torPdos);
            }
            //If the ''Path'' variable is set, but the userdata file does not exist,
            //the GUI is run to create this.
            else if (File.Exists(DiskHelper.GetRegistryValue("Path") + @".hidden\userdata") == false)
            {
                Application.Run(torPdos);
            }

            //Gets the local IP and the path to the users TorPDos-folder.
            string ownIp = NetworkHelper.GetLocalIpAddress();
            string path  = (DiskHelper.GetRegistryValue("Path"));

            //Starts the communication with the user, and ensures that
            //the user logs in.
            DiskHelper.ConsoleWrite("Welcome to TorPdos!");
            Console.WriteLine(@"Please login by typing: login [PASSWORD] or gui");
            while (running)
            {
                string console = Console.ReadLine();
                if (console != null)
                {
                    string[] param = console.Split(' ');
                    //Close program
                    if (console.Equals("quit") || console.Equals("q"))
                    {
                        Console.WriteLine(@"Quitting...");
                        _idx.Save();
                        _idx.Stop();
                        _p2P.SavePeer();
                        _p2P.Stop();
                        running = false;
                        Console.WriteLine(" \n Press any button to quit!");
                    }
                    else
                    {
                        //Handles the login of the user through the console.
                        while (IdHandler.GetUuid() == null)
                        {
                            if (console.StartsWith("login") && param.Length == 2)
                            {
                                if (IdHandler.GetUuid(param[1]) == "Invalid Password")
                                {
                                    Console.WriteLine();
                                    Console.WriteLine(@"Invalid password, try again");
                                    Console.WriteLine(@"Please login by typing: login [PASSWORD] or gui");
                                    console = Console.ReadLine();
                                    if (console != null)
                                    {
                                        param = console.Split(' ');
                                    }
                                }

                                //Gives the opportunity to open the GUI for login.
                            }
                            else if (console.Equals("gui"))
                            {
                                Application.Run(torPdos);
                            }
                            else
                            {
                                Console.WriteLine();
                                Console.WriteLine(@"Error! Try again");
                                Console.WriteLine(@"Please login by typing: login [PASSWORD] or gui");
                                console = Console.ReadLine();
                                param   = console.Split(' ');
                            }
                        }

                        //Handles the creation or loading of all the necessary
                        //files and directories.
                        if (firstRun)
                        {
                            // Load Index
                            if (!Directory.Exists(path))
                            {
                                Directory.CreateDirectory(path);
                            }

                            _idx         = new Index(path);
                            torPdos._idx = _idx;

                            // Prepare P2PNetwork
                            try{
                                _p2P = new Network(25565, _idx, path);
                                _p2P.Start();
                                torPdos._p2P = _p2P;
                            }
                            catch (SocketException) {
                                Application.Run(torPdos);
                            }

                            _idx.Load();
                            _idx.FileAdded   += Idx_FileAdded;
                            _idx.FileChanged += Idx_FileChanged;
                            _idx.FileDeleted += Idx_FileDeleted;
                            _idx.FileMissing += Idx_FileMissing;

                            if (!_idx.Load())
                            {
                                _idx.BuildIndex();
                            }

                            _idx.Start();

                            Console.WriteLine(@"Integrity check initialized...");
                            _idx.MakeIntegrityCheck();
                            Console.WriteLine(@"Integrity check finished!");

                            Console.WriteLine(@"Local: " + ownIp);
                            Console.WriteLine(@"Free space on C: " + DiskHelper.GetTotalAvailableSpace("C:\\"));
                            Console.WriteLine(@"UUID: " + IdHandler.GetUuid());
                            firstRun = false;

                            //Restart loop to take input
                            continue;
                        }

                        // Handle input
                        if (console.StartsWith("add") && param.Length == 3)
                        {
                            _p2P.AddPeer(param[1].Trim(), param[2].Trim());
                        }
                        else if (console.Equals("reindex"))
                        {
                            _idx.ReIndex();
                        }
                        else if (console.Equals("gui"))
                        {
                            MyForm torPdos2 = new MyForm();
                            Application.Run(torPdos2);
                        }
                        else if (console.Equals("status"))
                        {
                            _idx.Status();
                        }
                        else if (console.Equals("idxsave"))
                        {
                            _idx.Save();
                        }
                        else if (console.Equals("peersave"))
                        {
                            _p2P.SavePeer();
                        }
                        else if (console.Equals("ping"))
                        {
                            _p2P.Ping();
                        }
                        else if (console.Equals("integrity"))
                        {
                            _idx.MakeIntegrityCheck();
                        }
                        else if (console.Equals("list"))
                        {
                            List <Peer> peers = _p2P.GetPeerList();

                            Console.WriteLine();
                            Console.WriteLine(@"### Your Peerlist contains ###");
                            if (peers.Count > 0)
                            {
                                foreach (Peer peer in peers)
                                {
                                    RankingHandler rankingHandler = new RankingHandler();
                                    rankingHandler.GetRank(peer);
                                    Console.WriteLine(@"(R:" + peer.Rating + @") " + peer.GetUuid() + @" - " +
                                                      peer.GetIp() + @" - " +
                                                      (peer.IsOnline() ? "Online" : "Offline"));
                                    Console.WriteLine(@"disk: " + Convert.ToInt32((peer.diskSpace / 1e+9)) +
                                                      @"GB | avgPing: " + peer.GetAverageLatency() + "\n");
                                }
                            }
                            else
                            {
                                Console.WriteLine(@"The list is empty...");
                            }

                            Console.WriteLine();
                        }
                        else if (console.Trim().Equals(""))
                        {
                        }
                        else
                        {
                            Console.WriteLine(@"Unknown command");
                        }
                    }
                }
            }

            Console.ReadKey();
        }