summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--minetest.conf.example1
-rw-r--r--src/game.cpp63
-rw-r--r--src/main.cpp38
-rw-r--r--src/server.cpp5
-rw-r--r--src/server.h3
-rw-r--r--src/socket.cpp21
-rw-r--r--src/socket.h2
7 files changed, 87 insertions, 46 deletions
diff --git a/minetest.conf.example b/minetest.conf.example
index f728d6c88..4e4495338 100644
--- a/minetest.conf.example
+++ b/minetest.conf.example
@@ -438,6 +438,7 @@
#enable_ipv6 = true
# Enable/disable running an IPv6 server. An IPv6 server may be restricted
# to IPv6 clients, depending on system configuration.
+# Ignored if bind_address is set.
#ipv6_server = false
#main_menu_script =
diff --git a/src/game.cpp b/src/game.cpp
index 7d881fa88..f435a4d71 100644
--- a/src/game.cpp
+++ b/src/game.cpp
@@ -1147,28 +1147,35 @@ void the_game(bool &kill, bool random_input, InputHandler *input,
draw_load_screen(text, device, font,0,25);
delete[] text;
infostream<<"Creating server"<<std::endl;
- server = new Server(map_dir, gamespec,
- simple_singleplayer_mode);
std::string bind_str = g_settings->get("bind_address");
Address bind_addr(0,0,0,0, port);
- if (bind_str != "")
- {
- 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 (g_settings->getBool("ipv6_server")) {
- bind_addr.setAddress((IPv6AddressBytes*) NULL);
- }
- }
+ 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);
}
@@ -1193,31 +1200,33 @@ void the_game(bool &kill, bool random_input, InputHandler *input,
delete[] text;
}
Address connect_address(0,0,0,0, port);
- try{
- if(address == "")
- {
+ try {
+ connect_address.Resolve(address.c_str());
+ if (connect_address.isZero()) { // i.e. INADDR_ANY, IN6ADDR_ANY
//connect_address.Resolve("localhost");
- if(g_settings->getBool("enable_ipv6") && g_settings->getBool("ipv6_server"))
- {
+ if (connect_address.isIPv6()) {
IPv6AddressBytes addr_bytes;
addr_bytes.bytes[15] = 1;
connect_address.setAddress(&addr_bytes);
- }
- else
- {
+ } else {
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());
errorstream<<wide_to_narrow(error_message)<<std::endl;
// Break out of client scope
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
diff --git a/src/main.cpp b/src/main.cpp
index e52002772..baaf8ebde 100644
--- a/src/main.cpp
+++ b/src/main.cpp
@@ -1023,21 +1023,6 @@ int main(int argc, char *argv[])
if(port == 0)
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
std::string commanded_world = "";
if(cmd_args.exists("world"))
@@ -1223,8 +1208,29 @@ int main(int argc, char *argv[])
}
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
- Server server(world_path, gamespec, false);
+ Server server(world_path, gamespec, false, bind_addr.isIPv6());
// Database migration
if (cmd_args.exists("migrate")) {
diff --git a/src/server.cpp b/src/server.cpp
index 0cd8630c3..5c93988b8 100644
--- a/src/server.cpp
+++ b/src/server.cpp
@@ -166,7 +166,8 @@ v3f ServerSoundParams::getPos(ServerEnvironment *env, bool *pos_exists) const
Server::Server(
const std::string &path_world,
const SubgameSpec &gamespec,
- bool simple_singleplayer_mode
+ bool simple_singleplayer_mode,
+ bool ipv6
):
m_path_world(path_world),
m_gamespec(gamespec),
@@ -176,7 +177,7 @@ Server::Server(
m_con(PROTOCOL_ID,
512,
CONNECTION_TIMEOUT,
- g_settings->getBool("enable_ipv6") && g_settings->getBool("ipv6_server"),
+ ipv6,
this),
m_banmanager(NULL),
m_rollback(NULL),
diff --git a/src/server.h b/src/server.h
index c0928e574..ab89fbc6e 100644
--- a/src/server.h
+++ b/src/server.h
@@ -174,7 +174,8 @@ public:
Server(
const std::string &path_world,
const SubgameSpec &gamespec,
- bool simple_singleplayer_mode
+ bool simple_singleplayer_mode,
+ bool ipv6
);
~Server();
void start(Address bind_addr);
diff --git a/src/socket.cpp b/src/socket.cpp
index 00856fb00..bca9c5390 100644
--- a/src/socket.cpp
+++ b/src/socket.cpp
@@ -143,6 +143,15 @@ bool Address::operator!=(Address &address)
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;
memset(&hints, 0, sizeof(hints));
@@ -251,6 +260,18 @@ bool Address::isIPv6() const
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)
{
m_addr_family = AF_INET;
diff --git a/src/socket.h b/src/socket.h
index 7d35a32da..92e0cbb13 100644
--- a/src/socket.h
+++ b/src/socket.h
@@ -88,6 +88,7 @@ public:
Address(const IPv6AddressBytes * ipv6_bytes, u16 port);
bool operator==(Address &address);
bool operator!=(Address &address);
+ // Resolve() may throw ResolveError (address is unchanged in this case)
void Resolve(const char *name);
struct sockaddr_in getAddress() const;
unsigned short getPort() const;
@@ -97,6 +98,7 @@ public:
struct sockaddr_in6 getAddress6() const;
int getFamily() const;
bool isIPv6() const;
+ bool isZero() const;
void setPort(unsigned short port);
void print(std::ostream *s) const;
std::string serializeString() const;