Skip to content

Commit 6090e95

Browse files
kahrlsapier
authored and
sapier
committedApr 10, 2014
Infer ipv6_server from bind_address; fix client connect to IN(6)ADDR_ANY
1 parent edcad09 commit 6090e95

File tree

7 files changed

+87
-46
lines changed

7 files changed

+87
-46
lines changed
 

‎minetest.conf.example

+1
Original file line numberDiff line numberDiff line change
@@ -438,6 +438,7 @@
438438
#enable_ipv6 = true
439439
# Enable/disable running an IPv6 server. An IPv6 server may be restricted
440440
# to IPv6 clients, depending on system configuration.
441+
# Ignored if bind_address is set.
441442
#ipv6_server = false
442443

443444
#main_menu_script =

‎src/game.cpp

+36-27
Original file line numberDiff line numberDiff line change
@@ -1147,28 +1147,35 @@ void the_game(bool &kill, bool random_input, InputHandler *input,
11471147
draw_load_screen(text, device, font,0,25);
11481148
delete[] text;
11491149
infostream<<"Creating server"<<std::endl;
1150-
server = new Server(map_dir, gamespec,
1151-
simple_singleplayer_mode);
11521150

11531151
std::string bind_str = g_settings->get("bind_address");
11541152
Address bind_addr(0,0,0,0, port);
11551153

1156-
if (bind_str != "")
1157-
{
1158-
try {
1159-
bind_addr.Resolve(bind_str.c_str());
1160-
address = bind_str;
1161-
} catch (ResolveError &e) {
1162-
infostream << "Resolving bind address \"" << bind_str
1163-
<< "\" failed: " << e.what()
1164-
<< " -- Listening on all addresses." << std::endl;
1154+
if (g_settings->getBool("ipv6_server")) {
1155+
bind_addr.setAddress((IPv6AddressBytes*) NULL);
1156+
}
1157+
try {
1158+
bind_addr.Resolve(bind_str.c_str());
1159+
address = bind_str;
1160+
} catch (ResolveError &e) {
1161+
infostream << "Resolving bind address \"" << bind_str
1162+
<< "\" failed: " << e.what()
1163+
<< " -- Listening on all addresses." << std::endl;
1164+
}
11651165

1166-
if (g_settings->getBool("ipv6_server")) {
1167-
bind_addr.setAddress((IPv6AddressBytes*) NULL);
1168-
}
1169-
}
1166+
if(bind_addr.isIPv6() && !g_settings->getBool("enable_ipv6")) {
1167+
error_message = L"Unable to listen on " +
1168+
narrow_to_wide(bind_addr.serializeString()) +
1169+
L" because IPv6 is disabled";
1170+
errorstream<<wide_to_narrow(error_message)<<std::endl;
1171+
// Break out of client scope
1172+
return;
11701173
}
11711174

1175+
server = new Server(map_dir, gamespec,
1176+
simple_singleplayer_mode,
1177+
bind_addr.isIPv6());
1178+
11721179
server->start(bind_addr);
11731180
}
11741181

@@ -1193,31 +1200,33 @@ void the_game(bool &kill, bool random_input, InputHandler *input,
11931200
delete[] text;
11941201
}
11951202
Address connect_address(0,0,0,0, port);
1196-
try{
1197-
if(address == "")
1198-
{
1203+
try {
1204+
connect_address.Resolve(address.c_str());
1205+
if (connect_address.isZero()) { // i.e. INADDR_ANY, IN6ADDR_ANY
11991206
//connect_address.Resolve("localhost");
1200-
if(g_settings->getBool("enable_ipv6") && g_settings->getBool("ipv6_server"))
1201-
{
1207+
if (connect_address.isIPv6()) {
12021208
IPv6AddressBytes addr_bytes;
12031209
addr_bytes.bytes[15] = 1;
12041210
connect_address.setAddress(&addr_bytes);
1205-
}
1206-
else
1207-
{
1211+
} else {
12081212
connect_address.setAddress(127,0,0,1);
12091213
}
12101214
}
1211-
else
1212-
connect_address.Resolve(address.c_str());
12131215
}
1214-
catch(ResolveError &e)
1215-
{
1216+
catch(ResolveError &e) {
12161217
error_message = L"Couldn't resolve address: " + narrow_to_wide(e.what());
12171218
errorstream<<wide_to_narrow(error_message)<<std::endl;
12181219
// Break out of client scope
12191220
break;
12201221
}
1222+
if(connect_address.isIPv6() && !g_settings->getBool("enable_ipv6")) {
1223+
error_message = L"Unable to connect to " +
1224+
narrow_to_wide(connect_address.serializeString()) +
1225+
L" because IPv6 is disabled";
1226+
errorstream<<wide_to_narrow(error_message)<<std::endl;
1227+
// Break out of client scope
1228+
break;
1229+
}
12211230

12221231
/*
12231232
Create client

‎src/main.cpp

+22-16
Original file line numberDiff line numberDiff line change
@@ -1023,21 +1023,6 @@ int main(int argc, char *argv[])
10231023
if(port == 0)
10241024
port = 30000;
10251025

1026-
// Bind address
1027-
std::string bind_str = g_settings->get("bind_address");
1028-
Address bind_addr(0,0,0,0, port);
1029-
try {
1030-
bind_addr.Resolve(bind_str.c_str());
1031-
} catch (ResolveError &e) {
1032-
infostream << "Resolving bind address \"" << bind_str
1033-
<< "\" failed: " << e.what()
1034-
<< " -- Listening on all addresses." << std::endl;
1035-
1036-
if (g_settings->getBool("ipv6_server")) {
1037-
bind_addr.setAddress((IPv6AddressBytes*) NULL);
1038-
}
1039-
}
1040-
10411026
// World directory
10421027
std::string commanded_world = "";
10431028
if(cmd_args.exists("world"))
@@ -1223,8 +1208,29 @@ int main(int argc, char *argv[])
12231208
}
12241209
verbosestream<<_("Using gameid")<<" ["<<gamespec.id<<"]"<<std::endl;
12251210

1211+
// Bind address
1212+
std::string bind_str = g_settings->get("bind_address");
1213+
Address bind_addr(0,0,0,0, port);
1214+
1215+
if (g_settings->getBool("ipv6_server")) {
1216+
bind_addr.setAddress((IPv6AddressBytes*) NULL);
1217+
}
1218+
try {
1219+
bind_addr.Resolve(bind_str.c_str());
1220+
} catch (ResolveError &e) {
1221+
infostream << "Resolving bind address \"" << bind_str
1222+
<< "\" failed: " << e.what()
1223+
<< " -- Listening on all addresses." << std::endl;
1224+
}
1225+
if(bind_addr.isIPv6() && !g_settings->getBool("enable_ipv6")) {
1226+
errorstream << "Unable to listen on "
1227+
<< bind_addr.serializeString()
1228+
<< L" because IPv6 is disabled" << std::endl;
1229+
return 1;
1230+
}
1231+
12261232
// Create server
1227-
Server server(world_path, gamespec, false);
1233+
Server server(world_path, gamespec, false, bind_addr.isIPv6());
12281234

12291235
// Database migration
12301236
if (cmd_args.exists("migrate")) {

‎src/server.cpp

+3-2
Original file line numberDiff line numberDiff line change
@@ -166,7 +166,8 @@ v3f ServerSoundParams::getPos(ServerEnvironment *env, bool *pos_exists) const
166166
Server::Server(
167167
const std::string &path_world,
168168
const SubgameSpec &gamespec,
169-
bool simple_singleplayer_mode
169+
bool simple_singleplayer_mode,
170+
bool ipv6
170171
):
171172
m_path_world(path_world),
172173
m_gamespec(gamespec),
@@ -176,7 +177,7 @@ Server::Server(
176177
m_con(PROTOCOL_ID,
177178
512,
178179
CONNECTION_TIMEOUT,
179-
g_settings->getBool("enable_ipv6") && g_settings->getBool("ipv6_server"),
180+
ipv6,
180181
this),
181182
m_banmanager(NULL),
182183
m_rollback(NULL),

‎src/server.h

+2-1
Original file line numberDiff line numberDiff line change
@@ -174,7 +174,8 @@ class Server : public con::PeerHandler, public MapEventReceiver,
174174
Server(
175175
const std::string &path_world,
176176
const SubgameSpec &gamespec,
177-
bool simple_singleplayer_mode
177+
bool simple_singleplayer_mode,
178+
bool ipv6
178179
);
179180
~Server();
180181
void start(Address bind_addr);

‎src/socket.cpp

+21
Original file line numberDiff line numberDiff line change
@@ -143,6 +143,15 @@ bool Address::operator!=(Address &address)
143143

144144
void Address::Resolve(const char *name)
145145
{
146+
if (!name || name[0] == 0) {
147+
if (m_addr_family == AF_INET) {
148+
setAddress((u32) 0);
149+
} else if (m_addr_family == AF_INET6) {
150+
setAddress((IPv6AddressBytes*) 0);
151+
}
152+
return;
153+
}
154+
146155
struct addrinfo *resolved, hints;
147156
memset(&hints, 0, sizeof(hints));
148157

@@ -251,6 +260,18 @@ bool Address::isIPv6() const
251260
return m_addr_family == AF_INET6;
252261
}
253262

263+
bool Address::isZero() const
264+
{
265+
if (m_addr_family == AF_INET) {
266+
return m_address.ipv4.sin_addr.s_addr == 0;
267+
} else if (m_addr_family == AF_INET6) {
268+
static const char zero[16] = {0};
269+
return memcmp(m_address.ipv6.sin6_addr.s6_addr,
270+
zero, 16) == 0;
271+
}
272+
return false;
273+
}
274+
254275
void Address::setAddress(u32 address)
255276
{
256277
m_addr_family = AF_INET;

‎src/socket.h

+2
Original file line numberDiff line numberDiff line change
@@ -88,6 +88,7 @@ class Address
8888
Address(const IPv6AddressBytes * ipv6_bytes, u16 port);
8989
bool operator==(Address &address);
9090
bool operator!=(Address &address);
91+
// Resolve() may throw ResolveError (address is unchanged in this case)
9192
void Resolve(const char *name);
9293
struct sockaddr_in getAddress() const;
9394
unsigned short getPort() const;
@@ -97,6 +98,7 @@ class Address
9798
struct sockaddr_in6 getAddress6() const;
9899
int getFamily() const;
99100
bool isIPv6() const;
101+
bool isZero() const;
100102
void setPort(unsigned short port);
101103
void print(std::ostream *s) const;
102104
std::string serializeString() const;

0 commit comments

Comments
 (0)
Please sign in to comment.