Network: Use shorter UDP MTU where data can be split across multiple packets.
This commit is contained in:
@@ -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 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 = 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_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?
|
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.
|
* 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 = 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'.
|
static const uint NETWORK_NUM_LANGUAGES = 36; ///< Number of known languages (to the network protocol) + 1 for 'any'.
|
||||||
|
|
||||||
|
@@ -84,15 +84,17 @@ NetworkRecvStatus NetworkUDPSocketHandler::CloseConnection(bool error)
|
|||||||
* @param all send the packet using all sockets that can send it
|
* @param all send the packet using all sockets that can send it
|
||||||
* @param broadcast whether to send a broadcast message
|
* @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 (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();
|
p->PrepareToSend();
|
||||||
|
|
||||||
uint64 token = this->fragment_token++;
|
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;
|
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);
|
frag.Send_binary((const char *) p->buffer + offset, payload_size);
|
||||||
current_frag++;
|
current_frag++;
|
||||||
offset += payload_size;
|
offset += payload_size;
|
||||||
this->SendPacket(&frag, recv, all, broadcast);
|
this->SendPacket(&frag, recv, all, broadcast, short_mtu);
|
||||||
frag.ResetState(PACKET_UDP_EX_MULTI);
|
frag.ResetState(PACKET_UDP_EX_MULTI);
|
||||||
}
|
}
|
||||||
assert_msg(current_frag == frag_count, "%u, %u", current_frag, frag_count);
|
assert_msg(current_frag == frag_count, "%u, %u", current_frag, frag_count);
|
||||||
|
@@ -258,7 +258,7 @@ public:
|
|||||||
bool Listen();
|
bool Listen();
|
||||||
void Close() override;
|
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 ReceivePackets();
|
||||||
|
|
||||||
void SendNetworkGameInfo(Packet *p, const NetworkGameInfo *info);
|
void SendNetworkGameInfo(Packet *p, const NetworkGameInfo *info);
|
||||||
|
@@ -219,7 +219,7 @@ void ClientNetworkContentSocketHandler::RequestContentList(uint count, const Con
|
|||||||
* A packet begins with the packet size and a byte for the type.
|
* 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.
|
* Then this packet adds a uint16 for the count in this packet.
|
||||||
* The rest of the packet can be used for the IDs. */
|
* 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);
|
Packet *p = new Packet(PACKET_CONTENT_CLIENT_INFO_ID);
|
||||||
p->Send_uint16(p_count);
|
p->Send_uint16(p_count);
|
||||||
@@ -245,7 +245,7 @@ void ClientNetworkContentSocketHandler::RequestContentList(ContentVector *cv, bo
|
|||||||
|
|
||||||
this->Connect();
|
this->Connect();
|
||||||
|
|
||||||
const uint max_per_packet = min<uint>(255, (SEND_MTU - sizeof(PacketSize) - sizeof(byte) - sizeof(uint8)) /
|
const uint max_per_packet = min<uint>(255, (SEND_MTU_SHORT - sizeof(PacketSize) - sizeof(byte) - sizeof(uint8)) /
|
||||||
(sizeof(uint8) + sizeof(uint32) + (send_md5sum ? /*sizeof(ContentInfo::md5sum)*/16 : 0))) - 1;
|
(sizeof(uint8) + sizeof(uint32) + (send_md5sum ? /*sizeof(ContentInfo::md5sum)*/16 : 0))) - 1;
|
||||||
|
|
||||||
uint offset = 0;
|
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.
|
* 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.
|
* Then this packet adds a uint16 for the count in this packet.
|
||||||
* The rest of the packet can be used for the IDs. */
|
* 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);
|
Packet *p = new Packet(PACKET_CONTENT_CLIENT_CONTENT);
|
||||||
p->Send_uint16(p_count);
|
p->Send_uint16(p_count);
|
||||||
|
@@ -205,7 +205,7 @@ void ServerNetworkUDPSocketHandler::Reply_CLIENT_FIND_SERVER_extended(Packet *p,
|
|||||||
this->SendNetworkGameInfoExtended(&packet, ngi, flags, version);
|
this->SendNetworkGameInfoExtended(&packet, ngi, flags, version);
|
||||||
|
|
||||||
/* Let the client know that we are here */
|
/* 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());
|
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. */
|
* The name could be an empty string, if so take the filename. */
|
||||||
size_t required_length = sizeof(info.ident.grfid) + sizeof(info.ident.md5sum) +
|
size_t required_length = sizeof(info.ident.grfid) + sizeof(info.ident.md5sum) +
|
||||||
min(strlen(info.name) + 1, (size_t)NETWORK_GRF_NAME_LENGTH);
|
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();
|
flush_response();
|
||||||
}
|
}
|
||||||
packet_len += required_length;
|
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;
|
if (c->status != GCS_NOT_FOUND || strcmp(c->GetName(), UNKNOWN_GRF_NAME_PLACEHOLDER) != 0) continue;
|
||||||
in_request[in_request_count] = c;
|
in_request[in_request_count] = c;
|
||||||
in_request_count++;
|
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();
|
if (in_request_count > 0) flush_request();
|
||||||
|
Reference in New Issue
Block a user