forked from Mirrorlandia_minetest/minetest
Infer ipv6_server from bind_address; fix client connect to IN(6)ADDR_ANY
This commit is contained in:
parent
edcad09dee
commit
6090e95cdc
@ -438,6 +438,7 @@
|
|||||||
#enable_ipv6 = true
|
#enable_ipv6 = true
|
||||||
# Enable/disable running an IPv6 server. An IPv6 server may be restricted
|
# Enable/disable running an IPv6 server. An IPv6 server may be restricted
|
||||||
# to IPv6 clients, depending on system configuration.
|
# to IPv6 clients, depending on system configuration.
|
||||||
|
# Ignored if bind_address is set.
|
||||||
#ipv6_server = false
|
#ipv6_server = false
|
||||||
|
|
||||||
#main_menu_script =
|
#main_menu_script =
|
||||||
|
65
src/game.cpp
65
src/game.cpp
@ -1147,27 +1147,34 @@ void the_game(bool &kill, bool random_input, InputHandler *input,
|
|||||||
draw_load_screen(text, device, font,0,25);
|
draw_load_screen(text, device, font,0,25);
|
||||||
delete[] text;
|
delete[] text;
|
||||||
infostream<<"Creating server"<<std::endl;
|
infostream<<"Creating server"<<std::endl;
|
||||||
server = new Server(map_dir, gamespec,
|
|
||||||
simple_singleplayer_mode);
|
|
||||||
|
|
||||||
std::string bind_str = g_settings->get("bind_address");
|
std::string bind_str = g_settings->get("bind_address");
|
||||||
Address bind_addr(0,0,0,0, port);
|
Address bind_addr(0,0,0,0, port);
|
||||||
|
|
||||||
if (bind_str != "")
|
if (g_settings->getBool("ipv6_server")) {
|
||||||
{
|
bind_addr.setAddress((IPv6AddressBytes*) NULL);
|
||||||
try {
|
|
||||||
bind_addr.Resolve(bind_str.c_str());
|
|
||||||
address = bind_str;
|
|
||||||
} catch (ResolveError &e) {
|
|
||||||
infostream << "Resolving bind address \"" << bind_str
|
|
||||||
<< "\" failed: " << e.what()
|
|
||||||
<< " -- Listening on all addresses." << std::endl;
|
|
||||||
|
|
||||||
if (g_settings->getBool("ipv6_server")) {
|
|
||||||
bind_addr.setAddress((IPv6AddressBytes*) NULL);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
try {
|
||||||
|
bind_addr.Resolve(bind_str.c_str());
|
||||||
|
address = bind_str;
|
||||||
|
} catch (ResolveError &e) {
|
||||||
|
infostream << "Resolving bind address \"" << bind_str
|
||||||
|
<< "\" failed: " << e.what()
|
||||||
|
<< " -- Listening on all addresses." << std::endl;
|
||||||
|
}
|
||||||
|
|
||||||
|
if(bind_addr.isIPv6() && !g_settings->getBool("enable_ipv6")) {
|
||||||
|
error_message = L"Unable to listen on " +
|
||||||
|
narrow_to_wide(bind_addr.serializeString()) +
|
||||||
|
L" because IPv6 is disabled";
|
||||||
|
errorstream<<wide_to_narrow(error_message)<<std::endl;
|
||||||
|
// Break out of client scope
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
server = new Server(map_dir, gamespec,
|
||||||
|
simple_singleplayer_mode,
|
||||||
|
bind_addr.isIPv6());
|
||||||
|
|
||||||
server->start(bind_addr);
|
server->start(bind_addr);
|
||||||
}
|
}
|
||||||
@ -1193,31 +1200,33 @@ void the_game(bool &kill, bool random_input, InputHandler *input,
|
|||||||
delete[] text;
|
delete[] text;
|
||||||
}
|
}
|
||||||
Address connect_address(0,0,0,0, port);
|
Address connect_address(0,0,0,0, port);
|
||||||
try{
|
try {
|
||||||
if(address == "")
|
connect_address.Resolve(address.c_str());
|
||||||
{
|
if (connect_address.isZero()) { // i.e. INADDR_ANY, IN6ADDR_ANY
|
||||||
//connect_address.Resolve("localhost");
|
//connect_address.Resolve("localhost");
|
||||||
if(g_settings->getBool("enable_ipv6") && g_settings->getBool("ipv6_server"))
|
if (connect_address.isIPv6()) {
|
||||||
{
|
|
||||||
IPv6AddressBytes addr_bytes;
|
IPv6AddressBytes addr_bytes;
|
||||||
addr_bytes.bytes[15] = 1;
|
addr_bytes.bytes[15] = 1;
|
||||||
connect_address.setAddress(&addr_bytes);
|
connect_address.setAddress(&addr_bytes);
|
||||||
}
|
} else {
|
||||||
else
|
|
||||||
{
|
|
||||||
connect_address.setAddress(127,0,0,1);
|
connect_address.setAddress(127,0,0,1);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else
|
|
||||||
connect_address.Resolve(address.c_str());
|
|
||||||
}
|
}
|
||||||
catch(ResolveError &e)
|
catch(ResolveError &e) {
|
||||||
{
|
|
||||||
error_message = L"Couldn't resolve address: " + narrow_to_wide(e.what());
|
error_message = L"Couldn't resolve address: " + narrow_to_wide(e.what());
|
||||||
errorstream<<wide_to_narrow(error_message)<<std::endl;
|
errorstream<<wide_to_narrow(error_message)<<std::endl;
|
||||||
// Break out of client scope
|
// Break out of client scope
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
if(connect_address.isIPv6() && !g_settings->getBool("enable_ipv6")) {
|
||||||
|
error_message = L"Unable to connect to " +
|
||||||
|
narrow_to_wide(connect_address.serializeString()) +
|
||||||
|
L" because IPv6 is disabled";
|
||||||
|
errorstream<<wide_to_narrow(error_message)<<std::endl;
|
||||||
|
// Break out of client scope
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
Create client
|
Create client
|
||||||
|
38
src/main.cpp
38
src/main.cpp
@ -1023,21 +1023,6 @@ int main(int argc, char *argv[])
|
|||||||
if(port == 0)
|
if(port == 0)
|
||||||
port = 30000;
|
port = 30000;
|
||||||
|
|
||||||
// Bind address
|
|
||||||
std::string bind_str = g_settings->get("bind_address");
|
|
||||||
Address bind_addr(0,0,0,0, port);
|
|
||||||
try {
|
|
||||||
bind_addr.Resolve(bind_str.c_str());
|
|
||||||
} catch (ResolveError &e) {
|
|
||||||
infostream << "Resolving bind address \"" << bind_str
|
|
||||||
<< "\" failed: " << e.what()
|
|
||||||
<< " -- Listening on all addresses." << std::endl;
|
|
||||||
|
|
||||||
if (g_settings->getBool("ipv6_server")) {
|
|
||||||
bind_addr.setAddress((IPv6AddressBytes*) NULL);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// World directory
|
// World directory
|
||||||
std::string commanded_world = "";
|
std::string commanded_world = "";
|
||||||
if(cmd_args.exists("world"))
|
if(cmd_args.exists("world"))
|
||||||
@ -1223,8 +1208,29 @@ int main(int argc, char *argv[])
|
|||||||
}
|
}
|
||||||
verbosestream<<_("Using gameid")<<" ["<<gamespec.id<<"]"<<std::endl;
|
verbosestream<<_("Using gameid")<<" ["<<gamespec.id<<"]"<<std::endl;
|
||||||
|
|
||||||
|
// Bind address
|
||||||
|
std::string bind_str = g_settings->get("bind_address");
|
||||||
|
Address bind_addr(0,0,0,0, port);
|
||||||
|
|
||||||
|
if (g_settings->getBool("ipv6_server")) {
|
||||||
|
bind_addr.setAddress((IPv6AddressBytes*) NULL);
|
||||||
|
}
|
||||||
|
try {
|
||||||
|
bind_addr.Resolve(bind_str.c_str());
|
||||||
|
} catch (ResolveError &e) {
|
||||||
|
infostream << "Resolving bind address \"" << bind_str
|
||||||
|
<< "\" failed: " << e.what()
|
||||||
|
<< " -- Listening on all addresses." << std::endl;
|
||||||
|
}
|
||||||
|
if(bind_addr.isIPv6() && !g_settings->getBool("enable_ipv6")) {
|
||||||
|
errorstream << "Unable to listen on "
|
||||||
|
<< bind_addr.serializeString()
|
||||||
|
<< L" because IPv6 is disabled" << std::endl;
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
// Create server
|
// Create server
|
||||||
Server server(world_path, gamespec, false);
|
Server server(world_path, gamespec, false, bind_addr.isIPv6());
|
||||||
|
|
||||||
// Database migration
|
// Database migration
|
||||||
if (cmd_args.exists("migrate")) {
|
if (cmd_args.exists("migrate")) {
|
||||||
|
@ -166,7 +166,8 @@ v3f ServerSoundParams::getPos(ServerEnvironment *env, bool *pos_exists) const
|
|||||||
Server::Server(
|
Server::Server(
|
||||||
const std::string &path_world,
|
const std::string &path_world,
|
||||||
const SubgameSpec &gamespec,
|
const SubgameSpec &gamespec,
|
||||||
bool simple_singleplayer_mode
|
bool simple_singleplayer_mode,
|
||||||
|
bool ipv6
|
||||||
):
|
):
|
||||||
m_path_world(path_world),
|
m_path_world(path_world),
|
||||||
m_gamespec(gamespec),
|
m_gamespec(gamespec),
|
||||||
@ -176,7 +177,7 @@ Server::Server(
|
|||||||
m_con(PROTOCOL_ID,
|
m_con(PROTOCOL_ID,
|
||||||
512,
|
512,
|
||||||
CONNECTION_TIMEOUT,
|
CONNECTION_TIMEOUT,
|
||||||
g_settings->getBool("enable_ipv6") && g_settings->getBool("ipv6_server"),
|
ipv6,
|
||||||
this),
|
this),
|
||||||
m_banmanager(NULL),
|
m_banmanager(NULL),
|
||||||
m_rollback(NULL),
|
m_rollback(NULL),
|
||||||
|
@ -174,7 +174,8 @@ public:
|
|||||||
Server(
|
Server(
|
||||||
const std::string &path_world,
|
const std::string &path_world,
|
||||||
const SubgameSpec &gamespec,
|
const SubgameSpec &gamespec,
|
||||||
bool simple_singleplayer_mode
|
bool simple_singleplayer_mode,
|
||||||
|
bool ipv6
|
||||||
);
|
);
|
||||||
~Server();
|
~Server();
|
||||||
void start(Address bind_addr);
|
void start(Address bind_addr);
|
||||||
|
@ -143,6 +143,15 @@ bool Address::operator!=(Address &address)
|
|||||||
|
|
||||||
void Address::Resolve(const char *name)
|
void Address::Resolve(const char *name)
|
||||||
{
|
{
|
||||||
|
if (!name || name[0] == 0) {
|
||||||
|
if (m_addr_family == AF_INET) {
|
||||||
|
setAddress((u32) 0);
|
||||||
|
} else if (m_addr_family == AF_INET6) {
|
||||||
|
setAddress((IPv6AddressBytes*) 0);
|
||||||
|
}
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
struct addrinfo *resolved, hints;
|
struct addrinfo *resolved, hints;
|
||||||
memset(&hints, 0, sizeof(hints));
|
memset(&hints, 0, sizeof(hints));
|
||||||
|
|
||||||
@ -251,6 +260,18 @@ bool Address::isIPv6() const
|
|||||||
return m_addr_family == AF_INET6;
|
return m_addr_family == AF_INET6;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool Address::isZero() const
|
||||||
|
{
|
||||||
|
if (m_addr_family == AF_INET) {
|
||||||
|
return m_address.ipv4.sin_addr.s_addr == 0;
|
||||||
|
} else if (m_addr_family == AF_INET6) {
|
||||||
|
static const char zero[16] = {0};
|
||||||
|
return memcmp(m_address.ipv6.sin6_addr.s6_addr,
|
||||||
|
zero, 16) == 0;
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
void Address::setAddress(u32 address)
|
void Address::setAddress(u32 address)
|
||||||
{
|
{
|
||||||
m_addr_family = AF_INET;
|
m_addr_family = AF_INET;
|
||||||
|
@ -88,6 +88,7 @@ public:
|
|||||||
Address(const IPv6AddressBytes * ipv6_bytes, u16 port);
|
Address(const IPv6AddressBytes * ipv6_bytes, u16 port);
|
||||||
bool operator==(Address &address);
|
bool operator==(Address &address);
|
||||||
bool operator!=(Address &address);
|
bool operator!=(Address &address);
|
||||||
|
// Resolve() may throw ResolveError (address is unchanged in this case)
|
||||||
void Resolve(const char *name);
|
void Resolve(const char *name);
|
||||||
struct sockaddr_in getAddress() const;
|
struct sockaddr_in getAddress() const;
|
||||||
unsigned short getPort() const;
|
unsigned short getPort() const;
|
||||||
@ -97,6 +98,7 @@ public:
|
|||||||
struct sockaddr_in6 getAddress6() const;
|
struct sockaddr_in6 getAddress6() const;
|
||||||
int getFamily() const;
|
int getFamily() const;
|
||||||
bool isIPv6() const;
|
bool isIPv6() const;
|
||||||
|
bool isZero() const;
|
||||||
void setPort(unsigned short port);
|
void setPort(unsigned short port);
|
||||||
void print(std::ostream *s) const;
|
void print(std::ostream *s) const;
|
||||||
std::string serializeString() const;
|
std::string serializeString() const;
|
||||||
|
Loading…
Reference in New Issue
Block a user