Add ability to have sockets bind to a local IP address (#12998)

This commit is contained in:
Team XLink Developers 2022-11-30 10:35:42 -05:00 committed by GitHub
parent 630edde10f
commit b4757b514d
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
8 changed files with 55 additions and 2 deletions

View file

@ -129,10 +129,18 @@ s32 lv2_socket_native::bind(const sys_net_sockaddr& addr)
const auto* psa_in = reinterpret_cast<const sys_net_sockaddr_in*>(&addr); const auto* psa_in = reinterpret_cast<const sys_net_sockaddr_in*>(&addr);
auto& nph = g_fxo->get<named_thread<np::np_handler>>();
u32 saddr = nph.get_bind_ip();
if (saddr == 0)
{
// If zero use the supplied address
saddr = std::bit_cast<u32>(psa_in->sin_addr);
}
::sockaddr_in native_addr{}; ::sockaddr_in native_addr{};
native_addr.sin_family = AF_INET; native_addr.sin_family = AF_INET;
native_addr.sin_port = std::bit_cast<u16>(psa_in->sin_port); native_addr.sin_port = std::bit_cast<u16>(psa_in->sin_port);
native_addr.sin_addr.s_addr = std::bit_cast<u32>(psa_in->sin_addr); native_addr.sin_addr.s_addr = saddr;
::socklen_t native_addr_len = sizeof(native_addr); ::socklen_t native_addr_len = sizeof(native_addr);
sys_net.warning("[Native] Trying to bind %s:%d", native_addr.sin_addr, std::bit_cast<be_t<u16>, u16>(native_addr.sin_port)); sys_net.warning("[Native] Trying to bind %s:%d", native_addr.sin_addr, std::bit_cast<be_t<u16>, u16>(native_addr.sin_port));

View file

@ -371,6 +371,18 @@ namespace np
{ {
dns_ip = conv.s_addr; dns_ip = conv.s_addr;
} }
// 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;
}
} }
} }
@ -585,6 +597,11 @@ namespace np
return dns_ip; return dns_ip;
} }
u32 np_handler::get_bind_ip() const
{
return bind_ip;
}
s32 np_handler::get_net_status() const s32 np_handler::get_net_status() const
{ {
return is_connected ? CELL_NET_CTL_STATE_IPObtained : CELL_NET_CTL_STATE_Disconnected; return is_connected ? CELL_NET_CTL_STATE_IPObtained : CELL_NET_CTL_STATE_Disconnected;

View file

@ -79,6 +79,7 @@ namespace np
u32 get_local_ip_addr() const; u32 get_local_ip_addr() const;
u32 get_public_ip_addr() const; u32 get_public_ip_addr() const;
u32 get_dns_ip() const; u32 get_dns_ip() const;
u32 get_bind_ip() const;
s32 get_psn_status() const; s32 get_psn_status() const;
s32 get_net_status() const; s32 get_net_status() const;
@ -290,6 +291,7 @@ namespace np
be_t<u32> local_ip_addr{}; be_t<u32> local_ip_addr{};
be_t<u32> public_ip_addr{}; be_t<u32> public_ip_addr{};
be_t<u32> dns_ip = 0x08080808; be_t<u32> dns_ip = 0x08080808;
be_t<u32> bind_ip = 0x00000000;
// User infos // User infos
SceNpId npid{}; SceNpId npid{};

View file

@ -305,6 +305,7 @@ struct cfg_root : cfg::node
cfg::_enum<np_internet_status> net_active{this, "Internet enabled", np_internet_status::disabled}; cfg::_enum<np_internet_status> net_active{this, "Internet enabled", np_internet_status::disabled};
cfg::string ip_address{this, "IP address", "0.0.0.0"}; cfg::string ip_address{this, "IP address", "0.0.0.0"};
cfg::string bind_address{this, "Bind address", "0.0.0.0"};
cfg::string dns{this, "DNS address", "8.8.8.8"}; cfg::string dns{this, "DNS address", "8.8.8.8"};
cfg::string swap_list{this, "IP swap list", ""}; cfg::string swap_list{this, "IP swap list", ""};

View file

@ -170,6 +170,7 @@ enum class emu_settings_type
DNSAddress, DNSAddress,
IpSwapList, IpSwapList,
PSNStatus, PSNStatus,
BindAddress,
// System // System
LicenseArea, LicenseArea,
@ -348,6 +349,7 @@ inline static const QMap<emu_settings_type, cfg_location> settings_location =
{ emu_settings_type::DNSAddress, { "Net", "DNS address"}}, { emu_settings_type::DNSAddress, { "Net", "DNS address"}},
{ emu_settings_type::IpSwapList, { "Net", "IP swap list"}}, { emu_settings_type::IpSwapList, { "Net", "IP swap list"}},
{ emu_settings_type::PSNStatus, { "Net", "PSN status"}}, { emu_settings_type::PSNStatus, { "Net", "PSN status"}},
{ emu_settings_type::BindAddress, { "Net", "Bind address"}},
// System // System
{ emu_settings_type::LicenseArea, { "System", "License Area"}}, { emu_settings_type::LicenseArea, { "System", "License Area"}},

View file

@ -1281,6 +1281,9 @@ settings_dialog::settings_dialog(std::shared_ptr<gui_settings> gui_settings, std
m_emu_settings->EnhanceLineEdit(ui->edit_dns, emu_settings_type::DNSAddress); m_emu_settings->EnhanceLineEdit(ui->edit_dns, emu_settings_type::DNSAddress);
SubscribeTooltip(ui->gb_edit_dns, tooltips.settings.dns); SubscribeTooltip(ui->gb_edit_dns, tooltips.settings.dns);
m_emu_settings->EnhanceLineEdit(ui->edit_bind, emu_settings_type::BindAddress);
SubscribeTooltip(ui->gb_edit_bind, tooltips.settings.bind);
m_emu_settings->EnhanceLineEdit(ui->edit_swaps, emu_settings_type::IpSwapList); m_emu_settings->EnhanceLineEdit(ui->edit_swaps, emu_settings_type::IpSwapList);
SubscribeTooltip(ui->gb_edit_swaps, tooltips.settings.dns_swap); SubscribeTooltip(ui->gb_edit_swaps, tooltips.settings.dns_swap);

View file

@ -2081,7 +2081,7 @@
<property name="title"> <property name="title">
<string>Network Configuration</string> <string>Network Configuration</string>
</property> </property>
<layout class="QVBoxLayout" name="gb_network_status_layout" stretch="0,0,0,0"> <layout class="QVBoxLayout" name="gb_network_status_layout" stretch="0,0,0,0,0">
<item> <item>
<widget class="QGroupBox" name="gb_netStatusBox"> <widget class="QGroupBox" name="gb_netStatusBox">
<property name="title"> <property name="title">
@ -2132,6 +2132,25 @@
</layout> </layout>
</widget> </widget>
</item> </item>
<item>
<widget class="QGroupBox" name="gb_edit_bind">
<property name="title">
<string>Bind address</string>
</property>
<layout class="QVBoxLayout" name="gb_edit_bind_layout">
<item>
<widget class="QLineEdit" name="edit_bind">
<property name="sizePolicy">
<sizepolicy hsizetype="Preferred" vsizetype="Fixed">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
</widget>
</item>
</layout>
</widget>
</item>
<item> <item>
<spacer name="networkTabSpacerLeft"> <spacer name="networkTabSpacerLeft">
<property name="orientation"> <property name="orientation">

View file

@ -228,6 +228,7 @@ public:
const QString psn_status = tr("If set to Simulated, RPCS3 will fake PSN connection as best as it can."); const QString psn_status = tr("If set to Simulated, RPCS3 will fake PSN connection as best as it can.");
const QString dns = tr("DNS used to resolve hostnames by applications."); const QString dns = tr("DNS used to resolve hostnames by applications.");
const QString dns_swap = tr("DNS Swap List."); const QString dns_swap = tr("DNS Swap List.");
const QString bind = tr("Interface IP Address to bind to.");
// system // system