1
0
Fork 0
mirror of https://github.com/luanti-org/luanti.git synced 2025-07-17 17:08:39 +00:00

Switch from broadcast to multicast (ipv4)

This commit is contained in:
DustyBagel 2024-07-06 14:22:37 -05:00
parent a8163f6d25
commit fac62dc3d1
3 changed files with 72 additions and 32 deletions

View file

@ -17,32 +17,31 @@
local function get_sorted_servers()
local servers = {
lan = {},
fav = {},
public = {},
incompatible = {}
}
local merged_serverlist = table.copy(serverlistmgr.servers)
--Special thanks to proller <proller@gmail.com> for letting use use the get_lan_servers function.
if minetest.settings:get_bool("serverlist_lan") then
if core.get_lan_servers then
servers.lan = core.get_lan_servers();
for _, server in ipairs(servers.lan) do
local lan = core.get_lan_servers()
for _, server in ipairs(lan) do
server.is_compatible = is_server_protocol_compat(server.proto_min, server.proto_max)
server.is_local = true
table.insert(merged_serverlist, server)
end
else
print("core.get_lan_servers isn't defined.")
servers.lan = {}
end
else
servers.lan = {}
end
print(dump(servers.lan))
local favs = serverlistmgr.get_favorites()
local taken_favs = {}
local result = menudata.search_result or serverlistmgr.servers
local result = menudata.search_result or merged_serverlist
for _, server in ipairs(result) do
server.is_favorite = false
for index, fav in ipairs(favs) do
@ -56,7 +55,11 @@ local function get_sorted_servers()
if server.is_favorite then
table.insert(servers.fav, server)
elseif server.is_compatible then
if server.is_local then
table.insert(servers.lan, server)
else
table.insert(servers.public, server)
end
else
table.insert(servers.incompatible, server)
end
@ -389,6 +392,8 @@ local function main_button_handler(tabview, fields, name, tabdata)
serverlistmgr.add_favorite(server)
print("Adding this server to favorites: \n"..dump(server))
gamedata.servername = server.name
gamedata.serverdescription = server.description

View file

@ -68,13 +68,34 @@ typedef int socklen_t;
typedef int socket_t;
#endif
const char* adv_multicast_addr = "224.1.1.1";
const static unsigned short int adv_port = 29998;
static std::string ask_str;
bool use_ipv6 = true;
lan_adv::lan_adv() : Thread("lan_adv")
{
}
lan_adv::~lan_adv()
{
if (!stopRequested()) {
stop();
warningstream << "Thread Had to be forced to stop correctly." << std::endl;
}
if (stopRequested()) warningstream << "Lan Adv Thread is stopping." << std::endl;
if (server_port) {
Json::Value answer_json;
answer_json["port"] = server_port;
answer_json["cmd"] = "shutdown";
send_string(fastWriteJson(answer_json));
warningstream << "Server shut down message sent." << std::endl;
}
}
void lan_adv::ask()
{
if (!isRunning()) start();
@ -94,11 +115,26 @@ void lan_adv::send_string(const std::string &str)
sockaddr_in addr = {};
addr.sin_family = AF_INET;
addr.sin_port = htons(adv_port);
addr.sin_addr.s_addr = htonl(INADDR_BROADCAST);
UDPSocket socket_send(false);
int set_option_on = 1;
setsockopt(socket_send.GetHandle(), SOL_SOCKET, SO_BROADCAST,
(const char *)&set_option_on, sizeof(set_option_on));
// Full discloser, the use of inet_proto and the mreq stucture
// were suggested by ai.
inet_pton(AF_INET, adv_multicast_addr, &(addr.sin_addr));
struct ip_mreq mreq;
mreq.imr_multiaddr.s_addr = inet_addr(adv_multicast_addr);
mreq.imr_interface.s_addr = htonl(INADDR_ANY);
setsockopt(socket_send.GetHandle(), IPPROTO_IP, IP_ADD_MEMBERSHIP,
(const char *)&mreq, sizeof(mreq));
//int set_option_on = 2;
//setsockopt(socket_send.GetHandle(), SOL_SOCKET, IP_MULTICAST_TTL,
// (const char *)&set_option_on, sizeof(set_option_on));
socket_send.Send(Address(addr), str.c_str(), str.size());
} catch (const std::exception &e) {
verbosestream << "udp broadcast send4 fail " << e.what() << "\n";
@ -147,8 +183,8 @@ void lan_adv::send_string(const std::string &str)
addr.sin6_port = htons(adv_port);
UDPSocket socket_send(true);
int set_option_on = 1;
setsockopt(socket_send.GetHandle(), SOL_SOCKET, SO_BROADCAST,
(const char *)&set_option_on, sizeof(set_option_on));
//setsockopt(socket_send.GetHandle(), SOL_SOCKET, IPV6_MULTICAST_HOPS,
// (const char *)&set_option_on, sizeof(set_option_on));
auto use_scopes = scopes;
if (addr.sin6_scope_id) {
use_scopes.clear();
@ -169,7 +205,7 @@ void lan_adv::send_string(const std::string &str)
void lan_adv::serve(unsigned short port)
{
server_port = port;
if (isRunning()) stop();
stop();
start();
}
@ -187,8 +223,13 @@ void *lan_adv::run()
setsockopt(socket_recv.GetHandle(), SOL_SOCKET, SO_REUSEPORT,
(const char *)&set_option_on, sizeof(set_option_on));
#endif
setsockopt(socket_recv.GetHandle(), SOL_SOCKET, SO_BROADCAST,
(const char *)&set_option_on, sizeof(set_option_on));
struct ip_mreq mreq;
mreq.imr_multiaddr.s_addr = inet_addr(adv_multicast_addr);
mreq.imr_interface.s_addr = htonl(INADDR_ANY);
setsockopt(socket_recv.GetHandle(), IPPROTO_IP, IP_ADD_MEMBERSHIP,
(const char *)&mreq, sizeof(mreq));
setsockopt(socket_recv.GetHandle(), IPPROTO_IPV6, IPV6_V6ONLY,
(const char *)&set_option_off, sizeof(set_option_off));
socket_recv.setTimeoutMs(200);
@ -254,11 +295,11 @@ void *lan_adv::run()
server["clients"] = clients_num.load();
answer_str = fastWriteJson(server);
limiter[addr_str] = now + 3000;
UDPSocket socket_send(true);
addr.setPort(adv_port);
socket_send.Send(addr, answer_str.c_str(), answer_str.size());
send_string(answer_str);
//UDPSocket socket_send(true);
//addr.setPort(adv_port);
//socket_send.Send(addr, answer_str.c_str(), answer_str.size());
}
} else {
if (p["cmd"] == "ask") {
@ -284,13 +325,6 @@ void *lan_adv::run()
END_DEBUG_EXCEPTION_HANDLER;
}
if (server_port) {
Json::Value answer_json;
answer_json["port"] = server_port;
answer_json["cmd"] = "shutdown";
send_string(fastWriteJson(answer_json));
}
END_DEBUG_EXCEPTION_HANDLER;
return nullptr;

View file

@ -32,6 +32,7 @@ public:
void *run();
lan_adv();
~lan_adv();
void ask();
void send_string(const std::string &str);