diff options
Diffstat (limited to 'src/engine/shared/network.h')
| -rw-r--r-- | src/engine/shared/network.h | 90 |
1 files changed, 83 insertions, 7 deletions
diff --git a/src/engine/shared/network.h b/src/engine/shared/network.h index 259d600f..5924651f 100644 --- a/src/engine/shared/network.h +++ b/src/engine/shared/network.h @@ -6,6 +6,10 @@ #include "ringbuffer.h" #include "huffman.h" +#include <base/math.h> + +#include <engine/message.h> + /* CURRENT: @@ -75,12 +79,26 @@ enum NET_CONN_BUFFERSIZE=1024*32, + NET_CONNLIMIT_IPS=16, + NET_ENUM_TERMINATOR }; +typedef int SECURITY_TOKEN; + +SECURITY_TOKEN ToSecurityToken(unsigned char *pData); + +static const unsigned char SECURITY_TOKEN_MAGIC[] = {'T', 'K', 'E', 'N'}; + +enum +{ + NET_SECURITY_TOKEN_UNKNOWN = -1, + NET_SECURITY_TOKEN_UNSUPPORTED = 0, +}; typedef int (*NETFUNC_DELCLIENT)(int ClientID, const char* pReason, void *pUser); typedef int (*NETFUNC_NEWCLIENT)(int ClientID, void *pUser); +typedef int (*NETFUNC_NEWCLIENT_NOAUTH)(int ClientID, void *pUser); struct CNetChunk { @@ -136,11 +154,14 @@ class CNetConnection private: unsigned short m_Sequence; unsigned short m_Ack; + unsigned short m_PeerAck; unsigned m_State; int m_Token; + SECURITY_TOKEN m_SecurityToken; int m_RemoteClosed; bool m_BlockCloseMsg; + bool m_UnknownSeq; TStaticRingBuffer<CNetChunkResend, NET_CONN_BUFFERSIZE> m_Buffer; @@ -157,7 +178,6 @@ private: NETSTATS m_Stats; // - void Reset(); void ResetStats(); void SetError(const char *pString); void AckChunks(int Ack); @@ -167,6 +187,8 @@ private: void ResendChunk(CNetChunkResend *pResend); void Resend(); + bool HasSecurityToken; + public: void Init(NETSOCKET Socket, bool BlockCloseMsg); int Connect(NETADDR *pAddr); @@ -175,7 +197,7 @@ public: int Update(); int Flush(); - int Feed(CNetPacketConstruct *pPacket, NETADDR *pAddr); + int Feed(CNetPacketConstruct *pPacket, NETADDR *pAddr, SECURITY_TOKEN SecurityToken = NET_SECURITY_TOKEN_UNSUPPORTED); int QueueChunk(int Flags, int DataSize, const void *pData); const char *ErrorString(); @@ -191,6 +213,14 @@ public: int64 ConnectTime() const { return m_LastUpdateTime; } int AckSequence() const { return m_Ack; } + int SeqSequence() const { return m_Sequence; } + int SecurityToken() const { return m_SecurityToken; } + + // anti spoof + void DirectInit(NETADDR &Addr, SECURITY_TOKEN SecurityToken); + void SetUnknownSeq() { m_UnknownSeq = true; } + void SetSequence(int Sequence) { m_Sequence = Sequence; } + void Reset(); }; class CConsoleNetConnection @@ -250,6 +280,13 @@ class CNetServer CNetConnection m_Connection; }; + struct CSpamConn + { + NETADDR m_Addr; + int64 m_Time; + int m_Conns; + }; + NETSOCKET m_Socket; class CNetBan *m_pNetBan; CSlot m_aSlots[NET_MAX_CLIENTS]; @@ -257,13 +294,39 @@ class CNetServer int m_MaxClientsPerIP; NETFUNC_NEWCLIENT m_pfnNewClient; + NETFUNC_NEWCLIENT_NOAUTH m_pfnNewClientNoAuth; NETFUNC_DELCLIENT m_pfnDelClient; void *m_UserPtr; + + int m_NumConAttempts; // log flooding attacks + int64 m_TimeNumConAttempts; + unsigned char m_SecurityTokenSeed[16]; + + // vanilla connect flood detection + bool m_VConnHighLoad; + int64 m_VConnFirst; + int m_VConnNum; + + CSpamConn m_aSpamConns[NET_CONNLIMIT_IPS]; + CNetRecvUnpacker m_RecvUnpacker; + void OnTokenCtrlMsg(NETADDR &Addr, int ControlMsg, const CNetPacketConstruct &Packet); + void OnPreConnMsg(NETADDR &Addr, CNetPacketConstruct &Packet); + void OnConnCtrlMsg(NETADDR &Addr, int ClientID, int ControlMsg, const CNetPacketConstruct &Packet); + bool ClientExists(const NETADDR &Addr) { return GetClientSlot(Addr) != -1; }; + int GetClientSlot(const NETADDR &Addr); + void SendControl(NETADDR &Addr, int ControlMsg, const void *pExtra, int ExtraSize, SECURITY_TOKEN SecurityToken); + + int TryAcceptClient(NETADDR &Addr, SECURITY_TOKEN SecurityToken, bool VanillaAuth=false); + int NumClientsWithAddr(NETADDR Addr); + bool Connlimit(NETADDR Addr); + void SendMsgs(NETADDR &Addr, const CMsgPacker *Msgs[], int num); + public: - int SetCallbacks(NETFUNC_NEWCLIENT pfnNewClient, NETFUNC_DELCLIENT pfnDelClient, void *pUser); + // int SetCallbacks(NETFUNC_NEWCLIENT pfnNewClient, NETFUNC_DELCLIENT pfnDelClient, void *pUser); + int SetCallbacks(NETFUNC_NEWCLIENT pfnNewClient, NETFUNC_NEWCLIENT_NOAUTH pfnNewClientNoAuth, NETFUNC_DELCLIENT pfnDelClient, void *pUser); // bool Open(NETADDR BindAddr, class CNetBan *pNetBan, int MaxClients, int MaxClientsPerIP, int Flags); @@ -279,6 +342,7 @@ public: // status requests const NETADDR *ClientAddr(int ClientID) const { return m_aSlots[ClientID].m_Connection.PeerAddress(); } + bool HasSecurityToken(int ClientID) const { return m_aSlots[ClientID].m_Connection.SecurityToken() != NET_SECURITY_TOKEN_UNSUPPORTED; } NETSOCKET Socket() const { return m_Socket; } class CNetBan *NetBan() const { return m_pNetBan; } int NetType() const { return m_Socket.type; } @@ -286,6 +350,16 @@ public: // void SetMaxClientsPerIP(int Max); + bool SetTimedOut(int ClientID, int OrigID); + void SetTimeoutProtected(int ClientID); + + int ResetErrorString(int ClientID); + const char *ErrorString(int ClientID); + + // anti spoof + SECURITY_TOKEN GetToken(const NETADDR &Addr); + // vanilla token/gametick shouldn't be negative + SECURITY_TOKEN GetVanillaToken(const NETADDR &Addr) { return absolute(GetToken(Addr)); } }; class CNetConsole @@ -331,11 +405,10 @@ public: // client side class CNetClient { - NETADDR m_ServerAddr; CNetConnection m_Connection; CNetRecvUnpacker m_RecvUnpacker; - NETSOCKET m_Socket; public: + NETSOCKET m_Socket; // openness bool Open(NETADDR BindAddr, int Flags); int Close(); @@ -359,6 +432,8 @@ public: int State(); int GotProblems(); const char *ErrorString(); + + bool SecurityTokenUnknown() { return m_Connection.SecurityToken() == NET_SECURITY_TOKEN_UNKNOWN; } }; @@ -376,9 +451,10 @@ public: static int Compress(const void *pData, int DataSize, void *pOutput, int OutputSize); static int Decompress(const void *pData, int DataSize, void *pOutput, int OutputSize); - static void SendControlMsg(NETSOCKET Socket, NETADDR *pAddr, int Ack, int ControlMsg, const void *pExtra, int ExtraSize); + static void SendControlMsg(NETSOCKET Socket, NETADDR *pAddr, int Ack, int ControlMsg, const void *pExtra, int ExtraSize, SECURITY_TOKEN SecurityToken); static void SendPacketConnless(NETSOCKET Socket, NETADDR *pAddr, const void *pData, int DataSize); - static void SendPacket(NETSOCKET Socket, NETADDR *pAddr, CNetPacketConstruct *pPacket); + static void SendPacket(NETSOCKET Socket, NETADDR *pAddr, CNetPacketConstruct *pPacket, SECURITY_TOKEN SecurityToken); + static int UnpackPacket(unsigned char *pBuffer, int Size, CNetPacketConstruct *pPacket); // The backroom is ack-NET_MAX_SEQUENCE/2. Used for knowing if we acked a packet or not |