Merge 0d03ddfae9
into 1ba8541da9
This commit is contained in:
commit
6388365306
|
@ -69,9 +69,6 @@
|
||||||
[submodule "Externals/xxhash/xxHash"]
|
[submodule "Externals/xxhash/xxHash"]
|
||||||
path = Externals/xxhash/xxHash
|
path = Externals/xxhash/xxHash
|
||||||
url = https://github.com/Cyan4973/xxHash.git
|
url = https://github.com/Cyan4973/xxHash.git
|
||||||
[submodule "Externals/enet/enet"]
|
|
||||||
path = Externals/enet/enet
|
|
||||||
url = https://github.com/lsalzman/enet.git
|
|
||||||
[submodule "hidapi-src"]
|
[submodule "hidapi-src"]
|
||||||
path = Externals/hidapi/hidapi-src
|
path = Externals/hidapi/hidapi-src
|
||||||
url = https://github.com/libusb/hidapi
|
url = https://github.com/libusb/hidapi
|
||||||
|
@ -84,3 +81,6 @@
|
||||||
[submodule "Externals/Vulkan-Headers"]
|
[submodule "Externals/Vulkan-Headers"]
|
||||||
path = Externals/Vulkan-Headers
|
path = Externals/Vulkan-Headers
|
||||||
url = https://github.com/KhronosGroup/Vulkan-Headers.git
|
url = https://github.com/KhronosGroup/Vulkan-Headers.git
|
||||||
|
[submodule "enet"]
|
||||||
|
path = Externals/enet/enet
|
||||||
|
url = https://github.com/freeminer/enet.git
|
||||||
|
|
|
@ -660,7 +660,10 @@ endif()
|
||||||
|
|
||||||
dolphin_find_optional_system_library(pugixml Externals/pugixml)
|
dolphin_find_optional_system_library(pugixml Externals/pugixml)
|
||||||
|
|
||||||
dolphin_find_optional_system_library_pkgconfig(ENET libenet>=1.3.18 enet::enet Externals/enet)
|
# Using static enet from Externals since we are using a fork that supports
|
||||||
|
# IPv6 (freeminers/enet)
|
||||||
|
message(STATUS "Using static enet from Externals (freeminer/enet)")
|
||||||
|
add_subdirectory(Externals/enet)
|
||||||
|
|
||||||
dolphin_find_optional_system_library_pkgconfig(xxhash libxxhash>=0.8.2 xxhash::xxhash Externals/xxhash)
|
dolphin_find_optional_system_library_pkgconfig(xxhash libxxhash>=0.8.2 xxhash::xxhash Externals/xxhash)
|
||||||
|
|
||||||
|
|
|
@ -1 +1 @@
|
||||||
Subproject commit 2a85cd64459f6ba038d233a634d9440490dbba12
|
Subproject commit 9a74b511091a172cd78bf57f0d4a440f41600de1
|
|
@ -18,7 +18,7 @@ void WakeupThread(ENetHost* host)
|
||||||
address.port = host->address.port;
|
address.port = host->address.port;
|
||||||
else
|
else
|
||||||
enet_socket_get_address(host->socket, &address);
|
enet_socket_get_address(host->socket, &address);
|
||||||
address.host = 0x0100007f; // localhost
|
address.host = in6addr_loopback; // localhost or ::1
|
||||||
u8 byte = 0;
|
u8 byte = 0;
|
||||||
ENetBuffer buf;
|
ENetBuffer buf;
|
||||||
buf.data = &byte;
|
buf.data = &byte;
|
||||||
|
@ -62,4 +62,22 @@ bool SendPacket(ENetPeer* socket, const sf::Packet& packet, u8 channel_id)
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
std::optional<in6_addr> AddressFromString(const std::string& addr_str)
|
||||||
|
{
|
||||||
|
in6_addr addr;
|
||||||
|
memset(&addr, 0, sizeof(in6_addr));
|
||||||
|
if (!inet_pton(AF_INET6, addr_str.c_str(), &addr))
|
||||||
|
{
|
||||||
|
in_addr addr_v4;
|
||||||
|
if (!inet_pton(AF_INET, addr_str.c_str(), &addr_v4)) {
|
||||||
|
return {};
|
||||||
|
}
|
||||||
|
|
||||||
|
u32 v6_mapped_addr[4] = {0, 0, htonl(0x0000ffff), *reinterpret_cast<u32*>(&addr_v4)};
|
||||||
|
memcpy(&addr, v6_mapped_addr, sizeof(in6_addr));
|
||||||
|
}
|
||||||
|
|
||||||
|
return addr;
|
||||||
|
}
|
||||||
} // namespace Common::ENet
|
} // namespace Common::ENet
|
||||||
|
|
|
@ -7,6 +7,7 @@
|
||||||
|
|
||||||
#include <SFML/Network/Packet.hpp>
|
#include <SFML/Network/Packet.hpp>
|
||||||
#include <enet/enet.h>
|
#include <enet/enet.h>
|
||||||
|
#include <optional>
|
||||||
|
|
||||||
#include "Common/CommonTypes.h"
|
#include "Common/CommonTypes.h"
|
||||||
|
|
||||||
|
@ -21,6 +22,7 @@ using ENetHostPtr = std::unique_ptr<ENetHost, ENetHostDeleter>;
|
||||||
void WakeupThread(ENetHost* host);
|
void WakeupThread(ENetHost* host);
|
||||||
int ENET_CALLBACK InterceptCallback(ENetHost* host, ENetEvent* event);
|
int ENET_CALLBACK InterceptCallback(ENetHost* host, ENetEvent* event);
|
||||||
bool SendPacket(ENetPeer* socket, const sf::Packet& packet, u8 channel_id);
|
bool SendPacket(ENetPeer* socket, const sf::Packet& packet, u8 channel_id);
|
||||||
|
std::optional<in6_addr> AddressFromString(const std::string& addr);
|
||||||
|
|
||||||
// used for traversal packets and wake-up packets
|
// used for traversal packets and wake-up packets
|
||||||
constexpr int SKIPPABLE_EVENT = 42;
|
constexpr int SKIPPABLE_EVENT = 42;
|
||||||
|
|
|
@ -20,13 +20,13 @@ QoSSession::QoSSession(ENetPeer* peer, int tos_val) : m_peer(peer)
|
||||||
if (!QOSCreateHandle(&ver, &m_qos_handle))
|
if (!QOSCreateHandle(&ver, &m_qos_handle))
|
||||||
return;
|
return;
|
||||||
|
|
||||||
sockaddr_in sin = {};
|
sockaddr_in6 sin6 = {};
|
||||||
|
|
||||||
sin.sin_family = AF_INET;
|
sin6.sin6_family = AF_INET6;
|
||||||
sin.sin_port = ENET_HOST_TO_NET_16(peer->host->address.port);
|
sin6.sin6_port = ENET_HOST_TO_NET_16(peer->host->address.port);
|
||||||
sin.sin_addr.s_addr = peer->host->address.host;
|
memcpy(&sin6.sin6_addr, &peer->host->address.host, sizeof(struct in6_addr));
|
||||||
|
|
||||||
if (QOSAddSocketToFlow(m_qos_handle, peer->host->socket, reinterpret_cast<PSOCKADDR>(&sin),
|
if (QOSAddSocketToFlow(m_qos_handle, peer->host->socket, reinterpret_cast<PSOCKADDR>(&sin6),
|
||||||
QOSTrafficTypeControl, QOS_NON_ADAPTIVE_FLOW, &m_qos_flow_id))
|
QOSTrafficTypeControl, QOS_NON_ADAPTIVE_FLOW, &m_qos_flow_id))
|
||||||
{
|
{
|
||||||
// We shift the complete ToS value by 3 to get rid of the 3 bit ECN field
|
// We shift the complete ToS value by 3 to get rid of the 3 bit ECN field
|
||||||
|
|
|
@ -49,12 +49,17 @@ TraversalClient::FailureReason TraversalClient::GetFailureReason() const
|
||||||
|
|
||||||
void TraversalClient::ReconnectToServer()
|
void TraversalClient::ReconnectToServer()
|
||||||
{
|
{
|
||||||
if (enet_address_set_host(&m_ServerAddress, m_Server.c_str()))
|
if (auto addr = Common::ENet::AddressFromString(m_Server))
|
||||||
|
{
|
||||||
|
m_ServerAddress.host = *addr;
|
||||||
|
}
|
||||||
|
else
|
||||||
{
|
{
|
||||||
OnFailure(FailureReason::BadHost);
|
OnFailure(FailureReason::BadHost);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
m_ServerAddress.port = m_port;
|
m_ServerAddress.port = m_port;
|
||||||
|
m_ServerAddress.sin6_scope_id = 0;
|
||||||
|
|
||||||
m_State = State::Connecting;
|
m_State = State::Connecting;
|
||||||
|
|
||||||
|
@ -71,12 +76,16 @@ static ENetAddress MakeENetAddress(const TraversalInetAddress& address)
|
||||||
ENetAddress eaddr{};
|
ENetAddress eaddr{};
|
||||||
if (address.isIPV6)
|
if (address.isIPV6)
|
||||||
{
|
{
|
||||||
eaddr.port = 0; // no support yet :(
|
memcpy(&eaddr.host, &address.address, sizeof(address.address));
|
||||||
|
eaddr.port = ntohs(address.port);
|
||||||
|
eaddr.sin6_scope_id = 0;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
eaddr.host = address.address[0];
|
u32 ipv4_mapped_addr[4] = {0, 0, 0xffff0000, address.address[0]};
|
||||||
|
memcpy(&eaddr.host, &ipv4_mapped_addr, sizeof(ipv4_mapped_addr));
|
||||||
eaddr.port = ntohs(address.port);
|
eaddr.port = ntohs(address.port);
|
||||||
|
eaddr.sin6_scope_id = 0;
|
||||||
}
|
}
|
||||||
return eaddr;
|
return eaddr;
|
||||||
}
|
}
|
||||||
|
@ -97,7 +106,7 @@ void TraversalClient::ConnectToClient(std::string_view host)
|
||||||
|
|
||||||
bool TraversalClient::TestPacket(u8* data, size_t size, ENetAddress* from)
|
bool TraversalClient::TestPacket(u8* data, size_t size, ENetAddress* from)
|
||||||
{
|
{
|
||||||
if (from->host == m_ServerAddress.host && from->port == m_ServerAddress.port)
|
if (in6_equal(from->host, m_ServerAddress.host) && from->port == m_ServerAddress.port)
|
||||||
{
|
{
|
||||||
if (size < sizeof(TraversalPacket))
|
if (size < sizeof(TraversalPacket))
|
||||||
{
|
{
|
||||||
|
@ -299,7 +308,7 @@ void TraversalClient::NewTraversalTest()
|
||||||
if (m_TestSocket != ENET_SOCKET_NULL)
|
if (m_TestSocket != ENET_SOCKET_NULL)
|
||||||
enet_socket_destroy(m_TestSocket);
|
enet_socket_destroy(m_TestSocket);
|
||||||
m_TestSocket = enet_socket_create(ENET_SOCKET_TYPE_DATAGRAM);
|
m_TestSocket = enet_socket_create(ENET_SOCKET_TYPE_DATAGRAM);
|
||||||
ENetAddress addr = {ENET_HOST_ANY, 0};
|
ENetAddress addr = {in6addr_any, 0, 0};
|
||||||
if (m_TestSocket == ENET_SOCKET_NULL || enet_socket_bind(m_TestSocket, &addr) < 0)
|
if (m_TestSocket == ENET_SOCKET_NULL || enet_socket_bind(m_TestSocket, &addr) < 0)
|
||||||
{
|
{
|
||||||
// error, abort
|
// error, abort
|
||||||
|
@ -373,8 +382,8 @@ void TraversalClient::HandleTraversalTest()
|
||||||
waitCondition = 0;
|
waitCondition = 0;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
else if (rv < int(sizeof(packet)) || raddr.host != m_ServerAddress.host ||
|
else if (rv < int(sizeof(packet)) || !in6_equal(raddr.host, m_ServerAddress.host) ||
|
||||||
raddr.host != m_portAlt || packet.requestId != m_TestRequestId)
|
raddr.port != m_portAlt || packet.requestId != m_TestRequestId)
|
||||||
{
|
{
|
||||||
// irrelevant packet, ignore
|
// irrelevant packet, ignore
|
||||||
continue;
|
continue;
|
||||||
|
@ -452,7 +461,7 @@ bool EnsureTraversalClient(const std::string& server, u16 server_port, u16 serve
|
||||||
g_OldServerPortAlt = server_port_alt;
|
g_OldServerPortAlt = server_port_alt;
|
||||||
g_OldListenPort = listen_port;
|
g_OldListenPort = listen_port;
|
||||||
|
|
||||||
ENetAddress addr = {ENET_HOST_ANY, listen_port};
|
ENetAddress addr = {in6addr_any, listen_port, 0};
|
||||||
auto host = Common::ENet::ENetHostPtr{enet_host_create(&addr, // address
|
auto host = Common::ENet::ENetHostPtr{enet_host_create(&addr, // address
|
||||||
50, // peerCount
|
50, // peerCount
|
||||||
NetPlay::CHANNEL_COUNT, // channelLimit
|
NetPlay::CHANNEL_COUNT, // channelLimit
|
||||||
|
|
|
@ -147,8 +147,12 @@ NetPlayClient::NetPlayClient(const std::string& address, const u16 port, NetPlay
|
||||||
m_client->mtu = std::min(m_client->mtu, NetPlay::MAX_ENET_MTU);
|
m_client->mtu = std::min(m_client->mtu, NetPlay::MAX_ENET_MTU);
|
||||||
|
|
||||||
ENetAddress addr;
|
ENetAddress addr;
|
||||||
enet_address_set_host(&addr, address.c_str());
|
if (auto parsed_addr = Common::ENet::AddressFromString(address))
|
||||||
|
{
|
||||||
|
addr.host = *parsed_addr;
|
||||||
|
}
|
||||||
addr.port = port;
|
addr.port = port;
|
||||||
|
addr.sin6_scope_id = 0;
|
||||||
|
|
||||||
m_server = enet_host_connect(m_client, &addr, CHANNEL_COUNT, 0);
|
m_server = enet_host_connect(m_client, &addr, CHANNEL_COUNT, 0);
|
||||||
|
|
||||||
|
|
|
@ -152,8 +152,9 @@ NetPlayServer::NetPlayServer(const u16 port, const bool forward_port, NetPlayUI*
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
ENetAddress serverAddr;
|
ENetAddress serverAddr;
|
||||||
serverAddr.host = ENET_HOST_ANY;
|
serverAddr.host = in6addr_any;
|
||||||
serverAddr.port = port;
|
serverAddr.port = port;
|
||||||
|
serverAddr.sin6_scope_id = 0;
|
||||||
m_server = enet_host_create(&serverAddr, 10, CHANNEL_COUNT, 0, 0);
|
m_server = enet_host_create(&serverAddr, 10, CHANNEL_COUNT, 0, 0);
|
||||||
if (m_server != nullptr)
|
if (m_server != nullptr)
|
||||||
{
|
{
|
||||||
|
@ -304,8 +305,9 @@ void NetPlayServer::ThreadFunc()
|
||||||
{
|
{
|
||||||
// Actual client initialization is deferred to the receive event, so here
|
// Actual client initialization is deferred to the receive event, so here
|
||||||
// we'll just log the new connection.
|
// we'll just log the new connection.
|
||||||
INFO_LOG_FMT(NETPLAY, "Peer connected from: {:x}:{}", netEvent.peer->address.host,
|
char host_str[48];
|
||||||
netEvent.peer->address.port);
|
enet_address_get_host_ip(&netEvent.peer->address, host_str, 48);
|
||||||
|
INFO_LOG_FMT(NETPLAY, "Peer connected from: {}:{}", host_str, netEvent.peer->address.port);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case ENET_EVENT_TYPE_RECEIVE:
|
case ENET_EVENT_TYPE_RECEIVE:
|
||||||
|
@ -320,16 +322,19 @@ void NetPlayServer::ThreadFunc()
|
||||||
// uninitialized client, we'll assume this is their initialization packet
|
// uninitialized client, we'll assume this is their initialization packet
|
||||||
ConnectionError error;
|
ConnectionError error;
|
||||||
{
|
{
|
||||||
INFO_LOG_FMT(NETPLAY, "Initializing peer {:x}:{}", netEvent.peer->address.host,
|
char host_str[48];
|
||||||
netEvent.peer->address.port);
|
enet_address_get_host_ip(&netEvent.peer->address, host_str, 48);
|
||||||
|
INFO_LOG_FMT(NETPLAY, "Initializing peer {}:{}", host_str, netEvent.peer->address.port);
|
||||||
std::lock_guard lkg(m_crit.game);
|
std::lock_guard lkg(m_crit.game);
|
||||||
error = OnConnect(netEvent.peer, rpac);
|
error = OnConnect(netEvent.peer, rpac);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (error != ConnectionError::NoError)
|
if (error != ConnectionError::NoError)
|
||||||
{
|
{
|
||||||
INFO_LOG_FMT(NETPLAY, "Error {} initializing peer {:x}:{}", u8(error),
|
char host_str[48];
|
||||||
netEvent.peer->address.host, netEvent.peer->address.port);
|
enet_address_get_host_ip(&netEvent.peer->address, host_str, 48);
|
||||||
|
INFO_LOG_FMT(NETPLAY, "Error {} initializing peer {}:{}", u8(error), host_str,
|
||||||
|
netEvent.peer->address.port);
|
||||||
|
|
||||||
sf::Packet spac;
|
sf::Packet spac;
|
||||||
spac << error;
|
spac << error;
|
||||||
|
|
|
@ -1570,7 +1570,7 @@ bool MainWindow::NetPlayJoin()
|
||||||
u16 host_port;
|
u16 host_port;
|
||||||
if (server)
|
if (server)
|
||||||
{
|
{
|
||||||
host_ip = "127.0.0.1";
|
host_ip = "::1";
|
||||||
host_port = server->GetPort();
|
host_port = server->GetPort();
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
|
|
Loading…
Reference in New Issue