Skip to content

Commit 85fe75d

Browse files
ShadowNinjasapier
authored and
sapier
committedFeb 5, 2014
Add the option to bind to a specific address
1 parent 7f74317 commit 85fe75d

12 files changed

+118
-40
lines changed
 

‎builtin/mainmenu.lua

+20-4
Original file line numberDiff line numberDiff line change
@@ -626,6 +626,9 @@ function tabbuilder.handle_server_buttons(fields)
626626
gamedata.selected_world = filterlist.get_raw_index(worldlist,selected)
627627

628628
engine.setting_set("port",gamedata.port)
629+
if fields["te_serveraddr"] ~= nil then
630+
engine.setting_set("bind_address",fields["te_serveraddr"])
631+
end
629632

630633
menu.update_last_game(gamedata.selected_world)
631634
engine.start()
@@ -950,11 +953,24 @@ function tabbuilder.tab_server()
950953
dump(engine.setting_getbool("enable_damage")) .. "]"..
951954
"checkbox[0.5,1.15;cb_server_announce;".. fgettext("Public") .. ";" ..
952955
dump(engine.setting_getbool("server_announce")) .. "]"..
953-
"field[0.8,3.2;3,0.5;te_playername;".. fgettext("Name") .. ";" ..
956+
"field[0.8,3.2;3.5,0.5;te_playername;".. fgettext("Name") .. ";" ..
954957
engine.setting_get("name") .. "]" ..
955-
"pwdfield[0.8,4.2;3,0.5;te_passwd;".. fgettext("Password") .. "]" ..
956-
"field[0.8,5.2;3,0.5;te_serverport;".. fgettext("Server Port") .. ";" ..
957-
engine.setting_get("port") .."]" ..
958+
"pwdfield[0.8,4.2;3.5,0.5;te_passwd;".. fgettext("Password") .. "]"
959+
960+
local bind_addr = engine.setting_get("bind_address")
961+
if bind_addr ~= nil and bind_addr ~= "" then
962+
retval = retval ..
963+
"field[0.8,5.2;2.25,0.5;te_serveraddr;".. fgettext("Bind Address") .. ";" ..
964+
engine.setting_get("bind_address") .."]" ..
965+
"field[3.05,5.2;1.25,0.5;te_serverport;".. fgettext("Port") .. ";" ..
966+
engine.setting_get("port") .."]"
967+
else
968+
retval = retval ..
969+
"field[0.8,5.2;3.5,0.5;te_serverport;".. fgettext("Server Port") .. ";" ..
970+
engine.setting_get("port") .."]"
971+
end
972+
973+
retval = retval ..
958974
"textlist[4,0.25;7.5,3.7;srv_worlds;" ..
959975
menu.render_world_list() ..
960976
";" .. index .. "]"

‎minetest.conf.example

+3-1
Original file line numberDiff line numberDiff line change
@@ -231,7 +231,9 @@
231231
# Server stuff
232232
#
233233
# Network port to listen (UDP)
234-
#port =
234+
#port = 30000
235+
# Bind address
236+
#bind_address =
235237
# Name of server
236238
#server_name = Minetest server
237239
# Description of server

‎src/connection.cpp

+18-9
Original file line numberDiff line numberDiff line change
@@ -1597,8 +1597,8 @@ void ConnectionSendThread::processNonReliableCommand(ConnectionCommand &c)
15971597
return;
15981598
case CONNCMD_SERVE:
15991599
LOG(dout_con<<m_connection->getDesc()<<" UDP processing CONNCMD_SERVE port="
1600-
<<c.port<<std::endl);
1601-
serve(c.port);
1600+
<<c.address.serializeString()<<std::endl);
1601+
serve(c.address);
16021602
return;
16031603
case CONNCMD_CONNECT:
16041604
LOG(dout_con<<m_connection->getDesc()<<" UDP processing CONNCMD_CONNECT"<<std::endl);
@@ -1631,11 +1631,12 @@ void ConnectionSendThread::processNonReliableCommand(ConnectionCommand &c)
16311631
}
16321632
}
16331633

1634-
void ConnectionSendThread::serve(u16 port)
1634+
void ConnectionSendThread::serve(Address bind_address)
16351635
{
1636-
LOG(dout_con<<m_connection->getDesc()<<"UDP serving at port "<<port<<std::endl);
1636+
LOG(dout_con<<m_connection->getDesc()
1637+
<<"UDP serving at port " << bind_address.serializeString() <<std::endl);
16371638
try{
1638-
m_connection->m_udpSocket.Bind(port);
1639+
m_connection->m_udpSocket.Bind(bind_address);
16391640
m_connection->SetPeerID(PEER_ID_SERVER);
16401641
}
16411642
catch(SocketException &e){
@@ -1658,7 +1659,14 @@ void ConnectionSendThread::connect(Address address)
16581659
e.peerAdded(peer->id, peer->address);
16591660
m_connection->putEvent(e);
16601661

1661-
m_connection->m_udpSocket.Bind(0);
1662+
Address bind_addr;
1663+
1664+
if (address.isIPv6())
1665+
bind_addr.setAddress((IPv6AddressBytes*) NULL);
1666+
else
1667+
bind_addr.setAddress(0,0,0,0);
1668+
1669+
m_connection->m_udpSocket.Bind(bind_addr);
16621670

16631671
// Send a dummy packet to server with peer_id = PEER_ID_INEXISTENT
16641672
m_connection->SetPeerID(PEER_ID_INEXISTENT);
@@ -1716,7 +1724,8 @@ void ConnectionSendThread::send(u16 peer_id, u8 channelnum,
17161724
assert(channelnum < CHANNEL_COUNT);
17171725

17181726
PeerHelper peer = m_connection->getPeerNoEx(peer_id);
1719-
if(!peer) {
1727+
if(!peer)
1728+
{
17201729
LOG(dout_con<<m_connection->getDesc()<<" peer: peer_id="<<peer_id
17211730
<< ">>>NOT<<< found on sending packet"
17221731
<< ", channel " << (channelnum % 0xFF)
@@ -2766,10 +2775,10 @@ void Connection::putCommand(ConnectionCommand &c)
27662775
}
27672776
}
27682777

2769-
void Connection::Serve(unsigned short port)
2778+
void Connection::Serve(Address bind_addr)
27702779
{
27712780
ConnectionCommand c;
2772-
c.serve(port);
2781+
c.serve(bind_addr);
27732782
putCommand(c);
27742783
}
27752784

‎src/connection.h

+4-5
Original file line numberDiff line numberDiff line change
@@ -406,7 +406,6 @@ enum ConnectionCommandType{
406406
struct ConnectionCommand
407407
{
408408
enum ConnectionCommandType type;
409-
u16 port;
410409
Address address;
411410
u16 peer_id;
412411
u8 channelnum;
@@ -416,10 +415,10 @@ struct ConnectionCommand
416415

417416
ConnectionCommand(): type(CONNCMD_NONE), peer_id(PEER_ID_INEXISTENT), reliable(false), raw(false) {}
418417

419-
void serve(u16 port_)
418+
void serve(Address address_)
420419
{
421420
type = CONNCMD_SERVE;
422-
port = port_;
421+
address = address_;
423422
}
424423
void connect(Address address_)
425424
{
@@ -912,7 +911,7 @@ class ConnectionSendThread : public JThread {
912911

913912
void processReliableCommand (ConnectionCommand &c);
914913
void processNonReliableCommand (ConnectionCommand &c);
915-
void serve (u16 port);
914+
void serve (Address bind_address);
916915
void connect (Address address);
917916
void disconnect ();
918917
void disconnect_peer(u16 peer_id);
@@ -996,7 +995,7 @@ class Connection
996995
void putCommand(ConnectionCommand &c);
997996

998997
void SetTimeoutMs(int timeout){ m_bc_receive_timeout = timeout; }
999-
void Serve(unsigned short port);
998+
void Serve(Address bind_addr);
1000999
void Connect(Address address);
10011000
bool Connected();
10021001
void Disconnect();

‎src/defaultsettings.cpp

+1
Original file line numberDiff line numberDiff line change
@@ -175,6 +175,7 @@ void set_default_settings(Settings *settings)
175175
settings->setDefault("workaround_window_size","5");
176176
settings->setDefault("max_packets_per_iteration","1024");
177177
settings->setDefault("port", "30000");
178+
settings->setDefault("bind_address","");
178179
settings->setDefault("default_game", "minetest");
179180
settings->setDefault("motd", "");
180181
settings->setDefault("max_users", "15");

‎src/game.cpp

+23-3
Original file line numberDiff line numberDiff line change
@@ -909,8 +909,8 @@ bool nodePlacementPrediction(Client &client,
909909

910910
// Dont place node when player would be inside new node
911911
// NOTE: This is to be eventually implemented by a mod as client-side Lua
912-
if (!nodedef->get(n).walkable ||
913-
(client.checkPrivilege("noclip") && g_settings->getBool("noclip")) ||
912+
if (!nodedef->get(n).walkable ||
913+
(client.checkPrivilege("noclip") && g_settings->getBool("noclip")) ||
914914
(nodedef->get(n).walkable &&
915915
neighbourpos != player->getStandingNodePos() + v3s16(0,1,0) &&
916916
neighbourpos != player->getStandingNodePos() + v3s16(0,2,0))) {
@@ -1029,7 +1029,27 @@ void the_game(
10291029
infostream<<"Creating server"<<std::endl;
10301030
server = new Server(map_dir, gamespec,
10311031
simple_singleplayer_mode);
1032-
server->start(port);
1032+
1033+
std::string bind_str = g_settings->get("bind_address");
1034+
Address bind_addr(0,0,0,0, port);
1035+
1036+
if (bind_str != "")
1037+
{
1038+
try {
1039+
bind_addr.Resolve(bind_str.c_str());
1040+
address = bind_str;
1041+
} catch (ResolveError &e) {
1042+
infostream << "Resolving bind address \"" << bind_str
1043+
<< "\" failed: " << e.what()
1044+
<< " -- Listening on all addresses." << std::endl;
1045+
1046+
if (g_settings->getBool("ipv6_server")) {
1047+
bind_addr.setAddress((IPv6AddressBytes*) NULL);
1048+
}
1049+
}
1050+
}
1051+
1052+
server->start(bind_addr);
10331053
}
10341054

10351055
do{ // Client scope (breakable do-while(0))

‎src/main.cpp

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

1027+
// Bind address
1028+
std::string bind_str = g_settings->get("bind_address");
1029+
Address bind_addr(0,0,0,0, port);
1030+
try {
1031+
bind_addr.Resolve(bind_str.c_str());
1032+
} catch (ResolveError &e) {
1033+
infostream << "Resolving bind address \"" << bind_str
1034+
<< "\" failed: " << e.what()
1035+
<< " -- Listening on all addresses." << std::endl;
1036+
1037+
if (g_settings->getBool("ipv6_server")) {
1038+
bind_addr.setAddress((IPv6AddressBytes*) NULL);
1039+
}
1040+
}
1041+
10271042
// World directory
10281043
std::string commanded_world = "";
10291044
if(cmd_args.exists("world"))
@@ -1270,7 +1285,7 @@ int main(int argc, char *argv[])
12701285
return 0;
12711286
}
12721287

1273-
server.start(port);
1288+
server.start(bind_addr);
12741289

12751290
// Run server
12761291
dedicated_server_loop(server, kill);

‎src/server.cpp

+6-4
Original file line numberDiff line numberDiff line change
@@ -452,17 +452,18 @@ Server::~Server()
452452
}
453453
}
454454

455-
void Server::start(unsigned short port)
455+
void Server::start(Address bind_addr)
456456
{
457457
DSTACK(__FUNCTION_NAME);
458-
infostream<<"Starting server on port "<<port<<"..."<<std::endl;
458+
infostream<<"Starting server on "
459+
<< bind_addr.serializeString() <<"..."<<std::endl;
459460

460461
// Stop thread if already running
461462
m_thread->Stop();
462463

463464
// Initialize connection
464465
m_con.SetTimeoutMs(30);
465-
m_con.Serve(port);
466+
m_con.Serve(bind_addr);
466467

467468
// Start thread
468469
m_thread->Start();
@@ -477,7 +478,8 @@ void Server::start(unsigned short port)
477478
<<" \\/ \\/ \\/ \\/ \\/ "<<std::endl;
478479
actionstream<<"World at ["<<m_path_world<<"]"<<std::endl;
479480
actionstream<<"Server for gameid=\""<<m_gamespec.id
480-
<<"\" listening on port "<<port<<"."<<std::endl;
481+
<<"\" listening on "<<bind_addr.serializeString()<<":"
482+
<<bind_addr.getPort() << "."<<std::endl;
481483
}
482484

483485
void Server::stop()

‎src/server.h

+1-1
Original file line numberDiff line numberDiff line change
@@ -177,7 +177,7 @@ class Server : public con::PeerHandler, public MapEventReceiver,
177177
bool simple_singleplayer_mode
178178
);
179179
~Server();
180-
void start(unsigned short port);
180+
void start(Address bind_addr);
181181
void stop();
182182
// This is mainly a way to pass the time to the server.
183183
// Actual processing is done in an another thread.

‎src/socket.cpp

+19-8
Original file line numberDiff line numberDiff line change
@@ -92,24 +92,27 @@ void sockets_cleanup()
9292
Address::Address()
9393
{
9494
m_addr_family = 0;
95-
memset(&m_address, 0, sizeof m_address);
95+
memset(&m_address, 0, sizeof(m_address));
9696
m_port = 0;
9797
}
9898

9999
Address::Address(u32 address, u16 port)
100100
{
101+
memset(&m_address, 0, sizeof(m_address));
101102
setAddress(address);
102103
setPort(port);
103104
}
104105

105106
Address::Address(u8 a, u8 b, u8 c, u8 d, u16 port)
106107
{
108+
memset(&m_address, 0, sizeof(m_address));
107109
setAddress(a, b, c, d);
108110
setPort(port);
109111
}
110112

111113
Address::Address(const IPv6AddressBytes * ipv6_bytes, u16 port)
112114
{
115+
memset(&m_address, 0, sizeof(m_address));
113116
setAddress(ipv6_bytes);
114117
setPort(port);
115118
}
@@ -334,25 +337,33 @@ UDPSocket::~UDPSocket()
334337
#endif
335338
}
336339

337-
void UDPSocket::Bind(u16 port)
340+
void UDPSocket::Bind(Address addr)
338341
{
339342
if(socket_enable_debug_output)
340343
{
341344
dstream << "UDPSocket(" << (int) m_handle << ")::Bind(): "
342-
<< "port=" << port << std::endl;
345+
<< addr.serializeString() << ":"
346+
<< addr.getPort() << std::endl;
347+
}
348+
349+
if (addr.getFamily() != m_addr_family)
350+
{
351+
char errmsg[] = "Socket and bind address families do not match";
352+
errorstream << "Bind failed: " << errmsg << std::endl;
353+
throw SocketException(errmsg);
343354
}
344355

345356
if(m_addr_family == AF_INET6)
346357
{
347358
struct sockaddr_in6 address;
348359
memset(&address, 0, sizeof(address));
349360

361+
address = addr.getAddress6();
350362
address.sin6_family = AF_INET6;
351-
address.sin6_addr = in6addr_any;
352-
address.sin6_port = htons(port);
363+
address.sin6_port = htons(addr.getPort());
353364

354365
if(bind(m_handle, (const struct sockaddr *) &address,
355-
sizeof(struct sockaddr_in6)) < 0)
366+
sizeof(struct sockaddr_in6)) < 0)
356367
{
357368
dstream << (int) m_handle << ": Bind failed: "
358369
<< strerror(errno) << std::endl;
@@ -364,9 +375,9 @@ void UDPSocket::Bind(u16 port)
364375
struct sockaddr_in address;
365376
memset(&address, 0, sizeof(address));
366377

378+
address = addr.getAddress();
367379
address.sin_family = AF_INET;
368-
address.sin_addr.s_addr = INADDR_ANY;
369-
address.sin_port = htons(port);
380+
address.sin_port = htons(addr.getPort());
370381

371382
if(bind(m_handle, (const struct sockaddr *) &address,
372383
sizeof(struct sockaddr_in)) < 0)

‎src/socket.h

+1-1
Original file line numberDiff line numberDiff line change
@@ -115,7 +115,7 @@ class UDPSocket
115115
public:
116116
UDPSocket(bool ipv6);
117117
~UDPSocket();
118-
void Bind(unsigned short port);
118+
void Bind(Address addr);
119119
//void Close();
120120
//bool IsOpen();
121121
void Send(const Address & destination, const void * data, int size);

‎src/test.cpp

+6-3
Original file line numberDiff line numberDiff line change
@@ -1506,11 +1506,13 @@ struct TestSocket: public TestBase
15061506
void Run()
15071507
{
15081508
const int port = 30003;
1509+
Address address(0,0,0,0, port);
1510+
Address address6((IPv6AddressBytes*) NULL, port);
15091511

15101512
// IPv6 socket test
15111513
{
15121514
UDPSocket socket6(true);
1513-
socket6.Bind(port);
1515+
socket6.Bind(address6);
15141516

15151517
const char sendbuffer[] = "hello world!";
15161518
IPv6AddressBytes bytes;
@@ -1536,7 +1538,7 @@ struct TestSocket: public TestBase
15361538
// IPv4 socket test
15371539
{
15381540
UDPSocket socket(false);
1539-
socket.Bind(port);
1541+
socket.Bind(address);
15401542

15411543
const char sendbuffer[] = "hello world!";
15421544
socket.Send(Address(127,0,0,1,port), sendbuffer, sizeof(sendbuffer));
@@ -1656,7 +1658,8 @@ struct TestConnection: public TestBase
16561658

16571659
infostream<<"** Creating server Connection"<<std::endl;
16581660
con::Connection server(proto_id, 512, 5.0, false, &hand_server);
1659-
server.Serve(30001);
1661+
Address address(0,0,0,0, 30001);
1662+
server.Serve(address);
16601663

16611664
infostream<<"** Creating client Connection"<<std::endl;
16621665
con::Connection client(proto_id, 512, 5.0, false, &hand_client);

0 commit comments

Comments
 (0)
Please sign in to comment.