mirror of
https://github.com/RPCS3/rpcs3.git
synced 2025-07-02 13:01:27 +12:00
Make IP Binding more global
Some checks failed
Generate Translation Template / Generate Translation Template (push) Has been cancelled
Build RPCS3 / RPCS3 Linux ubuntu-24.04 gcc (push) Has been cancelled
Build RPCS3 / RPCS3 Linux ubuntu-24.04-arm clang (push) Has been cancelled
Build RPCS3 / RPCS3 Linux ubuntu-24.04 clang (push) Has been cancelled
Build RPCS3 / RPCS3 Windows (push) Has been cancelled
Some checks failed
Generate Translation Template / Generate Translation Template (push) Has been cancelled
Build RPCS3 / RPCS3 Linux ubuntu-24.04 gcc (push) Has been cancelled
Build RPCS3 / RPCS3 Linux ubuntu-24.04-arm clang (push) Has been cancelled
Build RPCS3 / RPCS3 Linux ubuntu-24.04 clang (push) Has been cancelled
Build RPCS3 / RPCS3 Windows (push) Has been cancelled
This commit is contained in:
parent
d21358e91f
commit
3894c903bc
17 changed files with 80 additions and 36 deletions
|
@ -7,6 +7,7 @@
|
|||
#include "sys_net_helpers.h"
|
||||
#include "Emu/NP/vport0.h"
|
||||
#include "Emu/NP/np_handler.h"
|
||||
#include "Emu/NP/np_helpers.h"
|
||||
|
||||
LOG_CHANNEL(sys_net);
|
||||
|
||||
|
@ -59,6 +60,7 @@ nt_p2p_port::nt_p2p_port(u16 port)
|
|||
|
||||
int ret_bind = 0;
|
||||
const u16 be_port = std::bit_cast<u16, be_t<u16>>(port);
|
||||
auto& nph = g_fxo->get<named_thread<np::np_handler>>();
|
||||
|
||||
if (is_ipv6)
|
||||
{
|
||||
|
@ -73,15 +75,23 @@ nt_p2p_port::nt_p2p_port(u16 port)
|
|||
else
|
||||
{
|
||||
::sockaddr_in p2p_ipv4_addr{.sin_family = AF_INET, .sin_port = be_port};
|
||||
ret_bind = ::bind(p2p_socket, reinterpret_cast<sockaddr*>(&p2p_ipv4_addr), sizeof(p2p_ipv4_addr));
|
||||
p2p_ipv4_addr.sin_addr.s_addr = nph.get_bind_ip();
|
||||
|
||||
if (ret_bind = ::bind(p2p_socket, reinterpret_cast<const sockaddr*>(&p2p_ipv4_addr), sizeof(p2p_ipv4_addr)); ret_bind == -1)
|
||||
{
|
||||
if (nph.get_bind_ip())
|
||||
{
|
||||
sys_net.error("Failed to bind to %s:%d, falling back to 0.0.0.0:%d", np::ip_to_string(nph.get_bind_ip()), port, port);
|
||||
p2p_ipv4_addr.sin_addr.s_addr = 0;
|
||||
ret_bind = ::bind(p2p_socket, reinterpret_cast<const sockaddr*>(&p2p_ipv4_addr), sizeof(p2p_ipv4_addr));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (ret_bind == -1)
|
||||
fmt::throw_exception("Failed to bind DGRAM socket to %d for P2P: %s!", port, get_last_error(true));
|
||||
|
||||
auto& nph = g_fxo->get<named_thread<np::np_handler>>();
|
||||
nph.upnp_add_port_mapping(port, "UDP");
|
||||
|
||||
sys_net.notice("P2P port %d was bound!", port);
|
||||
}
|
||||
|
||||
|
|
|
@ -1,5 +1,6 @@
|
|||
#include "stdafx.h"
|
||||
#include "Emu/IdManager.h"
|
||||
#include "Emu/system_config.h"
|
||||
#include "Emu/Cell/PPUThread.h"
|
||||
#include "lv2_socket.h"
|
||||
#include "sys_net_helpers.h"
|
||||
|
@ -199,6 +200,26 @@ void clear_ppu_to_awake(ppu_thread& ppu)
|
|||
g_fxo->get<p2p_context>().del_ppu_to_awake(&ppu);
|
||||
}
|
||||
|
||||
be_t<u32> resolve_binding_ip()
|
||||
{
|
||||
in_addr conv{};
|
||||
const std::string cfg_bind_addr = g_cfg.net.bind_address.to_string();
|
||||
|
||||
if (cfg_bind_addr == "0.0.0.0" || cfg_bind_addr == "")
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (!inet_pton(AF_INET, cfg_bind_addr.c_str(), &conv))
|
||||
{
|
||||
// Do not set to disconnected on invalid IP just error and continue using default (0.0.0.0)
|
||||
sys_net.error("Provided IP(%s) address for bind is invalid!", g_cfg.net.bind_address.to_string());
|
||||
return 0;
|
||||
}
|
||||
|
||||
return conv.s_addr;
|
||||
}
|
||||
|
||||
#ifdef _WIN32
|
||||
// Workaround function for WSAPoll not reporting failed connections
|
||||
// Note that this was fixed in Windows 10 version 2004 (after more than 10 years lol)
|
||||
|
|
|
@ -25,6 +25,7 @@ sys_net_sockaddr native_addr_to_sys_net_addr(const ::sockaddr_storage& native_ad
|
|||
bool is_ip_public_address(const ::sockaddr_in& addr);
|
||||
u32 network_clear_queue(ppu_thread& ppu);
|
||||
void clear_ppu_to_awake(ppu_thread& ppu);
|
||||
be_t<u32> resolve_binding_ip();
|
||||
|
||||
#ifdef _WIN32
|
||||
void windows_poll(std::vector<pollfd>& fds, unsigned long nfds, int timeout, std::vector<bool>& connecting);
|
||||
|
|
|
@ -1,3 +1,4 @@
|
|||
#include "Emu/Cell/lv2/sys_net/sys_net_helpers.h"
|
||||
#include "stdafx.h"
|
||||
#include "Emu/system_config.h"
|
||||
#include "ip_address.h"
|
||||
|
@ -6,6 +7,7 @@
|
|||
#include "util/endian.hpp"
|
||||
#include "util/types.hpp"
|
||||
#include "Emu/NP/rpcn_config.h"
|
||||
#include "Emu/Cell/lv2/sys_net/sys_net_helpers.h"
|
||||
#include <algorithm>
|
||||
|
||||
#ifndef _WIN32
|
||||
|
@ -103,6 +105,7 @@ namespace np
|
|||
// -IPv6 is not disabled in config
|
||||
// -Internet config is Connected
|
||||
// -PSN config is RPCN
|
||||
// -Bind IP is not set
|
||||
// -RPCN host has an IPv6
|
||||
// -Can connect to ipv6.google.com:413
|
||||
bool is_ipv6_supported(std::optional<IPV6_SUPPORT> force_state)
|
||||
|
@ -135,6 +138,9 @@ namespace np
|
|||
if (g_cfg.net.net_active != np_internet_status::enabled || g_cfg.net.psn_status != np_psn_status::psn_rpcn)
|
||||
return notice_and_disable("RPCN is disabled");
|
||||
|
||||
if (resolve_binding_ip())
|
||||
return notice_and_disable("Bind IP is used");
|
||||
|
||||
addrinfo* addr_info{};
|
||||
socket_type socket_ipv6{};
|
||||
const addrinfo hints{.ai_family = AF_INET6};
|
||||
|
|
|
@ -412,7 +412,7 @@ namespace np
|
|||
nc.bind_sce_np_port();
|
||||
|
||||
std::lock_guard lock(mutex_rpcn);
|
||||
rpcn = rpcn::rpcn_client::get_instance();
|
||||
rpcn = rpcn::rpcn_client::get_instance(bind_ip);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -455,19 +455,10 @@ namespace np
|
|||
}
|
||||
|
||||
// Convert bind address
|
||||
conv = {};
|
||||
if (!inet_pton(AF_INET, g_cfg.net.bind_address.to_string().c_str(), &conv))
|
||||
{
|
||||
// Do not set to disconnected on invalid IP just error and continue using default (0.0.0.0)
|
||||
nph_log.error("Provided IP(%s) address for bind is invalid!", g_cfg.net.bind_address.to_string());
|
||||
}
|
||||
else
|
||||
{
|
||||
bind_ip = conv.s_addr;
|
||||
bind_ip = resolve_binding_ip();
|
||||
|
||||
if (bind_ip)
|
||||
local_ip_addr = bind_ip;
|
||||
}
|
||||
if (bind_ip)
|
||||
local_ip_addr = bind_ip;
|
||||
|
||||
if (g_cfg.net.upnp_enabled)
|
||||
upnp.upnp_enable();
|
||||
|
@ -793,7 +784,7 @@ namespace np
|
|||
|
||||
if (!rpcn)
|
||||
{
|
||||
rpcn = rpcn::rpcn_client::get_instance();
|
||||
rpcn = rpcn::rpcn_client::get_instance(bind_ip);
|
||||
was_already_started = false;
|
||||
}
|
||||
|
||||
|
|
|
@ -11,7 +11,7 @@ namespace np
|
|||
{
|
||||
std::string ip_to_string(u32 ip_addr)
|
||||
{
|
||||
char ip_str[16];
|
||||
char ip_str[16]{};
|
||||
|
||||
inet_ntop(AF_INET, &ip_addr, ip_str, sizeof(ip_str));
|
||||
return std::string(ip_str);
|
||||
|
|
|
@ -212,6 +212,7 @@ namespace rpcn
|
|||
case rpcn::rpcn_state::failure_input: return localized_string_id::RPCN_ERROR_INVALID_INPUT;
|
||||
case rpcn::rpcn_state::failure_wolfssl: return localized_string_id::RPCN_ERROR_WOLFSSL;
|
||||
case rpcn::rpcn_state::failure_resolve: return localized_string_id::RPCN_ERROR_RESOLVE;
|
||||
case rpcn::rpcn_state::failure_binding: return localized_string_id::RPCN_ERROR_BINDING;
|
||||
case rpcn::rpcn_state::failure_connect: return localized_string_id::RPCN_ERROR_CONNECT;
|
||||
case rpcn::rpcn_state::failure_id: return localized_string_id::RPCN_ERROR_LOGIN_ERROR;
|
||||
case rpcn::rpcn_state::failure_id_already_logged_in: return localized_string_id::RPCN_ERROR_ALREADY_LOGGED;
|
||||
|
@ -316,8 +317,8 @@ namespace rpcn
|
|||
|
||||
// Constructor, destructor & singleton manager
|
||||
|
||||
rpcn_client::rpcn_client()
|
||||
: sem_connected(0), sem_authentified(0), sem_reader(0), sem_writer(0), sem_rpcn(0),
|
||||
rpcn_client::rpcn_client(u32 binding_address)
|
||||
: binding_address(binding_address), sem_connected(0), sem_authentified(0), sem_reader(0), sem_writer(0), sem_rpcn(0),
|
||||
thread_rpcn(std::thread(&rpcn_client::rpcn_thread, this)),
|
||||
thread_rpcn_reader(std::thread(&rpcn_client::rpcn_reader_thread, this)),
|
||||
thread_rpcn_writer(std::thread(&rpcn_client::rpcn_writer_thread, this))
|
||||
|
@ -349,7 +350,7 @@ namespace rpcn
|
|||
sem_authentified.release();
|
||||
}
|
||||
|
||||
std::shared_ptr<rpcn_client> rpcn_client::get_instance(bool check_config)
|
||||
std::shared_ptr<rpcn_client> rpcn_client::get_instance(u32 binding_address, bool check_config)
|
||||
{
|
||||
if (check_config && g_cfg.net.psn_status != np_psn_status::psn_rpcn)
|
||||
{
|
||||
|
@ -362,7 +363,7 @@ namespace rpcn
|
|||
sptr = instance.lock();
|
||||
if (!sptr)
|
||||
{
|
||||
sptr = std::shared_ptr<rpcn_client>(new rpcn_client());
|
||||
sptr = std::shared_ptr<rpcn_client>(new rpcn_client(binding_address));
|
||||
sptr->register_friend_cb(overlay_friend_callback, nullptr);
|
||||
instance = sptr;
|
||||
}
|
||||
|
@ -1074,6 +1075,16 @@ namespace rpcn
|
|||
return false;
|
||||
}
|
||||
|
||||
sockaddr_in sock_addr = {.sin_family = AF_INET};
|
||||
sock_addr.sin_addr.s_addr = binding_address;
|
||||
|
||||
if (::bind(sockfd, reinterpret_cast<const sockaddr*>(&sock_addr), sizeof(sock_addr)) == -1)
|
||||
{
|
||||
rpcn_log.error("bind: Failed to bind RPCN client socket to binding address!");
|
||||
state = rpcn_state::failure_binding;
|
||||
return false;
|
||||
}
|
||||
|
||||
if (::connect(sockfd, reinterpret_cast<struct sockaddr*>(&addr_rpcn), sizeof(addr_rpcn)) != 0)
|
||||
{
|
||||
rpcn_log.error("connect: Failed to connect to RPCN server!");
|
||||
|
|
|
@ -227,6 +227,7 @@ namespace rpcn
|
|||
atomic_t<bool> authentified = false;
|
||||
atomic_t<bool> want_conn = false;
|
||||
atomic_t<bool> want_auth = false;
|
||||
u32 binding_address = 0;
|
||||
std::binary_semaphore sem_connected, sem_authentified;
|
||||
std::mutex mutex_connected, mutex_authentified;
|
||||
|
||||
|
@ -253,7 +254,7 @@ namespace rpcn
|
|||
void handle_message(std::vector<u8> data);
|
||||
|
||||
private:
|
||||
rpcn_client();
|
||||
rpcn_client(u32 binding_address);
|
||||
|
||||
void rpcn_reader_thread();
|
||||
void rpcn_writer_thread();
|
||||
|
@ -287,7 +288,7 @@ namespace rpcn
|
|||
~rpcn_client();
|
||||
rpcn_client(rpcn_client& other) = delete;
|
||||
void operator=(const rpcn_client&) = delete;
|
||||
static std::shared_ptr<rpcn_client> get_instance(bool check_config = false);
|
||||
static std::shared_ptr<rpcn_client> get_instance(u32 binding_address, bool check_config = false);
|
||||
rpcn_state wait_for_connection();
|
||||
rpcn_state wait_for_authentified();
|
||||
bool terminate_connection();
|
||||
|
|
|
@ -98,6 +98,7 @@ namespace rpcn
|
|||
failure_input,
|
||||
failure_wolfssl,
|
||||
failure_resolve,
|
||||
failure_binding,
|
||||
failure_connect,
|
||||
failure_id,
|
||||
failure_id_already_logged_in,
|
||||
|
|
|
@ -655,7 +655,7 @@ namespace rsx
|
|||
|
||||
g_cfg_rpcn.load(); // Ensures config is loaded even if rpcn is not running for simulated
|
||||
|
||||
m_rpcn = rpcn::rpcn_client::get_instance();
|
||||
m_rpcn = rpcn::rpcn_client::get_instance(0);
|
||||
|
||||
m_rpcn->register_friend_cb(friend_callback, this);
|
||||
|
||||
|
|
|
@ -213,7 +213,7 @@ namespace rsx
|
|||
const bool preserve = options & SCE_NP_BASIC_RECV_MESSAGE_OPTIONS_PRESERVE;
|
||||
const bool include_bootable = options & SCE_NP_BASIC_RECV_MESSAGE_OPTIONS_INCLUDE_BOOTABLE;
|
||||
|
||||
m_rpcn = rpcn::rpcn_client::get_instance(true);
|
||||
m_rpcn = rpcn::rpcn_client::get_instance(0, true);
|
||||
|
||||
// Get list of messages
|
||||
const auto messages = m_rpcn->get_messages_and_register_cb(type, include_bootable, recvmessage_callback, this);
|
||||
|
|
|
@ -183,7 +183,7 @@ namespace rsx
|
|||
break; // Title already set in constructor
|
||||
}
|
||||
|
||||
m_rpcn = rpcn::rpcn_client::get_instance(true);
|
||||
m_rpcn = rpcn::rpcn_client::get_instance(0, true);
|
||||
|
||||
// Get list of messages
|
||||
rpcn::friend_data data;
|
||||
|
|
|
@ -163,6 +163,7 @@ enum class localized_string_id
|
|||
RPCN_ERROR_INVALID_INPUT,
|
||||
RPCN_ERROR_WOLFSSL,
|
||||
RPCN_ERROR_RESOLVE,
|
||||
RPCN_ERROR_BINDING,
|
||||
RPCN_ERROR_CONNECT,
|
||||
RPCN_ERROR_LOGIN_ERROR,
|
||||
RPCN_ERROR_ALREADY_LOGGED,
|
||||
|
|
|
@ -185,6 +185,7 @@ private:
|
|||
case localized_string_id::RPCN_ERROR_INVALID_INPUT: return tr("RPCN: Invalid Input (Wrong Host/Port)");
|
||||
case localized_string_id::RPCN_ERROR_WOLFSSL: return tr("RPCN Connection Error: WolfSSL Error");
|
||||
case localized_string_id::RPCN_ERROR_RESOLVE: return tr("RPCN Connection Error: Resolve Error");
|
||||
case localized_string_id::RPCN_ERROR_BINDING: return tr("RPCN Connection Error: Failed to bind to given binding IP");
|
||||
case localized_string_id::RPCN_ERROR_CONNECT: return tr("RPCN Connection Error");
|
||||
case localized_string_id::RPCN_ERROR_LOGIN_ERROR: return tr("RPCN Login Error: Identification Error");
|
||||
case localized_string_id::RPCN_ERROR_ALREADY_LOGGED: return tr("RPCN Login Error: User Already Logged In");
|
||||
|
|
|
@ -42,7 +42,7 @@ error_code recvmessage_dialog_frame::Exec(SceNpBasicMessageMainType type, SceNpB
|
|||
|
||||
m_dialog->setWindowTitle(tr("Choose message:"));
|
||||
|
||||
m_rpcn = rpcn::rpcn_client::get_instance(true);
|
||||
m_rpcn = rpcn::rpcn_client::get_instance(0, true);
|
||||
|
||||
QVBoxLayout* vbox_global = new QVBoxLayout();
|
||||
|
||||
|
|
|
@ -270,7 +270,7 @@ rpcn_account_dialog::rpcn_account_dialog(QWidget* parent)
|
|||
return;
|
||||
|
||||
{
|
||||
const auto rpcn = rpcn::rpcn_client::get_instance();
|
||||
const auto rpcn = rpcn::rpcn_client::get_instance(0);
|
||||
const auto avatar_url = "https://rpcs3.net/cdn/netplay/DefaultAvatar.png";
|
||||
|
||||
if (auto result = rpcn->wait_for_connection(); result != rpcn::rpcn_state::failure_no_failure)
|
||||
|
@ -325,7 +325,7 @@ rpcn_account_dialog::rpcn_account_dialog(QWidget* parent)
|
|||
|
||||
connect(btn_test, &QAbstractButton::clicked, this, [this]()
|
||||
{
|
||||
auto rpcn = rpcn::rpcn_client::get_instance();
|
||||
auto rpcn = rpcn::rpcn_client::get_instance(0);
|
||||
|
||||
if (auto res = rpcn->wait_for_connection(); res != rpcn::rpcn_state::failure_no_failure)
|
||||
{
|
||||
|
@ -342,7 +342,7 @@ rpcn_account_dialog::rpcn_account_dialog(QWidget* parent)
|
|||
|
||||
QMessageBox::information(this, tr("RPCN Account Valid!"), tr("Your account is valid!"), QMessageBox::Ok);
|
||||
});
|
||||
|
||||
|
||||
connect(checkbox_disable_ipv6, &QCheckBox::checkStateChanged, this, [this](Qt::CheckState state)
|
||||
{
|
||||
g_cfg_rpcn.set_ipv6_support(state == Qt::Unchecked);
|
||||
|
@ -761,7 +761,7 @@ void rpcn_account_edit_dialog::resend_token()
|
|||
if (!save_config())
|
||||
return;
|
||||
|
||||
const auto rpcn = rpcn::rpcn_client::get_instance();
|
||||
const auto rpcn = rpcn::rpcn_client::get_instance(0);
|
||||
|
||||
const std::string npid = g_cfg_rpcn.get_npid();
|
||||
const std::string password = g_cfg_rpcn.get_password();
|
||||
|
@ -814,7 +814,7 @@ void rpcn_account_edit_dialog::change_password()
|
|||
return;
|
||||
|
||||
{
|
||||
const auto rpcn = rpcn::rpcn_client::get_instance();
|
||||
const auto rpcn = rpcn::rpcn_client::get_instance(0);
|
||||
if (auto result = rpcn->wait_for_connection(); result != rpcn::rpcn_state::failure_no_failure)
|
||||
{
|
||||
const QString error_message = tr("Failed to connect to RPCN server:\n%0").arg(QString::fromStdString(rpcn::rpcn_state_to_string(result)));
|
||||
|
@ -859,7 +859,7 @@ void rpcn_account_edit_dialog::change_password()
|
|||
return;
|
||||
|
||||
{
|
||||
const auto rpcn = rpcn::rpcn_client::get_instance();
|
||||
const auto rpcn = rpcn::rpcn_client::get_instance(0);
|
||||
if (auto result = rpcn->wait_for_connection(); result != rpcn::rpcn_state::failure_no_failure)
|
||||
{
|
||||
const QString error_message = tr("Failed to connect to RPCN server:\n%0").arg(QString::fromStdString(rpcn::rpcn_state_to_string(result)));
|
||||
|
@ -1048,7 +1048,7 @@ rpcn_friends_dialog::rpcn_friends_dialog(QWidget* parent)
|
|||
setLayout(vbox_global);
|
||||
|
||||
// Tries to connect to RPCN
|
||||
m_rpcn = rpcn::rpcn_client::get_instance();
|
||||
m_rpcn = rpcn::rpcn_client::get_instance(0);
|
||||
|
||||
if (auto res = m_rpcn->wait_for_connection(); res != rpcn::rpcn_state::failure_no_failure)
|
||||
{
|
||||
|
|
|
@ -40,7 +40,7 @@ error_code sendmessage_dialog_frame::Exec(message_data& msg_data, std::set<std::
|
|||
|
||||
m_dialog->setWindowTitle(tr("Choose friend to message:"));
|
||||
|
||||
m_rpcn = rpcn::rpcn_client::get_instance(true);
|
||||
m_rpcn = rpcn::rpcn_client::get_instance(0, true);
|
||||
|
||||
QVBoxLayout* vbox_global = new QVBoxLayout();
|
||||
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue