/// <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; }
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."); }