123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277 |
- /*
- EQ2Emulator: Everquest II Server Emulator
- Copyright (C) 2007 EQ2EMulator Development Team (http://www.eq2emulator.net)
- This file is part of EQ2Emulator.
- EQ2Emulator 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.
- EQ2Emulator 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 EQ2Emulator. If not, see <http://www.gnu.org/licenses/>.
- */
- #ifndef TCP_CONNECTION_H
- #define TCP_CONNECTION_H
- /*
- Parent classes for interserver TCP Communication.
- -Quagmire
- */
- #ifdef WIN32
- #define snprintf _snprintf
- #define vsnprintf _vsnprintf
- #define strncasecmp _strnicmp
- #define strcasecmp _stricmp
- #include <process.h>
- #else
- #include <pthread.h>
- #include <sys/socket.h>
- #include <netinet/in.h>
- #include <arpa/inet.h>
- #include <netdb.h>
- #include <unistd.h>
- #include <errno.h>
- #include <fcntl.h>
- #define INVALID_SOCKET -1
- #define SOCKET_ERROR -1
- #include "unix.h"
- #endif
- #include "types.h"
- #include "Mutex.h"
- #include "linked_list.h"
- #include "queue.h"
- #include "servertalk.h"
- #include "timer.h"
- #include "MiscFunctions.h"
- class TCPServer;
- #define TCPConnection_ErrorBufferSize 1024
- #define MaxTCPReceiveBufferSize 524288
- #define TCPS_Ready 0
- #define TCPS_Connecting 1
- #define TCPS_Connected 100
- #define TCPS_Disconnecting 200
- #define TCPS_Disconnected 201
- #define TCPS_Closing 250
- #define TCPS_Error 255
- #ifndef DEF_eConnectionType
- #define DEF_eConnectionType
- enum eConnectionType {Incomming, Outgoing};
- #endif
- #ifdef WIN32
- void TCPServerLoop(void* tmp);
- void TCPConnectionLoop(void* tmp);
- #else
- void* TCPServerLoop(void* tmp);
- void* TCPConnectionLoop(void* tmp);
- #endif
- enum eTCPMode { modeConsole, modeTransition, modePacket };
- class TCPConnection {
- public:
- #pragma pack(1)
- struct TCPNetPacket_Struct {
- int32 size;
- struct {
- int8
- compressed : 1,
- destination : 1,
- flag3 : 1,
- flag4 : 1,
- flag5 : 1,
- flag6 : 1,
- flag7 : 1,
- flag8 : 1;
- } flags;
- int16 opcode;
- uchar buffer[0];
- };
- #pragma pack()
- static TCPNetPacket_Struct* MakePacket(ServerPacket* pack, int32 iDestination = 0);
- TCPConnection(TCPServer* iServer, SOCKET iSock, int32 irIP, int16 irPort, bool iOldFormat = false);
- TCPConnection(bool iOldFormat = false, TCPServer* iRelayServer = 0, eTCPMode iMode = modePacket); // for outgoing connections
- TCPConnection(TCPServer* iServer, TCPConnection* iRelayLink, int32 iRemoteID, int32 irIP, int16 irPort); // for relay connections
- virtual ~TCPConnection();
- // Functions for outgoing connections
- bool Connect(char* irAddress, int16 irPort, char* errbuf = 0);
- bool Connect(int32 irIP, int16 irPort, char* errbuf = 0);
- void AsyncConnect(char* irAddress, int16 irPort);
- void AsyncConnect(int32 irIP, int16 irPort);
- virtual void Disconnect(bool iSendRelayDisconnect = true);
- virtual bool SendPacket(ServerPacket* pack, int32 iDestination = 0);
- virtual bool SendPacket(TCPNetPacket_Struct* tnps);
- bool Send(const uchar* data, sint32 size);
- char* PopLine();
- ServerPacket* PopPacket(); // OutQueuePop()
- inline int32 GetrIP() { return rIP; }
- inline int16 GetrPort() { return rPort; }
- virtual int8 GetState();
- eTCPMode GetMode() { return TCPMode; }
- inline bool Connected() { return (GetState() == TCPS_Connected); }
- inline bool ConnectReady() { return (bool) (GetState() == TCPS_Ready && ConnectionType == Outgoing); }
- void Free(); // Inform TCPServer that this connection object is no longer referanced
- inline int32 GetID() { return id; }
- inline bool IsRelayServer() { return RelayServer; }
- inline int32 GetRemoteID() { return RemoteID; }
- inline TCPConnection* GetRelayLink() { return RelayLink; }
- bool GetEcho();
- void SetEcho(bool iValue);
- protected:
- friend class TCPServer;
- virtual bool Process();
- void SetState(int8 iState);
- inline bool IsFree() { return pFree; }
- bool CheckNetActive();
- #ifdef WIN32
- friend void TCPConnectionLoop(void* tmp);
- #else
- friend void* TCPConnectionLoop(void* tmp);
- #endif
- SOCKET sock;
- bool RunLoop();
- Mutex MLoopRunning;
- Mutex MAsyncConnect;
- bool GetAsyncConnect();
- bool SetAsyncConnect(bool iValue);
- char* charAsyncConnect;
-
- #ifdef WIN32
- friend class TCPConnection;
- #endif
- void OutQueuePush(ServerPacket* pack);
- void RemoveRelay(TCPConnection* relay, bool iSendRelayDisconnect);
- private:
- void ProcessNetworkLayerPacket(ServerPacket* pack);
- void SendNetErrorPacket(const char* reason = 0);
- TCPServer* Server;
- TCPConnection* RelayLink;
- int32 RemoteID;
- sint32 RelayCount;
- bool pOldFormat;
- bool SendData(char* errbuf = 0);
- bool RecvData(char* errbuf = 0);
- bool ProcessReceivedData(char* errbuf = 0);
- bool ProcessReceivedDataAsPackets(char* errbuf = 0);
- bool ProcessReceivedDataAsOldPackets(char* errbuf = 0);
- void ClearBuffers();
- bool pAsyncConnect;
- eConnectionType ConnectionType;
- eTCPMode TCPMode;
- bool RelayServer;
- Mutex MRunLoop;
- bool pRunLoop;
- SOCKET connection_socket;
- int32 id;
- int32 rIP;
- int16 rPort; // host byte order
- bool pFree;
- Mutex MState;
- int8 pState;
- void LineOutQueuePush(char* line);
- MyQueue<char> LineOutQueue;
- MyQueue<ServerPacket> OutQueue;
- Mutex MOutQueueLock;
- Timer* keepalive_timer;
- Timer* timeout_timer;
- uchar* recvbuf;
- sint32 recvbuf_size;
- sint32 recvbuf_used;
- sint32 recvbuf_echo;
- bool pEcho;
- Mutex MEcho;
- void InModeQueuePush(TCPNetPacket_Struct* tnps);
- MyQueue<TCPNetPacket_Struct> InModeQueue;
- Mutex MSendQueue;
- uchar* sendbuf;
- sint32 sendbuf_size;
- sint32 sendbuf_used;
- bool ServerSendQueuePop(uchar** data, sint32* size);
- void ServerSendQueuePushEnd(const uchar* data, sint32 size);
- void ServerSendQueuePushEnd(uchar** data, sint32 size);
- void ServerSendQueuePushFront(uchar* data, sint32 size);
- };
- class TCPServer {
- public:
- TCPServer(int16 iPort = 0, bool iOldFormat = false);
- virtual ~TCPServer();
- bool Open(int16 iPort = 0, char* errbuf = 0); // opens the port
- void Close(); // closes the port
- bool IsOpen();
- inline int16 GetPort() { return pPort; }
- TCPConnection* NewQueuePop();
- void SendPacket(ServerPacket* pack);
- void SendPacket(TCPConnection::TCPNetPacket_Struct** tnps);
- protected:
- #ifdef WIN32
- friend void TCPServerLoop(void* tmp);
- #else
- friend void* TCPServerLoop(void* tmp);
- #endif
- void Process();
- bool RunLoop();
- Mutex MLoopRunning;
- friend class TCPConnection;
- inline int32 GetNextID() { return NextID++; }
- void AddConnection(TCPConnection* con);
- TCPConnection* GetConnection(int32 iID);
- private:
- void ListenNewConnections();
- int32 NextID;
- bool pOldFormat;
- Mutex MRunLoop;
- bool pRunLoop;
- Mutex MSock;
- SOCKET sock;
- int16 pPort;
- Mutex MNewQueue;
- MyQueue<TCPConnection> NewQueue;
- void CheckInQueue();
- Mutex MInQueue;
- TCPConnection::TCPNetPacket_Struct* InQueuePop();
- MyQueue<TCPConnection::TCPNetPacket_Struct> InQueue;
- LinkedList<TCPConnection*>* list;
- };
- #endif
|