diff --git a/source/glest_game/menu/menu_state_join_game.cpp b/source/glest_game/menu/menu_state_join_game.cpp index ce6ecf97..acfcffd4 100644 --- a/source/glest_game/menu/menu_state_join_game.cpp +++ b/source/glest_game/menu/menu_state_join_game.cpp @@ -503,7 +503,7 @@ void MenuStateJoinGame::keyDown(char key){ } } -void MenuStateJoinGame::keyPress(char c){ +void MenuStateJoinGame::keyPress(char c) { ClientInterface* clientInterface= NetworkManager::getInstance().getClientInterface(); if(clientInterface->isConnected() == false) { @@ -511,34 +511,28 @@ void MenuStateJoinGame::keyPress(char c){ Config &configKeys = Config::getInstance(std::pair(cfgMainKeys,cfgUserKeys)); - if(c>='0' && c<='9'){ + if(c>='0' && c<='9') { - if(labelServerIp.getText().size()getSocket()->getConnectedIPAddress()); sendMessage(&sendNetworkMessageIntro); SystemFlags::OutputDebug(SystemFlags::debugNetwork,"In [%s::%s Line: %d]\n",__FILE__,__FUNCTION__,__LINE__); diff --git a/source/glest_game/network/connection_slot.cpp b/source/glest_game/network/connection_slot.cpp index 73a7e3de..2b2694ff 100644 --- a/source/glest_game/network/connection_slot.cpp +++ b/source/glest_game/network/connection_slot.cpp @@ -158,6 +158,7 @@ ConnectionSlot::ConnectionSlot(ServerInterface* serverInterface, int playerIndex SystemFlags::OutputDebug(SystemFlags::debugNetwork,"In [%s::%s] Line: %d\n",__FILE__,__FUNCTION__,__LINE__); + this->connectedRemoteIPAddress = 0; this->sessionKey = 0; this->serverInterface = serverInterface; this->playerIndex = playerIndex; @@ -257,7 +258,7 @@ void ConnectionSlot::update(bool checkForNewClients) { SystemFlags::OutputDebug(SystemFlags::debugNetwork,"In [%s::%s Line: %d] !!!!!!!!WARNING - no open slots, disconnecting client\n",__FILE__,__FUNCTION__,__LINE__); if(socket != NULL) { - NetworkMessageIntro networkMessageIntro(sessionKey,getNetworkVersionString(), getHostName(), playerIndex, nmgstNoSlots); + NetworkMessageIntro networkMessageIntro(sessionKey,getNetworkVersionString(), getHostName(), playerIndex, nmgstNoSlots, 0); sendMessage(&networkMessageIntro); } @@ -267,7 +268,7 @@ void ConnectionSlot::update(bool checkForNewClients) { SystemFlags::OutputDebug(SystemFlags::debugNetwork,"In [%s::%s Line: %d] client will be assigned to the next open slot\n",__FILE__,__FUNCTION__,__LINE__); if(socket != NULL) { - NetworkMessageIntro networkMessageIntro(sessionKey,getNetworkVersionString(), getHostName(), playerIndex, nmgstOk); + NetworkMessageIntro networkMessageIntro(sessionKey,getNetworkVersionString(), getHostName(), playerIndex, nmgstOk, 0); sendMessage(&networkMessageIntro); } } @@ -362,6 +363,7 @@ void ConnectionSlot::update(bool checkForNewClients) { int msgSessionId = networkMessageIntro.getSessionId(); name= networkMessageIntro.getName(); versionString = networkMessageIntro.getVersionString(); + this->connectedRemoteIPAddress = networkMessageIntro.getExternalIp(); SystemFlags::OutputDebug(SystemFlags::debugNetwork,"In [%s::%s] got name [%s] versionString [%s], msgSessionId = %d\n",__FILE__,__FUNCTION__,name.c_str(),versionString.c_str(),msgSessionId); @@ -423,6 +425,8 @@ void ConnectionSlot::update(bool checkForNewClients) { SystemFlags::OutputDebug(SystemFlags::debugNetwork,"In [%s::%s Line: %d]\n",__FILE__,__FUNCTION__,__LINE__); gotIntro = true; + this->serverInterface->addClientToServerIPAddress(this->getSocket()->getConnectedIPAddress(this->getSocket()->getIp()),this->connectedRemoteIPAddress); + if(getAllowGameDataSynchCheck() == true && serverInterface->getGameSettings() != NULL) { SystemFlags::OutputDebug(SystemFlags::debugNetwork,"In [%s::%s Line: %d] sending NetworkMessageSynchNetworkGameData\n",__FILE__,__FUNCTION__,__LINE__); diff --git a/source/glest_game/network/connection_slot.h b/source/glest_game/network/connection_slot.h index 9d48d1c6..33fb206b 100644 --- a/source/glest_game/network/connection_slot.h +++ b/source/glest_game/network/connection_slot.h @@ -114,6 +114,7 @@ private: bool gotLagCountWarning; string versionString; int sessionKey; + uint32 connectedRemoteIPAddress; public: ConnectionSlot(ServerInterface* serverInterface, int playerIndex); @@ -124,6 +125,8 @@ public: void setPlayerIndex(int value) { playerIndex = value; } int getPlayerIndex() {return playerIndex;} + uint32 getConnectedRemoteIPAddress() const { return connectedRemoteIPAddress; } + void setReady() {ready= true;} const string &getName() const {return name;} void setName(string value) {name = value;} diff --git a/source/glest_game/network/network_message.cpp b/source/glest_game/network/network_message.cpp index 8a75e0ab..9627b683 100644 --- a/source/glest_game/network/network_message.cpp +++ b/source/glest_game/network/network_message.cpp @@ -123,22 +123,25 @@ void NetworkMessage::send(Socket* socket, const void* data, int dataSize) const // class NetworkMessageIntro // ===================================================== -NetworkMessageIntro::NetworkMessageIntro(){ +NetworkMessageIntro::NetworkMessageIntro() { data.messageType= -1; data.sessionId= -1; data.playerIndex= -1; data.gameState = nmgstInvalid; + data.externalIp = 0; } NetworkMessageIntro::NetworkMessageIntro(int32 sessionId,const string &versionString, const string &name, int playerIndex, - NetworkGameStateType gameState) { + NetworkGameStateType gameState, + uint32 externalIp) { data.messageType = nmtIntro; data.sessionId = sessionId; data.versionString = versionString; data.name = name; data.playerIndex = static_cast(playerIndex); data.gameState = static_cast(gameState); + data.externalIp = externalIp; } bool NetworkMessageIntro::receive(Socket* socket){ diff --git a/source/glest_game/network/network_message.h b/source/glest_game/network/network_message.h index 568582aa..dc1d4b4a 100644 --- a/source/glest_game/network/network_message.h +++ b/source/glest_game/network/network_message.h @@ -84,13 +84,14 @@ private: static const int maxNameSize= 32; private: - struct Data{ + struct Data { int8 messageType; int32 sessionId; NetworkString versionString; NetworkString name; int16 playerIndex; int8 gameState; + uint32 externalIp; }; private: @@ -98,13 +99,14 @@ private: public: NetworkMessageIntro(); - NetworkMessageIntro(int32 sessionId, const string &versionString, const string &name, int playerIndex, NetworkGameStateType gameState); + NetworkMessageIntro(int32 sessionId, const string &versionString, const string &name, int playerIndex, NetworkGameStateType gameState, uint32 externalIp); int32 getSessionId() const { return data.sessionId;} string getVersionString() const { return data.versionString.getString(); } string getName() const { return data.name.getString(); } int getPlayerIndex() const { return data.playerIndex; } NetworkGameStateType getGameState() const { return static_cast(data.gameState); } + uint32 getExternalIp() const { return data.externalIp;} virtual bool receive(Socket* socket); virtual void send(Socket* socket) const; diff --git a/source/glest_game/network/server_interface.cpp b/source/glest_game/network/server_interface.cpp index 101be803..90a20b52 100644 --- a/source/glest_game/network/server_interface.cpp +++ b/source/glest_game/network/server_interface.cpp @@ -143,6 +143,10 @@ ServerInterface::~ServerInterface() { SystemFlags::OutputDebug(SystemFlags::debugNetwork,"In [%s::%s Line: %d]\n",__FILE__,__FUNCTION__,__LINE__); } +void ServerInterface::addClientToServerIPAddress(uint32 clientIp,uint32 ServerIp) { + FTPServerThread::addClientToServerIPAddress(clientIp,ServerIp); +} + void ServerInterface::addSlot(int playerIndex) { SystemFlags::OutputDebug(SystemFlags::debugNetwork,"In [%s::%s Line: %d]\n",__FILE__,__FUNCTION__,__LINE__); diff --git a/source/glest_game/network/server_interface.h b/source/glest_game/network/server_interface.h index 3d3a8d10..a8095859 100644 --- a/source/glest_game/network/server_interface.h +++ b/source/glest_game/network/server_interface.h @@ -122,6 +122,7 @@ public: Mutex * getServerSynchAccessor() { return &serverSynchAccessor; } virtual void simpleTask(); + void addClientToServerIPAddress(uint32 clientIp,uint32 ServerIp); private: diff --git a/source/shared_lib/include/feathery_ftp/ftp.h b/source/shared_lib/include/feathery_ftp/ftp.h index fae1b9d7..a8ed2d60 100755 --- a/source/shared_lib/include/feathery_ftp/ftp.h +++ b/source/shared_lib/include/feathery_ftp/ftp.h @@ -61,7 +61,9 @@ typedef struct int rxBufWriteIdx; ///< currect write index of receive buffer rxBuf char rxBuf[LEN_RXBUF]; ///< receive buffer for ftp commands char workingDir[MAX_PATH_LEN]; ///< current working directory (absolute path which is relative to the root-path of the user account) - ip_t remoteIp; ///< IP of connected ftp client + ip_t remoteIp; ///< IP of connected ftp client + //ip_t remoteFTPServerIp; ///< IP of the FTP Server from the clients perspective + port_t remoteFTPServerPassivePort; ///< Port of the FTP Server from the clients perspective related to Passive connection port_t remotePort; ///< Port of connected ftp client for control connection port_t remoteDataPort; ///< Port of connected ftp client for data connection int passive; ///< TRUE, if passive-mode is activated via PSV command @@ -127,7 +129,7 @@ typedef struct extern int ftpOpenSession(socket_t ctrlSocket, ip_t remoteIp, port_t remotePort); extern int ftpCloseSession(int id); -extern ftpSession_S* ftpGetSession(int id); +extern ftpSession_S* ftpGetSession(int id); extern int ftpAuthSession(int id); extern const char* ftpGetRealPath(int id, const char* path, int normalize); extern int ftpChangeDir(int id, const char* path); @@ -151,7 +153,7 @@ extern uint32_t ftpGetUnixTime(void); extern char *ftpStrcpy(char *dest, const char *src); -extern void ftpArchInit(void); +extern void ftpArchInit(); extern void ftpArchCleanup(void); extern int ftpGetLocalTime(ftpTime_S *t); extern void* ftpOpenDir(const char* path); diff --git a/source/shared_lib/include/feathery_ftp/ftpIfc.h b/source/shared_lib/include/feathery_ftp/ftpIfc.h index 13c0e316..4a1c51cd 100644 --- a/source/shared_lib/include/feathery_ftp/ftpIfc.h +++ b/source/shared_lib/include/feathery_ftp/ftpIfc.h @@ -32,6 +32,8 @@ #define FTP_ACC_DIR 8 #define FTP_ACC_FULL (FTP_ACC_RD | FTP_ACC_WR | FTP_ACC_LS | FTP_ACC_DIR) +#include "ftpTypes.h" + #ifdef __cplusplus extern "C" { #endif @@ -40,7 +42,7 @@ int ftpCreateAccount(const char* name, const char* passw, const char* root, int int ftpStart(int portNumber); int ftpShutdown(void); void ftpExecute(void); -int ftpState(void); +int ftpState(void); #ifdef __cplusplus } diff --git a/source/shared_lib/include/feathery_ftp/ftpTypes.h b/source/shared_lib/include/feathery_ftp/ftpTypes.h index c2947ba0..5dae868e 100755 --- a/source/shared_lib/include/feathery_ftp/ftpTypes.h +++ b/source/shared_lib/include/feathery_ftp/ftpTypes.h @@ -4,7 +4,7 @@ * * ftpTypes.h - global type definitions * - * Definitions of fixed size integers an helper macros. + * Definitions of fixed size integers an helper macros. * * * This program is free software: you can redistribute it and/or modify @@ -59,5 +59,10 @@ typedef uint16_t port_t; #ifndef TRUE #define TRUE 1 #endif + +ip_t (*ftpFindExternalFTPServerIp)(ip_t clientIp); +void (*ftpAddUPNPPortForward)(int internalPort, int externalPort); +void (*ftpRemoveUPNPPortForward)(int internalPort, int externalPort); + #endif diff --git a/source/shared_lib/include/platform/posix/miniftpserver.h b/source/shared_lib/include/platform/posix/miniftpserver.h index f65fb04a..582ae4f6 100644 --- a/source/shared_lib/include/platform/posix/miniftpserver.h +++ b/source/shared_lib/include/platform/posix/miniftpserver.h @@ -15,6 +15,7 @@ #include "base_thread.h" #include #include +#include "types.h" #include "leak_dumper.h" @@ -25,12 +26,14 @@ namespace Shared { namespace PlatformCommon { // ===================================================== // class FTPServerThread // ===================================================== +uint32 FindExternalFTPServerIp(uint32 clientIp); class FTPServerThread : public BaseThread { protected: std::pair mapsPath; int portNumber; + //uint32 externalIp; public: @@ -38,6 +41,9 @@ public: virtual void execute(); virtual void signalQuit(); virtual bool shutdownAndWait(); + + static void addClientToServerIPAddress(uint32 clientIp,uint32 ServerIp); + }; }}//end namespace diff --git a/source/shared_lib/include/platform/posix/socket.h b/source/shared_lib/include/platform/posix/socket.h index 7e905a17..dd86ebdc 100644 --- a/source/shared_lib/include/platform/posix/socket.h +++ b/source/shared_lib/include/platform/posix/socket.h @@ -21,6 +21,7 @@ #include #include "base_thread.h" #include "simple_threads.h" +#include "types.h" using std::string; @@ -49,6 +50,10 @@ using namespace Shared::PlatformCommon; namespace Shared{ namespace Platform { + +void AddUPNPPortForward(int internalPort, int externalPort); +void RemoveUPNPPortForward(int internalPort, int externalPort); + // // This interface describes the methods a callback object must implement // when signaled with detected servers @@ -99,6 +104,7 @@ protected: time_t lastDebugEvent; static int broadcast_portno; std::string ipAddress; + std::string connectedIpAddress; SimpleTaskThread *pingThread; std::map pingCache; @@ -149,6 +155,8 @@ public: virtual std::string getIpAddress(); virtual void setIpAddress(std::string value) { ipAddress = value; } + uint32 getConnectedIPAddress(string IP=""); + static bool isUPNP; protected: @@ -219,6 +227,10 @@ public: void NETdiscoverUPnPDevices(); + static bool enabledUPNP; + static bool upnp_add_redirect(int ports[2]); + static void upnp_rem_redirect(int ext_port); + protected: bool portBound; @@ -227,15 +239,11 @@ protected: static int externalPort; static int ftpServerPort; - static bool enabledUPNP; - BroadCastSocketThread *broadCastThread; void startBroadCastThread(); bool isBroadCastThreadRunning(); static int upnp_init(void *param); - static bool upnp_add_redirect(int ports[4]); - static void upnp_rem_redirect(int ext_port); void NETaddRedirects(int ports[4]); void NETremRedirects(int ext_port); diff --git a/source/shared_lib/sources/feathery_ftp/ftpCmds.c b/source/shared_lib/sources/feathery_ftp/ftpCmds.c index 51f0dd3a..9bff3211 100755 --- a/source/shared_lib/sources/feathery_ftp/ftpCmds.c +++ b/source/shared_lib/sources/feathery_ftp/ftpCmds.c @@ -679,15 +679,38 @@ LOCAL int ftpCmdPasv(int sessionId, const char* args, int len) ftpSendMsg(MSG_NORMAL, sessionId, 425, ftpMsg012); return 1; } - ftpGetSession(sessionId)->passiveDataSocket = s; - sprintf(str, "%s (%d,%d,%d,%d,%d,%d)", - ftpMsg029, - (ip >> 24) & 0xFF, - (ip >> 16) & 0xFF, - (ip >> 8) & 0xFF, - ip & 0xFF, - (port >> 8) & 0xFF, - port & 0xFF); + ftpGetSession(sessionId)->passiveDataSocket = s; + + if(ftpFindExternalFTPServerIp(ftpGetSession(sessionId)->remoteIp) > 0) + { + ftpGetSession(sessionId)->remoteFTPServerPassivePort = port; + if(ftpAddUPNPPortForward) { + ftpAddUPNPPortForward(port, port); + } + + ip_t remoteFTPServerIp = ftpFindExternalFTPServerIp(ftpGetSession(sessionId)->remoteIp); + + sprintf(str, "%s (%d,%d,%d,%d,%d,%d)", + ftpMsg029, + (remoteFTPServerIp >> 24) & 0xFF, + (remoteFTPServerIp >> 16) & 0xFF, + (remoteFTPServerIp >> 8) & 0xFF, + remoteFTPServerIp & 0xFF, + (port >> 8) & 0xFF, + port & 0xFF); + } + else + { + sprintf(str, "%s (%d,%d,%d,%d,%d,%d)", + ftpMsg029, + (ip >> 24) & 0xFF, + (ip >> 16) & 0xFF, + (ip >> 8) & 0xFF, + ip & 0xFF, + (port >> 8) & 0xFF, + port & 0xFF); + } + ftpSendMsg(MSG_NORMAL, sessionId, 227, str); ftpGetSession(sessionId)->passive = TRUE; return 0; diff --git a/source/shared_lib/sources/feathery_ftp/ftpSession.c b/source/shared_lib/sources/feathery_ftp/ftpSession.c index 9bb250ed..2793682d 100644 --- a/source/shared_lib/sources/feathery_ftp/ftpSession.c +++ b/source/shared_lib/sources/feathery_ftp/ftpSession.c @@ -32,7 +32,6 @@ #include "ftpConfig.h" #include "ftp.h" - /** * @brief array that holds the data of all ftp sessions * @@ -119,7 +118,14 @@ int ftpAuthSession(int id) * @return 0 */ int ftpCloseSession(int id) -{ +{ + if(ftpFindExternalFTPServerIp != NULL && ftpFindExternalFTPServerIp(sessions[id].remoteIp) > 0) + { + if(ftpRemoveUPNPPortForward) + { + ftpRemoveUPNPPortForward(sessions[id].remoteFTPServerPassivePort, sessions[id].remoteFTPServerPassivePort); + } + } ftpCloseSocket(sessions[id].ctrlSocket); ftpCloseTransmission(id); diff --git a/source/shared_lib/sources/feathery_ftp/ftpTargetPosix.c b/source/shared_lib/sources/feathery_ftp/ftpTargetPosix.c index 4ac0c9d6..f61ddc0c 100644 --- a/source/shared_lib/sources/feathery_ftp/ftpTargetPosix.c +++ b/source/shared_lib/sources/feathery_ftp/ftpTargetPosix.c @@ -35,18 +35,20 @@ #include "ftpTypes.h" #include "ftpConfig.h" -#include "ftp.h" +#include "ftp.h" ip_t ownIp; +//ip_t ownExternalIp; LOCAL fd_set watchedSockets; LOCAL fd_set signaledSockets; LOCAL int maxSockNr; -void ftpArchInit(void) +void ftpArchInit() { - ownIp = 0; + ownIp = 0; + //ownExternalIp = externalIp; maxSockNr = 0; FD_ZERO(&watchedSockets); FD_ZERO(&signaledSockets); @@ -260,7 +262,10 @@ socket_t ftpEstablishDataConnection(int passive, ip_t *ip, port_t *port) } *port = ntohs(myAddr.sin_port); - *ip = ownIp; + *ip = ownIp; + //if(ownExternalIp > 0) { + // *ip = ownExternalIp; + //} if(listen(dataSocket, 1)) { @@ -339,7 +344,7 @@ socket_t ftpAcceptServerConnection(socket_t server, ip_t *remoteIP, port_t *remo #endif } - ownIp = ntohl(sockinfo.sin_addr.s_addr); // eigene IP-Adresse abspeichern (wird dir PASV benätigt) + ownIp = ntohl(sockinfo.sin_addr.s_addr); // eigene IP-Adresse abspeichern (wird dir PASV benätigt) } #if DBG_LOG printf("Verbindung mit %s auf Port %d akzeptiert.\n", inet_ntoa(sockinfo.sin_addr), *remotePort); diff --git a/source/shared_lib/sources/feathery_ftp/ftpTargetWin32.c b/source/shared_lib/sources/feathery_ftp/ftpTargetWin32.c index b8d9e176..c07aa625 100644 --- a/source/shared_lib/sources/feathery_ftp/ftpTargetWin32.c +++ b/source/shared_lib/sources/feathery_ftp/ftpTargetWin32.c @@ -32,16 +32,18 @@ #pragma comment(lib, "ws2_32") #pragma comment(lib, "MSWSOCK") -ip_t ownIp; +ip_t ownIp; +//ip_t ownExternalIp; LOCAL fd_set watchedSockets; LOCAL fd_set signaledSockets; LOCAL int maxSockNr; -void ftpArchInit(void) +void ftpArchInit() { WSADATA wsaData; - ownIp = 0; + ownIp = 0; + //ownExternalIp = externalIp; maxSockNr = 0; FD_ZERO(&watchedSockets); WSAStartup(MAKEWORD(2, 0),&wsaData); @@ -291,6 +293,9 @@ socket_t ftpEstablishDataConnection(int passive, ip_t *ip, port_t *port) *port = ntohs(myAddr.sin_port); *ip = ownIp; + //if(ownExternalIp > 0) { + // *ip = ownExternalIp; + //} if(listen(dataSocket, 1)) { diff --git a/source/shared_lib/sources/platform/posix/miniftpserver.cpp b/source/shared_lib/sources/platform/posix/miniftpserver.cpp index 95d681e6..0010ccff 100644 --- a/source/shared_lib/sources/platform/posix/miniftpserver.cpp +++ b/source/shared_lib/sources/platform/posix/miniftpserver.cpp @@ -14,6 +14,7 @@ #include "util.h" #include "platform_common.h" #include "ftpIfc.h" +#include "socket.h" #include #include @@ -25,9 +26,22 @@ using namespace Shared::PlatformCommon; namespace Shared { namespace PlatformCommon { +static std::map clientToFTPServerList; + +uint32 FindExternalFTPServerIp(uint32 clientIp) { + return clientToFTPServerList[clientIp]; +} + FTPServerThread::FTPServerThread(std::pair mapsPath,int portNumber) : BaseThread() { - this->mapsPath = mapsPath; - this->portNumber = portNumber; + this->mapsPath = mapsPath; + this->portNumber = portNumber; + //this->externalIp = externalIp; + + //void (*ftpAddUPNPPortForward)(int internalPort, int externalPort) = NULL; + //void (*ftpRemoveUPNPPortForward)(int internalPort, int externalPort) = NULL; + ftpAddUPNPPortForward = &AddUPNPPortForward; + ftpRemoveUPNPPortForward = &RemoveUPNPPortForward; + ftpFindExternalFTPServerIp = &FindExternalFTPServerIp; } void FTPServerThread::signalQuit() { @@ -39,7 +53,14 @@ bool FTPServerThread::shutdownAndWait() { if(SystemFlags::VERBOSE_MODE_ENABLED) printf ("===> FTP Server: shutdownAndWait\n"); signalQuit(); - return BaseThread::shutdownAndWait(); + bool ret = BaseThread::shutdownAndWait(); + clientToFTPServerList.clear(); + return ret; +} + +void FTPServerThread::addClientToServerIPAddress(uint32 clientIp,uint32 ServerIp) { + //ftpSetSessionRemoteServerIp(clientIp, ServerIp); + clientToFTPServerList[clientIp] = ServerIp; } void FTPServerThread::execute() { diff --git a/source/shared_lib/sources/platform/posix/socket.cpp b/source/shared_lib/sources/platform/posix/socket.cpp index 952a9f43..2fc5bc51 100644 --- a/source/shared_lib/sources/platform/posix/socket.cpp +++ b/source/shared_lib/sources/platform/posix/socket.cpp @@ -620,6 +620,20 @@ string getNetworkInterfaceBroadcastAddress(string ipAddress) return broadCastAddress; } +uint32 Socket::getConnectedIPAddress(string IP) { + sockaddr_in addr; + memset(&addr, 0, sizeof(addr)); + + addr.sin_family= AF_INET; + if(IP == "") { + IP = connectedIpAddress; + } + addr.sin_addr.s_addr= inet_addr(IP.c_str()); + //addr.sin_port= htons(port); + + return SockAddrToUint32((struct sockaddr *)&addr); +} + std::vector Socket::getLocalIPAddressList() { std::vector ipList; @@ -734,14 +748,16 @@ bool Socket::isSocketValid(const PLATFORM_SOCKET *validateSocket) { #endif } -Socket::Socket(PLATFORM_SOCKET sock){ +Socket::Socket(PLATFORM_SOCKET sock) { this->pingThread = NULL; this->sock= sock; + this->connectedIpAddress = ""; } -Socket::Socket() -{ +Socket::Socket() { this->pingThread = NULL; + this->connectedIpAddress = ""; + sock = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP); if(isSocketValid() == false) { throwException("Error creating socket"); @@ -1411,6 +1427,7 @@ void ClientSocket::connect(const Ip &ip, int port) SystemFlags::OutputDebug(SystemFlags::debugNetwork,"Connecting to host [%s] on port = %d\n", ip.getString().c_str(),port); + connectedIpAddress = ""; int err= ::connect(sock, reinterpret_cast(&addr), sizeof(addr)); if(err < 0) { SystemFlags::OutputDebug(SystemFlags::debugNetwork,"In [%s::%s] #2 Error connecting socket for IP: %s for Port: %d err = %d error = %s\n",__FILE__,__FUNCTION__,ip.getString().c_str(),port,err,getLastSocketErrorFormattedText().c_str()); @@ -1436,14 +1453,12 @@ void ClientSocket::connect(const Ip &ip, int port) err = select((int)sock + 1, NULL, &myset, NULL, &tv); } - if (err < 0 && getLastSocketError() != PLATFORM_SOCKET_INTERRUPTED) - { + if (err < 0 && getLastSocketError() != PLATFORM_SOCKET_INTERRUPTED) { SystemFlags::OutputDebug(SystemFlags::debugNetwork,"In [%s::%s] Error connecting %s\n",__FILE__,__FUNCTION__,getLastSocketErrorFormattedText().c_str()); //throwException(szBuf); break; } - else if (err > 0) - { + else if (err > 0) { // Socket selected for write lon = sizeof(int); #ifndef WIN32 @@ -1457,8 +1472,7 @@ void ClientSocket::connect(const Ip &ip, int port) break; } // Check the value returned... - if (valopt) - { + if(valopt) { SystemFlags::OutputDebug(SystemFlags::debugNetwork,"In [%s::%s] Error in delayed connection() %d - [%s]\n",__FILE__,__FUNCTION__,valopt, strerror(valopt)); //throwException(szBuf); break; @@ -1469,8 +1483,7 @@ void ClientSocket::connect(const Ip &ip, int port) break; } - else - { + else { SystemFlags::OutputDebug(SystemFlags::debugNetwork,"In [%s::%s] Timeout in select() - Cancelling!\n",__FILE__,__FUNCTION__); //throwException(szBuf); @@ -1480,20 +1493,19 @@ void ClientSocket::connect(const Ip &ip, int port) } while (1); } - if(err < 0) - { + if(err < 0) { SystemFlags::OutputDebug(SystemFlags::debugNetwork,"In [%s::%s] Before END sock = %d, err = %d, error = %s\n",__FILE__,__FUNCTION__,sock,err,getLastSocketErrorFormattedText().c_str()); //throwException(szBuf); disconnectSocket(); } - else - { + else { SystemFlags::OutputDebug(SystemFlags::debugNetwork,"In [%s::%s] Valid recovery for connection sock = %d, err = %d, error = %s\n",__FILE__,__FUNCTION__,sock,err,getLastSocketErrorFormattedText().c_str()); + connectedIpAddress = ip.getString(); } } - else - { + else { SystemFlags::OutputDebug(SystemFlags::debugNetwork,"Connected to host [%s] on port = %d sock = %d err = %d", ip.getString().c_str(),port,sock,err); + connectedIpAddress = ip.getString(); } } @@ -1824,6 +1836,85 @@ Socket *ServerSocket::accept() { return result; } +void AddUPNPPortForward(int internalPort, int externalPort) { + struct UPNPDev *devlist=NULL; + struct UPNPDev *dev=NULL; + char *descXML=NULL; + int descXMLsize = 0; + char buf[255]=""; + //int *externalPort = (int *)asdf; + + memset(&urls, 0, sizeof(struct UPNPUrls)); + memset(&data, 0, sizeof(struct IGDdatas)); + + SystemFlags::OutputDebug(SystemFlags::debugNetwork,"Socket::isUPNP = %d\n", Socket::isUPNP); + + if(Socket::isUPNP) { + SystemFlags::OutputDebug(SystemFlags::debugNetwork,"Searching for UPnP devices for automatic port forwarding...\n"); + devlist = upnpDiscover(2000, NULL, NULL, 0); + SystemFlags::OutputDebug(SystemFlags::debugNetwork,"UPnP device search finished.\n"); + + if (devlist) { + dev = devlist; + while (dev) { + if (strstr(dev->st, "InternetGatewayDevice")) + break; + dev = dev->pNext; + } + if (!dev) { + dev = devlist; /* defaulting to first device */ + } + + SystemFlags::OutputDebug(SystemFlags::debugNetwork,"UPnP device found: %s %s\n", dev->descURL, dev->st); + + descXML = (char *)miniwget_getaddr(dev->descURL, &descXMLsize, lanaddr, sizeof(lanaddr)); + SystemFlags::OutputDebug(SystemFlags::debugNetwork,"LAN address: %s\n", lanaddr); + if (descXML) { + parserootdesc (descXML, descXMLsize, &data); + free (descXML); descXML = 0; + GetUPNPUrls (&urls, &data, dev->descURL); + } + sprintf(buf, "UPnP device found: %s %s LAN address %s", dev->descURL, dev->st, lanaddr); + //addDumpInfo(buf); + freeUPNPDevlist(devlist); + + if (!urls.controlURL || urls.controlURL[0] == '\0') { + sprintf(buf, "controlURL not available, UPnP disabled"); + //addDumpInfo(buf); + //obj->DiscoveredServers(); + //return false; + return; + } + + //obj->DiscoveredServers(); + int ports[2] = { externalPort, internalPort }; + ServerSocket::upnp_add_redirect(ports); + ServerSocket::enabledUPNP = true; + //return true; + return; + } + sprintf(buf, "UPnP device not found."); + //addDumpInfo(buf); + SystemFlags::OutputDebug(SystemFlags::debugNetwork,"No UPnP devices found.\n"); + + //obj->DiscoveredServers(); + //return false; + return; + } + else { + sprintf(buf, "UPnP detection routine disabled by user."); + //addDumpInfo(buf); + SystemFlags::OutputDebug(SystemFlags::debugNetwork,"UPnP detection routine disabled by user.\n"); + + //obj->DiscoveredServers(); + //return false; + return; + } +} + +void RemoveUPNPPortForward(int internalPort, int externalPort) { + ServerSocket::upnp_rem_redirect(externalPort); +} // // This code below handles Universal Plug and Play Router Port Forwarding @@ -1902,7 +1993,7 @@ int ServerSocket::upnp_init(void *param) { } } -bool ServerSocket::upnp_add_redirect(int ports[4]) { +bool ServerSocket::upnp_add_redirect(int ports[2]) { char externalIP[16]=""; char ext_port_str[16]=""; char int_port_str[16]=""; @@ -1923,16 +2014,16 @@ bool ServerSocket::upnp_add_redirect(int ports[4]) { return false; } - sprintf(ext_port_str, "%d", ports[2]); - sprintf(int_port_str, "%d", ports[3]); + //sprintf(ext_port_str, "%d", ports[2]); + //sprintf(int_port_str, "%d", ports[3]); - r = UPNP_AddPortMapping(urls.controlURL, data.servicetype, - ext_port_str, int_port_str, lanaddr, "MegaGlest (FTP) - www.megaglest.org", "TCP", 0); + //r = UPNP_AddPortMapping(urls.controlURL, data.servicetype, + // ext_port_str, int_port_str, lanaddr, "MegaGlest (FTP) - www.megaglest.org", "TCP", 0); - if (r != UPNPCOMMAND_SUCCESS) { - SystemFlags::OutputDebug(SystemFlags::debugNetwork,"AddPortMapping(%s, %s, %s) failed\n", ext_port_str, int_port_str, lanaddr); + //if (r != UPNPCOMMAND_SUCCESS) { + // SystemFlags::OutputDebug(SystemFlags::debugNetwork,"AddPortMapping(%s, %s, %s) failed\n", ext_port_str, int_port_str, lanaddr); //return false; - } + //} return true; @@ -1953,7 +2044,10 @@ void ServerSocket::NETaddRedirects(int ports[4]) { // upnp_done = true; //} //if (upnp) { - upnp_add_redirect(ports); + int portsA[2] = { ports[0], ports[1] }; + upnp_add_redirect(portsA); + int portsB[2] = { ports[2], ports[3] }; + upnp_add_redirect(portsB); //} }