コード例 #1
0
        /// <summary>
        /// Finds the peers that have the file and add them in the list of peers.
        /// </summary>
        public void FindPeers()
        {
            // search the file in net
            Utilities.FileSearcher.SearchFile(this.Name);

            // get the file from the list of found files
            Lists.FilesFoundList.File file = Lists.FilesFoundList.GetFile(this.Name, this.SHA1);

            if (file != null)
            {
                for (int i = 0; i < file.ListPeers.Count; i++)
                {
                    try
                    {
                        Objects.Peer peer = Lists.PeersList.GetPeerByIP(file.ListPeers[i].IP);

                        if (peer != null)
                        {
                            AddPeer(peer);
                        }
                    }
                    catch
                    {
                    }
                }
            }
        }
コード例 #2
0
ファイル: Downloader.cs プロジェクト: cuteofdragon/ikiwi
        /// <summary>
        /// Send a new FPR to the peer for download a file pack of a not-downloading file part.
        /// </summary>
        /// <param name="download">The download object.</param>
        /// <param name="Peer">The IP address of peer to send the FPR message.</param>
        /// <returns>Return true if the message has been sended.</returns>
        private static bool StartDownloadNextFilePart(Objects.Download download, Objects.Peer Peer)
        {
            // the index of the not-downloaded file parts
            int[] index = new int[download.RemainingFileParts];

            int n = 0;

            // get the not-downloaded file parts
            for (int i = 0; i < download.ListFileParts.Length; i++)
            {
                if (download.ListFileParts[i] == 128 || (download.ListFileParts[i] > 0 && i == (download.ListFileParts.Length - 1)))
                {
                    index[n] = i;

                    n++;
                }
            }

            // select a random not-downloaded file part to download

            Random random = new Random();

            if (n > 0)
            {
                while (true)
                {
                    int a = 0;

                    if (download.RemainingFileParts != 0)
                    {
                        a = random.Next(n);

                        if (download.ListFileParts[index[a]] != 0)
                        {
                            // start to download the file part

                            string[] Params = new string[3];
                            Params[0] = download.Name;
                            Params[1] = download.SHA1;
                            Params[2] = (index[a] * 16384).ToString();

                            Messages.IMessage FprMess = Messages.MessagesFactory.Instance.CreateMessage(Messages.Commands.FPR, Params);

                            Peer.Send(FprMess);

                            return(true);
                        }
                    }
                    else
                    {
                        return(false);
                    }
                }
            }
            else
            {
                return(false);
            }
        }
コード例 #3
0
        /// <summary>
        /// Get the info of a single peer.
        /// </summary>
        /// <param name="PeerID">The ID of peer.</param>
        public static void GetSinglePeerInfoByID(string PeerID)
        {
            IMessage iPImessage = MessagesFactory.Instance.CreateMessage(Commands.PI, "");

            Objects.Peer peer = Lists.PeersList.GetPeerByID(PeerID);

            if (peer != null)
            {
                peer.Send(iPImessage);
            }
        }
コード例 #4
0
        /// <summary>
        /// Generic message.
        /// </summary>
        /// <param name="CommandName">The command name.</param>
        /// <param name="MessageID">The message ID.</param>
        /// <param name="TTL">The time to live.</param>
        /// <param name="Encryption">Indicates if the message is encrypted or not.</param>
        /// <param name="SenderPeer">The sender peer.</param>
        public AbstractMessage(Commands CommandName, String MessageID, int TTL, bool Encryption, Objects.Peer SenderPeer = null)
        {
            this.m_cmdCommandName = CommandName;
            this.m_nTTL           = TTL;
            this.m_bEncrypted     = Encryption;
            this.m_senderPeer     = SenderPeer;

            if (MessageID == String.Empty)
            {
                this.m_ID = this.GenerateID();
            }
            else
            {
                this.m_ID = MessageID;
            }
        }
コード例 #5
0
ファイル: AbstractMessage.cs プロジェクト: pesapower/ikiwi
        /// <summary>
        /// Generic message.
        /// </summary>
        /// <param name="CommandName">The command name.</param>
        /// <param name="MessageID">The message ID.</param>
        /// <param name="TTL">The time to live.</param>
        /// <param name="Encryption">Indicates if the message is encrypted or not.</param>
        /// <param name="SenderPeer">The sender peer.</param>
        public AbstractMessage(Commands CommandName, String MessageID, int TTL, bool Encryption, Objects.Peer SenderPeer = null)
        {
            this.m_cmdCommandName = CommandName;
            this.m_nTTL = TTL;
            this.m_bEncrypted = Encryption;
            this.m_senderPeer = SenderPeer;

            if (MessageID == String.Empty)
            {
                this.m_ID = this.GenerateID();
            }
            else
            {
                this.m_ID = MessageID;
            }
        }
コード例 #6
0
ファイル: Downloader.cs プロジェクト: cuteofdragon/ikiwi
        /// <summary>
        /// Control if there is the minimum number of uploader peers else get other uploader peers.
        /// </summary>
        /// <param name="download">The download object.</param>
        /// <returns>Return true if there is the minimum number of the uploader peers else return false.</returns>
        private static bool CheckMinNumberOfUploaderPeers(Objects.Download download)
        {
            if (download.ListUploaderPeers.Count < NumPeersForEachDownloads)
            {
                System.Random random = new Random();

                while (download.ListUploaderPeers.Count < NumPeersForEachDownloads)
                {
                    // control if there are peers that have this file
                    if (download.ListPeers.Count == 0)
                    {
                        download.FindPeers();
                    }

                    if (download.ListPeers.Count > download.ListUploaderPeers.Count)
                    {
                        // get a casual peer
                        Objects.Peer peer = download.ListPeers[random.Next(download.ListPeers.Count)];

                        // control if the peer is already an uploader
                        if (download.SearchUploaderPeer(peer.Key) == null)
                        {
                            // add the peer in the list of the uploader peers of the download
                            download.AddUploaderPeer(peer);

                            // send a FPR message to the new uploader peer
                            if (StartDownloadNextFilePart(download, peer) == false)
                            {
                                DownloadFirstNotDownloadedFilePack(download, peer);
                            }
                        }
                    }
                    else
                    {
                        return(false);
                    }
                }

                return(true);
            }
            else
            {
                return(true);
            }
        }
コード例 #7
0
        /// <summary>
        /// Adds a peer in the list of uploader peers of this download.
        /// </summary>
        /// <param name="peer"></param>
        public void AddUploaderPeer(Objects.Peer peer)
        {
            if (this.ListUploaderPeers.Count > 0)
            {
                int n   = 0;
                int max = ListPeers.Count - 1;
                int min = 0;

                while (max >= min)
                {
                    n = (max + min) / 2;

                    if (peer.Key > this.ListUploaderPeers[n].Key)
                    {
                        min = n + 1;
                    }
                    else if (peer.Key < this.ListUploaderPeers[n].Key)
                    {
                        max = n - 1;
                    }
                    else
                    {
                        return;
                    }
                }

                if (peer.Key < this.ListUploaderPeers[n].Key)
                {
                    n--;
                }

                this.ListUploaderPeers.Add(this.ListUploaderPeers[this.ListUploaderPeers.Count - 1]);

                for (int i = this.ListUploaderPeers.Count - 1; i > n + 1; i--)
                {
                    this.ListUploaderPeers[i] = this.ListUploaderPeers[i - 1];
                }

                this.ListUploaderPeers[n + 1] = peer;
            }
            else
            {
                this.ListUploaderPeers.Add(peer);
            }
        }
コード例 #8
0
        /// <summary>
        /// Adds the peer to the list.
        /// If exist another peer with same ID he will be automatically updated ( delete and write on ).
        /// </summary>
        /// <param name="peer">Peer object to add.</param>
        public static void AddPeer(Objects.Peer peer)
        {
            peer.Date = DateTime.UtcNow;

            for (int i = 0; i < m_peersList.Count; i++)
            {
                if (m_peersList[i].IP == peer.IP)
                {
                    m_peersList[i] = peer;

                    PeersList.NewOrUpdatedOrDeletedPeer = true;

                    return;
                }
            }

            m_peersList.Add(peer);

            PeersList.NewOrUpdatedOrDeletedPeer = true;
        }
コード例 #9
0
        /// <summary>
        /// Update the info about the peers of the selected download.
        /// </summary>
        private void UpdateSelectedDownloadPeers()
        {
            if (this.InvokeRequired)
            {
                this.Invoke(new MethodInvoker(() => { this.UpdateSelectedDownloadPeers(); }));
            }
            else
            {
                if (this.SelectedDownload != null)
                {
                    DataGridViewRowCollection rows = this.dataGridView_SelectedDownloadPeers.Rows;

                    if (rows.Count > this.SelectedDownload.ListPeers.Count)
                    {
                        rows.Clear();
                    }

                    for (int i = 0; i < this.SelectedDownload.ListPeers.Count; i++)
                    {
                        Objects.Peer peer = this.SelectedDownload.ListPeers[i];

                        if (i >= rows.Count)
                        {
                            rows.Add(
                                peer.IP,
                                Utilities.Converterer.AutoConvertSizeFromByte(peer.DownloadSpeed) + "/s");
                        }
                        else
                        {
                            rows[i].SetValues(
                                peer.IP,
                                Utilities.Converterer.AutoConvertSizeFromByte(peer.DownloadSpeed) + "/s");
                        }
                    }
                }
            }
        }
コード例 #10
0
ファイル: Downloader.cs プロジェクト: cuteofdragon/ikiwi
        /// <summary>
        /// Send a new FPR to the peer for download the next not-downloaded file pack of a this file part.
        /// </summary>
        /// <param name="download">The download object.</param>
        /// <param name="Peer">The IP address of peer to send the FPR message.</param>
        /// <returns>Return true if the message has been sended.</returns>
        private static bool DownloadFirstNotDownloadedFilePack(Objects.Download download, Objects.Peer Peer)
        {
            for (int i = 0; i < download.ListFileParts.Length; i++)
            {
                if (download.ListFileParts[i] > 0)
                {
                    int a = i * 128;

                    for (int n = 0; n < 128; n++)
                    {
                        if (download.ListFilePacks[a + n] == false)
                        {
                            // start to download the file part

                            string[] Params = new string[3];
                            Params[0] = download.Name;
                            Params[1] = download.SHA1;
                            Params[2] = ((a + n) * 16384).ToString();

                            Messages.IMessage FprMess = Messages.MessagesFactory.Instance.CreateMessage(Messages.Commands.FPR, Params);

                            Peer.Send(FprMess);

                            return(true);
                        }
                    }
                }
            }

            return(false);
        }
コード例 #11
0
ファイル: Downloader.cs プロジェクト: cuteofdragon/ikiwi
        /// <summary>
        /// Send a new FPR to the peer for download the next not-downloaded file pack of a this file part.
        /// </summary>
        /// <param name="filePackNum">The number of the file pack.</param>
        /// <param name="filePartNum">The number of the file part.</param>
        /// <param name="download">The download object.</param>
        /// <param name="Peer">The IP address of peer to send the FPR message.</param>
        /// <returns>Return true if the message has been sended; return false if the file part is completed.</returns>
        private static bool DownloadNextFilePackOfAFilePart(int filePackNum, int filePartNum, Objects.Download download, Objects.Peer Peer)
        {
            int nPack   = filePackNum;
            int partEnd = (filePartNum * 128) + 128;

            for (int i = 0; i < 128; i++)
            {
                if (nPack < download.ListFilePacks.Length)
                {
                    if (download.ListFilePacks[nPack] == false)
                    {
                        // download this file pack

                        string[] Params = new string[3];
                        Params[0] = download.Name;
                        Params[1] = download.SHA1;
                        Params[2] = (nPack * 16384).ToString();

                        Messages.IMessage FprMess = Messages.MessagesFactory.Instance.CreateMessage(Messages.Commands.FPR, Params);

                        Peer.Send(FprMess);

                        return(true);
                    }
                }
                else
                {
                    return(false);
                }

                if (nPack < partEnd)
                {
                    nPack++;
                }
                else
                {
                    nPack = filePartNum * 128;
                }
            }

            return(false);
        }
コード例 #12
0
        /// <summary>
        /// Build a new XML_List with all the peers are contained in the Lists.PeersList.
        /// </summary>
        public static void Build_XML_List()
        {
            XmlDocument list = new XmlDocument();

            list.LoadXml("<Peers></Peers>");

            for (int i = 0; i < Lists.PeersList.Count; i++)
            {
                Objects.Peer peer = (Objects.Peer)Lists.PeersList.List[i];

                if (peer.ID != "" && peer.ID != null)
                {
                    XmlElement XE_peer = list.CreateElement("_" + peer.ID);

                    XmlElement peer_IP = list.CreateElement("IP");
                    peer_IP.InnerText = peer.IP;
                    XE_peer.AppendChild(peer_IP);

                    XmlElement peer_time = list.CreateElement("Time");
                    peer_time.InnerText = peer.Date.ToString();
                    XE_peer.AppendChild(peer_time);

                    XmlElement peer_files = list.CreateElement("Files");

                    try
                    {
                        for (int j = 0; j < peer.Files.Count; j++)
                        {
                            Objects.Peer.File file = peer.Files[j];

                            XmlElement file_sha = list.CreateElement("_" + file.SHA1);

                            XmlElement file_name = list.CreateElement("Name");
                            file_name.InnerText = file.Name;
                            file_sha.AppendChild(file_name);

                            XmlElement file_size = list.CreateElement("Size");
                            file_size.InnerText = file.Size.ToString();
                            file_sha.AppendChild(file_size);

                            peer_files.AppendChild(file_sha);
                        }
                    }
                    catch
                    {
                    }

                    XE_peer.AppendChild(peer_files);

                    list.DocumentElement.AppendChild(XE_peer);
                }
            }

            // save the list
            XmlTextWriter writer = new XmlTextWriter(Global.iKiwiPath + "List.xml", null);

            writer.Formatting = Formatting.Indented;


            while (true)
            {
                try
                {
                    list.Save(writer);
                    writer.Flush();
                    writer.Close();
                    return;
                }
                catch
                {
                    Thread.Sleep(1);
                }
            }
        }
コード例 #13
0
ファイル: Downloader.cs プロジェクト: cuteofdragon/ikiwi
        /// <summary>
        /// Logs a downloaded file pack and send a new FPR message if is necessary.
        /// </summary>
        /// <param name="Download">The download object.</param>
        /// <param name="StartPoint">The star point of the file pack.</param>
        /// <param name="SenderPeer">The sender peer object.</param>
        /// <param name="Status">If the file-pack has been written or not ( other ).</param>
        public static void LogFilePack(Objects.Download Download, int StartPoint, Objects.Peer SenderPeer, Status_FilePack Status)
        {
            // indicate the downloading of a file pack
            SenderPeer.FilePackDownloaded = true;

            if (Status == Status_FilePack.Written)
            {
                #region ...

                int filePackNum = StartPoint / 16384;
                int filePartNum = StartPoint / 2097152;

                // control if the file pack is already been downloaded
                if (Download.ListFilePacks[filePackNum] == false)
                {
                    // update the list of file packs
                    Download.ListFilePacks[filePackNum] = true;

                    // update the number of remaining file packs
                    Download.RemainingFilePacks--;

                    // update the list of file parts
                    Download.ListFileParts[filePartNum]--;

                    // control if the file part is completed
                    if (Download.ListFileParts[filePartNum] == 0)
                    {
                        // update the number of remaining file parts
                        Download.RemainingFileParts--;

                        // control if the download is finished
                        if (Download.RemainingFilePacks == 0)
                        {
                            // move the completed download from temp-directory to shared-directory
                            File.Move(Global.TempDirectory + Download.Name, Global.SharedDirectory + Download.Name);

                            // update download's informations
                            Download.Progress = 100;
                            Download.Active   = false;
                        }
                        else
                        {
                            // send a new FPR to the peer for the next not downloaded file pack of a new file part
                            StartDownloadNextFilePart(Download, SenderPeer);
                        }
                    }
                    else
                    {
                        // send a new FPR to the peer for the next not downloaded file pack of a this file part
                        if (DownloadNextFilePackOfAFilePart(filePackNum, filePartNum, Download, SenderPeer) == false)
                        {
                            StartDownloadNextFilePart(Download, SenderPeer);
                        }
                    }

                    // log the file pack
                    Download.LogFilePack(SenderPeer.IP, filePackNum);

                    NewOrUpdatedDownload = true;
                }

                #endregion
            }

            // if the FilePack is damaged, will send a new FPR-mess to the peer;
            else if (Status == Status_FilePack.Damaged)
            {
                #region ...

                string[] Params = new string[3];
                Params[0] = Download.Name;
                Params[1] = Download.SHA1;
                Params[2] = StartPoint.ToString();

                Messages.IMessage FprMess = Messages.MessagesFactory.Instance.CreateMessage(Messages.Commands.FPR, Params);

                SenderPeer.Send(FprMess);

                #endregion
            }
        }
コード例 #14
0
 /// <summary>
 /// Update the existing old with the new peer ( delete and write on ).
 /// If the peer doesn't exist in the list he will be created.
 /// </summary>
 /// <param name="peer">Peer object to update</param>
 public static void UpdatePeer(Objects.Peer peer)
 {
     AddPeer(peer);
 }
コード例 #15
0
ファイル: Bouncer.cs プロジェクト: pesapower/ikiwi
        /// <summary>
        /// Manage the request connection;
        /// it decide if create a new connection or not.
        /// </summary>
        private static void DoAcceptTcpClient(IAsyncResult ar)
        {
            try
            {
                // start a new asynchronous listening
                m_clientAccepted.Set();

                // get the TcpClient and the NetworkStream
                TcpClient Client = ((TcpListener)ar.AsyncState).EndAcceptTcpClient(ar);
                NetworkStream Stream = Client.GetStream();

                Thread.Sleep(10);

                // get the request message in UTF16 form

                int i = 0;
                int num_bytes_read = 0;
                byte[] Bytes = new byte[3072];
                byte[] Req_message_byte = new byte[3072];

                do
                {
                    if (Stream.DataAvailable)
                    {
                        i = Stream.Read(Bytes, 0, Bytes.Length);
                        Array.Copy(Bytes, 0, Req_message_byte, num_bytes_read, i);
                        num_bytes_read += i;
                    }
                    else
                    {
                        Thread.Sleep(10);

                        if (!Stream.DataAvailable)
                        {
                            break;
                        }

                        i = 1;
                    }
                } while (i != 0);

                string Req_message = System.Text.Encoding.Unicode.GetString(Req_message_byte);

                // control if the message is correct or not
                string[] sub_Req_message = Req_message.Split('\n');

                try
                {
                    if (sub_Req_message[0].Substring(0, 4) == "Nova" && sub_Req_message[1].Substring(0, 7) == "CONNECT")
                    {
                        string Client_IP = sub_Req_message[2].Substring("Local-IP: ".Length).Trim();

                        bool connectionAccepted = false;

                        // process the request
                        if (Lists.PeersList.Count < Global.MaxNumberInputConnections)
                        {
                            connectionAccepted = true;
                        }
                        else
                        {
                            // control if there are peers that are not uploading or downloading to or from this client
                            for (int n = 0; n < Lists.PeersList.List.Count; n++)
                            {
                                try
                                {
                                    if (Lists.PeersList.List[n].DownloadInProgress == false && Lists.PeersList.List[n].UploadInProgress == false)
                                    {
                                        // remove this peer from the peers list
                                        Lists.PeersList.RemoveAndClosePeerAt(n);

                                        // accept the input connection
                                        connectionAccepted = true;

                                        break;
                                    }
                                }
                                catch
                                {
                                }
                            }
                        }

                        if (connectionAccepted == true)
                        {
                            Utilities.Log.Write("Connection request from " + Client_IP + " accepted", Utilities.Log.LogCategory.ConnectionRequests);

                            // create a new Objects.Peer object
                            Objects.Peer peer = new Objects.Peer(Client_IP, Client, Stream);
                            peer.ID = "EMPTY";

                            // the reply
                            string Reply_message =
                                Global.P2P_Protocol + "\n" +
                                "CONNECT_OK" + "\n" +
                                "Local-IP: " + Global.MyRemoteIP + ":" + Global.ListeningPort + "\n" +
                                "Remote-IP: " + Client_IP + "\n" +
                                "User-Agent: " + Global.UserAgent;

                            // send the reply
                            MessageSender.Send(Reply_message, Client, true);

                            // add the peer in the Lists.PeersList()
                            Lists.PeersList.AddPeer(peer);
                        }
                        else
                        {
                            Utilities.Log.Write("Connection request from " + Client_IP + " refused", Utilities.Log.LogCategory.ConnectionRequests);

                            string Reply_message =
                                Global.P2P_Protocol + "\n" +
                                "CONNECT_NO" + "\n" +
                                "Local-IP: " + Global.MyRemoteIP + ":" + Global.ListeningPort + "\n" +
                                "Remote-IP: " + Client_IP + "\n" +
                                "User-Agent: " + Global.UserAgent;

                            byte[] buffer = System.Text.Encoding.Unicode.GetBytes(Reply_message);
                            Stream.Write(buffer, 0, buffer.Length);

                            Stream.Close();
                            Client.Close();
                        }
                    }
                    else
                    {
                        Utilities.Log.Write("Connection request isn't valid", Utilities.Log.LogCategory.ConnectionRequests);

                        Stream.Close();
                        Client.Close();
                    }
                }
                catch(Exception)
                {
                    Utilities.Log.Write("Connection request isn't valid", Utilities.Log.LogCategory.ConnectionRequests);

                    Stream.Close();
                    Client.Close();
                }
            }
            catch (Exception ex)
            {
                Utilities.Log.Write("Error to process a connection request: " + ex.Message, Utilities.Log.LogCategory.ConnectionRequests);
            }
        }
コード例 #16
0
ファイル: Downloader.cs プロジェクト: cuteofdragon/ikiwi
        /// <summary>
        /// Process a file pack.
        /// </summary>
        /// <param name="FileName">The name of the file.</param>
        /// <param name="FileID">The ID of the file.</param>
        /// <param name="StartPoint">The star point of the file pack.</param>
        /// <param name="PackID">The ID of the binary data.</param>
        /// <param name="Binary">The binary data.</param>
        /// <param name="SenderPeer">The sender peer object.</param>
        public static void ProcessFilePack(string FileName, string FileID, int StartPoint, string PackID, byte[] Binary, Objects.Peer SenderPeer)
        {
            Objects.Download download = Downloader.SearchDownload(FileName, FileID);

            // control if exist this download and if it is actived
            if (download != null && download.Active == true)
            {
                // control that the binaryPack isn't damaged

                SHA1 sha1 = new SHA1CryptoServiceProvider();

                if (PackID == BitConverter.ToString(sha1.ComputeHash(Binary)).Replace("-", ""))
                {
                    #region Write to the file

                    while (true)
                    {
                        try
                        {
                            // open ( or create ) the file ( in temp-directory )
                            FileStream fs = new FileStream((Global.TempDirectory + @"\" + FileName), FileMode.OpenOrCreate);

                            // lock the access to file
                            fs.Lock(StartPoint, 16384);

                            // set the start-point
                            fs.Seek(StartPoint, SeekOrigin.Begin);

                            int count = 16384;

                            if ((download.Size - StartPoint) < 16384)
                            {
                                count = ((int)download.Size - StartPoint);
                            }

                            // write the filePack in the file ( temp )
                            fs.Write(Binary, 0, count);

                            // unlock the access to file
                            fs.Unlock(StartPoint, 16384);

                            fs.Close();

                            // log the file pack
                            Downloader.LogFilePack(download, StartPoint, SenderPeer, Downloader.Status_FilePack.Written);

                            break;
                        }

                        catch (IOException)                         // the file is already locked
                        {
                            Thread.Sleep(1);
                        }

                        catch (Exception ex)                         // other problem
                        {
                            Utilities.Log.Write("Downloader.cs: error to write in a file: \n" + ex.Message, Utilities.Log.LogCategory.Error);
                            break;
                        }
                    }

                    #endregion
                }
                else
                {
                    // log
                    // communicate to Downloader that the FilePack is damaged
                    Downloader.LogFilePack(download, StartPoint, SenderPeer, Downloader.Status_FilePack.Damaged);
                }
            }
        }
コード例 #17
0
 /// <summary>
 /// Generic message.
 /// </summary>
 /// <param name="CommandName">The command name.</param>
 /// <param name="TTL">The time to live.</param>
 /// <param name="Encrypted">Indicates if the message is encrypted or not.</param>
 /// <param name="SenderPeer">The sender peer.</param>
 public AbstractMessage(Commands CommandName, int TTL, bool Encrypted, Objects.Peer SenderPeer = null)
     : this(CommandName, string.Empty, TTL, Encrypted, SenderPeer)
 {
 }
コード例 #18
0
        /// <summary>
        /// Manage the request connection;
        /// it decide if create a new connection or not.
        /// </summary>
        private static void DoAcceptTcpClient(IAsyncResult ar)
        {
            try
            {
                // start a new asynchronous listening
                m_clientAccepted.Set();

                // get the TcpClient and the NetworkStream
                TcpClient     Client = ((TcpListener)ar.AsyncState).EndAcceptTcpClient(ar);
                NetworkStream Stream = Client.GetStream();

                Thread.Sleep(10);

                // get the request message in UTF16 form

                int    i = 0;
                int    num_bytes_read   = 0;
                byte[] Bytes            = new byte[3072];
                byte[] Req_message_byte = new byte[3072];

                do
                {
                    if (Stream.DataAvailable)
                    {
                        i = Stream.Read(Bytes, 0, Bytes.Length);
                        Array.Copy(Bytes, 0, Req_message_byte, num_bytes_read, i);
                        num_bytes_read += i;
                    }
                    else
                    {
                        Thread.Sleep(10);

                        if (!Stream.DataAvailable)
                        {
                            break;
                        }

                        i = 1;
                    }
                } while (i != 0);

                string Req_message = System.Text.Encoding.Unicode.GetString(Req_message_byte);

                // control if the message is correct or not
                string[] sub_Req_message = Req_message.Split('\n');

                try
                {
                    if (sub_Req_message[0].Substring(0, 4) == "Nova" && sub_Req_message[1].Substring(0, 7) == "CONNECT")
                    {
                        string Client_IP = sub_Req_message[2].Substring("Local-IP: ".Length).Trim();

                        bool connectionAccepted = false;

                        // process the request
                        if (Lists.PeersList.Count < Global.MaxNumberInputConnections)
                        {
                            connectionAccepted = true;
                        }
                        else
                        {
                            // control if there are peers that are not uploading or downloading to or from this client
                            for (int n = 0; n < Lists.PeersList.List.Count; n++)
                            {
                                try
                                {
                                    if (Lists.PeersList.List[n].DownloadInProgress == false && Lists.PeersList.List[n].UploadInProgress == false)
                                    {
                                        // remove this peer from the peers list
                                        Lists.PeersList.RemoveAndClosePeerAt(n);

                                        // accept the input connection
                                        connectionAccepted = true;

                                        break;
                                    }
                                }
                                catch
                                {
                                }
                            }
                        }

                        if (connectionAccepted == true)
                        {
                            Utilities.Log.Write("Connection request from " + Client_IP + " accepted", Utilities.Log.LogCategory.ConnectionRequests);

                            // create a new Objects.Peer object
                            Objects.Peer peer = new Objects.Peer(Client_IP, Client, Stream);
                            peer.ID = "EMPTY";

                            // the reply
                            string Reply_message =
                                Global.P2P_Protocol + "\n" +
                                "CONNECT_OK" + "\n" +
                                "Local-IP: " + Global.MyRemoteIP + ":" + Global.ListeningPort + "\n" +
                                "Remote-IP: " + Client_IP + "\n" +
                                "User-Agent: " + Global.UserAgent;

                            // send the reply
                            MessageSender.Send(Reply_message, Client, true);

                            // add the peer in the Lists.PeersList()
                            Lists.PeersList.AddPeer(peer);
                        }
                        else
                        {
                            Utilities.Log.Write("Connection request from " + Client_IP + " refused", Utilities.Log.LogCategory.ConnectionRequests);

                            string Reply_message =
                                Global.P2P_Protocol + "\n" +
                                "CONNECT_NO" + "\n" +
                                "Local-IP: " + Global.MyRemoteIP + ":" + Global.ListeningPort + "\n" +
                                "Remote-IP: " + Client_IP + "\n" +
                                "User-Agent: " + Global.UserAgent;

                            byte[] buffer = System.Text.Encoding.Unicode.GetBytes(Reply_message);
                            Stream.Write(buffer, 0, buffer.Length);

                            Stream.Close();
                            Client.Close();
                        }
                    }
                    else
                    {
                        Utilities.Log.Write("Connection request isn't valid", Utilities.Log.LogCategory.ConnectionRequests);

                        Stream.Close();
                        Client.Close();
                    }
                }
                catch (Exception)
                {
                    Utilities.Log.Write("Connection request isn't valid", Utilities.Log.LogCategory.ConnectionRequests);

                    Stream.Close();
                    Client.Close();
                }
            }
            catch (Exception ex)
            {
                Utilities.Log.Write("Error to process a connection request: " + ex.Message, Utilities.Log.LogCategory.ConnectionRequests);
            }
        }
コード例 #19
0
ファイル: MessagesFactory.cs プロジェクト: cuteofdragon/ikiwi
        /// <summary>
        /// Creates a message object from the input data.
        /// </summary>
        /// <param name="Message">The received message.</param>
        /// <param name="SenderPeer">IP:Port of the sender.</param>
        /// <returns>Returns the message objetc.</returns>
        public Messages.IMessage ParseMessage(byte[] Message, Objects.Peer SenderPeer)
        {
            // message parts

            Messages.Commands messageCommand;
            string            messageID  = string.Empty;
            int  messageTTL              = 0;
            bool messageEncryption       = false;
            int  messageParametersLength = 0;

            byte[] messageParameters;

            // split byte array

            int start = 0;
            int count = 0;

            byte[] buffer = null;

            while (true)
            {
                try
                {
                    // get the command

                    if (Message[start + 4] == RETURN_CHAR_UTF16[0] && Message[start + 5] == RETURN_CHAR_UTF16[1])
                    {
                        count = 4;
                    }
                    else if (Message[start + 6] == RETURN_CHAR_UTF16[0] && Message[start + 7] == RETURN_CHAR_UTF16[1])
                    {
                        count = 6;
                    }
                    else
                    {
                        // the message is invalid
                        Utilities.Log.Write("Invalid input message from " + SenderPeer.IP, Utilities.Log.LogCategory.InputMessages);

                        return(null);
                    }

                    buffer = new byte[count];

                    Buffer.BlockCopy(Message, start, buffer, 0, count);

                    if (Enum.TryParse <Messages.Commands>(ASCIIEncoding.Unicode.GetString(buffer), out messageCommand))
                    {
                        // get the other message parts

                        bool b = false;

                        for (int a = 0; a <= 3; a++)
                        {
                            start += count + 2;

                            b = false;

                            for (int i = start; i <= Message.Length - 1; i += 2)
                            {
                                if (Message[i] == RETURN_CHAR_UTF16[0] && Message[i + 1] == RETURN_CHAR_UTF16[1])
                                {
                                    count = i - start;

                                    b = true;

                                    break;
                                }
                            }

                            if (b == true)
                            {
                                buffer = new Byte[count];

                                Buffer.BlockCopy(Message, start, buffer, 0, count);

                                switch (a)
                                {
                                case 0:
                                {
                                    messageID = ASCIIEncoding.Unicode.GetString(buffer);
                                    break;
                                }

                                case 1:
                                {
                                    messageTTL = int.Parse(ASCIIEncoding.Unicode.GetString(buffer));
                                    break;
                                }

                                case 2:
                                {
                                    if (ASCIIEncoding.Unicode.GetString(buffer) == "0")
                                    {
                                        messageEncryption = false;
                                    }
                                    else
                                    {
                                        messageEncryption = true;
                                    }
                                    break;
                                }

                                case 3:
                                {
                                    messageParametersLength = int.Parse(ASCIIEncoding.Unicode.GetString(buffer));
                                    break;
                                }
                                }
                            }
                            else
                            {
                                // return the incompleted message
                                break;
                            }
                        }

                        // get the parameters of the message

                        start += count + 2;

                        count = messageParametersLength;

                        // control if the message is complete
                        if (count <= Message.Length - start)
                        {
                            messageParameters = new byte[count];

                            Buffer.BlockCopy(Message, start, messageParameters, 0, count);

                            // process the single message

                            #region get parameters and create the message object

                            // control if the message is encrypted
                            if (messageEncryption == true)
                            {
                                // decrypt the message
                                if (messageCommand == Commands.EK)
                                {
                                    messageParameters = Utilities.Cryptography.RsaDecryptByteToByte(messageParameters, SenderPeer.MyAsymmetricEncryptionKey);
                                }
                                else
                                {
                                    messageParameters = Utilities.Cryptography.AesDecryptByteToByte(messageParameters, SenderPeer.SymmetricEncryptionKey);
                                }
                            }

                            string[] strParameters;

                            IMessage message;

                            if (messageCommand == Commands.FP || messageCommand == Commands.XL)
                            {
                                byte[] binaryPart;

                                if (messageCommand == Commands.FP)
                                {
                                    strParameters = new string[4];

                                    // split the byte array

                                    int parStart = -2;

                                    int parCount = 0;

                                    byte[] parBuffer = null;

                                    bool _b = false;

                                    for (int a = 0; a <= 3; a++)
                                    {
                                        parStart = parStart + parCount + 2;

                                        _b = false;

                                        for (int i = parStart; i <= messageParameters.Length - parStart; i += 2)
                                        {
                                            if (messageParameters[i] == RETURN_CHAR_UTF16[0] && messageParameters[i + 1] == RETURN_CHAR_UTF16[1])
                                            {
                                                parCount = i - parStart;

                                                _b = true;

                                                break;
                                            }
                                        }

                                        if (_b == true)
                                        {
                                            parBuffer = new Byte[parCount];

                                            Buffer.BlockCopy(messageParameters, parStart, parBuffer, 0, parCount);

                                            strParameters[a] = ASCIIEncoding.Unicode.GetString(parBuffer);
                                        }
                                    }

                                    parStart = parStart + parCount + 8;

                                    //parCount = Parameters.Length - start;

                                    binaryPart = new byte[16384];

                                    Buffer.BlockCopy(messageParameters, parStart, binaryPart, 0, binaryPart.Length);
                                }
                                else
                                {
                                    strParameters = new string[0];

                                    binaryPart = new Byte[messageParameters.Length - 6];

                                    Buffer.BlockCopy(messageParameters, 6, binaryPart, 0, binaryPart.Length);
                                }

                                message = CreateMessage(messageCommand, messageID, messageTTL, messageEncryption, strParameters, binaryPart);
                            }
                            else
                            {
                                strParameters = ASCIIEncoding.Unicode.GetString(messageParameters).Split('\n');

                                strParameters[strParameters.Length - 1] = strParameters[strParameters.Length - 1].TrimEnd('\0');

                                message = MessagesFactory.Instance.CreateMessage(messageCommand, messageID, messageTTL, messageEncryption, strParameters);
                            }

                            message.SenderPeer = SenderPeer;

                            return(message);

                            #endregion

                            // check if there are other messages to be processed
                        }
                        else
                        {
                            // return the incompleted message
                            return(null);
                        }
                    }
                    else
                    {
                        // the message command is invalid
                        Utilities.Log.Write("Invalid input message from " + SenderPeer.IP, Utilities.Log.LogCategory.InputMessages);

                        return(null);
                    }
                }
                catch (Exception ex)
                {
                    Utilities.Log.Write("Error to process a message from " + SenderPeer.IP + ": " + ex.Message, Utilities.Log.LogCategory.Error);

                    return(null);
                }
            }
        }