Пример #1
0
        /// <summary>
        /// Diese Methode dient zur Anbindung der P2P Topology an die Hierarchische.
        /// Es wird ein entsprechendes Paket in das hierarchische Netz gesendet.
        /// </summary>
        /// <param name="p2pRequest"></param>
        /// <param name="username"></param>
        /// <param name="kaEvent"></param>
        /// <param name="writeResult">übergebe die Methode writeResult</param>
        void ConnectP2P(P2PRequest p2pRequest, string username, KaEvent kaEvent, Action <Request, string> writeResult)
        {
            //P2P Teil
            P2PPackage p2p = new P2PPackage(username, kaEvent)
            {
                P2Prequest = p2pRequest
            };

            //Sende Teil
            Package sendPackage = new Package(p2p);
            Package recievePackage;

            recievePackage = Send(sendPackage, KnownServers.GetRandomWellKnownPeer());

            if (recievePackage != null)
            {
                switch (recievePackage.p2p.P2PAnswer)
                {
                case P2PAnswer.Success:
                    writeResult(Request.Success, InviteSuccess);
                    break;

                case P2PAnswer.Failure:
                    writeResult(Request.Failure, InviteFail);
                    break;

                default:
                    writeResult(Request.Failure, InviteFail);
                    break;
                }
            }
            else
            {
                writeResult(Request.Error, Error);
            }
        }
Пример #2
0
        /// <summary>
        /// Resolve Acquired Packages and trigger corresponding requests. For Client
        /// </summary>
        /// <param name="package"></param>
        public Package ResolvePackage(Package package)
        {
            switch (package.request)
            {
            /// In case of Login Request try to login to the server database and set Request accordingly
            case Request.Login:
                Console.WriteLine(LoginRequest);
                if (package.serverSwitched)
                {
                    if (database.Login(package.user))
                    {
                        List <KaEvent> kaEvents;
                        kaEvents         = database.Read(package.user.name);
                        package.kaEvents = kaEvents;
                        try
                        {
                            package.invites = database.ReadInvites(package.user.name);
                        }
                        catch (Exception ex)
                        {
                            Console.WriteLine("ReadInvites failed.\n{0}\n{1}", ex.Message, ex.StackTrace);
                        }
                        writeResult(Request.Success, LoginSuccess);
                    }
                    else
                    {
                        writeResult(Request.Failure, LoginFail);
                    }
                }
                else
                {
                    if (ServerConfig.structure == Structure.HIERARCHY)
                    {
                        ///if serverID > 0 => Hierarchy
                        if (package.user.serverID > 0)
                        {
                            //Hierarchie Login
                            HierarchiePackage hierarchie = new HierarchiePackage
                            {
                                HierarchieRequest = HierarchieRequest.UserLogin,
                                login             = package.user.name,
                                destinationID     = package.user.serverID
                            };
                            hierarchie = HierarchyLogic.ResolveHierarchie(hierarchie);

                            switch (hierarchie.HierarchieAnswer)
                            {
                            case HierarchieAnswer.Success:
                                package.sourceServer = hierarchie.destinationAdress;
                                writeResult(Request.ChangeServer, ChangeServer);
                                break;

                            case HierarchieAnswer.Failure:
                                writeResult(Request.Failure, LoginFail);
                                break;

                            case HierarchieAnswer.Error:
                                writeResult(Request.Error, Error);
                                break;

                            default:
                                writeResult(Request.Failure, Error);
                                break;
                            }
                        }
                        ///else => Send to P2P
                        else
                        {
                            //P2P Teil
                            P2PPackage p2p = new P2PPackage(package.user.name)
                            {
                                P2Prequest = P2PRequest.Login
                            };

                            //Sende Teil
                            Package sendPackage = new Package(p2p);
                            Package recievePackage;
                            recievePackage = Send(sendPackage, KnownServers.GetRandomWellKnownPeer());

                            if (recievePackage != null)
                            {
                                switch (recievePackage.p2p.P2PAnswer)
                                {
                                case P2PAnswer.Success:
                                    package.sourceServer = recievePackage.p2p.lastIP;
                                    writeResult(Request.ChangeServer, ChangeServer);
                                    break;

                                case P2PAnswer.Failure:
                                    writeResult(Request.Failure, LoginFail);
                                    break;

                                default:
                                    writeResult(Request.Failure, LoginFail);
                                    break;
                                }
                            }
                            else
                            {
                                writeResult(Request.Error, Error);
                            }
                        }
                    }
                    else if (ServerConfig.structure == Structure.P2P)
                    {
                        ///if serverID == 0 => P2P
                        if (package.user.serverID == 0)
                        {
                            //P2P Teil
                            P2PPackage p2p = new P2PPackage(package.user.name)
                            {
                                P2Prequest = P2PRequest.Login
                            };
                            p2p = P2PLogic.ResolveP2P(p2p);

                            switch (p2p.P2PAnswer)
                            {
                            case P2PAnswer.Success:
                                package.sourceServer = p2p.lastIP;
                                writeResult(Request.ChangeServer, ChangeServer);
                                break;

                            case P2PAnswer.Failure:
                                writeResult(Request.Failure, LoginFail);
                                break;

                            default:
                                writeResult(Request.Failure, LoginFail);
                                break;
                            }
                        }
                        ///else =>  Send to Hierarchy
                        else
                        {
                            //Hierarchie Login
                            HierarchiePackage hierarchie = new HierarchiePackage
                            {
                                HierarchieRequest = HierarchieRequest.UserLogin,
                                login             = package.user.name,
                                destinationID     = package.user.serverID
                            };

                            //Sende Teil
                            Package sendPackage = new Package(hierarchie);
                            Package recievePackage;
                            recievePackage = Send(sendPackage, KnownServers.Root);

                            if (recievePackage != null)
                            {
                                switch (hierarchie.HierarchieAnswer)
                                {
                                case HierarchieAnswer.Success:
                                    package.sourceServer = hierarchie.destinationAdress;
                                    writeResult(Request.ChangeServer, ChangeServer);
                                    break;

                                case HierarchieAnswer.Failure:
                                    writeResult(Request.Failure, LoginFail);
                                    break;

                                case HierarchieAnswer.Error:
                                    writeResult(Request.Error, Error);
                                    break;

                                default:
                                    writeResult(Request.Failure, Error);
                                    break;
                                }
                            }
                            else
                            {
                                writeResult(Request.Error, Error);
                            }
                        }
                    }
                }
                break;

            /// In case of Register Request try to login to the server database and set Request accordingly
            case Request.Register:
                Console.WriteLine(RegisterRequest);
                try
                {
                    if (package.serverSwitched)
                    {
                        if (database.RegisterUser(package.user, package.passwordConfirm))
                        {
                            writeResult(Request.Success, RegisterSuccess);
                            package.user.serverID = ServerConfig.serverID;
                        }
                        else
                        {
                            writeResult(Request.Failure, RegisterFail);
                        }
                    }
                    else
                    {
                        if (ServerConfig.structure == Structure.HIERARCHY)
                        {
                            //Hierarchie Teil
                            HierarchiePackage hierarchie = new HierarchiePackage
                            {
                                HierarchieRequest = HierarchieRequest.RegisterUser
                            };
                            hierarchie = HierarchyLogic.ResolveHierarchie(hierarchie);

                            if (hierarchie.HierarchieAnswer == HierarchieAnswer.UserExistent)
                            {
                                writeResult(Request.UserExistent, UserExistent);
                                break;
                            }

                            //P2P Teil
                            //ConnectP2P(P2PRequest.NewUser, package.user.name, writeResult);

                            //P2P Teil
                            P2PPackage p2p = new P2PPackage(package.user.name)
                            {
                                P2Prequest = P2PRequest.NewUser
                            };

                            //Sende Teil
                            Package sendPackage = new Package(p2p);
                            Package recievePackage;
                            recievePackage = Send(sendPackage, KnownServers.GetRandomWellKnownPeer());

                            if (recievePackage != null)
                            {
                                switch (recievePackage.p2p.P2PAnswer)
                                {
                                case P2PAnswer.Success:
                                    if (hierarchie.anzUser < recievePackage.p2p.anzUser)
                                    {
                                        package.sourceServer = hierarchie.destinationAdress;
                                    }
                                    else
                                    {
                                        package.sourceServer = recievePackage.p2p.lastIP;
                                    }
                                    writeResult(Request.ChangeServer, ChangeServer);
                                    break;

                                ///user already exists
                                case P2PAnswer.UserExistent:
                                    writeResult(Request.UserExistent, UserExistent);
                                    break;

                                case P2PAnswer.Error:
                                    Console.WriteLine(recievePackage.p2p.ErrorMsg);
                                    writeResult(Request.Error, Error);
                                    break;

                                default:
                                    package.sourceServer = hierarchie.destinationAdress;
                                    writeResult(Request.ChangeServer, ChangeServer);
                                    break;
                                }
                            }
                            else
                            {
                                package.sourceServer = hierarchie.destinationAdress;
                                writeResult(Request.ChangeServer, ChangeServer);
                            }
                        }
                        else if (ServerConfig.structure == Structure.P2P)
                        {
                            //P2P Teil
                            P2PPackage p2p = new P2PPackage
                            {
                                P2Prequest = P2PRequest.NewUser
                            };
                            p2p = P2PLogic.ResolveP2P(p2p);

                            ///user is already existent
                            if (p2p.P2PAnswer == P2PAnswer.Visited)
                            {
                                writeResult(Request.UserExistent, UserExistent);
                                break;
                            }

                            //Hierarchie Teil
                            HierarchiePackage hierarchie = new HierarchiePackage
                            {
                                HierarchieRequest = HierarchieRequest.RegisterUser
                            };

                            //Sende Teil
                            Package sendPackage = new Package(hierarchie);
                            Package recievePackage;
                            recievePackage = Send(sendPackage, KnownServers.Root);
                            if (recievePackage != null)
                            {
                                switch (recievePackage.hierarchie.HierarchieAnswer)
                                {
                                case HierarchieAnswer.Success:
                                    if (p2p.anzUser < recievePackage.hierarchie.anzUser)
                                    {
                                        package.sourceServer = p2p.lastIP;
                                    }
                                    else
                                    {
                                        package.sourceServer = recievePackage.hierarchie.destinationAdress;
                                    }
                                    writeResult(Request.ChangeServer, RegisterSuccess);
                                    break;

                                ///user already exists
                                case HierarchieAnswer.UserExistent:
                                    writeResult(Request.UserExistent, UserExistent);
                                    break;

                                default:
                                    package.sourceServer = p2p.lastIP;
                                    writeResult(Request.ChangeServer, ChangeServer);
                                    break;
                                }
                            }
                            else
                            {
                                package.sourceServer = p2p.lastIP;
                                writeResult(Request.ChangeServer, ChangeServer);
                            }
                        }
                    }
                }
                catch (Exception e)
                {
                    Console.WriteLine(e.GetType().FullName);
                    Console.WriteLine(e.Message);
                    writeResult(Request.Failure, RegisterFail);
                }
                break;

            case Request.Save:
                Console.WriteLine(SaveRequest);
                try
                {
                    database.SaveEvent(package.kaEvents[0]);
                    writeResult(Request.Success, SaveSuccess);
                }
                catch (Exception e)
                {
                    Console.WriteLine(e.GetType().FullName);
                    Console.WriteLine(e.Message);
                    writeResult(Request.Failure, SaveFail);
                }
                break;

            case Request.Delete:
                Console.WriteLine(DeleteRequest);
                try
                {
                    database.DeleteEvent(package.kaEvents[0].TerminID);
                    writeResult(Request.Success, DeleteSuccess);
                }
                catch (Exception e)
                {
                    Console.WriteLine(e.GetType().FullName);
                    Console.WriteLine(e.Message);
                    writeResult(Request.Failure, DeleteFail);
                }
                break;

            case Request.Load:
                Console.WriteLine(LoadRequest);
                try
                {
                    List <KaEvent> kaEvents;
                    //kaEvents = database.LoadEvents(package.user, package.kaEvents[0].Beginn);
                    kaEvents         = database.Read(package.user.name);
                    package.kaEvents = kaEvents;
                    writeResult(Request.Success, LoadSuccess);
                }
                catch (Exception e)
                {
                    Console.WriteLine(e.GetType().FullName);
                    Console.WriteLine(e.Message);
                    writeResult(Request.Failure, LoadFail);
                }
                break;

            case Request.Test:
                Console.WriteLine(TestRequest);
                break;

            case Request.Invite:
                //Prüfung ServerID
                Console.WriteLine(InviteRequest);
                if (ServerConfig.structure == Structure.HIERARCHY)
                {
                    /*
                     * Hier ist nur Client-Server.
                     * Wenn Server-Server Invite message ist, wird es bei resolveHierarchie erledigt
                     * Das hier sollte wenn möglich als Asynchron, bzw. nach art Fire und Forget.
                     * Wenn mehrere User eingetragen wird, hat der Server eine lange Anschreibezeit
                     * */

                    foreach (User member in package.kaEvents[0].members)
                    {
                        ///member is user in current server
                        if (member.serverID == ServerConfig.serverID)
                        {
                            if (database.UserExist(member.name))
                            {
                                database.SaveInvites(member.name, package.kaEvents[0]);
                                writeResult(Request.Success, InviteSuccess);
                            }
                            else
                            {
                                writeResult(Request.Failure, UserNotFound);
                            }
                        }
                        ///member is user in hierarchy topology
                        else if (member.serverID > 0)
                        {
                            HierarchiePackage hierarchie = new HierarchiePackage
                            {
                                HierarchieRequest = HierarchieRequest.Invite,
                                invite            = package.kaEvents[0],
                                login             = member.name,
                                destinationID     = member.serverID
                            };
                            HierarchyLogic.ResolveHierarchie(hierarchie);

                            switch (hierarchie.HierarchieAnswer)
                            {
                            case HierarchieAnswer.Success:
                                writeResult(Request.Success, InviteSuccess);
                                break;

                            case HierarchieAnswer.Failure:
                                writeResult(Request.Failure, InviteFail);
                                break;

                            default:
                                break;
                            }
                        }
                        ///member is user in p2p topology
                        else
                        {
                            //P2P Teil
                            P2PPackage p2p = new P2PPackage(member.name, package.kaEvents[0])
                            {
                                P2Prequest = P2PRequest.Invite
                            };

                            //Sende Teil
                            Package sendPackage = new Package(p2p);
                            Package recievePackage;
                            recievePackage = Send(sendPackage, KnownServers.GetRandomWellKnownPeer());

                            if (recievePackage != null)
                            {
                                switch (recievePackage.p2p.P2PAnswer)
                                {
                                case P2PAnswer.Success:
                                    writeResult(Request.Success, InviteSuccess);
                                    break;

                                case P2PAnswer.Failure:
                                    writeResult(Request.Failure, InviteFail);
                                    break;

                                default:
                                    writeResult(Request.Failure, InviteFail);
                                    break;
                                }
                            }
                            else
                            {
                                writeResult(Request.Error, Error);
                            }
                        }
                    }
                }
                else if (ServerConfig.structure == Structure.P2P)
                {
                    //Logik P2P Invite
                    List <User> list = package.kaEvents[0].members;

                    foreach (User member in list)
                    {
                        ///member is user in p2p topology
                        if (member.serverID == 0)
                        {
                            if (database.UserExist(member.name))
                            {
                                database.SaveInvites(member.name, package.kaEvents[0]);
                                writeResult(Request.Success, InviteSuccess);
                            }
                            else
                            {
                                P2PPackage p2p = new P2PPackage(member.name, package.kaEvents[0])
                                {
                                    P2Prequest = P2PRequest.Invite
                                };
                                p2p = P2PLogic.ResolveP2P(p2p);

                                switch (p2p.P2PAnswer)
                                {
                                case P2PAnswer.Success:
                                    writeResult(Request.Success, InviteSuccess);
                                    break;

                                case P2PAnswer.Failure:
                                    writeResult(Request.Failure, InviteFail);
                                    break;

                                default:
                                    writeResult(Request.Error, Error);
                                    break;
                                }
                            }
                        }
                        ///member is user in hierarchy topology
                        else
                        {
                            //Hierarchie Teil
                            HierarchiePackage hierarchie = new HierarchiePackage
                            {
                                HierarchieRequest = HierarchieRequest.Invite,
                                invite            = package.kaEvents[0],
                                login             = member.name,
                                destinationID     = member.serverID
                            };

                            //SendeTeil
                            Package sendPackage = new Package(hierarchie);
                            Package recievePackage;
                            recievePackage = Send(sendPackage, KnownServers.Root);

                            if (recievePackage != null)
                            {
                                switch (recievePackage.hierarchie.HierarchieAnswer)
                                {
                                case HierarchieAnswer.Success:
                                    writeResult(Request.Success, InviteSuccess);
                                    break;

                                case HierarchieAnswer.Failure:
                                    writeResult(Request.Failure, InviteFail);
                                    break;

                                default:
                                    writeResult(Request.Failure, InviteFail);
                                    break;
                                }
                            }
                            else
                            {
                                writeResult(Request.Error, Error);
                            }
                        }
                    }
                }
                break;

            case Request.AnswerInvite:
                //TODO für P2P und Hierarchisch
                database.AnswerInvite(package.kaEvents[0], package.user.name, package.answerInvite);
                break;

            default:
                Console.WriteLine(RequestUnknown);
                break;
            }

            return(package);

            void writeResult(Request request, string line)
            {
                Console.WriteLine(line);
                package.request = request;
            }
        }
Пример #3
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);
            }
        }