예제 #1
0
        /// <summary>
        /// Das Handling von P2PPaketen.
        /// </summary>
        /// <param name="package"></param>
        /// <returns></returns>
        public static P2PPackage ResolveP2P(P2PPackage package)
        {
            if (ServerConfig.CheckPackageID(package.GetPackageID()))
            {
                try
                {
                    List <P2PPackage> returnList;

                    switch (package.P2Prequest)
                    {
                    case P2PRequest.NewServer:
                        //0. Falls ich ihn noch nicht als Nachbarn habe.
                        if (!ServerConfig.neighbours.Exists(x => x.ToString() == package.GetSource()))
                        {
                            //1. Anzahl Verbindungen (s. neighbours)
                            if (package.anzConn == P2PPackage.AnzConnInit || package.anzConn > ServerConfig.neighbours.Count)
                            {    //Wenn das Paket noch nicht angefasst wurde, oder wir ein mind. genausogutes Angebot haben geht es als Antwort zurück.
                                package.anzConn = ServerConfig.neighbours.Count;
                                package.lastIP  = ServerConfig.host.ToString();
                            }
                            else if (package.anzConn == ServerConfig.neighbours.Count)
                            {
                                package.lastIP = ServerConfig.host.ToString();
                            }
                        }
                        //2. Test on TTL
                        if (package.DecrementTTL() == 0)
                        {
                            package.P2PAnswer = P2PAnswer.Timeout;
                            break;
                        }
                        //3. Forking to other servers via flooding
                        returnList = Forward();
                        //Comparing answers
                        foreach (P2PPackage p in returnList)
                        {
                            if (p.P2PAnswer == P2PAnswer.Error)
                            {
                                package.ErrorMsg = GenerateErrorString();
                                /*package.Exception = p.Exception;*/
                            }
                            else if (package.anzConn >= p.anzConn)
                            {
                                package.anzConn = p.anzConn;
                                package.lastIP  = p.lastIP;
                            }
                        }
                        break;

                    case P2PRequest.RegisterServer:
                        //1. Nimm Server in neighbours auf. (Falls noch nicht existent)
                        if (!ServerConfig.neighbours.Exists(x => x.ToString() == package.GetSource()))
                        {
                            ServerConfig.neighbours.Add(IPAddress.Parse(package.GetSource()));
                            package.P2PAnswer = P2PAnswer.Success;
                        }
                        else
                        {
                            package.P2PAnswer = P2PAnswer.Visited;
                        }
                        break;

                    case P2PRequest.NewUser:
                        //0. Existiert der User?
                        if (ServerLogic.database.UserExist(package.GetUsername()))
                        {
                            package.P2PAnswer = P2PAnswer.UserExistent;
                            break;
                        }
                        //1. Anzahl User
                        int anzUser = ServerLogic.database.GetUserCount();
                        if (package.anzUser == P2PPackage.AnzUserInit || package.anzUser > anzUser)
                        {    // siehe case NewServer
                            package.anzUser = anzUser;
                            package.lastIP  = ServerConfig.host.ToString();
                        }
                        else if (package.anzUser == anzUser)
                        {
                            package.lastIP = ServerConfig.host.ToString();
                        }
                        //2. Test on TTL ???? -> Nein! Nicht vereinbar mit nur einem User im gesamten Netz.

                        /*if (package.DecrementTTL() == 0)
                         * {
                         *  package.P2PAnswer = P2PAnswer.Timeout;
                         *  break;
                         * }*/
                        //3. Forking to other servers via flooding
                        returnList = Forward();
                        //Comparing answers
                        foreach (P2PPackage p in returnList)
                        {
                            if (p.P2PAnswer == P2PAnswer.Error)
                            {
                                package.ErrorMsg = p.ErrorMsg;
                                /*package.Exception = p.Exception;*/
                                package.P2PAnswer = P2PAnswer.Error;
                                return(package);
                            }
                            else if (package.anzUser >= p.anzUser)
                            {
                                package.anzUser = p.anzUser;
                                package.lastIP  = p.lastIP;
                            }
                        }
                        package.P2PAnswer = P2PAnswer.Success;
                        break;

                    /*
                     * case P2PRequest.RegisterUser:
                     *  //Client should connect directly to register.
                     *  break;
                     */

                    case P2PRequest.Login:
                        //1. Check Datenbank nach user
                        if (!ServerLogic.database.UserExist(package.GetUsername()))     //2. Wenn nicht gefunden => weiterleiten
                        {
                            returnList = Forward();
                            //Falls nur ein return => Success
                            if (returnList.Count == 1)
                            {
                                package.P2PAnswer = returnList.First().P2PAnswer;
                                package.lastIP    = returnList.First().lastIP;
                            }
                            else if (returnList.Count > 1)
                            {
                                foreach (P2PPackage p in returnList)
                                {
                                    if (p.P2PAnswer == P2PAnswer.Success)
                                    {
                                        package.lastIP = p.lastIP;
                                    }
                                }
                            }
                            else
                            {
                                package.P2PAnswer = P2PAnswer.Failure;     //Error?
                            }
                        }
                        else
                        {
                            package.lastIP    = ServerConfig.host.ToString();
                            package.P2PAnswer = P2PAnswer.Success;
                        }
                        break;

                    case P2PRequest.Invite:
                        //1. Check Datenbank nach user
                        if (!ServerLogic.database.UserExist(package.GetUsername()))     //2. Wenn nicht gefunden => weiterleiten
                        {
                            returnList = Forward();

                            foreach (P2PPackage p in returnList)
                            {
                                if (p.P2PAnswer == P2PAnswer.Success)
                                {
                                    package.P2PAnswer = p.P2PAnswer;
                                    package.lastIP    = p.lastIP;
                                }
                            }
                        }
                        else
                        {
                            ServerLogic.database.SaveInvites(package.GetUsername(), package.GetInvite());
                            package.lastIP    = ServerConfig.host.ToString();
                            package.P2PAnswer = P2PAnswer.Success;
                        }
                        break;

                    default:

                        break;
                    }
                }
                catch (Exception ex)
                {
                    Console.WriteLine(ex.Message);
                    package.P2PAnswer = P2PAnswer.Error;
                    package.ErrorMsg  = GenerateErrorString(ex);
                    /*package.Exception = ex;*/
                    //throw;
                }
            }
            else
            {
                package.P2PAnswer = P2PAnswer.Visited; //Node wurde bereits angefragt, keine Aktion nötig
            }

            return(package);

            List <P2PPackage> Forward()
            {
                Package sendPackage = new Package(package);
                Package recievePackage;

                List <P2PPackage> returnList = new List <P2PPackage>();

                foreach (IPAddress iPAddress in ServerConfig.neighbours)
                {
                    recievePackage = ServerLogic.Send(sendPackage, iPAddress);
                    if (recievePackage != null)
                    {
                        if (recievePackage != null && recievePackage.p2p.P2PAnswer == P2PAnswer.Success)
                        {
                            return new List <P2PPackage>()
                                   {
                                       recievePackage.p2p
                                   }
                        }
                        ;
                        returnList.Add(recievePackage.p2p);
                    }
                }

                return(returnList);
            }
        }