/*==LICENSE==* CyanWorlds.com Engine - MMOG client, server and tools Copyright (C) 2011 Cyan Worlds, Inc. This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program. If not, see . You can contact Cyan Worlds, Inc. by email legal@cyan.com or by snail mail at: Cyan Worlds, Inc. 14617 N Newport Hwy Mead, WA 99021 *==LICENSE==*/ /***************************************************************************** * * $/Plasma20/Sources/Plasma/NucleusLib/pnIniExe/Private/pnIniSrv.cpp * ***/ #include "../Pch.h" #pragma hdrstop #ifdef SERVER /***************************************************************************** * * Internal * ***/ const unsigned CLASS_C_SUBNET_MASK = 0xFFFFFF00; const NetAddressNode LOOPBACK_ADDRESS_NODE = 0x7F000001; //============================================================================ struct PrivilegedAddressBlock : THashKeyVal { HASHLINK(PrivilegedAddressBlock) link; NetAddressNode startAddress; NetAddressNode endAddress; EServerRights serverRights; }; //============================================================================ #define ADDRESS_BLOCK_TABLE HASHTABLEDECL(PrivilegedAddressBlock, THashKeyVal, link) static CCritSect s_critsect; static ADDRESS_BLOCK_TABLE s_addressBlocks; //============================================================================ static void SrvRightsDestroy () { s_critsect.Enter(); { s_addressBlocks.Clear(); } s_critsect.Leave(); } //============================================================================ AUTO_INIT_FUNC(InitSrvRightsIni) { atexit(SrvRightsDestroy); } //============================================================================ static EServerRights GetServerRightsFromString(const wchar string[]) { if (StrCmpI(string, L"Server") == 0) return kSrvRightsServer; else if (StrCmpI(string, L"Basic") == 0) return kSrvRightsBasic; else return kSrvRightsNone; } static void IAddAddressBlock(ADDRESS_BLOCK_TABLE & addrList, NetAddressNode startAddr, NetAddressNode endAddr, EServerRights srvRights) { PrivilegedAddressBlock* addrBlock = NEW(PrivilegedAddressBlock); addrBlock->startAddress = startAddr; addrBlock->serverRights = srvRights; if (endAddr == 0) addrBlock->endAddress = addrBlock->startAddress; else addrBlock->endAddress = endAddr; if ( (addrBlock->startAddress & CLASS_C_SUBNET_MASK) != (addrBlock->endAddress & CLASS_C_SUBNET_MASK) ) { LogMsg(kLogDebug, L"IniSrv: Error creating privileged address block - start address and end address aren't from the same subnet."); DEL(addrBlock); } else { addrBlock->SetValue(startAddr & CLASS_C_SUBNET_MASK); addrList.Add(addrBlock); } } /***************************************************************************** * * Exports * ***/ //============================================================================ EServerRights SrvIniGetServerRightsByNode (NetAddressNode addrNode) { EServerRights retVal = kSrvRightsBasic; unsigned addrSubNet = (addrNode & CLASS_C_SUBNET_MASK); s_critsect.Enter(); { PrivilegedAddressBlock* addrBlock = s_addressBlocks.Find(addrSubNet); while (addrBlock) { if (addrBlock->startAddress <= addrNode && addrNode <= addrBlock->endAddress) { retVal = addrBlock->serverRights; break; } addrBlock = s_addressBlocks.FindNext(addrSubNet, addrBlock); } } s_critsect.Leave(); return retVal; } //============================================================================ EServerRights SrvIniGetServerRights (const NetAddress & addr) { NetAddressNode addrNode = NetAddressGetNode(addr); return SrvIniGetServerRightsByNode(addrNode); } //============================================================================ void SrvIniParseServerRights (Ini * ini) { unsigned iter; const IniValue *value; ADDRESS_BLOCK_TABLE newaddresstable; ADDRESS_BLOCK_TABLE removeaddresstable; value = IniGetFirstValue( ini, L"Privileged Addresses", L"Addr", &iter ); // add ini file address blocks while (value) { wchar valStr[20]; NetAddressNode start; NetAddressNode end; EServerRights rights; IniGetString(value, valStr, arrsize(valStr), 0); start = NetAddressNodeFromString(valStr, nil); IniGetString(value, valStr, arrsize(valStr), 1); end = NetAddressNodeFromString(valStr, nil); IniGetString(value, valStr, arrsize(valStr), 2); rights = GetServerRightsFromString(valStr); IAddAddressBlock(newaddresstable, start, end, rights); value = IniGetNextValue(value, &iter); } // Add local addresses and loopback NetAddressNode nodes[16]; unsigned count = NetAddressGetLocal(arrsize(nodes), nodes); for (unsigned i = 0; i < count; ++i) { IAddAddressBlock(newaddresstable, nodes[i], nodes[i], kSrvRightsServer); } IAddAddressBlock(newaddresstable, LOOPBACK_ADDRESS_NODE, LOOPBACK_ADDRESS_NODE, kSrvRightsServer); s_critsect.Enter(); { while (PrivilegedAddressBlock* addrBlock = s_addressBlocks.Head()) removeaddresstable.Add(addrBlock); while (PrivilegedAddressBlock* addrBlock = newaddresstable.Head()) s_addressBlocks.Add(addrBlock); } s_critsect.Leave(); removeaddresstable.Clear(); } #endif