// ============================================================== // This file is part of Glest Shared Library (www.glest.org) // // Copyright (C) 2005 Matthias Braun // // You can redistribute this code and/or modify it under // the terms of the GNU General Public License as published // by the Free Software Foundation; either version 2 of the // License, or (at your option) any later version // ============================================================== #ifndef _SHARED_PLATFORM_SOCKET_H_ #define _SHARED_PLATFORM_SOCKET_H_ #include #include #include #include #include #include #include "base_thread.h" #include "simple_threads.h" #include "types.h" using std::string; #ifdef WIN32 #ifdef __MINGW32__ #include #else #include #endif typedef SOCKET PLATFORM_SOCKET; #else #include #include #include #include #include typedef int PLATFORM_SOCKET; #endif #include "leak_dumper.h" using namespace Shared::PlatformCommon; namespace Shared { namespace Platform { // The callback Interface used by the UPNP discovery process class FTPClientValidationInterface { public: virtual int isValidClientType(uint32 clientIp) = 0; }; // The callback Interface used by the UPNP discovery process class UPNPInitInterface { public: virtual void UPNPInitStatus(bool result) = 0; }; // // This interface describes the methods a callback object must implement // when signaled with detected servers // class DiscoveredServersInterface { public: virtual void DiscoveredServers(std::vector serverList) = 0; }; // ===================================================== // class IP // ===================================================== class Ip { private: unsigned char bytes[4]; public: Ip(); Ip(unsigned char byte0, unsigned char byte1, unsigned char byte2, unsigned char byte3); Ip(const string& ipString); unsigned char getByte(int byteIndex) {return bytes[byteIndex];} string getString() const; }; // ===================================================== // class Socket // ===================================================== #ifdef WIN32 class SocketManager{ public: SocketManager(); ~SocketManager(); }; #endif //class Socket : public SimpleTaskCallbackInterface { class Socket { protected: #ifdef WIN32 static SocketManager wsaManager; #endif PLATFORM_SOCKET sock; time_t lastDebugEvent; static int broadcast_portno; std::string ipAddress; std::string connectedIpAddress; //SimpleTaskThread *pingThread; std::map pingCache; time_t lastThreadedPing; Mutex pingThreadAccessor; Mutex dataSynchAccessorRead; Mutex dataSynchAccessorWrite; Mutex inSocketDestructorSynchAccessor; bool inSocketDestructor; public: Socket(PLATFORM_SOCKET sock); Socket(); virtual ~Socket(); //virtual void simpleTask(BaseThread *callingThread); static int getBroadCastPort() { return broadcast_portno; } static void setBroadCastPort(int value) { broadcast_portno = value; } static std::vector getLocalIPAddressList(); // Int lookup is socket fd while bool result is whether or not that socket was signalled for reading static bool hasDataToRead(std::map &socketTriggeredList); static bool hasDataToRead(PLATFORM_SOCKET socket); bool hasDataToRead(); virtual void disconnectSocket(); PLATFORM_SOCKET getSocketId() const { return sock; } int getDataToRead(bool wantImmediateReply=false); int send(const void *data, int dataSize); int receive(void *data, int dataSize, bool tryReceiveUntilDataSizeMet); int peek(void *data, int dataSize, bool mustGetData=true); void setBlock(bool block); static void setBlock(bool block, PLATFORM_SOCKET socket); bool isReadable(); bool isWritable(); bool isConnected(); static string getHostName(); static string getIp(); bool isSocketValid() const; static bool isSocketValid(const PLATFORM_SOCKET *validateSocket); static double getAveragePingMS(std::string host, int pingCount=5); float getThreadedPingMS(std::string host); virtual std::string getIpAddress(); virtual void setIpAddress(std::string value) { ipAddress = value; } uint32 getConnectedIPAddress(string IP=""); protected: static void throwException(string str); }; class BroadCastClientSocketThread : public BaseThread { private: DiscoveredServersInterface *discoveredServersCB; public: BroadCastClientSocketThread(DiscoveredServersInterface *cb); virtual void execute(); }; // ===================================================== // class ClientSocket // ===================================================== class ClientSocket: public Socket { public: ClientSocket(); virtual ~ClientSocket(); void connect(const Ip &ip, int port); static void discoverServers(DiscoveredServersInterface *cb); static void stopBroadCastClientThread(); protected: static BroadCastClientSocketThread *broadCastClientThread; static void startBroadCastClientThread(DiscoveredServersInterface *cb); }; class BroadCastSocketThread : public BaseThread { private: public: BroadCastSocketThread(); virtual ~BroadCastSocketThread(); virtual void execute(); virtual bool canShutdown(bool deleteSelfIfShutdownDelayed=false); }; // ===================================================== // class ServerSocket // ===================================================== class ServerSocket: public Socket, public UPNPInitInterface { protected: bool portBound; int boundPort; static int externalPort; static int ftpServerPort; SDL_Thread *upnpdiscoverThread; static int maxPlayerCount; virtual void UPNPInitStatus(bool result); BroadCastSocketThread *broadCastThread; void startBroadCastThread(); bool isBroadCastThreadRunning(); vector blockIPList; public: ServerSocket(); virtual ~ServerSocket(); void bind(int port); void listen(int connectionQueueSize= SOMAXCONN); Socket *accept(); void stopBroadCastThread(); void addIPAddressToBlockedList(string value); bool isIPAddressBlocked(string value) const; void removeBlockedIPAddress(string value); void clearBlockedIPAddress(); bool hasBlockedIPAddresses() const; void setBindPort(int port) { boundPort = port; } int getBindPort() const { return boundPort; } bool isPortBound() const { return portBound; } static void setExternalPort(int port) { externalPort = port; } static int getExternalPort() { return externalPort; } static void setFTPServerPort(int port) { ftpServerPort = port; } static int getFTPServerPort() { return ftpServerPort; } virtual void disconnectSocket(); void NETdiscoverUPnPDevices(); static void setMaxPlayerCount(int value) { maxPlayerCount=value; } }; // ===================================================== // class UPNP_Tools // ===================================================== class UPNP_Tools { public: static bool isUPNP; static bool enabledUPNP; static int upnp_init(void *param); static bool upnp_add_redirect(int ports[2]); static void upnp_rem_redirect(int ext_port); static void NETaddRedirects(std::vector UPNPPortForwardList); static void NETremRedirects(int ext_port); static void AddUPNPPortForward(int internalPort, int externalPort); static void RemoveUPNPPortForward(int internalPort, int externalPort); }; }}//end namespace #endif