about summary refs log tree commit diff
path: root/src/engine/shared/network.h
diff options
context:
space:
mode:
Diffstat (limited to 'src/engine/shared/network.h')
-rw-r--r--src/engine/shared/network.h90
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