Allow binding specific server IP. (#633)

For the netlink dialog, leave the server IP text field enabled when the
server radio button is selected and bind it to the new option
gopts.server_ip which defaults to "*" for binding on all addresses,
which was the previous behavior.

Copy this value to the new GBALink global IP_LINK_BIND_ADDRESS and use
it when creating a listening socket.

SFML supports creating sf:IpAddress values from hostnames, consequently
no additional code is needed to support hostnames in the netlink dialog.

Change GetLinkServerHost to return the primary local address when the
value is "*", which was the previous behavior, and the set value
otherwise.

Remove the min/max macros from GBALink as they are unnecessary and
conflict with std headers.

Require at least SFML 2.4 instead of 2.x for the IP binding
functionality in cmake.

- Fix #632

Signed-off-by: Rafael Kitover <rkitover@gmail.com>
This commit is contained in:
Rafael Kitover 2020-03-16 16:37:01 +00:00 committed by GitHub
parent 4f49c89a98
commit abb8234174
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
6 changed files with 44 additions and 47 deletions

View File

@ -131,7 +131,7 @@ if(WIN32 AND ((NOT (MINGW AND MSYS)) OR CMAKE_TOOLCHAIN_FILE MATCHES mxe) AND NO
set(SFML_STATIC_LIBRARIES TRUE)
endif()
find_package(SFML 2 COMPONENTS network system)
find_package(SFML 2.4 COMPONENTS network system)
if(SFML_FOUND)
set(ENABLE_LINK_DEFAULT ON)

View File

@ -1,7 +1,8 @@
// This file was written by denopqrihg
// with major changes by tjm
#include <stdio.h>
#include <string.h>
#include <cstring>
#include <string>
// malloc.h does not seem to exist on Mac OS 10.7 and is an error on FreeBSD
#if defined(__APPLE__) || defined(__FreeBSD__) || defined(__NetBSD__)
@ -49,45 +50,6 @@ enum siocnt_lo_32bit {
SIO_IRQ_ENABLE = 0x4000
};
#ifdef __clang__
// don't define these min/max functions, they don't compile
#else
// The usual min/max functions for built-in types.
//
// template<typename T> T min( T x, T y ) { return x < y ? x : y; }
// template<typename T> T max( T x, T y ) { return x > y ? x : y; }
#define BLARGG_DEF_MIN_MAX(type) \
static inline type blargg_min(type x, type y) \
{ \
if (y < x) \
x = y; \
return x; \
} \
static inline type blargg_max(type x, type y) \
{ \
if (x < y) \
x = y; \
return x; \
}
BLARGG_DEF_MIN_MAX(int)
BLARGG_DEF_MIN_MAX(unsigned)
BLARGG_DEF_MIN_MAX(long)
BLARGG_DEF_MIN_MAX(unsigned long)
BLARGG_DEF_MIN_MAX(float)
BLARGG_DEF_MIN_MAX(double)
#undef min
#define min blargg_min
#undef max
#define max blargg_max
#endif // not clang
// Joybus
bool gba_joybus_enabled = false;
bool gba_joybus_active = false;
@ -103,6 +65,8 @@ bool speedhack = true;
uint32_t IP_LINK_PORT = 5738;
std::string IP_LINK_BIND_ADDRESS = "*";
#include "../common/Port.h"
#include "GBA.h"
#include "GBALink.h"
@ -567,8 +531,12 @@ void GetLinkServerHost(char* const host, size_t size)
if (linkDriver && linkDriver->mode == LINK_GAMECUBE_DOLPHIN)
strncpy(host, joybusHostAddr.toString().c_str(), size);
else if (lanlink.server)
strncpy(host, sf::IpAddress::getLocalAddress().toString().c_str(), size);
else if (lanlink.server) {
if (IP_LINK_BIND_ADDRESS == "*")
strncpy(host, sf::IpAddress::getLocalAddress().toString().c_str(), size);
else
strncpy(host, IP_LINK_BIND_ADDRESS.c_str(), size);
}
else
strncpy(host, lc.serveraddr.toString().c_str(), size);
}
@ -1077,7 +1045,9 @@ static ConnectionState InitSocket()
// too bad Listen() doesn't take an address as well
// then again, old code used INADDR_ANY anyway
if (lanlink.tcplistener.listen(IP_LINK_PORT) == sf::Socket::Error)
sf::IpAddress bind_ip = IP_LINK_BIND_ADDRESS == "*" ? sf::IpAddress::Any : IP_LINK_BIND_ADDRESS;
if (lanlink.tcplistener.listen(IP_LINK_PORT, bind_ip) == sf::Socket::Error)
// Note: old code closed socket & retried once on bind failure
return LINK_ERROR; // FIXME: error code?
else

View File

@ -5,6 +5,8 @@
extern uint32_t IP_LINK_PORT;
extern std::string IP_LINK_BIND_ADDRESS;
/**
* Link modes to be passed to InitLink
*/

View File

@ -76,6 +76,20 @@ public:
(void)ev; // unused params
okb->SetLabel(_("Start!"));
}
void BindServerIP(wxCommandEvent& ev)
{
(void)ev; // unused param
auto *tc = XRCCTRL(*dlg, "ServerIP", wxTextCtrl);
tc->SetValidator(wxTextValidator(wxFILTER_NONE, &gopts.server_ip));
tc->SetValue(gopts.server_ip);
}
void BindLinkHost(wxCommandEvent& ev)
{
(void)ev; // unused param
auto *tc = XRCCTRL(*dlg, "ServerIP", wxTextCtrl);
tc->SetValidator(wxTextValidator(wxFILTER_NONE, &gopts.link_host));
tc->SetValue(gopts.link_host);
}
void ClientOKButton(wxCommandEvent& ev)
{
(void)ev; // unused params
@ -89,7 +103,8 @@ public:
if (!dlg->Validate() || !dlg->TransferDataFromWindow())
return;
IP_LINK_PORT = gopts.link_port;
IP_LINK_PORT = gopts.link_port;
IP_LINK_BIND_ADDRESS = gopts.server_ip;
if (!server) {
bool valid = SetLinkServerHost(gopts.link_host.utf8_str());
@ -3203,9 +3218,7 @@ bool MainFrame::BindControls()
getrbi("Link4P", net_link_handler.n_players, 4);
addrber(rb, false);
getlab("ServerIPLab");
addrber(lab, true);
gettc("ServerIP", gopts.link_host);
addrber(tc, true);
getutc("ServerPort", gopts.link_port);
wxWindow* okb = d->FindWindow(wxID_OK);
@ -3220,6 +3233,15 @@ bool MainFrame::BindControls()
NULL, &net_link_handler);
}
// Bind server IP when the server radio button is selected.
d->Connect(XRCID("Server"), wxEVT_COMMAND_RADIOBUTTON_SELECTED,
wxCommandEventHandler(NetLink_t::BindServerIP),
NULL, &net_link_handler);
// Bind client link_host when client radio button is selected.
d->Connect(XRCID("Client"), wxEVT_COMMAND_RADIOBUTTON_SELECTED,
wxCommandEventHandler(NetLink_t::BindLinkHost),
NULL, &net_link_handler);
// this should intercept wxID_OK before the dialog handler gets it
d->Connect(wxID_OK, wxEVT_COMMAND_BUTTON_CLICKED,
wxCommandEventHandler(NetLink_t::NetConnect),

View File

@ -223,6 +223,7 @@ opt_desc opts[] = {
BOOLOPT("GBA/LinkAuto", "LinkAuto", wxTRANSLATE("Enable link at boot"), gopts.link_auto),
INTOPT("GBA/LinkFast", "SpeedOn", wxTRANSLATE("Enable faster network protocol by default"), linkHacks, 0, 1),
STROPT("GBA/LinkHost", "", wxTRANSLATE("Default network link client host"), gopts.link_host),
STROPT("GBA/ServerIP", "", wxTRANSLATE("Default network link server IP to bind"), gopts.server_ip),
UINTOPT("GBA/LinkPort", "", wxTRANSLATE("Default network link port (server and client)"), gopts.link_port, 0, 65535),
INTOPT("GBA/LinkProto", "LinkProto", wxTRANSLATE("Default network protocol"), gopts.link_proto, 0, 1),
INTOPT("GBA/LinkTimeout", "LinkTimeout", wxTRANSLATE("Link timeout (ms)"), linkTimeout, 0, 9999999),
@ -360,6 +361,7 @@ opts_t::opts_t()
autoPatch = true;
// quick fix for issues #48 and #445
link_host = "127.0.0.1";
server_ip = "*";
link_port = 5738;
}

View File

@ -38,6 +38,7 @@ extern struct opts_t {
wxString gba_bios;
int gba_link_type;
wxString link_host;
wxString server_ip;
uint32_t link_port;
int link_proto;
bool link_auto;