Changeset - r25270:0e1af506fef0
[Not reviewed]
master
0 8 0
Rubidium - 3 years ago 2021-04-18 12:49:39
rubidium@openttd.org
Codechange: differentiate between UDP, TCP and compatibility MTU values
8 files changed with 20 insertions and 18 deletions:
0 comments (0 inline, 0 general)
src/network/core/config.h
Show inline comments
 
@@ -30,7 +30,9 @@ static const uint16 NETWORK_DEFAULT_PORT
 
static const uint16 NETWORK_ADMIN_PORT            = 3977;         ///< The default port for admin network
 
static const uint16 NETWORK_DEFAULT_DEBUGLOG_PORT = 3982;         ///< The default port debug-log is sent to (TCP)
 

	
 
static const uint16 SEND_MTU                      = 1460;         ///< Number of bytes we can pack in a single packet
 
static const uint16 UDP_MTU                       = 1460;         ///< Number of bytes we can pack in a single UDP packet
 
static const uint16 TCP_MTU                       = 1460;         ///< Number of bytes we can pack in a single TCP packet
 
static const uint16 COMPAT_MTU                    = 1460;         ///< Number of bytes we can pack in a single packet for backward compatibility
 

	
 
static const byte NETWORK_GAME_ADMIN_VERSION      =    1;         ///< What version of the admin network do we use?
 
static const byte NETWORK_GAME_INFO_VERSION       =    4;         ///< What version of game-info do we use?
 
@@ -46,14 +48,14 @@ static const uint NETWORK_PASSWORD_LENGT
 
static const uint NETWORK_CLIENTS_LENGTH          =  200;         ///< The maximum length for the list of clients that controls a company, in bytes including '\0'
 
static const uint NETWORK_CLIENT_NAME_LENGTH      =   25;         ///< The maximum length of a client's name, in bytes including '\0'
 
static const uint NETWORK_RCONCOMMAND_LENGTH      =  500;         ///< The maximum length of a rconsole command, in bytes including '\0'
 
static const uint NETWORK_GAMESCRIPT_JSON_LENGTH  = SEND_MTU - 3; ///< The maximum length of a gamescript json string, in bytes including '\0'. Must not be longer than SEND_MTU including header (3 bytes)
 
static const uint NETWORK_GAMESCRIPT_JSON_LENGTH  = COMPAT_MTU-3; ///< The maximum length of a gamescript json string, in bytes including '\0'. Must not be longer than COMPAT_MTU including header (3 bytes)
 
static const uint NETWORK_CHAT_LENGTH             =  900;         ///< The maximum length of a chat message, in bytes including '\0'
 

	
 
static const uint NETWORK_GRF_NAME_LENGTH         =   80;         ///< Maximum length of the name of a GRF
 

	
 
/**
 
 * Maximum number of GRFs that can be sent.
 
 * This limit is reached when PACKET_UDP_SERVER_RESPONSE reaches the maximum size of SEND_MTU bytes.
 
 * This limit is reached when PACKET_UDP_SERVER_RESPONSE reaches the maximum size of UDP_MTU bytes.
 
 */
 
static const uint NETWORK_MAX_GRF_COUNT           =   62;
 

	
src/network/core/packet.cpp
Show inline comments
 
@@ -39,7 +39,7 @@ Packet::Packet(NetworkSocketHandler *cs,
 
/**
 
 * Creates a packet to send
 
 * @param type  The type of the packet to send
 
 * @param limit The maximum number of bytes the packet may have. Default is SEND_MTU.
 
 * @param limit The maximum number of bytes the packet may have. Default is COMPAT_MTU.
 
 *              Be careful of compatibility with older clients/servers when changing
 
 *              the limit as it might break things if the other side is not expecting
 
 *              much larger packets than what they support.
src/network/core/packet.h
Show inline comments
 
@@ -56,7 +56,7 @@ private:
 

	
 
public:
 
	Packet(NetworkSocketHandler *cs, size_t limit, size_t initial_read_size = sizeof(PacketSize));
 
	Packet(PacketType type, size_t limit = SEND_MTU);
 
	Packet(PacketType type, size_t limit = COMPAT_MTU);
 

	
 
	static void AddToQueue(Packet **queue, Packet *packet);
 
	static Packet *PopFromQueue(Packet **queue);
src/network/core/tcp.cpp
Show inline comments
 
@@ -126,7 +126,7 @@ Packet *NetworkTCPSocketHandler::Receive
 
	if (!this->IsConnected()) return nullptr;
 

	
 
	if (this->packet_recv == nullptr) {
 
		this->packet_recv = new Packet(this, SEND_MTU);
 
		this->packet_recv = new Packet(this, TCP_MTU);
 
	}
 

	
 
	Packet *p = this->packet_recv;
src/network/core/udp.cpp
Show inline comments
 
@@ -119,8 +119,8 @@ void NetworkUDPSocketHandler::ReceivePac
 
			struct sockaddr_storage client_addr;
 
			memset(&client_addr, 0, sizeof(client_addr));
 

	
 
			/* The limit is SEND_MTU, but also allocate that much as we need to read the whole packet in one go. */
 
			Packet p(this, SEND_MTU, SEND_MTU);
 
			/* The limit is UDP_MTU, but also allocate that much as we need to read the whole packet in one go. */
 
			Packet p(this, UDP_MTU, UDP_MTU);
 
			socklen_t client_len = sizeof(client_addr);
 

	
 
			/* Try to receive anything */
src/network/network_admin.cpp
Show inline comments
 
@@ -560,8 +560,8 @@ NetworkRecvStatus ServerNetworkAdminSock
 
	/* If the length of both strings, plus the 2 '\0' terminations and 3 bytes of the packet
 
	 * are bigger than the MTU, just ignore the message. Better safe than sorry. It should
 
	 * never occur though as the longest strings are chat messages, which are still 30%
 
	 * smaller than SEND_MTU. */
 
	if (strlen(origin) + strlen(string) + 2 + 3 >= SEND_MTU) return NETWORK_RECV_STATUS_OKAY;
 
	 * smaller than COMPAT_MTU. */
 
	if (strlen(origin) + strlen(string) + 2 + 3 >= COMPAT_MTU) return NETWORK_RECV_STATUS_OKAY;
 

	
 
	Packet *p = new Packet(ADMIN_PACKET_SERVER_CONSOLE);
 

	
 
@@ -610,7 +610,7 @@ NetworkRecvStatus ServerNetworkAdminSock
 
	for (uint i = 0; i < CMD_END; i++) {
 
		const char *cmdname = GetCommandName(i);
 

	
 
		/* Should SEND_MTU be exceeded, start a new packet
 
		/* Should COMPAT_MTU be exceeded, start a new packet
 
		 * (magic 5: 1 bool "more data" and one uint16 "command id", one
 
		 * byte for string '\0' termination and 1 bool "no more data" */
 
		if (p->CanWriteToPacket(strlen(cmdname) + 5)) {
src/network/network_content.cpp
Show inline comments
 
@@ -221,9 +221,9 @@ void ClientNetworkContentSocketHandler::
 
		 * A packet begins with the packet size and a byte for the type.
 
		 * Then this packet adds a uint16 for the count in this packet.
 
		 * The rest of the packet can be used for the IDs. */
 
		uint p_count = std::min<uint>(count, (SEND_MTU - sizeof(PacketSize) - sizeof(byte) - sizeof(uint16)) / sizeof(uint32));
 
		uint p_count = std::min<uint>(count, (COMPAT_MTU - sizeof(PacketSize) - sizeof(byte) - sizeof(uint16)) / sizeof(uint32));
 

	
 
		Packet *p = new Packet(PACKET_CONTENT_CLIENT_INFO_ID);
 
		Packet *p = new Packet(PACKET_CONTENT_CLIENT_INFO_ID, COMPAT_MTU);
 
		p->Send_uint16(p_count);
 

	
 
		for (uint i = 0; i < p_count; i++) {
 
@@ -248,7 +248,7 @@ void ClientNetworkContentSocketHandler::
 
	this->Connect();
 

	
 
	assert(cv->size() < 255);
 
	assert(cv->size() < (SEND_MTU - sizeof(PacketSize) - sizeof(byte) - sizeof(uint8)) /
 
	assert(cv->size() < (COMPAT_MTU - sizeof(PacketSize) - sizeof(byte) - sizeof(uint8)) /
 
			(sizeof(uint8) + sizeof(uint32) + (send_md5sum ? /*sizeof(ContentInfo::md5sum)*/16 : 0)));
 

	
 
	Packet *p = new Packet(send_md5sum ? PACKET_CONTENT_CLIENT_INFO_EXTID_MD5 : PACKET_CONTENT_CLIENT_INFO_EXTID);
 
@@ -363,7 +363,7 @@ void ClientNetworkContentSocketHandler::
 
		 * A packet begins with the packet size and a byte for the type.
 
		 * Then this packet adds a uint16 for the count in this packet.
 
		 * The rest of the packet can be used for the IDs. */
 
		uint p_count = std::min<uint>(count, (SEND_MTU - sizeof(PacketSize) - sizeof(byte) - sizeof(uint16)) / sizeof(uint32));
 
		uint p_count = std::min<uint>(count, (COMPAT_MTU - sizeof(PacketSize) - sizeof(byte) - sizeof(uint16)) / sizeof(uint32));
 

	
 
		Packet *p = new Packet(PACKET_CONTENT_CLIENT_CONTENT);
 
		p->Send_uint16(p_count);
src/network/network_udp.cpp
Show inline comments
 
@@ -256,10 +256,10 @@ void ServerNetworkUDPSocketHandler::Rece
 
/**
 
 * A client has requested the names of some NewGRFs.
 
 *
 
 * Replying this can be tricky as we have a limit of SEND_MTU bytes
 
 * Replying this can be tricky as we have a limit of UDP_MTU bytes
 
 * in the reply packet and we can send up to 100 bytes per NewGRF
 
 * (GRF ID, MD5sum and NETWORK_GRF_NAME_LENGTH bytes for the name).
 
 * As SEND_MTU is _much_ less than 100 * NETWORK_MAX_GRF_COUNT, it
 
 * As UDP_MTU is _much_ less than 100 * NETWORK_MAX_GRF_COUNT, it
 
 * could be that a packet overflows. To stop this we only reply
 
 * with the first N NewGRFs so that if the first N + 1 NewGRFs
 
 * would be sent, the packet overflows.
 
@@ -295,7 +295,7 @@ void ServerNetworkUDPSocketHandler::Rece
 
		 * The name could be an empty string, if so take the filename. */
 
		packet_len += sizeof(c.grfid) + sizeof(c.md5sum) +
 
				std::min(strlen(f->GetName()) + 1, (size_t)NETWORK_GRF_NAME_LENGTH);
 
		if (packet_len > SEND_MTU - 4) { // 4 is 3 byte header + grf count in reply
 
		if (packet_len > UDP_MTU - 4) { // 4 is 3 byte header + grf count in reply
 
			break;
 
		}
 
		in_reply[in_reply_count] = f;
0 comments (0 inline, 0 general)