Esempio n. 1
0
        /// <summary>
        /// Abort all active connections. Call this function only when shutting down.
        /// </summary>
        public static void AbortAll()
        {
            Console.WriteLine("Closing all active connections, please wait...");

            lock (connectionListLock)
            {
                foreach (TCPConnection connection in connections)
                {
                    try
                    {
                        connection.Abort();
                    }
                    catch { }
                }
            }

            // Terminate all connection handler threads
            ConnectionThreadManager.TerminateAll();
        }
Esempio n. 2
0
        /// <summary>
        /// Create a new connection instance to handle an inbound connection
        /// </summary>
        /// <param name="socket">TCP socket for communicating with the remote server</param>
        /// <param name="connectionLogWriter">Log writer module</param>
        /// <param name="serverList">Server List object</param>
        /// <param name="geoIP">GeoIP resolver</param>
        /// <param name="md5Manager">MD5 database manager</param>
        /// <param name="banManager">IP ban manager</param>
        /// <param name="cdKeyValidator">CD key validator</param>
        /// <param name="gameStats">Game stats module</param>
        public Connection(Socket socket, IConnectionLogWriter logWriter, ServerList serverList, GeoIP geoIP, MD5Manager md5Manager, IPBanManager banManager, ICDKeyValidator cdKeyValidator, IGameStatsLog gameStats)
            : this(socket, logWriter, serverList, geoIP)
        {
            // Raise the NewConnection event for connected packet analysers
            OnNewConnection();

            // Check whether the remote host is banned
            if (banManager.IsBanned((socket.RemoteEndPoint as IPEndPoint).Address))
            {
                ConnectionLog("BANNED");
                socket.Close();
                return;
            }

            this.md5Manager     = md5Manager;
            this.cdKeyValidator = cdKeyValidator;
            this.gameStats      = gameStats;

            // Handle this connection in a new thread
            ConnectionThreadManager.CreateStart(new ThreadStart(Handle));
        }
Esempio n. 3
0
        /// <summary>
        /// Handle the connection
        /// </summary>
        protected virtual void Handle()
        {
            try
            {
                // Initialise validation context for this session
                validationContext = cdKeyValidator.BeginValidation("login");

                // Log the new connection to the connection log
                ConnectionLog("ACCEPT LOCALPORT={0} SALT={1}", LocalPort, cdKeyValidator.GetSalt(validationContext));

                // Send the challenge salt
                Send(cdKeyValidator.GetSalt(validationContext).ToString());

                // Read back the authentication from the player
                InboundPacket login = Receive();

                cdKey       = login.PopString();  // Get the first MD5 which should be the CD key hash
                saltedCDKey = login.PopString();  // Get the second MD5 which should be the CD key plus salt hash
                type        = login.PopString();  // Type of client eg. CLIENT or SERVER
                version     = login.PopInt();     // Client's engine version

                // Write the login info to the connection log
                ConnectionLog("CONNECT MD5={0} SALTED={1} TYPE={2} VERSION={3}", cdKey, saltedCDKey, type, version);

                // Set values into the validation context
                validationContext.SetClientInfo(cdKey, saltedCDKey, type, version);

                // Check the CD key
                if (Validate(validationContext))
                {
                    if (version < Protocol.MIN_SUPPORTED_CLIENT_VERSION)
                    {
                        ConnectionLog(Protocol.LOGIN_RESPONSE_UPGRADE);
                        MasterServer.Log("{0} at {1} rejected, outdated version: got {2}", type, (socket.RemoteEndPoint as IPEndPoint).Address.ToString(), version);

                        // This is my best guess for how an UPGRADE packet should be structured, if it's wrong it seems to crash the client
                        OutboundPacket UpgradePacket = new OutboundPacket(Protocol.LOGIN_RESPONSE_UPGRADE);
                        UpgradePacket.Append(Protocol.MIN_SUPPORTED_CLIENT_VERSION);
                        UpgradePacket.Append(0x00);

                        // Send the UPGRADE response
                        Send(UpgradePacket);
                    }
                    else
                    {
                        // Send MSLIST packet if enabled, if the MSLIST is sent successfully then close the
                        // connection (SendMSList() returns true if the MSLIST was sent)
                        if (!SendMSList())
                        {
                            switch (type)
                            {
                            case Protocol.HOST_CLIENT:  HandleClientConnection(login);  break;

                            case Protocol.HOST_SERVER:  HandleServerConnection(login);  break;

                            default:                    HandleUnknownConnection(login); break;
                            }
                        }
                    }
                }
            }
            catch (ThreadAbortException)
            {
                aborted = true;
            }
            catch (Exception ex)
            {
                ConnectionLog("EXCEPTION: {0}", ex.Message);
            }

            try
            {
                socket.Close();
            }
            catch { }

            ConnectionLog("CLOSED");

            ConnectionThreadManager.Remove(Thread.CurrentThread);
            ConnectionManager.DeRegister(this);
        }