Browse Source

Player reverse DNS resolution is now threaded.

Updated Jupiter.
pull/3/head
Jessica James 9 years ago
parent
commit
27f2adcd4c
  1. 2
      Jupiter
  2. BIN
      Release/Bot.lib
  3. BIN
      Release/Plugins/RenX.Core.lib
  4. 2
      RenX.Core/RenX_BanDatabase.cpp
  5. 9
      RenX.Core/RenX_PlayerInfo.h
  6. 5
      RenX.Core/RenX_Plugin.cpp
  7. 1
      RenX.Core/RenX_Plugin.h
  8. 73
      RenX.Core/RenX_Server.cpp
  9. 1
      RenX.Core/RenX_Server.h
  10. 18
      RenX.Core/RenX_Tags.cpp
  11. 25
      RenX.Logging/RenX_Logging.cpp
  12. 4
      RenX.Logging/RenX_Logging.h

2
Jupiter

@ -1 +1 @@
Subproject commit 5620679e80b2489358d0bdcb90e03ca5f530dbde
Subproject commit 2d834a64a6123f968531f81d797f4a97be1f0cac

BIN
Release/Bot.lib

Binary file not shown.

BIN
Release/Plugins/RenX.Core.lib

Binary file not shown.

2
RenX.Core/RenX_BanDatabase.cpp

@ -165,6 +165,8 @@ void RenX::BanDatabase::add(RenX::Server *server, const RenX::PlayerInfo *player
entry->steamid = player->steamid;
entry->ip = player->ip32;
entry->prefix_length = 32U;
if (player->rdns_thread.joinable())
player->rdns_thread.join();
entry->rdns = player->rdns;
entry->name = player->name;
entry->banner = banner;

9
RenX.Core/RenX_PlayerInfo.h

@ -25,6 +25,9 @@
*/
#include <chrono>
#include <mutex>
#include <thread>
#include "Jupiter/Reference_String.h"
#include "Jupiter/String.h"
#include "Jupiter/INIFile.h"
#include "RenX.h"
@ -48,11 +51,12 @@ namespace RenX
// TODO: Add backpack
Jupiter::StringS name;
Jupiter::StringS ip;
Jupiter::StringS rdns;
Jupiter::StringS adminType;
Jupiter::StringS uuid;
Jupiter::StringS character;
Jupiter::StringS vehicle;
Jupiter::StringS rdns;
std::mutex rdns_mutex;
uint64_t steamid = 0;
uint32_t ip32 = 0;
uint16_t ban_flags = 0;
@ -61,6 +65,7 @@ namespace RenX
int id = 0;
bool isBot = false;
bool is_dev = false;
bool rdns_resolved = false;
unsigned short ping = 0;
double score = 0.0f;
double credits = 0.0f;
@ -85,10 +90,12 @@ namespace RenX
mutable Jupiter::StringS gamePrefix;
mutable Jupiter::StringS formatNamePrefix;
mutable std::thread rdns_thread;
mutable int access = 0;
mutable Jupiter::INIFile varData; // This will be replaced later with a more dedicated type.
};
static Jupiter::ReferenceString rdns_pending = STRING_LITERAL_AS_REFERENCE("RDNS_PENDING");
}
/** Re-enable warnings */

5
RenX.Core/RenX_Plugin.cpp

@ -61,6 +61,11 @@ void RenX::Plugin::RenX_OnPlayerUUIDChange(Server *, const RenX::PlayerInfo *, c
return;
}
void RenX::Plugin::RenX_OnPlayerRDNS(Server *, const RenX::PlayerInfo *)
{
return;
}
void RenX::Plugin::RenX_OnServerCreate(Server *)
{
return;

1
RenX.Core/RenX_Plugin.h

@ -48,6 +48,7 @@ namespace RenX
virtual void RenX_OnPlayerCreate(Server *server, const PlayerInfo *player);
virtual void RenX_OnPlayerDelete(Server *server, const PlayerInfo *player);
virtual void RenX_OnPlayerUUIDChange(Server *server, const PlayerInfo *player, const Jupiter::ReadableString &newUUID);
virtual void RenX_OnPlayerRDNS(Server *server, const PlayerInfo *player);
virtual void RenX_OnServerCreate(Server *server);
virtual void RenX_OnServerDisconnect(Server *server, RenX::DisconnectReason reason);
virtual bool RenX_OnBan(Server *server, const PlayerInfo *player, Jupiter::StringType &data);

73
RenX.Core/RenX_Server.cpp

@ -59,9 +59,40 @@ int RenX::Server::think()
}
else
{
auto cycle_player_rdns = [this]() // Cycles through any pending RDNS resolutions, and fires events as necessary.
{
if (this->player_rdns_resolutions_pending != 0)
{
RenX::PlayerInfo *player;
Jupiter::ArrayList<RenX::Plugin> &xPlugins = *RenX::getCore()->getPlugins();
for (Jupiter::DLList<RenX::PlayerInfo>::Node *node = this->players.getNode(0); node != nullptr; node = node->next)
{
player = node->data;
if (player->rdns_thread.joinable() && player->rdns_mutex.try_lock()) // RDNS event hasn't fired AND RDNS value has been resolved
{
player->rdns_mutex.unlock();
player->rdns_thread.join();
--this->player_rdns_resolutions_pending;
// Check for bans
this->banCheck(player);
// Fire RDNS resolved event
for (size_t index = 0; index < xPlugins.size(); ++index)
xPlugins.get(++index)->RenX_OnPlayerRDNS(this, player);
if (this->player_rdns_resolutions_pending == 0) // No more resolutions pending
return;
}
}
}
};
// Connected and fine
if (RenX::Server::sock.recv() > 0)
if (RenX::Server::sock.recv() > 0) // Data received
{
cycle_player_rdns();
Jupiter::ReadableString::TokenizeResult<Jupiter::Reference_String> result = Jupiter::ReferenceString::tokenize(RenX::Server::sock.getBuffer(), '\n');
if (result.token_count != 0)
{
@ -77,8 +108,10 @@ int RenX::Server::think()
}
}
}
else if (Jupiter::Socket::getLastError() == 10035)
else if (Jupiter::Socket::getLastError() == 10035) // Operation would block (no new data)
{
cycle_player_rdns();
if (RenX::Server::awaitingPong == false && std::chrono::steady_clock::now() - RenX::Server::lastActivity >= RenX::Server::pingRate)
{
RenX::Server::lastActivity = std::chrono::steady_clock::now();
@ -464,7 +497,7 @@ void RenX::Server::banCheck(RenX::PlayerInfo *player)
if ((this->localSteamBan && entry->steamid != 0 && entry->steamid == player->steamid)
|| (this->localIPBan && entry->ip != 0 && (entry->ip & netmask) == (player->ip32 & netmask))
|| (this->localRDNSBan && entry->rdns.isNotEmpty() && entry->is_rdns_ban() && player->rdns.match(entry->rdns))
|| (this->localRDNSBan && entry->rdns.isNotEmpty() && entry->is_rdns_ban() && player->rdns_thread.joinable() == false && player->rdns.match(entry->rdns))
|| (this->localNameBan && entry->name.isNotEmpty() && entry->name.equalsi(player->name)))
{
player->ban_flags |= entry->flags;
@ -625,6 +658,13 @@ bool RenX::Server::removePlayer(int id)
xPlugins.get(i)->RenX_OnPlayerDelete(this, p);
if (p->isBot)
--this->bot_count;
if (p->rdns_thread.joinable()) // Close the RDNS thread, if one exists
{
--this->player_rdns_resolutions_pending;
p->rdns_thread.join();
}
delete p;
return true;
}
@ -1151,6 +1191,14 @@ void RenX::Server::sendLogChan(const Jupiter::ReadableString &msg) const
}
}
void resolve_rdns(RenX::PlayerInfo *player)
{
player->rdns_mutex.lock();
char *resolved = Jupiter::Socket::resolveHostname_alloc(Jupiter::CStringS(player->ip).c_str(), 0);
player->rdns.capture(resolved, strlen(resolved));
player->rdns_mutex.unlock();
}
#define PARSE_PLAYER_DATA_P(DATA) \
Jupiter::ReferenceString name; \
TeamType team; \
@ -1277,7 +1325,10 @@ void RenX::Server::processLine(const Jupiter::ReadableString &line)
r->ip = ip;
r->ip32 = Jupiter::Socket::pton4(Jupiter::CStringS(r->ip).c_str());
if (this->resolvesRDNS() && r->ip32 != 0)
r->rdns = Jupiter::Socket::resolveHostname(Jupiter::CStringS(r->ip).c_str(), 0);
{
r->rdns_thread = std::thread(resolve_rdns, r);
++this->player_rdns_resolutions_pending;
}
r->steamid = steamid;
if (r->isBot = isBot)
r->formatNamePrefix = IRCCOLOR "05[B]";
@ -1306,7 +1357,11 @@ void RenX::Server::processLine(const Jupiter::ReadableString &line)
{
r->ip = ip;
r->ip32 = Jupiter::Socket::pton4(Jupiter::CStringS(r->ip).c_str());
r->rdns = Jupiter::Socket::resolveHostname(Jupiter::CStringS(r->ip).c_str(), 0);
if (this->resolvesRDNS())
{
r->rdns_thread = std::thread(resolve_rdns, r);
++this->player_rdns_resolutions_pending;
}
recalcUUID = true;
}
if (r->steamid == 0U && steamid != 0U)
@ -3056,9 +3111,17 @@ void RenX::Server::wipeData()
player = RenX::Server::players.remove(0U);
for (size_t index = 0; index < xPlugins.size(); ++index)
xPlugins.get(index)->RenX_OnPlayerDelete(this, player);
if (player->rdns_thread.joinable()) // Close the RDNS thread, if one exists
{
--this->player_rdns_resolutions_pending;
player->rdns_thread.join();
}
delete player;
}
RenX::Server::bot_count = 0;
RenX::Server::player_rdns_resolutions_pending = 0;
RenX::Server::buildings.emptyAndDelete();
RenX::Server::mutators.emptyAndDelete();
RenX::Server::maps.emptyAndDelete();

1
RenX.Core/RenX_Server.h

@ -975,6 +975,7 @@ namespace RenX
int mineLimit = 0;
int timeLimit = 0;
size_t bot_count = 0;
size_t player_rdns_resolutions_pending = 0;
unsigned int rconVersion = 0;
double crateRespawnAfterPickup = 0.0;
uuid_func calc_uuid;

18
RenX.Core/RenX_Tags.cpp

@ -499,7 +499,14 @@ void TagsImp::processTags(Jupiter::StringType &msg, const RenX::Server *server,
PROCESS_TAG(this->INTERNAL_NAME_TAG, RenX::getFormattedPlayerName(player));
PROCESS_TAG(this->INTERNAL_RAW_NAME_TAG, player->name);
PROCESS_TAG(this->INTERNAL_IP_TAG, player->ip);
PROCESS_TAG(this->INTERNAL_RDNS_TAG, player->rdns);
if (player->rdns_thread.joinable())
{
PROCESS_TAG(this->INTERNAL_RDNS_TAG, RenX::rdns_pending);
}
else
{
PROCESS_TAG(this->INTERNAL_RDNS_TAG, player->rdns);
}
PROCESS_TAG(this->INTERNAL_UUID_TAG, player->uuid);
PROCESS_TAG(this->INTERNAL_ID_TAG, Jupiter::StringS::Format("%d", player->id));
PROCESS_TAG(this->INTERNAL_CHARACTER_TAG, RenX::translateName(player->character));
@ -537,7 +544,14 @@ void TagsImp::processTags(Jupiter::StringType &msg, const RenX::Server *server,
PROCESS_TAG(this->INTERNAL_VICTIM_NAME_TAG, RenX::getFormattedPlayerName(victim));
PROCESS_TAG(this->INTERNAL_VICTIM_RAW_NAME_TAG, victim->name);
PROCESS_TAG(this->INTERNAL_VICTIM_IP_TAG, victim->ip);
PROCESS_TAG(this->INTERNAL_VICTIM_RDNS_TAG, victim->rdns);
if (victim->rdns_thread.joinable())
{
PROCESS_TAG(this->INTERNAL_VICTIM_RDNS_TAG, RenX::rdns_pending);
}
else
{
PROCESS_TAG(this->INTERNAL_VICTIM_RDNS_TAG, victim->rdns);
}
PROCESS_TAG(this->INTERNAL_VICTIM_UUID_TAG, victim->uuid);
PROCESS_TAG(this->INTERNAL_VICTIM_ID_TAG, Jupiter::StringS::Format("%d", victim->id));
PROCESS_TAG(this->INTERNAL_VICTIM_CHARACTER_TAG, RenX::translateName(victim->character));

25
RenX.Logging/RenX_Logging.cpp

@ -30,6 +30,7 @@ using namespace Jupiter::literals;
void RenX_LoggingPlugin::init()
{
RenX_LoggingPlugin::muteOwnExecute = Jupiter::IRC::Client::Config->getBool(RenX_LoggingPlugin::getName(), "MuteOwnExecute"_jrs, true);
RenX_LoggingPlugin::playerRDNSPublic = Jupiter::IRC::Client::Config->getBool(RenX_LoggingPlugin::getName(), "PlayerRDNSPublic"_jrs, false);
RenX_LoggingPlugin::joinPublic = Jupiter::IRC::Client::Config->getBool(RenX_LoggingPlugin::getName(), "JoinPublic"_jrs, true);
RenX_LoggingPlugin::partPublic = Jupiter::IRC::Client::Config->getBool(RenX_LoggingPlugin::getName(), "PartPublic"_jrs, true);
RenX_LoggingPlugin::kickPublic = Jupiter::IRC::Client::Config->getBool(RenX_LoggingPlugin::getName(), "KickPublic"_jrs, true);
@ -107,14 +108,17 @@ void RenX_LoggingPlugin::init()
RenX_LoggingPlugin::otherPublic = Jupiter::IRC::Client::Config->getBool(RenX_LoggingPlugin::getName(), "OtherPublic"_jrs, false);
/** Event formats */
RenX_LoggingPlugin::playerRDNSFmt = Jupiter::IRC::Client::Config->get(this->getName(), "PlayerRDNSFormat"_jrs,
Jupiter::StringS::Format(IRCCOLOR "05[RDNS] " IRCBOLD "%.*s" IRCNORMAL "'s hostname is " IRCBOLD "%.*s", RenX::tags->nameTag.size(), RenX::tags->nameTag.ptr(), RenX::tags->rdnsTag.size(), RenX::tags->rdnsTag.ptr()));
RenX_LoggingPlugin::joinPublicFmt = Jupiter::IRC::Client::Config->get(this->getName(), "JoinPublicFormat"_jrs,
Jupiter::StringS::Format(IRCCOLOR "12[Join] " IRCBOLD "%.*s" IRCBOLD " joined the game fighting for the %.*s!", RenX::tags->nameTag.size(), RenX::tags->nameTag.ptr(), RenX::tags->teamLongTag.size(), RenX::tags->teamLongTag.ptr()));
RenX_LoggingPlugin::joinAdminFmt = Jupiter::IRC::Client::Config->get(this->getName(), "JoinAdminFormat"_jrs,
Jupiter::StringS::Format(IRCCOLOR "12[Join] " IRCBOLD "%.*s" IRCBOLD " joined the game fighting for the %.*s from " IRCBOLD "%.*s" IRCBOLD " using Steam ID " IRCBOLD "%.*s" IRCBOLD ". Their hostname is: " IRCBOLD "%.*s", RenX::tags->nameTag.size(), RenX::tags->nameTag.ptr(), RenX::tags->teamLongTag.size(), RenX::tags->teamLongTag.ptr(), RenX::tags->ipTag.size(), RenX::tags->ipTag.ptr(), RenX::tags->steamTag.size(), RenX::tags->steamTag.ptr(), RenX::tags->rdnsTag.size(), RenX::tags->rdnsTag.ptr()));
Jupiter::StringS::Format(IRCCOLOR "12[Join] " IRCBOLD "%.*s" IRCBOLD " joined the game fighting for the %.*s from " IRCBOLD "%.*s" IRCBOLD " using Steam ID " IRCBOLD "%.*s" IRCBOLD ".", RenX::tags->nameTag.size(), RenX::tags->nameTag.ptr(), RenX::tags->teamLongTag.size(), RenX::tags->teamLongTag.ptr(), RenX::tags->ipTag.size(), RenX::tags->ipTag.ptr(), RenX::tags->steamTag.size(), RenX::tags->steamTag.ptr()));
RenX_LoggingPlugin::joinNoSteamAdminFmt = Jupiter::IRC::Client::Config->get(this->getName(), "JoinNoSteamAdminFormat"_jrs,
Jupiter::StringS::Format(IRCCOLOR "12[Join] " IRCBOLD "%.*s" IRCBOLD " joined the game fighting for the %.*s from " IRCBOLD "%.*s" IRCBOLD ", but is " IRCBOLD "not" IRCBOLD " using Steam. Their hostname is: " IRCBOLD "%.*s", RenX::tags->nameTag.size(), RenX::tags->nameTag.ptr(), RenX::tags->teamLongTag.size(), RenX::tags->teamLongTag.ptr(), RenX::tags->ipTag.size(), RenX::tags->ipTag.ptr(), RenX::tags->rdnsTag.size(), RenX::tags->rdnsTag.ptr()));
Jupiter::StringS::Format(IRCCOLOR "12[Join] " IRCBOLD "%.*s" IRCBOLD " joined the game fighting for the %.*s from " IRCBOLD "%.*s" IRCBOLD ", but is " IRCBOLD "not" IRCBOLD " using Steam.", RenX::tags->nameTag.size(), RenX::tags->nameTag.ptr(), RenX::tags->teamLongTag.size(), RenX::tags->teamLongTag.ptr(), RenX::tags->ipTag.size(), RenX::tags->ipTag.ptr()));
RenX_LoggingPlugin::partFmt = Jupiter::IRC::Client::Config->get(this->getName(), "PartFormat"_jrs,
Jupiter::StringS::Format(IRCCOLOR "12[Part] " IRCBOLD "%.*s" IRCBOLD " left the %.*s.", RenX::tags->nameTag.size(), RenX::tags->nameTag.ptr(), RenX::tags->teamLongTag.size(), RenX::tags->teamLongTag.ptr()));
@ -416,6 +420,7 @@ void RenX_LoggingPlugin::init()
Jupiter::StringS::Format(IRCCOLOR "06[Other]" IRCCOLOR " %.*s", RenX::tags->messageTag.size(), RenX::tags->messageTag.ptr()));
/** Sanitize tags */
RenX::sanitizeTags(playerRDNSFmt);
RenX::sanitizeTags(joinPublicFmt);
RenX::sanitizeTags(joinAdminFmt);
RenX::sanitizeTags(joinNoSteamAdminFmt);
@ -523,6 +528,22 @@ void RenX_LoggingPlugin::init()
typedef void(RenX::Server::*logFuncType)(const Jupiter::ReadableString &msg) const;
void RenX_LoggingPlugin::RenX_OnPlayerRDNS(RenX::Server *server, const RenX::PlayerInfo *player)
{
logFuncType func;
if (RenX_LoggingPlugin::playerRDNSPublic)
func = &RenX::Server::sendLogChan;
else
func = &RenX::Server::sendAdmChan;
Jupiter::String msg = this->playerRDNSFmt;
if (msg.isNotEmpty())
{
RenX::processTags(msg, server, player);
(server->*func)(msg);
}
}
void RenX_LoggingPlugin::RenX_OnJoin(RenX::Server *server, const RenX::PlayerInfo *player)
{
Jupiter::String msg;

4
RenX.Logging/RenX_Logging.h

@ -25,6 +25,8 @@
class RenX_LoggingPlugin : public RenX::Plugin
{
public: // RenX::Plugin
void RenX_OnPlayerRDNS(RenX::Server *server, const RenX::PlayerInfo *player) override;
void RenX_OnJoin(RenX::Server *server, const RenX::PlayerInfo *player) override;
void RenX_OnPart(RenX::Server *server, const RenX::PlayerInfo *player) override;
void RenX_OnKick(RenX::Server *server, const RenX::PlayerInfo *player, const Jupiter::ReadableString &reason) override;
@ -135,6 +137,7 @@ private:
STRING_LITERAL_AS_NAMED_REFERENCE(name, "RenX.Logging");
unsigned int muteOwnExecute : 1;
unsigned int playerRDNSPublic : 1;
unsigned int joinPublic : 1;
unsigned int partPublic : 1;
unsigned int kickPublic : 1;
@ -212,6 +215,7 @@ private:
unsigned int otherPublic : 1;
/** Event formats */
Jupiter::String playerRDNSFmt;
Jupiter::StringS joinPublicFmt, joinAdminFmt, joinNoSteamAdminFmt;
Jupiter::StringS partFmt;
Jupiter::StringS kickFmt;

Loading…
Cancel
Save