finished IPv6 support (master servers aren't compatible with 0.5 and older). Closes #233

This commit is contained in:
oy 2011-03-30 12:08:33 +02:00
parent 693bd39e77
commit 59d56cd332
14 changed files with 628 additions and 131 deletions

View file

@ -593,7 +593,7 @@ static int priv_net_extract(const char *hostname, char *host, int max_host, int
if(hostname[0] == '[')
{
// ipv6 mode
for(i = 1; i < max_host-1 && hostname[i] && hostname[i] != ']'; i++)
for(i = 1; i < max_host && hostname[i] && hostname[i] != ']'; i++)
host[i-1] = hostname[i];
host[i-1] = 0;
if(hostname[i] != ']') // malformatted
@ -711,6 +711,7 @@ int net_addr_from_str(NETADDR *addr, const char *string)
struct sockaddr_in6 sa6;
char buf[128];
int i;
str++;
for(i = 0; i < 127 && str[i] && str[i] != ']'; i++)
buf[i] = str[i];
buf[i] = 0;

View file

@ -698,7 +698,7 @@ void CClient::Connect(const char *pAddress)
char aBufMsg[256];
str_format(aBufMsg, sizeof(aBufMsg), "could not find the address of %s, connecting to localhost", aBuf);
m_pConsole->Print(IConsole::OUTPUT_LEVEL_STANDARD, "client", aBufMsg);
net_host_lookup("localhost", &m_ServerAddress, NETTYPE_IPV4);
net_host_lookup("localhost", &m_ServerAddress, NETTYPE_ALL);
}
m_RconAuthed = 0;
@ -1052,34 +1052,31 @@ void CClient::ProcessConnlessPacket(CNetChunk *pPacket)
bool Valid = false;
for(int i = 0; i < IMasterServer::MAX_MASTERSERVERS; ++i)
{
NETADDR Addr = m_pMasterServer->GetAddr(i);
if(net_addr_comp(&pPacket->m_Address, &Addr) == 0)
if(m_pMasterServer->IsValid(i))
{
Valid = true;
break;
NETADDR Addr = m_pMasterServer->GetAddr(i);
if(net_addr_comp(&pPacket->m_Address, &Addr) == 0)
{
Valid = true;
break;
}
}
}
if(!Valid)
return;
int Size = pPacket->m_DataSize-sizeof(SERVERBROWSE_LIST);
int Num = Size/sizeof(MASTERSRV_ADDR);
MASTERSRV_ADDR *pAddrs = (MASTERSRV_ADDR *)((char*)pPacket->m_pData+sizeof(SERVERBROWSE_LIST));
int i;
for(i = 0; i < Num; i++)
int Num = Size/sizeof(CMastersrvAddr);
CMastersrvAddr *pAddrs = (CMastersrvAddr *)((char*)pPacket->m_pData+sizeof(SERVERBROWSE_LIST));
for(int i = 0; i < Num; i++)
{
NETADDR Addr;
// convert address
mem_zero(&Addr, sizeof(Addr));
Addr.type = NETTYPE_IPV4;
Addr.ip[0] = pAddrs[i].m_aIp[0];
Addr.ip[1] = pAddrs[i].m_aIp[1];
Addr.ip[2] = pAddrs[i].m_aIp[2];
Addr.ip[3] = pAddrs[i].m_aIp[3];
Addr.port = (pAddrs[i].m_aPort[1]<<8) | pAddrs[i].m_aPort[0];
// copy address
Addr.type = (pAddrs->m_aType[0]<<24) | (pAddrs->m_aType[1]<<16) | (pAddrs->m_aType[2]<<8) | pAddrs->m_aType[3];
mem_copy(Addr.ip, pAddrs->m_aIp, sizeof(Addr.ip));
Addr.port = (pAddrs->m_aPort[0]<<8) | pAddrs->m_aPort[1];
m_ServerBrowser.Set(Addr, IServerBrowser::SET_MASTER_ADD, -1, 0x0);
}
}

View file

@ -380,15 +380,8 @@ CServerBrowser::CServerEntry *CServerBrowser::Add(const NETADDR &Addr)
pEntry->m_Info.m_NetAddr = Addr;
pEntry->m_Info.m_Latency = 999;
str_format(pEntry->m_Info.m_aAddress, sizeof(pEntry->m_Info.m_aAddress), "%d.%d.%d.%d:%d",
Addr.ip[0], Addr.ip[1], Addr.ip[2],
Addr.ip[3], Addr.port);
str_format(pEntry->m_Info.m_aName, sizeof(pEntry->m_Info.m_aName), "%d.%d.%d.%d:%d",
Addr.ip[0], Addr.ip[1], Addr.ip[2],
Addr.ip[3], Addr.port);
/*if(serverlist_type == IServerBrowser::TYPE_LAN)
pEntry->m_Info.latency = (time_get()-broadcast_time)*1000/time_freq();*/
net_addr_str(&Addr, pEntry->m_Info.m_aAddress, sizeof(pEntry->m_Info.m_aAddress));
str_copy(pEntry->m_Info.m_aName, pEntry->m_Info.m_aAddress, sizeof(pEntry->m_Info.m_aName));
// check if it's a favorite
for(i = 0; i < m_NumFavoriteServers; i++)
@ -526,10 +519,10 @@ void CServerBrowser::RequestImpl(const NETADDR &Addr, CServerEntry *pEntry) cons
if(g_Config.m_Debug)
{
char aAddrStr[NETADDR_MAXSTRSIZE];
net_addr_str(&Addr, aAddrStr, sizeof(aAddrStr));
char aBuf[256];
str_format(aBuf, sizeof(aBuf),"requesting server info from %d.%d.%d.%d:%d",
Addr.ip[0], Addr.ip[1], Addr.ip[2],
Addr.ip[3], Addr.port);
str_format(aBuf, sizeof(aBuf),"requesting server info from %s", aAddrStr);
m_pConsole->Print(IConsole::OUTPUT_LEVEL_DEBUG, "client_srvbrowse", aBuf);
}
@ -556,7 +549,7 @@ void CServerBrowser::Request(const NETADDR &Addr) const
void CServerBrowser::Update(bool ForceResort)
{
int64 Timeout = time_freq()/2; // TODO 0.6: increase this again
int64 Timeout = time_freq();
int64 Now = time_get();
int Count;
CServerEntry *pEntry, *pNext;
@ -578,10 +571,10 @@ void CServerBrowser::Update(bool ForceResort)
for(i = 0; i < IMasterServer::MAX_MASTERSERVERS; i++)
{
Addr = m_pMasterServer->GetAddr(i);
if(!Addr.ip[0] && !Addr.ip[1] && !Addr.ip[2] && !Addr.ip[3])
if(!m_pMasterServer->IsValid(i))
continue;
Addr = m_pMasterServer->GetAddr(i);
Packet.m_Address = Addr;
m_pNetClient->Send(&Packet);
}
@ -667,8 +660,10 @@ void CServerBrowser::AddFavorite(const NETADDR &Addr)
if(g_Config.m_Debug)
{
char aAddrStr[NETADDR_MAXSTRSIZE];
net_addr_str(&Addr, aAddrStr, sizeof(aAddrStr));
char aBuf[256];
str_format(aBuf, sizeof(aBuf), "added fav, %d.%d.%d.%d:%d", Addr.ip[0], Addr.ip[1], Addr.ip[2], Addr.ip[3], Addr.port);
str_format(aBuf, sizeof(aBuf), "added fav, %s", aAddrStr);
m_pConsole->Print(IConsole::OUTPUT_LEVEL_DEBUG, "client_srvbrowse", aBuf);
}
}

View file

@ -26,6 +26,7 @@ public:
virtual void DumpServers() = 0;
virtual NETADDR GetAddr(int Index) = 0;
virtual const char *GetName(int Index) = 0;
virtual bool IsValid(int Index) = 0;
};
class IEngineMasterServer : public IMasterServer

View file

@ -124,18 +124,18 @@ void CRegister::RegisterUpdate()
int i;
for(i = 0; i < IMasterServer::MAX_MASTERSERVERS; i++)
{
if(!m_pMasterServer->IsValid(i))
{
m_aMasterserverInfo[i].m_Valid = 0;
m_aMasterserverInfo[i].m_Count = 0;
continue;
}
NETADDR Addr = m_pMasterServer->GetAddr(i);
m_aMasterserverInfo[i].m_Addr = Addr;
m_aMasterserverInfo[i].m_Count = 0;
if(!Addr.ip[0] && !Addr.ip[1] && !Addr.ip[2] && !Addr.ip[3])
m_aMasterserverInfo[i].m_Valid = 0;
else
{
m_aMasterserverInfo[i].m_Valid = 1;
m_aMasterserverInfo[i].m_Count = -1;
m_aMasterserverInfo[i].m_LastSend = 0;
}
m_aMasterserverInfo[i].m_Valid = 1;
m_aMasterserverInfo[i].m_Count = -1;
m_aMasterserverInfo[i].m_LastSend = 0;
}
m_pConsole->Print(IConsole::OUTPUT_LEVEL_STANDARD, "register", "fetching server counts");

View file

@ -13,8 +13,7 @@
static int HostLookupThread(void *pUser)
{
CHostLookup *pLookup = (CHostLookup *)pUser;
net_host_lookup(pLookup->m_aHostname, &pLookup->m_Addr, NETTYPE_IPV4);
return 0;
return net_host_lookup(pLookup->m_aHostname, &pLookup->m_Addr, NETTYPE_ALL);
}
class CEngine : public IEngine

View file

@ -34,6 +34,7 @@ public:
};
int Status() const { return m_Status; }
int Result() const {return m_Result; }
};
class CJobPool

View file

@ -18,6 +18,7 @@ public:
{
char m_aHostname[128];
NETADDR m_Addr;
bool m_Valid;
CHostLookup m_Lookup;
} ;
@ -44,8 +45,11 @@ public:
dbg_msg("engine/mastersrv", "refreshing master server addresses");
// add lookup jobs
for(i = 0; i < MAX_MASTERSERVERS; i++)
for(i = 0; i < MAX_MASTERSERVERS; i++)
{
m_pEngine->HostLookup(&m_aMasterServers[i].m_Lookup, m_aMasterServers[i].m_aHostname);
m_aMasterServers[i].m_Valid = false;
}
m_NeedsUpdate = 1;
return 0;
@ -64,8 +68,14 @@ public:
m_NeedsUpdate = 1;
else
{
m_aMasterServers[i].m_Addr = m_aMasterServers[i].m_Lookup.m_Addr;
m_aMasterServers[i].m_Addr.port = 8300;
if(m_aMasterServers[i].m_Lookup.m_Job.Result() == 0)
{
m_aMasterServers[i].m_Addr = m_aMasterServers[i].m_Lookup.m_Addr;
m_aMasterServers[i].m_Addr.port = 8300;
m_aMasterServers[i].m_Valid = true;
}
else
m_aMasterServers[i].m_Valid = false;
}
}
@ -91,13 +101,18 @@ public:
return m_aMasterServers[Index].m_aHostname;
}
virtual bool IsValid(int Index)
{
return m_aMasterServers[Index].m_Valid;
}
virtual void DumpServers()
{
for(int i = 0; i < MAX_MASTERSERVERS; i++)
{
dbg_msg("mastersrv", "#%d = %d.%d.%d.%d", i,
m_aMasterServers[i].m_Addr.ip[0], m_aMasterServers[i].m_Addr.ip[1],
m_aMasterServers[i].m_Addr.ip[2], m_aMasterServers[i].m_Addr.ip[3]);
char aAddrStr[NETADDR_MAXSTRSIZE];
net_addr_str(&m_aMasterServers[i].m_Addr, aAddrStr, sizeof(aAddrStr));
dbg_msg("mastersrv", "#%d = %s", i, aAddrStr);
}
}
@ -136,13 +151,10 @@ public:
if(!pLine)
break;
// parse line
if(sscanf(pLine, "%s %d.%d.%d.%d", Info.m_aHostname, &aIp[0], &aIp[1], &aIp[2], &aIp[3]) == 5)
// parse line
char aAddrStr[NETADDR_MAXSTRSIZE];
if(sscanf(pLine, "%s %s", Info.m_aHostname, aAddrStr) == 2 && net_addr_from_str(&Info.m_Addr, aAddrStr) == 0)
{
Info.m_Addr.ip[0] = (unsigned char)aIp[0];
Info.m_Addr.ip[1] = (unsigned char)aIp[1];
Info.m_Addr.ip[2] = (unsigned char)aIp[2];
Info.m_Addr.ip[3] = (unsigned char)aIp[3];
Info.m_Addr.port = 8300;
if(Count != MAX_MASTERSERVERS)
{
@ -174,10 +186,10 @@ public:
for(int i = 0; i < MAX_MASTERSERVERS; i++)
{
char aAddrStr[NETADDR_MAXSTRSIZE];
net_addr_str(&m_aMasterServers[i].m_Addr, aAddrStr, sizeof(aAddrStr));
char aBuf[1024];
str_format(aBuf, sizeof(aBuf), "%s %d.%d.%d.%d\n", m_aMasterServers[i].m_aHostname,
m_aMasterServers[i].m_Addr.ip[0], m_aMasterServers[i].m_Addr.ip[1],
m_aMasterServers[i].m_Addr.ip[2], m_aMasterServers[i].m_Addr.ip[3]);
str_format(aBuf, sizeof(aBuf), "%s %s\n", m_aMasterServers[i].m_aHostname, aAddrStr);
io_write(File, aBuf, str_length(aBuf));
}

View file

@ -117,9 +117,13 @@ int CNetServer::BanNum()
void CNetServer::BanRemoveByObject(CBan *pBan)
{
int IpHash = (pBan->m_Info.m_Addr.ip[0]+pBan->m_Info.m_Addr.ip[1]+pBan->m_Info.m_Addr.ip[2]+pBan->m_Info.m_Addr.ip[3])&0xff;
dbg_msg("netserver", "removing ban on %d.%d.%d.%d",
pBan->m_Info.m_Addr.ip[0], pBan->m_Info.m_Addr.ip[1], pBan->m_Info.m_Addr.ip[2], pBan->m_Info.m_Addr.ip[3]);
int IpHash = (pBan->m_Info.m_Addr.ip[0]+pBan->m_Info.m_Addr.ip[1]+pBan->m_Info.m_Addr.ip[2]+pBan->m_Info.m_Addr.ip[3]+
pBan->m_Info.m_Addr.ip[4]+pBan->m_Info.m_Addr.ip[5]+pBan->m_Info.m_Addr.ip[6]+pBan->m_Info.m_Addr.ip[7]+
pBan->m_Info.m_Addr.ip[8]+pBan->m_Info.m_Addr.ip[9]+pBan->m_Info.m_Addr.ip[10]+pBan->m_Info.m_Addr.ip[11]+
pBan->m_Info.m_Addr.ip[12]+pBan->m_Info.m_Addr.ip[13]+pBan->m_Info.m_Addr.ip[14]+pBan->m_Info.m_Addr.ip[15])&0xff;
char aAddrStr[NETADDR_MAXSTRSIZE];
net_addr_str(&pBan->m_Info.m_Addr, aAddrStr, sizeof(aAddrStr));
dbg_msg("netserver", "removing ban on %s", aAddrStr);
MACRO_LIST_UNLINK(pBan, m_BanPool_FirstUsed, m_pPrev, m_pNext);
MACRO_LIST_UNLINK(pBan, m_aBans[IpHash], m_pHashPrev, m_pHashNext);
MACRO_LIST_LINK_FIRST(pBan, m_BanPool_FirstFree, m_pPrev, m_pNext);
@ -127,7 +131,8 @@ void CNetServer::BanRemoveByObject(CBan *pBan)
int CNetServer::BanRemove(NETADDR Addr)
{
int IpHash = (Addr.ip[0]+Addr.ip[1]+Addr.ip[2]+Addr.ip[3])&0xff;
int IpHash = (Addr.ip[0]+Addr.ip[1]+Addr.ip[2]+Addr.ip[3]+Addr.ip[4]+Addr.ip[5]+Addr.ip[6]+Addr.ip[7]+
Addr.ip[8]+Addr.ip[9]+Addr.ip[10]+Addr.ip[11]+Addr.ip[12]+Addr.ip[13]+Addr.ip[14]+Addr.ip[15])&0xff;
CBan *pBan = m_aBans[IpHash];
MACRO_LIST_FIND(pBan, m_pHashNext, net_addr_comp(&pBan->m_Info.m_Addr, &Addr) == 0);
@ -143,7 +148,8 @@ int CNetServer::BanRemove(NETADDR Addr)
int CNetServer::BanAdd(NETADDR Addr, int Seconds, const char *pReason)
{
int IpHash = (Addr.ip[0]+Addr.ip[1]+Addr.ip[2]+Addr.ip[3])&0xff;
int IpHash = (Addr.ip[0]+Addr.ip[1]+Addr.ip[2]+Addr.ip[3]+Addr.ip[4]+Addr.ip[5]+Addr.ip[6]+Addr.ip[7]+
Addr.ip[8]+Addr.ip[9]+Addr.ip[10]+Addr.ip[11]+Addr.ip[12]+Addr.ip[13]+Addr.ip[14]+Addr.ip[15])&0xff;
int Stamp = -1;
CBan *pBan;
@ -284,7 +290,8 @@ int CNetServer::Recv(CNetChunk *pChunk)
{
CBan *pBan = 0;
NETADDR BanAddr = Addr;
int IpHash = (BanAddr.ip[0]+BanAddr.ip[1]+BanAddr.ip[2]+BanAddr.ip[3])&0xff;
int IpHash = (BanAddr.ip[0]+BanAddr.ip[1]+BanAddr.ip[2]+BanAddr.ip[3]+BanAddr.ip[4]+BanAddr.ip[5]+BanAddr.ip[6]+BanAddr.ip[7]+
BanAddr.ip[8]+BanAddr.ip[9]+BanAddr.ip[10]+BanAddr.ip[11]+BanAddr.ip[12]+BanAddr.ip[13]+BanAddr.ip[14]+BanAddr.ip[15])&0xff;
int Found = 0;
BanAddr.port = 0;

View file

@ -11,7 +11,7 @@
enum {
MTU = 1400,
MAX_SERVERS_PER_PACKET=128,
MAX_SERVERS_PER_PACKET=40,
MAX_PACKETS=16,
MAX_SERVERS=MAX_SERVERS_PER_PACKET*MAX_PACKETS,
MAX_BANS=128,
@ -29,12 +29,6 @@ struct CCheckServer
static CCheckServer m_aCheckServers[MAX_SERVERS];
static int m_NumCheckServers = 0;
struct NETADDR_IPv4
{
unsigned char m_aIp[4];
unsigned short m_Port;
};
struct CServerEntry
{
NETADDR m_Address;
@ -49,7 +43,7 @@ struct CPacketData
int m_Size;
struct {
unsigned char m_aHeader[sizeof(SERVERBROWSE_LIST)];
NETADDR_IPv4 m_aServers[MAX_SERVERS_PER_PACKET];
CMastersrvAddr m_aServers[MAX_SERVERS_PER_PACKET];
} m_Data;
};
@ -75,8 +69,6 @@ struct CBanEntry
static CBanEntry m_aBans[MAX_BANS];
static int m_NumBans = 0;
//static int64 server_expire[MAX_SERVERS];
static CNetClient m_NetChecker; // NAT/FW checker
static CNetClient m_NetOp; // main
@ -100,16 +92,19 @@ void BuildPackets()
// copy server addresses
for(int i = 0; i < Chunk; i++)
{
// TODO: ipv6 support
m_aPackets[m_NumPackets].m_Data.m_aServers[i].m_aIp[0] = pCurrent->m_Address.ip[0];
m_aPackets[m_NumPackets].m_Data.m_aServers[i].m_aIp[1] = pCurrent->m_Address.ip[1];
m_aPackets[m_NumPackets].m_Data.m_aServers[i].m_aIp[2] = pCurrent->m_Address.ip[2];
m_aPackets[m_NumPackets].m_Data.m_aServers[i].m_aIp[3] = pCurrent->m_Address.ip[3];
m_aPackets[m_NumPackets].m_Data.m_aServers[i].m_Port = pCurrent->m_Address.port;
m_aPackets[m_NumPackets].m_Data.m_aServers[i].m_aType[0] = (pCurrent->m_Address.type>>24)&0xff;
m_aPackets[m_NumPackets].m_Data.m_aServers[i].m_aType[1] = (pCurrent->m_Address.type>>16)&0xff;
m_aPackets[m_NumPackets].m_Data.m_aServers[i].m_aType[2] = (pCurrent->m_Address.type>>8)&0xff;
m_aPackets[m_NumPackets].m_Data.m_aServers[i].m_aType[3] = pCurrent->m_Address.type&0xff;
mem_copy(m_aPackets[m_NumPackets].m_Data.m_aServers[i].m_aIp, pCurrent->m_Address.ip,
sizeof(m_aPackets[m_NumPackets].m_Data.m_aServers[i].m_aIp));
m_aPackets[m_NumPackets].m_Data.m_aServers[i].m_aPort[0] = (pCurrent->m_Address.port>>8)&0xff;
m_aPackets[m_NumPackets].m_Data.m_aServers[i].m_aPort[1] = pCurrent->m_Address.port&0xff;
pCurrent++;
}
m_aPackets[m_NumPackets].m_Size = sizeof(SERVERBROWSE_LIST) + sizeof(NETADDR_IPv4)*Chunk;
m_aPackets[m_NumPackets].m_Size = sizeof(SERVERBROWSE_LIST) + sizeof(NETADDR)*Chunk;
m_NumPackets++;
}
@ -160,9 +155,11 @@ void AddCheckserver(NETADDR *pInfo, NETADDR *pAlt)
return;
}
dbg_msg("mastersrv", "checking: %d.%d.%d.%d:%d (%d.%d.%d.%d:%d)",
pInfo->ip[0], pInfo->ip[1], pInfo->ip[2], pInfo->ip[3], pInfo->port,
pAlt->ip[0], pAlt->ip[1], pAlt->ip[2], pAlt->ip[3], pAlt->port);
char aAddrStr[NETADDR_MAXSTRSIZE];
net_addr_str(pInfo, aAddrStr, sizeof(aAddrStr));
char aAltAddrStr[NETADDR_MAXSTRSIZE];
net_addr_str(pAlt, aAltAddrStr, sizeof(aAltAddrStr));
dbg_msg("mastersrv", "checking: %s (%s)", aAddrStr, aAltAddrStr);
m_aCheckServers[m_NumCheckServers].m_Address = *pInfo;
m_aCheckServers[m_NumCheckServers].m_AltAddress = *pAlt;
m_aCheckServers[m_NumCheckServers].m_TryCount = 0;
@ -173,13 +170,13 @@ void AddCheckserver(NETADDR *pInfo, NETADDR *pAlt)
void AddServer(NETADDR *pInfo)
{
// see if server already exists in list
int i;
for(i = 0; i < m_NumServers; i++)
for(int i = 0; i < m_NumServers; i++)
{
if(net_addr_comp(&m_aServers[i].m_Address, pInfo) == 0)
{
dbg_msg("mastersrv", "updated: %d.%d.%d.%d:%d",
pInfo->ip[0], pInfo->ip[1], pInfo->ip[2], pInfo->ip[3], pInfo->port);
char aAddrStr[NETADDR_MAXSTRSIZE];
net_addr_str(pInfo, aAddrStr, sizeof(aAddrStr));
dbg_msg("mastersrv", "updated: %s", aAddrStr);
m_aServers[i].m_Expire = time_get()+time_freq()*EXPIRE_TIME;
return;
}
@ -192,8 +189,9 @@ void AddServer(NETADDR *pInfo)
return;
}
dbg_msg("mastersrv", "added: %d.%d.%d.%d:%d",
pInfo->ip[0], pInfo->ip[1], pInfo->ip[2], pInfo->ip[3], pInfo->port);
char aAddrStr[NETADDR_MAXSTRSIZE];
net_addr_str(pInfo, aAddrStr, sizeof(aAddrStr));
dbg_msg("mastersrv", "added: %s", aAddrStr);
m_aServers[m_NumServers].m_Address = *pInfo;
m_aServers[m_NumServers].m_Expire = time_get()+time_freq()*EXPIRE_TIME;
m_NumServers++;
@ -209,11 +207,11 @@ void UpdateServers()
{
if(m_aCheckServers[i].m_TryCount == 10)
{
dbg_msg("mastersrv", "check failed: %d.%d.%d.%d:%d",
m_aCheckServers[i].m_Address.ip[0], m_aCheckServers[i].m_Address.ip[1],
m_aCheckServers[i].m_Address.ip[2], m_aCheckServers[i].m_Address.ip[3],m_aCheckServers[i].m_Address.port,
m_aCheckServers[i].m_AltAddress.ip[0], m_aCheckServers[i].m_AltAddress.ip[1],
m_aCheckServers[i].m_AltAddress.ip[2], m_aCheckServers[i].m_AltAddress.ip[3],m_aCheckServers[i].m_AltAddress.port);
char aAddrStr[NETADDR_MAXSTRSIZE];
net_addr_str(&m_aCheckServers[i].m_Address, aAddrStr, sizeof(aAddrStr));
char aAltAddrStr[NETADDR_MAXSTRSIZE];
net_addr_str(&m_aCheckServers[i].m_AltAddress, aAltAddrStr, sizeof(aAltAddrStr));
dbg_msg("mastersrv", "check failed: %s (%s)", aAddrStr, aAltAddrStr);
// FAIL!!
SendError(&m_aCheckServers[i].m_Address);
@ -243,9 +241,9 @@ void PurgeServers()
if(m_aServers[i].m_Expire < Now)
{
// remove server
dbg_msg("mastersrv", "expired: %d.%d.%d.%d:%d",
m_aServers[i].m_Address.ip[0], m_aServers[i].m_Address.ip[1],
m_aServers[i].m_Address.ip[2], m_aServers[i].m_Address.ip[3], m_aServers[i].m_Address.port);
char aAddrStr[NETADDR_MAXSTRSIZE];
net_addr_str(&m_aServers[i].m_Address, aAddrStr, sizeof(aAddrStr));
dbg_msg("mastersrv", "expired: %s", aAddrStr);
m_aServers[i] = m_aServers[m_NumServers-1];
m_NumServers--;
}
@ -282,21 +280,19 @@ void ConAddBan(IConsole::IResult *pResult, void *pUser)
return;
}
net_addr_from_str(&m_aBans[m_NumBans].m_Address, pResult->GetString(0));
if(CheckBan(m_aBans[m_NumBans].m_Address))
if(net_addr_from_str(&m_aBans[m_NumBans].m_Address, pResult->GetString(0)) != 0)
{
dbg_msg("mastersrv", "duplicate ban: %d.%d.%d.%d:%d",
m_aBans[m_NumBans].m_Address.ip[0], m_aBans[m_NumBans].m_Address.ip[1],
m_aBans[m_NumBans].m_Address.ip[2], m_aBans[m_NumBans].m_Address.ip[3],
m_aBans[m_NumBans].m_Address.port);
dbg_msg("mastersrv", "error: invalid address");
return;
}
dbg_msg("mastersrv", "ban added: %d.%d.%d.%d:%d",
m_aBans[m_NumBans].m_Address.ip[0], m_aBans[m_NumBans].m_Address.ip[1],
m_aBans[m_NumBans].m_Address.ip[2], m_aBans[m_NumBans].m_Address.ip[3],
m_aBans[m_NumBans].m_Address.port);
if(CheckBan(m_aBans[m_NumBans].m_Address))
{
dbg_msg("mastersrv", "duplicate ban: %s", pResult->GetString(0));
return;
}
dbg_msg("mastersrv", "ban added: %s", pResult->GetString(0));
m_NumBans++;
}
@ -315,15 +311,22 @@ int main(int argc, const char **argv) // ignore_convention
net_init();
mem_zero(&BindAddr, sizeof(BindAddr));
BindAddr.type = NETTYPE_ALL;
BindAddr.port = MASTERSERVER_PORT;
m_NetOp.Open(BindAddr, 0);
if(!m_NetOp.Open(BindAddr, 0))
{
dbg_msg("mastersrv", "couldn't start network (op)");
return -1;
}
BindAddr.port = MASTERSERVER_PORT+1;
m_NetChecker.Open(BindAddr, 0);
// TODO: check socket for errors
if(!m_NetChecker.Open(BindAddr, 0))
{
dbg_msg("mastersrv", "couldn't start network (checker)");
return -1;
}
//mem_copy(data.header, SERVERBROWSE_LIST, sizeof(SERVERBROWSE_LIST));
mem_copy(m_CountData.m_Header, SERVERBROWSE_COUNT, sizeof(SERVERBROWSE_COUNT));
IKernel *pKernel = IKernel::Create();

View file

@ -4,19 +4,20 @@
#define MASTERSRV_MASTERSRV_H
static const int MASTERSERVER_PORT = 8300;
typedef struct MASTERSRV_ADDR
struct CMastersrvAddr
{
unsigned char m_aIp[4];
unsigned char m_aType[4];
unsigned char m_aIp[16];
unsigned char m_aPort[2];
} MASTERSRV_ADDR;
};
static const unsigned char SERVERBROWSE_HEARTBEAT[] = {255, 255, 255, 255, 'b', 'e', 'a', 't'};
static const unsigned char SERVERBROWSE_HEARTBEAT[] = {255, 255, 255, 255, 'b', 'e', 'a', '2'};
static const unsigned char SERVERBROWSE_GETLIST[] = {255, 255, 255, 255, 'r', 'e', 'q', 't'};
static const unsigned char SERVERBROWSE_LIST[] = {255, 255, 255, 255, 'l', 'i', 's', 't'};
static const unsigned char SERVERBROWSE_GETLIST[] = {255, 255, 255, 255, 'r', 'e', 'q', '2'};
static const unsigned char SERVERBROWSE_LIST[] = {255, 255, 255, 255, 'l', 'i', 's', '2'};
static const unsigned char SERVERBROWSE_GETCOUNT[] = {255, 255, 255, 255, 'c', 'o', 'u', 'n'};
static const unsigned char SERVERBROWSE_COUNT[] = {255, 255, 255, 255, 's', 'i', 'z', 'e'};
static const unsigned char SERVERBROWSE_GETCOUNT[] = {255, 255, 255, 255, 'c', 'o', 'u', '2'};
static const unsigned char SERVERBROWSE_COUNT[] = {255, 255, 255, 255, 's', 'i', 'z', '2'};
static const unsigned char SERVERBROWSE_GETINFO[] = {255, 255, 255, 255, 'g', 'i', 'e', '3'};
static const unsigned char SERVERBROWSE_INFO[] = {255, 255, 255, 255, 'i', 'n', 'f', '3'};

View file

@ -127,7 +127,11 @@ void Run(int Port, NETADDR Dest)
Delaycounter--;
if(m_ConfigLog)
dbg_msg("crapnet", "<< %08d %d.%d.%d.%d:%5d (%d)", p->m_ID, From.ip[0], From.ip[1], From.ip[2], From.ip[3], From.port, p->m_DataSize);
{
char aAddrStr[NETADDR_MAXSTRSIZE];
net_addr_str(&From, aAddrStr, sizeof(aAddrStr));
dbg_msg("crapnet", "<< %08d %s (%d)", p->m_ID, aAddrStr, p->m_DataSize);
}
}
//
@ -188,10 +192,9 @@ void Run(int Port, NETADDR Dest)
if(m_ConfigLog)
{
dbg_msg("crapnet", ">> %08d %d.%d.%d.%d:%5d (%d) %s", p->m_ID,
p->m_SendTo.ip[0], p->m_SendTo.ip[1],
p->m_SendTo.ip[2], p->m_SendTo.ip[3],
p->m_SendTo.port, p->m_DataSize, aFlags);
char aAddrStr[NETADDR_MAXSTRSIZE];
net_addr_str(&p->m_SendTo, aAddrStr, sizeof(aAddrStr));
dbg_msg("crapnet", ">> %08d %s (%d) %s", p->m_ID, aAddrStr, p->m_DataSize, aFlags);
}

449
src/tools/mastersrv_old.cpp Normal file
View file

@ -0,0 +1,449 @@
/* (c) Magnus Auvinen. See licence.txt in the root of the distribution for more information. */
/* If you are missing that file, acquire a complete release at teeworlds.com. */
#include <base/system.h>
#include <engine/shared/network.h>
#include <engine/shared/config.h>
#include <engine/console.h>
#include <engine/storage.h>
#include <engine/kernel.h>
#include "mastersrv_old.h"
enum {
MTU = 1400,
MAX_SERVERS_PER_PACKET=128,
MAX_PACKETS=16,
MAX_SERVERS=MAX_SERVERS_PER_PACKET*MAX_PACKETS,
MAX_BANS=128,
EXPIRE_TIME = 90
};
struct CCheckServer
{
NETADDR m_Address;
NETADDR m_AltAddress;
int m_TryCount;
int64 m_TryTime;
};
static CCheckServer m_aCheckServers[MAX_SERVERS];
static int m_NumCheckServers = 0;
struct NETADDR_IPv4
{
unsigned char m_aIp[4];
unsigned short m_Port;
};
struct CServerEntry
{
NETADDR m_Address;
int64 m_Expire;
};
static CServerEntry m_aServers[MAX_SERVERS];
static int m_NumServers = 0;
struct CPacketData
{
int m_Size;
struct {
unsigned char m_aHeader[sizeof(SERVERBROWSE_LIST)];
NETADDR_IPv4 m_aServers[MAX_SERVERS_PER_PACKET];
} m_Data;
};
CPacketData m_aPackets[MAX_PACKETS];
static int m_NumPackets = 0;
struct CCountPacketData
{
unsigned char m_Header[sizeof(SERVERBROWSE_COUNT)];
unsigned char m_High;
unsigned char m_Low;
};
static CCountPacketData m_CountData;
struct CBanEntry
{
NETADDR m_Address;
int64 m_Expire;
};
static CBanEntry m_aBans[MAX_BANS];
static int m_NumBans = 0;
//static int64 server_expire[MAX_SERVERS];
static CNetClient m_NetChecker; // NAT/FW checker
static CNetClient m_NetOp; // main
IConsole *m_pConsole;
void BuildPackets()
{
CServerEntry *pCurrent = &m_aServers[0];
int ServersLeft = m_NumServers;
m_NumPackets = 0;
while(ServersLeft && m_NumPackets < MAX_PACKETS)
{
int Chunk = ServersLeft;
if(Chunk > MAX_SERVERS_PER_PACKET)
Chunk = MAX_SERVERS_PER_PACKET;
ServersLeft -= Chunk;
// copy header
mem_copy(m_aPackets[m_NumPackets].m_Data.m_aHeader, SERVERBROWSE_LIST, sizeof(SERVERBROWSE_LIST));
// copy server addresses
for(int i = 0; i < Chunk; i++)
{
// TODO: ipv6 support
m_aPackets[m_NumPackets].m_Data.m_aServers[i].m_aIp[0] = pCurrent->m_Address.ip[0];
m_aPackets[m_NumPackets].m_Data.m_aServers[i].m_aIp[1] = pCurrent->m_Address.ip[1];
m_aPackets[m_NumPackets].m_Data.m_aServers[i].m_aIp[2] = pCurrent->m_Address.ip[2];
m_aPackets[m_NumPackets].m_Data.m_aServers[i].m_aIp[3] = pCurrent->m_Address.ip[3];
m_aPackets[m_NumPackets].m_Data.m_aServers[i].m_Port = pCurrent->m_Address.port;
pCurrent++;
}
m_aPackets[m_NumPackets].m_Size = sizeof(SERVERBROWSE_LIST) + sizeof(NETADDR_IPv4)*Chunk;
m_NumPackets++;
}
}
void SendOk(NETADDR *pAddr)
{
CNetChunk p;
p.m_ClientID = -1;
p.m_Address = *pAddr;
p.m_Flags = NETSENDFLAG_CONNLESS;
p.m_DataSize = sizeof(SERVERBROWSE_FWOK);
p.m_pData = SERVERBROWSE_FWOK;
// send on both to be sure
m_NetChecker.Send(&p);
m_NetOp.Send(&p);
}
void SendError(NETADDR *pAddr)
{
CNetChunk p;
p.m_ClientID = -1;
p.m_Address = *pAddr;
p.m_Flags = NETSENDFLAG_CONNLESS;
p.m_DataSize = sizeof(SERVERBROWSE_FWERROR);
p.m_pData = SERVERBROWSE_FWERROR;
m_NetOp.Send(&p);
}
void SendCheck(NETADDR *pAddr)
{
CNetChunk p;
p.m_ClientID = -1;
p.m_Address = *pAddr;
p.m_Flags = NETSENDFLAG_CONNLESS;
p.m_DataSize = sizeof(SERVERBROWSE_FWCHECK);
p.m_pData = SERVERBROWSE_FWCHECK;
m_NetChecker.Send(&p);
}
void AddCheckserver(NETADDR *pInfo, NETADDR *pAlt)
{
// add server
if(m_NumCheckServers == MAX_SERVERS)
{
dbg_msg("mastersrv", "error: mastersrv is full");
return;
}
dbg_msg("mastersrv", "checking: %d.%d.%d.%d:%d (%d.%d.%d.%d:%d)",
pInfo->ip[0], pInfo->ip[1], pInfo->ip[2], pInfo->ip[3], pInfo->port,
pAlt->ip[0], pAlt->ip[1], pAlt->ip[2], pAlt->ip[3], pAlt->port);
m_aCheckServers[m_NumCheckServers].m_Address = *pInfo;
m_aCheckServers[m_NumCheckServers].m_AltAddress = *pAlt;
m_aCheckServers[m_NumCheckServers].m_TryCount = 0;
m_aCheckServers[m_NumCheckServers].m_TryTime = 0;
m_NumCheckServers++;
}
void AddServer(NETADDR *pInfo)
{
// see if server already exists in list
int i;
for(i = 0; i < m_NumServers; i++)
{
if(net_addr_comp(&m_aServers[i].m_Address, pInfo) == 0)
{
dbg_msg("mastersrv", "updated: %d.%d.%d.%d:%d",
pInfo->ip[0], pInfo->ip[1], pInfo->ip[2], pInfo->ip[3], pInfo->port);
m_aServers[i].m_Expire = time_get()+time_freq()*EXPIRE_TIME;
return;
}
}
// add server
if(m_NumServers == MAX_SERVERS)
{
dbg_msg("mastersrv", "error: mastersrv is full");
return;
}
dbg_msg("mastersrv", "added: %d.%d.%d.%d:%d",
pInfo->ip[0], pInfo->ip[1], pInfo->ip[2], pInfo->ip[3], pInfo->port);
m_aServers[m_NumServers].m_Address = *pInfo;
m_aServers[m_NumServers].m_Expire = time_get()+time_freq()*EXPIRE_TIME;
m_NumServers++;
}
void UpdateServers()
{
int64 Now = time_get();
int64 Freq = time_freq();
for(int i = 0; i < m_NumCheckServers; i++)
{
if(Now > m_aCheckServers[i].m_TryTime+Freq)
{
if(m_aCheckServers[i].m_TryCount == 10)
{
dbg_msg("mastersrv", "check failed: %d.%d.%d.%d:%d",
m_aCheckServers[i].m_Address.ip[0], m_aCheckServers[i].m_Address.ip[1],
m_aCheckServers[i].m_Address.ip[2], m_aCheckServers[i].m_Address.ip[3],m_aCheckServers[i].m_Address.port,
m_aCheckServers[i].m_AltAddress.ip[0], m_aCheckServers[i].m_AltAddress.ip[1],
m_aCheckServers[i].m_AltAddress.ip[2], m_aCheckServers[i].m_AltAddress.ip[3],m_aCheckServers[i].m_AltAddress.port);
// FAIL!!
SendError(&m_aCheckServers[i].m_Address);
m_aCheckServers[i] = m_aCheckServers[m_NumCheckServers-1];
m_NumCheckServers--;
i--;
}
else
{
m_aCheckServers[i].m_TryCount++;
m_aCheckServers[i].m_TryTime = Now;
if(m_aCheckServers[i].m_TryCount&1)
SendCheck(&m_aCheckServers[i].m_Address);
else
SendCheck(&m_aCheckServers[i].m_AltAddress);
}
}
}
}
void PurgeServers()
{
int64 Now = time_get();
int i = 0;
while(i < m_NumServers)
{
if(m_aServers[i].m_Expire < Now)
{
// remove server
dbg_msg("mastersrv", "expired: %d.%d.%d.%d:%d",
m_aServers[i].m_Address.ip[0], m_aServers[i].m_Address.ip[1],
m_aServers[i].m_Address.ip[2], m_aServers[i].m_Address.ip[3], m_aServers[i].m_Address.port);
m_aServers[i] = m_aServers[m_NumServers-1];
m_NumServers--;
}
else
i++;
}
}
bool CheckBan(NETADDR Addr)
{
for(int i = 0; i < m_NumBans; i++)
{
if(net_addr_comp(&m_aBans[i].m_Address, &Addr) == 0)
{
return true;
}
}
Addr.port = 0;
for(int i = 0; i < m_NumBans; i++)
{
if(net_addr_comp(&m_aBans[i].m_Address, &Addr) == 0)
{
return true;
}
}
return false;
}
void ConAddBan(IConsole::IResult *pResult, void *pUser)
{
if(m_NumBans == MAX_BANS)
{
dbg_msg("mastersrv", "error: banlist is full");
return;
}
net_addr_from_str(&m_aBans[m_NumBans].m_Address, pResult->GetString(0));
if(CheckBan(m_aBans[m_NumBans].m_Address))
{
dbg_msg("mastersrv", "duplicate ban: %d.%d.%d.%d:%d",
m_aBans[m_NumBans].m_Address.ip[0], m_aBans[m_NumBans].m_Address.ip[1],
m_aBans[m_NumBans].m_Address.ip[2], m_aBans[m_NumBans].m_Address.ip[3],
m_aBans[m_NumBans].m_Address.port);
return;
}
dbg_msg("mastersrv", "ban added: %d.%d.%d.%d:%d",
m_aBans[m_NumBans].m_Address.ip[0], m_aBans[m_NumBans].m_Address.ip[1],
m_aBans[m_NumBans].m_Address.ip[2], m_aBans[m_NumBans].m_Address.ip[3],
m_aBans[m_NumBans].m_Address.port);
m_NumBans++;
}
void ReloadBans()
{
m_NumBans = 0;
m_pConsole->ExecuteFile("master.cfg");
}
int main(int argc, const char **argv) // ignore_convention
{
int64 LastBuild = 0, LastBanReload = 0;
NETADDR BindAddr;
dbg_logger_stdout();
net_init();
mem_zero(&BindAddr, sizeof(BindAddr));
BindAddr.port = MASTERSERVER_PORT;
m_NetOp.Open(BindAddr, 0);
BindAddr.port = MASTERSERVER_PORT+1;
m_NetChecker.Open(BindAddr, 0);
// TODO: check socket for errors
//mem_copy(data.header, SERVERBROWSE_LIST, sizeof(SERVERBROWSE_LIST));
mem_copy(m_CountData.m_Header, SERVERBROWSE_COUNT, sizeof(SERVERBROWSE_COUNT));
IKernel *pKernel = IKernel::Create();
IStorage *pStorage = CreateStorage("Teeworlds", argc, argv);
m_pConsole = CreateConsole(CFGFLAG_MASTER);
m_pConsole->Register("ban", "s", CFGFLAG_MASTER, ConAddBan, 0, "Ban IP from mastersrv");
bool RegisterFail = !pKernel->RegisterInterface(pStorage);
RegisterFail |= !pKernel->RegisterInterface(m_pConsole);
if(RegisterFail)
return -1;
dbg_msg("mastersrv", "started");
while(1)
{
m_NetOp.Update();
m_NetChecker.Update();
// process m_aPackets
CNetChunk Packet;
while(m_NetOp.Recv(&Packet))
{
// check if the server is banned
if(CheckBan(Packet.m_Address)) continue;
if(Packet.m_DataSize == sizeof(SERVERBROWSE_HEARTBEAT)+2 &&
mem_comp(Packet.m_pData, SERVERBROWSE_HEARTBEAT, sizeof(SERVERBROWSE_HEARTBEAT)) == 0)
{
NETADDR Alt;
unsigned char *d = (unsigned char *)Packet.m_pData;
Alt = Packet.m_Address;
Alt.port =
(d[sizeof(SERVERBROWSE_HEARTBEAT)]<<8) |
d[sizeof(SERVERBROWSE_HEARTBEAT)+1];
// add it
AddCheckserver(&Packet.m_Address, &Alt);
}
else if(Packet.m_DataSize == sizeof(SERVERBROWSE_GETCOUNT) &&
mem_comp(Packet.m_pData, SERVERBROWSE_GETCOUNT, sizeof(SERVERBROWSE_GETCOUNT)) == 0)
{
dbg_msg("mastersrv", "count requested, responding with %d", m_NumServers);
CNetChunk p;
p.m_ClientID = -1;
p.m_Address = Packet.m_Address;
p.m_Flags = NETSENDFLAG_CONNLESS;
p.m_DataSize = sizeof(m_CountData);
p.m_pData = &m_CountData;
m_CountData.m_High = (m_NumServers>>8)&0xff;
m_CountData.m_Low = m_NumServers&0xff;
m_NetOp.Send(&p);
}
else if(Packet.m_DataSize == sizeof(SERVERBROWSE_GETLIST) &&
mem_comp(Packet.m_pData, SERVERBROWSE_GETLIST, sizeof(SERVERBROWSE_GETLIST)) == 0)
{
// someone requested the list
dbg_msg("mastersrv", "requested, responding with %d m_aServers", m_NumServers);
CNetChunk p;
p.m_ClientID = -1;
p.m_Address = Packet.m_Address;
p.m_Flags = NETSENDFLAG_CONNLESS;
for(int i = 0; i < m_NumPackets; i++)
{
p.m_DataSize = m_aPackets[i].m_Size;
p.m_pData = &m_aPackets[i].m_Data;
m_NetOp.Send(&p);
}
}
}
// process m_aPackets
while(m_NetChecker.Recv(&Packet))
{
// check if the server is banned
if(CheckBan(Packet.m_Address)) continue;
if(Packet.m_DataSize == sizeof(SERVERBROWSE_FWRESPONSE) &&
mem_comp(Packet.m_pData, SERVERBROWSE_FWRESPONSE, sizeof(SERVERBROWSE_FWRESPONSE)) == 0)
{
// remove it from checking
for(int i = 0; i < m_NumCheckServers; i++)
{
if(net_addr_comp(&m_aCheckServers[i].m_Address, &Packet.m_Address) == 0 ||
net_addr_comp(&m_aCheckServers[i].m_AltAddress, &Packet.m_Address) == 0)
{
m_NumCheckServers--;
m_aCheckServers[i] = m_aCheckServers[m_NumCheckServers];
break;
}
}
AddServer(&Packet.m_Address);
SendOk(&Packet.m_Address);
}
}
if(time_get()-LastBanReload > time_freq()*300)
{
LastBanReload = time_get();
ReloadBans();
}
if(time_get()-LastBuild > time_freq()*5)
{
LastBuild = time_get();
PurgeServers();
UpdateServers();
BuildPackets();
}
// be nice to the CPU
thread_sleep(1);
}
return 0;
}

28
src/tools/mastersrv_old.h Normal file
View file

@ -0,0 +1,28 @@
/* (c) Magnus Auvinen. See licence.txt in the root of the distribution for more information. */
/* If you are missing that file, acquire a complete release at teeworlds.com. */
#ifndef MASTERSRV_MASTERSRV_H
#define MASTERSRV_MASTERSRV_H
static const int MASTERSERVER_PORT = 8300;
typedef struct MASTERSRV_ADDR
{
unsigned char m_aIp[4];
unsigned char m_aPort[2];
} MASTERSRV_ADDR;
static const unsigned char SERVERBROWSE_HEARTBEAT[] = {255, 255, 255, 255, 'b', 'e', 'a', 't'};
static const unsigned char SERVERBROWSE_GETLIST[] = {255, 255, 255, 255, 'r', 'e', 'q', 't'};
static const unsigned char SERVERBROWSE_LIST[] = {255, 255, 255, 255, 'l', 'i', 's', 't'};
static const unsigned char SERVERBROWSE_GETCOUNT[] = {255, 255, 255, 255, 'c', 'o', 'u', 'n'};
static const unsigned char SERVERBROWSE_COUNT[] = {255, 255, 255, 255, 's', 'i', 'z', 'e'};
static const unsigned char SERVERBROWSE_GETINFO[] = {255, 255, 255, 255, 'g', 'i', 'e', '3'};
static const unsigned char SERVERBROWSE_INFO[] = {255, 255, 255, 255, 'i', 'n', 'f', '3'};
static const unsigned char SERVERBROWSE_FWCHECK[] = {255, 255, 255, 255, 'f', 'w', '?', '?'};
static const unsigned char SERVERBROWSE_FWRESPONSE[] = {255, 255, 255, 255, 'f', 'w', '!', '!'};
static const unsigned char SERVERBROWSE_FWOK[] = {255, 255, 255, 255, 'f', 'w', 'o', 'k'};
static const unsigned char SERVERBROWSE_FWERROR[] = {255, 255, 255, 255, 'f', 'w', 'e', 'r'};
#endif