Use a lower default MTU for ENet hosts, and make it configurable.
This fixes packet loss issues on some VPN solutions. Patch By: sera Differential Revision: https://code.wildfiregames.com/D4967 This was SVN commit r27599.
This commit is contained in:
parent
ac3d187dcd
commit
ef71533d70
@ -525,6 +525,7 @@ lateobservers = everyone ; Allow observers to join the game after it st
|
|||||||
observerlimit = 8 ; Prevent further observer joins in running games if this limit is reached
|
observerlimit = 8 ; Prevent further observer joins in running games if this limit is reached
|
||||||
observermaxlag = -1 ; Make clients wait for observers if they lag more than X turns behind. -1 means "never wait for observers".
|
observermaxlag = -1 ; Make clients wait for observers if they lag more than X turns behind. -1 means "never wait for observers".
|
||||||
autocatchup = true ; Auto-accelerate the sim rate if lagging behind (as an observer).
|
autocatchup = true ; Auto-accelerate the sim rate if lagging behind (as an observer).
|
||||||
|
enetmtu = 1372 ; Lower ENet protocol MTU in case packets get further fragmented on the UDP layer which may cause drops.
|
||||||
|
|
||||||
[overlay]
|
[overlay]
|
||||||
fps = "false" ; Show frames per second in top right corner
|
fps = "false" ; Show frames per second in top right corner
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
/* Copyright (C) 2022 Wildfire Games.
|
/* Copyright (C) 2023 Wildfire Games.
|
||||||
* This file is part of 0 A.D.
|
* This file is part of 0 A.D.
|
||||||
*
|
*
|
||||||
* 0 A.D. is free software: you can redistribute it and/or modify
|
* 0 A.D. is free software: you can redistribute it and/or modify
|
||||||
@ -20,6 +20,7 @@
|
|||||||
#include "NetClient.h"
|
#include "NetClient.h"
|
||||||
|
|
||||||
#include "NetClientTurnManager.h"
|
#include "NetClientTurnManager.h"
|
||||||
|
#include "NetEnet.h"
|
||||||
#include "NetMessage.h"
|
#include "NetMessage.h"
|
||||||
#include "NetSession.h"
|
#include "NetSession.h"
|
||||||
|
|
||||||
@ -247,7 +248,7 @@ bool CNetClient::TryToConnect(const CStr& hostJID, bool localNetwork)
|
|||||||
}
|
}
|
||||||
|
|
||||||
ENetAddress hostAddr{ ENET_HOST_ANY, ENET_PORT_ANY };
|
ENetAddress hostAddr{ ENET_HOST_ANY, ENET_PORT_ANY };
|
||||||
ENetHost* enetClient = enet_host_create(&hostAddr, 1, 1, 0, 0);
|
ENetHost* enetClient = PS::Enet::CreateHost(&hostAddr, 1, 1);
|
||||||
|
|
||||||
if (!enetClient)
|
if (!enetClient)
|
||||||
{
|
{
|
||||||
|
62
source/network/NetEnet.cpp
Normal file
62
source/network/NetEnet.cpp
Normal file
@ -0,0 +1,62 @@
|
|||||||
|
/* Copyright (C) 2023 Wildfire Games.
|
||||||
|
* This file is part of 0 A.D.
|
||||||
|
*
|
||||||
|
* 0 A.D. is free software: you can redistribute it and/or modify
|
||||||
|
* it under the terms of the GNU General Public License as published by
|
||||||
|
* the Free Software Foundation, either version 2 of the License, or
|
||||||
|
* (at your option) any later version.
|
||||||
|
*
|
||||||
|
* 0 A.D. is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
* GNU General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU General Public License
|
||||||
|
* along with 0 A.D. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "precompiled.h"
|
||||||
|
|
||||||
|
#include "NetEnet.h"
|
||||||
|
|
||||||
|
#include "ps/ConfigDB.h"
|
||||||
|
#include "ps/containers/Span.h"
|
||||||
|
|
||||||
|
namespace PS
|
||||||
|
{
|
||||||
|
|
||||||
|
namespace Enet
|
||||||
|
{
|
||||||
|
|
||||||
|
// ENet protocol MTU
|
||||||
|
// ENet by default uses 1400 as ENet packet fragment max size, adding ICMP and
|
||||||
|
// IPv4 headers this may exceed the MTU for some VPN solutions [1], so provide
|
||||||
|
// a lower default.
|
||||||
|
// MTU negotiation server-side needs [2], which was merged after enet-1.3.17,
|
||||||
|
// so the user configured value may be ignored on older versions.
|
||||||
|
// [1] https://github.com/lsalzman/enet/issues/132
|
||||||
|
// [2] https://github.com/lsalzman/enet/pull/222
|
||||||
|
constexpr enet_uint32 HOST_DEFAULT_MTU = 1372;
|
||||||
|
|
||||||
|
ENetHost* CreateHost(const ENetAddress* address, size_t peerCount, size_t channelLimit)
|
||||||
|
{
|
||||||
|
// TODO: Maybe allow user to set rate limits?
|
||||||
|
|
||||||
|
ENetHost* host = enet_host_create(address, peerCount, channelLimit, 0, 0);
|
||||||
|
if (!host)
|
||||||
|
return nullptr;
|
||||||
|
|
||||||
|
// Public ENet API doesn't offer a means to change MTU, so do it in a
|
||||||
|
// way least likely to break with ENet updates.
|
||||||
|
enet_uint32 mtu = HOST_DEFAULT_MTU;
|
||||||
|
CFG_GET_VAL("network.enetmtu", mtu);
|
||||||
|
host->mtu = mtu;
|
||||||
|
for (ENetPeer& p : PS::span{host->peers, host->peerCount})
|
||||||
|
enet_peer_reset(&p);
|
||||||
|
|
||||||
|
return host;
|
||||||
|
}
|
||||||
|
|
||||||
|
} // namespace Enet
|
||||||
|
|
||||||
|
} // namespace PS
|
44
source/network/NetEnet.h
Normal file
44
source/network/NetEnet.h
Normal file
@ -0,0 +1,44 @@
|
|||||||
|
/* Copyright (C) 2023 Wildfire Games.
|
||||||
|
*
|
||||||
|
* Permission is hereby granted, free of charge, to any person obtaining
|
||||||
|
* a copy of this software and associated documentation files (the
|
||||||
|
* "Software"), to deal in the Software without restriction, including
|
||||||
|
* without limitation the rights to use, copy, modify, merge, publish,
|
||||||
|
* distribute, sublicense, and/or sell copies of the Software, and to
|
||||||
|
* permit persons to whom the Software is furnished to do so, subject to
|
||||||
|
* the following conditions:
|
||||||
|
*
|
||||||
|
* The above copyright notice and this permission notice shall be included
|
||||||
|
* in all copies or substantial portions of the Software.
|
||||||
|
*
|
||||||
|
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
||||||
|
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
||||||
|
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
|
||||||
|
* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
|
||||||
|
* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
|
||||||
|
* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
|
||||||
|
* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef INCLUDED_NETENET
|
||||||
|
#define INCLUDED_NETENET
|
||||||
|
|
||||||
|
#include "lib/external_libraries/enet.h"
|
||||||
|
|
||||||
|
namespace PS
|
||||||
|
{
|
||||||
|
|
||||||
|
namespace Enet
|
||||||
|
{
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Wrapper for enet_host_create setting default values and custom mtu, taking
|
||||||
|
* care of user configuration.
|
||||||
|
*/
|
||||||
|
ENetHost* CreateHost(const ENetAddress* address, size_t peerCount, size_t channelLimit);
|
||||||
|
|
||||||
|
} // namespace Enet
|
||||||
|
|
||||||
|
} // namespace PS
|
||||||
|
|
||||||
|
#endif // #ifndef INCLUDED_NETENET
|
@ -1,4 +1,4 @@
|
|||||||
/* Copyright (C) 2022 Wildfire Games.
|
/* Copyright (C) 2023 Wildfire Games.
|
||||||
* This file is part of 0 A.D.
|
* This file is part of 0 A.D.
|
||||||
*
|
*
|
||||||
* 0 A.D. is free software: you can redistribute it and/or modify
|
* 0 A.D. is free software: you can redistribute it and/or modify
|
||||||
@ -20,6 +20,7 @@
|
|||||||
#include "NetServer.h"
|
#include "NetServer.h"
|
||||||
|
|
||||||
#include "NetClient.h"
|
#include "NetClient.h"
|
||||||
|
#include "NetEnet.h"
|
||||||
#include "NetMessage.h"
|
#include "NetMessage.h"
|
||||||
#include "NetSession.h"
|
#include "NetSession.h"
|
||||||
#include "NetServerTurnManager.h"
|
#include "NetServerTurnManager.h"
|
||||||
@ -223,7 +224,7 @@ bool CNetServerWorker::SetupConnection(const u16 port)
|
|||||||
addr.port = port;
|
addr.port = port;
|
||||||
|
|
||||||
// Create ENet server
|
// Create ENet server
|
||||||
m_Host = enet_host_create(&addr, MAX_CLIENTS, CHANNEL_COUNT, 0, 0);
|
m_Host = PS::Enet::CreateHost(&addr, MAX_CLIENTS, CHANNEL_COUNT);
|
||||||
if (!m_Host)
|
if (!m_Host)
|
||||||
{
|
{
|
||||||
LOGERROR("Net server: enet_host_create failed");
|
LOGERROR("Net server: enet_host_create failed");
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
/* Copyright (C) 2021 Wildfire Games.
|
/* Copyright (C) 2023 Wildfire Games.
|
||||||
* This file is part of 0 A.D.
|
* This file is part of 0 A.D.
|
||||||
*
|
*
|
||||||
* 0 A.D. is free software: you can redistribute it and/or modify
|
* 0 A.D. is free software: you can redistribute it and/or modify
|
||||||
@ -20,6 +20,7 @@
|
|||||||
#include "NetSession.h"
|
#include "NetSession.h"
|
||||||
|
|
||||||
#include "NetClient.h"
|
#include "NetClient.h"
|
||||||
|
#include "NetEnet.h"
|
||||||
#include "NetMessage.h"
|
#include "NetMessage.h"
|
||||||
#include "NetServer.h"
|
#include "NetServer.h"
|
||||||
#include "NetStats.h"
|
#include "NetStats.h"
|
||||||
@ -60,12 +61,8 @@ bool CNetClientSession::Connect(const CStr& server, const u16 port, ENetHost* en
|
|||||||
ENSURE(!m_Host);
|
ENSURE(!m_Host);
|
||||||
ENSURE(!m_Server);
|
ENSURE(!m_Server);
|
||||||
|
|
||||||
// Create ENet host
|
// Create ENet host if necessary.
|
||||||
ENetHost* host;
|
ENetHost* host = enetClient != nullptr ? enetClient : PS::Enet::CreateHost(nullptr, 1, CHANNEL_COUNT);
|
||||||
if (enetClient != nullptr)
|
|
||||||
host = enetClient;
|
|
||||||
else
|
|
||||||
host = enet_host_create(NULL, 1, CHANNEL_COUNT, 0, 0);
|
|
||||||
|
|
||||||
if (!host)
|
if (!host)
|
||||||
return false;
|
return false;
|
||||||
|
Loading…
Reference in New Issue
Block a user