You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

203 lines
5.8 KiB

/*==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 <http://www.gnu.org/licenses/>.
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<unsigned> {
HASHLINK(PrivilegedAddressBlock) link;
NetAddressNode startAddress;
NetAddressNode endAddress;
EServerRights serverRights;
};
//============================================================================
#define ADDRESS_BLOCK_TABLE HASHTABLEDECL(PrivilegedAddressBlock, THashKeyVal<unsigned>, 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