From 1a236dbefce8dde11039938a4f035b2c9c126df6 Mon Sep 17 00:00:00 2001 From: heinrich5991 Date: Wed, 20 Dec 2017 16:56:34 +0100 Subject: [PATCH] Send connection information to external server --- src/base/system.c | 19 ++++++++ src/base/system.h | 46 +++++++++++++++++++ src/engine/server/server.cpp | 69 ++++++++++++++++++++++++++-- src/engine/server/server.h | 23 +++++++++- src/engine/shared/config_variables.h | 4 ++ 5 files changed, 155 insertions(+), 6 deletions(-) diff --git a/src/base/system.c b/src/base/system.c index aacc2b7e1..12d9d8bc0 100644 --- a/src/base/system.c +++ b/src/base/system.c @@ -1825,6 +1825,25 @@ int net_init() return 0; } +#if defined(CONF_FAMILY_UNIX) +UNIXSOCKET net_unnamed_unix_create() +{ + return socket(AF_UNIX, SOCK_DGRAM, 0); +} + +int net_unix_send(UNIXSOCKET sock, UNIXSOCKETADDR *addr, void *data, int size) +{ + return sendto(sock, data, size, 0, (struct sockaddr *)addr, sizeof(struct sockaddr_un)); +} + +void net_unix_set_addr(UNIXSOCKETADDR *addr, const char *path) +{ + mem_zero(addr, sizeof(addr)); + addr->sun_family = AF_UNIX; + str_copy(addr->sun_path, path, sizeof(addr->sun_path)); +} +#endif + int fs_listdir_info(const char *dir, FS_LISTDIR_INFO_CALLBACK cb, int type, void *user) { #if defined(CONF_FAMILY_WINDOWS) diff --git a/src/base/system.h b/src/base/system.h index 10471fd53..849da455a 100644 --- a/src/base/system.h +++ b/src/base/system.h @@ -12,6 +12,10 @@ #include "stddef.h" #include +#ifdef CONF_FAMILY_UNIX +#include +#endif + #ifdef __cplusplus extern "C" { #endif @@ -601,6 +605,10 @@ typedef struct unsigned short port; } NETADDR; +#ifdef CONF_FAMILY_UNIX +typedef int UNIXSOCKET; +typedef struct sockaddr_un UNIXSOCKETADDR; +#endif /* Function: net_init Initiates network functionallity. @@ -825,6 +833,44 @@ int net_tcp_recv(NETSOCKET sock, void *data, int maxsize); */ int net_tcp_close(NETSOCKET sock); +#if defined(CONF_FAMILY_UNIX) +/* Group: Network Unix Sockets */ + +/* + Function: net_unnamed_unix_create + Creates an unnamed unix dgram socket. + + Returns: + On success it returns a handle to the socket. On failure it returns -1. +*/ +UNIXSOCKET net_unnamed_unix_create(); + +/* + Function: net_unix_send + Sends data to a Unix socket. + + Parameters: + sock - Socket to use. + addr - Where to send the packet. + data - Pointer to the packet data to send. + size - Size of the packet. + + Returns: + Number of bytes sent. Negative value on failure. +*/ +int net_unix_send(UNIXSOCKET sock, UNIXSOCKETADDR *addr, void *data, int size); + +/* + Function: net_unix_set_addr + Sets the unixsocketaddress for a path to a socket file. + + Parameters: + addr - Pointer to the addressstruct to fill. + path - Path to the (named) unix socket. +*/ +void net_unix_set_addr(UNIXSOCKETADDR *addr, const char *path); +#endif + /* Group: Strings */ /* diff --git a/src/engine/server/server.cpp b/src/engine/server/server.cpp index 6d3f04e42..23dbec6c9 100644 --- a/src/engine/server/server.cpp +++ b/src/engine/server/server.cpp @@ -323,6 +323,10 @@ CServer::CServer() m_ServerInfoNumRequests = 0; m_ServerInfoHighLoad = false; +#ifdef CONF_FAMILY_UNIX + m_ConnLoggingSocketCreated = false; +#endif + #if defined (CONF_SQL) for (int i = 0; i < MAX_SQLSERVERS; i++) { @@ -791,7 +795,9 @@ int CServer::NewClientNoAuthCallback(int ClientID, bool Reset, void *pUser) } pThis->SendMap(ClientID); - +#if defined(CONF_FAMILY_UNIX) + pThis->SendConnLoggingCommand(OPEN_SESSION, pThis->m_NetServer.ClientAddr(ClientID)); +#endif return 0; } @@ -812,6 +818,10 @@ int CServer::NewClientCallback(int ClientID, void *pUser) memset(&pThis->m_aClients[ClientID].m_Addr, 0, sizeof(NETADDR)); pThis->m_aClients[ClientID].Reset(); pThis->GameServer()->OnClientEngineJoin(ClientID); + +#if defined(CONF_FAMILY_UNIX) + pThis->SendConnLoggingCommand(OPEN_SESSION, pThis->m_NetServer.ClientAddr(ClientID)); +#endif return 0; } @@ -840,6 +850,23 @@ void CServer::InitDnsbl(int ClientID) pEngine->AddJob(m_aClients[ClientID].m_pDnsblLookup = std::make_shared(aBuf, NETTYPE_IPV4)); } +#ifdef CONF_FAMILY_UNIX +void CServer::SendConnLoggingCommand(CONN_LOGGING_CMD Cmd, const NETADDR* pAddr) +{ + if(!g_Config.m_SvConnLoggingServer[0] || !m_ConnLoggingSocketCreated) + return; + + // pack the data and send it + unsigned char aData[23] = {0}; + aData[0] = Cmd; + mem_copy(&aData[1], &pAddr->type, 4); + mem_copy(&aData[5], pAddr->ip, 16); + mem_copy(&aData[21], &pAddr->port, 2); + + net_unix_socket_send(m_ConnLoggingSocket, &m_ConnLoggingDestAddr, aData, sizeof(aData)); +} +#endif + int CServer::DelClientCallback(int ClientID, const char *pReason, void *pUser) { CServer *pThis = (CServer *)pUser; @@ -869,7 +896,9 @@ int CServer::DelClientCallback(int ClientID, const char *pReason, void *pUser) pThis->m_aClients[ClientID].m_Snapshots.PurgeAll(); pThis->GameServer()->OnClientEngineDrop(ClientID, pReason); - +#if defined(CONF_FAMILY_UNIX) + pThis->SendConnLoggingCommand(CLOSE_SESSION, pThis->m_NetServer.ClientAddr(ClientID)); +#endif return 0; } @@ -2612,6 +2641,34 @@ void CServer::ConchainRconHelperPasswordChange(IConsole::IResult *pResult, void ((CServer *)pUserData)->ConchainRconPasswordChangeGeneric(AUTHED_HELPER, pResult); } +#if defined(CONF_FAMILY_UNIX) +void CServer::ConchainConnLoggingServerChange(IConsole::IResult *pResult, void *pUserData, IConsole::FCommandCallback pfnCallback, void *pCallbackUserData) +{ + pfnCallback(pResult, pCallbackUserData); + if(pResult->NumArguments() == 1) + { + CServer *pServer = (CServer *)pUserData; + + // open socket to send new connections + if(!pServer->m_ConnLoggingSocketCreated) + { + pServer->m_ConnLoggingSocket = net_unnamed_unix_socket_create(); + if(pServer->m_ConnLoggingSocket == -1) + { + pServer->Console()->Print(IConsole::OUTPUT_LEVEL_STANDARD, "server", "Failed to created socket for communication with the connection logging server."); + } + else + { + pServer->m_ConnLoggingSocketCreated = true; + } + } + + // set the destination address for the connection logging + net_unix_socket_set_addr(&pServer->m_ConnLoggingDestAddr, pResult->GetString(0)); + } +} +#endif + void CServer::RegisterCommands() { m_pConsole = Kernel()->RequestInterface(); @@ -2630,11 +2687,9 @@ void CServer::RegisterCommands() Console()->Register("reload", "", CFGFLAG_SERVER, ConMapReload, this, "Reload the map"); -#if defined (CONF_SQL) - +#if defined(CONF_SQL) Console()->Register("add_sqlserver", "s['r'|'w'] s[Database] s[Prefix] s[User] s[Password] s[IP] i[Port] ?i[SetUpDatabase ?]", CFGFLAG_SERVER|CFGFLAG_NONTEEHISTORIC, ConAddSqlServer, this, "add a sqlserver"); Console()->Register("dump_sqlservers", "s['r'|'w']", CFGFLAG_SERVER, ConDumpSqlServers, this, "dumps all sqlservers readservers = r, writeservers = w"); - #endif Console()->Register("dnsbl_status", "", CFGFLAG_SERVER, ConDnsblStatus, this, "List blacklisted players"); @@ -2657,6 +2712,10 @@ void CServer::RegisterCommands() Console()->Chain("sv_rcon_mod_password", ConchainRconModPasswordChange, this); Console()->Chain("sv_rcon_helper_password", ConchainRconHelperPasswordChange, this); +#if defined(CONF_FAMILY_UNIX) + Console()->Chain("sv_conn_logging_server", ConchainConnLoggingServerChange, this); +#endif + // register console commands in sub parts m_ServerBan.InitServerBan(Console(), Storage(), this); m_pGameServer->OnConsoleInit(); diff --git a/src/engine/server/server.h b/src/engine/server/server.h index 433cf4f29..598b323d7 100644 --- a/src/engine/server/server.h +++ b/src/engine/server/server.h @@ -85,11 +85,17 @@ class CServer : public IServer class IConsole *m_pConsole; class IStorage *m_pStorage; -#if defined (CONF_SQL) +#if defined(CONF_SQL) CSqlServer *m_apSqlReadServers[MAX_SQLSERVERS]; CSqlServer *m_apSqlWriteServers[MAX_SQLSERVERS]; #endif +#if defined(CONF_FAMILY_UNIX) + UNIXSOCKETADDR m_ConnLoggingDestAddr; + bool m_ConnLoggingSocketCreated; + UNIXSOCKET m_ConnLoggingSocket; +#endif + public: class IGameServer *GameServer() { return m_pGameServer; } class IConsole *Console() { return m_pConsole; } @@ -324,6 +330,10 @@ public: static void ConchainRconModPasswordChange(IConsole::IResult *pResult, void *pUserData, IConsole::FCommandCallback pfnCallback, void *pCallbackUserData); static void ConchainRconHelperPasswordChange(IConsole::IResult *pResult, void *pUserData, IConsole::FCommandCallback pfnCallback, void *pCallbackUserData); +#if defined(CONF_FAMILY_UNIX) + static void ConchainConnLoggingServerChange(IConsole::IResult *pResult, void *pUserData, IConsole::FCommandCallback pfnCallback, void *pCallbackUserData); +#endif + void RegisterCommands(); @@ -358,6 +368,17 @@ public: bool ErrorShutdown() const { return m_aErrorShutdownReason[0] != 0; } void SetErrorShutdown(const char *pReason); + +#ifdef CONF_FAMILY_UNIX + enum CONN_LOGGING_CMD + { + OPEN_SESSION=1, + CLOSE_SESSION=2, + }; + + void SendConnLoggingCommand(CONN_LOGGING_CMD cmd, const NETADDR *pAddr); +#endif + }; #endif diff --git a/src/engine/shared/config_variables.h b/src/engine/shared/config_variables.h index 8cfda65d2..2119a609b 100644 --- a/src/engine/shared/config_variables.h +++ b/src/engine/shared/config_variables.h @@ -373,6 +373,10 @@ MACRO_CONFIG_INT(SvNetlimitAlpha, sv_netlimit_alpha, 50, 1, 100, CFGFLAG_SERVER, MACRO_CONFIG_INT(SvConnlimit, sv_connlimit, 4, 0, 100, CFGFLAG_SERVER, "Connlimit: Number of connections an IP is allowed to do in a timespan") MACRO_CONFIG_INT(SvConnlimitTime, sv_connlimit_time, 20, 0, 1000, CFGFLAG_SERVER, "Connlimit: Time in which IP's connections are counted") +#if defined(CONF_FAMILY_UNIX) +MACRO_CONFIG_STR(SvConnLoggingServer, sv_conn_logging_server, 128, "", CFGFLAG_SERVER, "Unix socket server for IP address logging") +#endif + MACRO_CONFIG_INT(ClUnpredictedShadow, cl_unpredicted_shadow, 0, 0, 1, CFGFLAG_CLIENT|CFGFLAG_SAVE, "Show unpredicted shadow tee to estimate your delay") MACRO_CONFIG_INT(ClPredictDDRace, cl_predict_ddrace, 1, 0, 1, CFGFLAG_CLIENT|CFGFLAG_SAVE, "Predict some DDRace tiles") MACRO_CONFIG_INT(ClShowNinja, cl_show_ninja, 1, 0, 1, CFGFLAG_CLIENT|CFGFLAG_SAVE, "Show ninja skin")