Exemplo n.º 1
0
        /// <summary
        /// advance the WFIFO cursor (marking 'len' bytes for sending)
        /// </sumary>
        public void WFIFOSET(int fd, int len)
        {
            int         newreserve;
            socket_data s = session[fd];

            if (!session_isValid(fd) || s.wdata <= 0)
            {
                return;
            }

            // we have written len bytes to the buffer already before calling WFIFOSET
            if (s.wdata_size + len > s.max_wdata)
            {   // actually there was a buffer overflow already
                IPAddress ip = s.client_addr;
                console.fatalerror("WFIFOSET: Write Buffer Overflow. Connection " + fd + " (" + ip.ToString() + ") has written " + len + " bytes on a " + s.wdata_size + "/" + s.max_wdata + " bytes buffer.");
                console.debug("Likely command that caused it: 0x" + (s.wdata + s.wdata_size).ToString("x"));
                // no other chance, make a better fifo model
                Environment.Exit(1);
            }

            if (len > 0xFFFF)
            {
                // dynamic packets allow up to UINT16_MAX bytes (<packet_id>.W <packet_len>.W ...)
                // all known fixed-size packets are within this limit, so use the same limit
                console.fatalerror("WFIFOSET: Packet 0x" + (s.wdata + s.wdata_size).ToString("x") + " is too big. (len=" + len + ", max=" + 0xFFFF + ")");
                Environment.Exit(1);
            }
            else if (len == 0)
            {
                // abuses the fact, that the code that did WFIFOHEAD(fd,0), already wrote
                // the packet type into memory, even if it could have overwritten vital data
                // this can happen when a new packet was added on map-server, but packet len table was not updated
                console.warning("WFIFOSET: Attempted to send zero-length packet, most likely 0x" + WFIFOW(fd, 0).ToString("x4") + " (please report this).");
                return;
            }

            if (!s.flag.server)
            {
                if (len > socket_max_client_packet)
                {// see declaration of socket_max_client_packet for details
                    console.error("WFIFOSET: Dropped too large client packet 0x" + WFIFOW(fd, 0).ToString("x4") + " (length=" + len + ", max=" + socket_max_client_packet + ").");
                    return;
                }
                if (s.wdata_size + len > WFIFO_MAX)
                {// reached maximum write fifo size
                    console.error("WFIFOSET: Maximum write buffer size for client connection " + fd + " exceeded, most likely caused by packet 0x" + WFIFOW(fd, 0).ToString("x4") + " (len=" + len + ", ip=" + s.client_addr.ToString() + ").");
                    set_eof(fd);
                    return;
                }
            }

            s.wdata_size += len;
            //If the interserver has 200% of its normal size full, flush the data.
            if (s.flag.server && s.wdata_size >= 2 * FIFOSIZE_SERVERLINK)
            {
                flush_fifo(fd);
            }

            return;
        }
Exemplo n.º 2
0
        public void socket_init(timer timer)
        {
            // Maximum packet size in bytes, which the client is able to handle.
            // Larger packets cause a buffer overflow and stack corruption.
            if (mmo.PACKETVER < 20131223)
            {
                socket_max_client_packet = 24576;
            }
            else
            {
                socket_max_client_packet = 65636;
            }

            string SOCKET_CONF_FILENAME = @"conf\packet_athena.conf";

            access_allow = new List <AccessControl>();
            access_deny  = new List <AccessControl>();

            session    = new socket_data[FD_SETSIZE];
            session[0] = new socket_data();

            // Get initial local ips
            addr_  = new short[16];
            naddr_ = getips(ref addr_, 16);

            if (SEND_SHORTLIST)
            {
                send_shortlist_set = new int[(FD_SETSIZE + 31) / 32];
            }

            config_read(SOCKET_CONF_FILENAME);

            // initialise last send-receive tick
            last_tick = timer.time(null);

            // session[0] is now currently used for disconnected sessions of the map server, and as such,
            // should hold enough buffer (it is a vacuum so to speak) as it is never flushed. [Skotlex]
            create_session(0);

            // Delete old connection history every 5 minutes
            connect_history = new ConnectHistory[0x10000];
            timer.add_timer_interval(timer.time(null) + 1000, "connect_check_clear", null, 0, 5 * 60 * 1000);

            console.info("Server supports up to '" + FD_SETSIZE + "' concurrent connections.");
        }