diff --git a/src/network/core/config.h b/src/network/core/config.h index a641b021db..4a17036d8d 100644 --- a/src/network/core/config.h +++ b/src/network/core/config.h @@ -33,6 +33,7 @@ static const uint16 NETWORK_ADMIN_PORT = 3977; ///< The defau 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 SEND_MTU_SHORT = 1400; ///< Number of bytes we can pack in a single packet (conservative) 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? @@ -59,6 +60,7 @@ static const uint NETWORK_GRF_NAME_LENGTH = 80; ///< Maximum l * This limit is reached when PACKET_UDP_SERVER_RESPONSE reaches the maximum size of SEND_MTU bytes. */ static const uint NETWORK_MAX_GRF_COUNT = 62; +static const uint NETWORK_MAX_GRF_COUNT_SHORT = 59; static const uint NETWORK_NUM_LANGUAGES = 36; ///< Number of known languages (to the network protocol) + 1 for 'any'. diff --git a/src/network/core/udp.cpp b/src/network/core/udp.cpp index af1c1f813d..c75e0d9398 100644 --- a/src/network/core/udp.cpp +++ b/src/network/core/udp.cpp @@ -84,15 +84,17 @@ NetworkRecvStatus NetworkUDPSocketHandler::CloseConnection(bool error) * @param all send the packet using all sockets that can send it * @param broadcast whether to send a broadcast message */ -void NetworkUDPSocketHandler::SendPacket(Packet *p, NetworkAddress *recv, bool all, bool broadcast) +void NetworkUDPSocketHandler::SendPacket(Packet *p, NetworkAddress *recv, bool all, bool broadcast, bool short_mtu) { if (this->sockets.size() == 0) this->Listen(); - if (p->size > SEND_MTU) { + const uint MTU = short_mtu ? SEND_MTU_SHORT : SEND_MTU; + + if (p->size > MTU) { p->PrepareToSend(); uint64 token = this->fragment_token++; - const uint PAYLOAD_MTU = SEND_MTU - (1 + 2 + 8 + 1 + 1 + 2); + const uint PAYLOAD_MTU = MTU - (1 + 2 + 8 + 1 + 1 + 2); const uint8 frag_count = (p->size + PAYLOAD_MTU - 1) / PAYLOAD_MTU; @@ -108,7 +110,7 @@ void NetworkUDPSocketHandler::SendPacket(Packet *p, NetworkAddress *recv, bool a frag.Send_binary((const char *) p->buffer + offset, payload_size); current_frag++; offset += payload_size; - this->SendPacket(&frag, recv, all, broadcast); + this->SendPacket(&frag, recv, all, broadcast, short_mtu); frag.ResetState(PACKET_UDP_EX_MULTI); } assert_msg(current_frag == frag_count, "%u, %u", current_frag, frag_count); diff --git a/src/network/core/udp.h b/src/network/core/udp.h index 5728264f15..74718229fc 100644 --- a/src/network/core/udp.h +++ b/src/network/core/udp.h @@ -258,7 +258,7 @@ public: bool Listen(); void Close() override; - void SendPacket(Packet *p, NetworkAddress *recv, bool all = false, bool broadcast = false); + void SendPacket(Packet *p, NetworkAddress *recv, bool all = false, bool broadcast = false, bool short_mtu = false); void ReceivePackets(); void SendNetworkGameInfo(Packet *p, const NetworkGameInfo *info); diff --git a/src/network/network_content.cpp b/src/network/network_content.cpp index 4f28c9330d..adc96ee625 100644 --- a/src/network/network_content.cpp +++ b/src/network/network_content.cpp @@ -219,7 +219,7 @@ void ClientNetworkContentSocketHandler::RequestContentList(uint count, const Con * 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 = min(count, (SEND_MTU - sizeof(PacketSize) - sizeof(byte) - sizeof(uint16)) / sizeof(uint32)); + uint p_count = min(count, (SEND_MTU_SHORT - sizeof(PacketSize) - sizeof(byte) - sizeof(uint16)) / sizeof(uint32)); Packet *p = new Packet(PACKET_CONTENT_CLIENT_INFO_ID); p->Send_uint16(p_count); @@ -245,7 +245,7 @@ void ClientNetworkContentSocketHandler::RequestContentList(ContentVector *cv, bo this->Connect(); - const uint max_per_packet = min(255, (SEND_MTU - sizeof(PacketSize) - sizeof(byte) - sizeof(uint8)) / + const uint max_per_packet = min(255, (SEND_MTU_SHORT - sizeof(PacketSize) - sizeof(byte) - sizeof(uint8)) / (sizeof(uint8) + sizeof(uint32) + (send_md5sum ? /*sizeof(ContentInfo::md5sum)*/16 : 0))) - 1; uint offset = 0; @@ -361,7 +361,7 @@ void ClientNetworkContentSocketHandler::DownloadSelectedContentFallback(const Co * 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 = min(count, (SEND_MTU - sizeof(PacketSize) - sizeof(byte) - sizeof(uint16)) / sizeof(uint32)); + uint p_count = min(count, (SEND_MTU_SHORT - sizeof(PacketSize) - sizeof(byte) - sizeof(uint16)) / sizeof(uint32)); Packet *p = new Packet(PACKET_CONTENT_CLIENT_CONTENT); p->Send_uint16(p_count); diff --git a/src/network/network_udp.cpp b/src/network/network_udp.cpp index c72fef20a9..8ee0df01ef 100644 --- a/src/network/network_udp.cpp +++ b/src/network/network_udp.cpp @@ -205,7 +205,7 @@ void ServerNetworkUDPSocketHandler::Reply_CLIENT_FIND_SERVER_extended(Packet *p, this->SendNetworkGameInfoExtended(&packet, ngi, flags, version); /* Let the client know that we are here */ - this->SendPacket(&packet, client_addr); + this->SendPacket(&packet, client_addr, false, false, true); DEBUG(net, 2, "[udp] queried (extended: %u) from %s", version, client_addr->GetHostname()); } @@ -341,7 +341,7 @@ void ServerNetworkUDPSocketHandler::Receive_CLIENT_GET_NEWGRFS(Packet *p, Networ * The name could be an empty string, if so take the filename. */ size_t required_length = sizeof(info.ident.grfid) + sizeof(info.ident.md5sum) + min(strlen(info.name) + 1, (size_t)NETWORK_GRF_NAME_LENGTH); - if (packet_len + required_length > SEND_MTU - 4) { // 4 is 3 byte header + grf count in reply + if (packet_len + required_length > SEND_MTU_SHORT - 4) { // 4 is 3 byte header + grf count in reply flush_response(); } packet_len += required_length; @@ -432,7 +432,7 @@ void ClientNetworkUDPSocketHandler::Receive_SERVER_RESPONSE_Common(Packet *p, Ne if (c->status != GCS_NOT_FOUND || strcmp(c->GetName(), UNKNOWN_GRF_NAME_PLACEHOLDER) != 0) continue; in_request[in_request_count] = c; in_request_count++; - if (in_request_count == NETWORK_MAX_GRF_COUNT) flush_request(); + if (in_request_count == NETWORK_MAX_GRF_COUNT_SHORT) flush_request(); } if (in_request_count > 0) flush_request();