Exemple #1
0
        public static void SVC_GetChallenge( )
        {
            Int32 i;
            Int32 oldest;
            Int32 oldestTime;

            oldest     = 0;
            oldestTime = 0x7fffffff;
            for (i = 0; i < Defines.MAX_CHALLENGES; i++)
            {
                if (NET.CompareBaseAdr(Globals.net_from, SV_INIT.svs.challenges[i].adr))
                {
                    break;
                }
                if (SV_INIT.svs.challenges[i].time < oldestTime)
                {
                    oldestTime = SV_INIT.svs.challenges[i].time;
                    oldest     = i;
                }
            }

            if (i == Defines.MAX_CHALLENGES)
            {
                SV_INIT.svs.challenges[oldest].challenge = Lib.Rand() & 0x7fff;
                SV_INIT.svs.challenges[oldest].adr       = Globals.net_from;
                SV_INIT.svs.challenges[oldest].time      = ( Int32 )Globals.curtime;
                i = oldest;
            }

            Netchan.OutOfBandPrint(Defines.NS_SERVER, Globals.net_from, "challenge " + SV_INIT.svs.challenges[i].challenge);
        }
Exemple #2
0
        public static void SV_ReadPackets( )
        {
            Int32    i;
            client_t cl;
            var      qport = 0;

            while (NET.GetPacket(Defines.NS_SERVER, Globals.net_from, Globals.net_message))
            {
                if ((Globals.net_message.data[0] == -1) && (Globals.net_message.data[1] == -1) && (Globals.net_message.data[2] == -1) && (Globals.net_message.data[3] == -1))
                {
                    SV_ConnectionlessPacket();
                    continue;
                }

                MSG.BeginReading(Globals.net_message);
                MSG.ReadLong(Globals.net_message);
                MSG.ReadLong(Globals.net_message);
                qport = MSG.ReadShort(Globals.net_message) & 0xffff;
                for (i = 0; i < SV_MAIN.maxclients.value; i++)
                {
                    cl = SV_INIT.svs.clients[i];
                    if (cl.state == Defines.cs_free)
                    {
                        continue;
                    }
                    if (!NET.CompareBaseAdr(Globals.net_from, cl.netchan.remote_address))
                    {
                        continue;
                    }
                    if (cl.netchan.qport != qport)
                    {
                        continue;
                    }
                    if (cl.netchan.remote_address.port != Globals.net_from.port)
                    {
                        Com.Printf("SV_ReadPackets: fixing up a translated port\\n");
                        cl.netchan.remote_address.port = Globals.net_from.port;
                    }

                    if (Netchan.Process(cl.netchan, Globals.net_message))
                    {
                        if (cl.state != Defines.cs_zombie)
                        {
                            cl.lastmessage = SV_INIT.svs.realtime;
                            SV_USER.SV_ExecuteClientMessage(cl);
                        }
                    }

                    break;
                }

                if (i != SV_MAIN.maxclients.value)
                {
                    continue;
                }
            }
        }
Exemple #3
0
        /**
         * Returns a challenge number that can be used in a subsequent
         * client_connect command. We do this to prevent denial of service attacks
         * that flood the server with invalid connection IPs. With a challenge, they
         * must give a valid IP address.
         */
        public static void SVC_GetChallenge()
        {
            int i;
            int oldest;
            int oldestTime;

            oldest     = 0;
            oldestTime = 0x7fffffff;

            // see if we already have a challenge for this ip
            for (i = 0; i < Defines.MAX_CHALLENGES; i++)
            {
                if (NET.CompareBaseAdr(Globals.net_from, SV_INIT.svs.challenges[i].adr))
                {
                    break;
                }

                if (SV_INIT.svs.challenges[i].time < oldestTime)
                {
                    oldestTime = SV_INIT.svs.challenges[i].time;
                    oldest     = i;
                }
            }

            if (i == Defines.MAX_CHALLENGES)
            {
                // overwrite the oldest
                SV_INIT.svs.challenges[oldest].challenge = Lib.rand() & 0x7fff;
                SV_INIT.svs.challenges[oldest].adr       = Globals.net_from;
                SV_INIT.svs.challenges[oldest].time      = (int)Globals.curtime;
                i = oldest;
            }

            // send it back
            Netchan.OutOfBandPrint(Defines.NS_SERVER, Globals.net_from, "challenge " + SV_INIT.svs.challenges[i].challenge);
        }
Exemple #4
0
        public static void SVC_DirectConnect( )
        {
            String   userinfo;
            netadr_t adr;
            Int32    i;
            client_t cl;
            Int32    version;
            Int32    qport;

            adr = Globals.net_from;
            Com.DPrintf("SVC_DirectConnect ()\\n");
            version = Lib.Atoi(Cmd.Argv(1));
            if (version != Defines.PROTOCOL_VERSION)
            {
                Netchan.OutOfBandPrint(Defines.NS_SERVER, adr, "print\\nServer is version " + Globals.VERSION + "\\n");
                Com.DPrintf("    rejected connect from version " + version + "\\n");
                return;
            }

            qport = Lib.Atoi(Cmd.Argv(2));
            var challenge = Lib.Atoi(Cmd.Argv(3));

            userinfo = Cmd.Argv(4);
            userinfo = Info.Info_SetValueForKey(userinfo, "ip", NET.AdrToString(Globals.net_from));
            if (SV_INIT.sv.attractloop)
            {
                if (!NET.IsLocalAddress(adr))
                {
                    Com.Printf("Remote connect in attract loop.  Ignored.\\n");
                    Netchan.OutOfBandPrint(Defines.NS_SERVER, adr, "print\\nConnection refused.\\n");
                    return;
                }
            }

            if (!NET.IsLocalAddress(adr))
            {
                for (i = 0; i < Defines.MAX_CHALLENGES; i++)
                {
                    if (NET.CompareBaseAdr(Globals.net_from, SV_INIT.svs.challenges[i].adr))
                    {
                        if (challenge == SV_INIT.svs.challenges[i].challenge)
                        {
                            break;
                        }
                        Netchan.OutOfBandPrint(Defines.NS_SERVER, adr, "print\\nBad challenge.\\n");
                        return;
                    }
                }

                if (i == Defines.MAX_CHALLENGES)
                {
                    Netchan.OutOfBandPrint(Defines.NS_SERVER, adr, "print\\nNo challenge for address.\\n");
                    return;
                }
            }

            for (i = 0; i < SV_MAIN.maxclients.value; i++)
            {
                cl = SV_INIT.svs.clients[i];
                if (cl.state == Defines.cs_free)
                {
                    continue;
                }
                if (NET.CompareBaseAdr(adr, cl.netchan.remote_address) && (cl.netchan.qport == qport || adr.port == cl.netchan.remote_address.port))
                {
                    if (!NET.IsLocalAddress(adr) && (SV_INIT.svs.realtime - cl.lastconnect) < (( Int32 )SV_MAIN.sv_reconnect_limit.value * 1000))
                    {
                        Com.DPrintf(NET.AdrToString(adr) + ":reconnect rejected : too soon\\n");
                        return;
                    }

                    Com.Printf(NET.AdrToString(adr) + ":reconnect\\n");
                    Gotnewcl(i, challenge, userinfo, adr, qport);
                    return;
                }
            }

            var index = -1;

            for (i = 0; i < SV_MAIN.maxclients.value; i++)
            {
                cl = SV_INIT.svs.clients[i];
                if (cl.state == Defines.cs_free)
                {
                    index = i;
                    break;
                }
            }

            if (index == -1)
            {
                Netchan.OutOfBandPrint(Defines.NS_SERVER, adr, "print\\nServer is full.\\n");
                Com.DPrintf("Rejected a connection.\\n");
                return;
            }

            Gotnewcl(index, challenge, userinfo, adr, qport);
        }
Exemple #5
0
        /**
         * Reads packets from the network or loopback.
         */
        public static void SV_ReadPackets()
        {
            int      i;
            client_t cl;
            var      qport = 0;

            while (NET.GetPacket(Defines.NS_SERVER, Globals.net_from, Globals.net_message))
            {
                // check for connectionless packet (0xffffffff) first
                if (Globals.net_message.data[0] == 255 &&
                    Globals.net_message.data[1] == 255 &&
                    Globals.net_message.data[2] == 255 &&
                    Globals.net_message.data[3] == 255)
                {
                    SV_MAIN.SV_ConnectionlessPacket();

                    continue;
                }

                // read the qport out of the message so we can fix up
                // stupid address translating routers
                MSG.BeginReading(Globals.net_message);
                MSG.ReadLong(Globals.net_message);                 // sequence number
                MSG.ReadLong(Globals.net_message);                 // sequence number
                qport = MSG.ReadShort(Globals.net_message) & 0xffff;

                // check for packets from connected clients
                for (i = 0; i < SV_MAIN.maxclients.value; i++)
                {
                    cl = SV_INIT.svs.clients[i];

                    if (cl.state == Defines.cs_free)
                    {
                        continue;
                    }

                    if (!NET.CompareBaseAdr(Globals.net_from, cl.netchan.remote_address))
                    {
                        continue;
                    }

                    if (cl.netchan.qport != qport)
                    {
                        continue;
                    }

                    if (cl.netchan.remote_address.port != Globals.net_from.port)
                    {
                        Com.Printf("SV_ReadPackets: fixing up a translated port\n");
                        cl.netchan.remote_address.port = Globals.net_from.port;
                    }

                    if (Netchan.Process(cl.netchan, Globals.net_message))
                    {
                        // this is a valid, sequenced packet, so process it
                        if (cl.state != Defines.cs_zombie)
                        {
                            cl.lastmessage = SV_INIT.svs.realtime;                             // don't timeout
                            SV_USER.SV_ExecuteClientMessage(cl);
                        }
                    }

                    break;
                }

                if (i != SV_MAIN.maxclients.value)
                {
                    continue;
                }
            }
        }
Exemple #6
0
        /**
         * A connection request that did not come from the master.
         */
        public static void SVC_DirectConnect()
        {
            string   userinfo;
            netadr_t adr;
            int      i;
            client_t cl;

            int version;
            int qport;

            adr = Globals.net_from;

            Com.DPrintf("SVC_DirectConnect ()\n");

            version = Lib.atoi(Cmd.Argv(1));

            if (version != Defines.PROTOCOL_VERSION)
            {
                Netchan.OutOfBandPrint(Defines.NS_SERVER, adr, "print\nServer is version " + Globals.VERSION + "\n");
                Com.DPrintf("    rejected connect from version " + version + "\n");

                return;
            }

            qport = Lib.atoi(Cmd.Argv(2));
            var challenge = Lib.atoi(Cmd.Argv(3));

            userinfo = Cmd.Argv(4);

            // force the IP key/value pair so the game can filter based on ip
            userinfo = Info.Info_SetValueForKey(userinfo, "ip", NET.AdrToString(Globals.net_from));

            // attractloop servers are ONLY for local clients
            if (SV_INIT.sv.attractloop)
            {
                if (!NET.IsLocalAddress(adr))
                {
                    Com.Printf("Remote connect in attract loop.  Ignored.\n");
                    Netchan.OutOfBandPrint(Defines.NS_SERVER, adr, "print\nConnection refused.\n");

                    return;
                }
            }

            // see if the challenge is valid
            if (!NET.IsLocalAddress(adr))
            {
                for (i = 0; i < Defines.MAX_CHALLENGES; i++)
                {
                    if (NET.CompareBaseAdr(Globals.net_from, SV_INIT.svs.challenges[i].adr))
                    {
                        if (challenge == SV_INIT.svs.challenges[i].challenge)
                        {
                            break;                             // good
                        }
                        Netchan.OutOfBandPrint(Defines.NS_SERVER, adr, "print\nBad challenge.\n");

                        return;
                    }
                }

                if (i == Defines.MAX_CHALLENGES)
                {
                    Netchan.OutOfBandPrint(Defines.NS_SERVER, adr, "print\nNo challenge for address.\n");

                    return;
                }
            }

            // if there is already a slot for this ip, reuse it
            for (i = 0; i < SV_MAIN.maxclients.value; i++)
            {
                cl = SV_INIT.svs.clients[i];

                if (cl.state == Defines.cs_free)
                {
                    continue;
                }

                if (NET.CompareBaseAdr(adr, cl.netchan.remote_address) && (cl.netchan.qport == qport || adr.port == cl.netchan.remote_address.port))
                {
                    if (!NET.IsLocalAddress(adr) && SV_INIT.svs.realtime - cl.lastconnect < (int)SV_MAIN.sv_reconnect_limit.value * 1000)
                    {
                        Com.DPrintf(NET.AdrToString(adr) + ":reconnect rejected : too soon\n");

                        return;
                    }

                    Com.Printf(NET.AdrToString(adr) + ":reconnect\n");

                    SV_MAIN.gotnewcl(i, challenge, userinfo, adr, qport);

                    return;
                }
            }

            // find a client slot
            //newcl = null;
            var index = -1;

            for (i = 0; i < SV_MAIN.maxclients.value; i++)
            {
                cl = SV_INIT.svs.clients[i];

                if (cl.state == Defines.cs_free)
                {
                    index = i;

                    break;
                }
            }

            if (index == -1)
            {
                Netchan.OutOfBandPrint(Defines.NS_SERVER, adr, "print\nServer is full.\n");
                Com.DPrintf("Rejected a connection.\n");

                return;
            }

            SV_MAIN.gotnewcl(index, challenge, userinfo, adr, qport);
        }