From 9d2c841843bfe91f8479fdc06b5091f666099028 Mon Sep 17 00:00:00 2001 From: "madmaxoft@gmail.com" Date: Tue, 5 Mar 2013 09:53:29 +0000 Subject: IPv6 support + removed cTCPLink from Lua API git-svn-id: http://mc-server.googlecode.com/svn/trunk@1253 0a769ca7-a7f5-676a-18bf-c427514a06d6 --- source/OSSupport/Socket.cpp | 68 ++++++++++++++------ source/OSSupport/Socket.h | 63 +++++++++--------- source/OSSupport/SocketThreads.cpp | 14 ++-- source/OSSupport/TCPLink.cpp | 128 ------------------------------------- source/OSSupport/TCPLink.h | 22 ------- 5 files changed, 88 insertions(+), 207 deletions(-) delete mode 100644 source/OSSupport/TCPLink.cpp delete mode 100644 source/OSSupport/TCPLink.h (limited to 'source/OSSupport') diff --git a/source/OSSupport/Socket.cpp b/source/OSSupport/Socket.cpp index e0cecc0e3..2412852d5 100644 --- a/source/OSSupport/Socket.cpp +++ b/source/OSSupport/Socket.cpp @@ -155,14 +155,14 @@ int cSocket::GetLastError() -int cSocket::SetReuseAddress() +bool cSocket::SetReuseAddress(void) { -#if defined(_WIN32) || defined(ANDROID_NDK) - char yes = 1; -#else - int yes = 1; -#endif - return setsockopt(m_Socket, SOL_SOCKET, SO_REUSEADDR, &yes, sizeof(int)); + #if defined(_WIN32) || defined(ANDROID_NDK) + char yes = 1; + #else + int yes = 1; + #endif + return (setsockopt(m_Socket, SOL_SOCKET, SO_REUSEADDR, &yes, sizeof(int)) == 0); } @@ -184,9 +184,9 @@ int cSocket::WSAStartup() -cSocket cSocket::CreateSocket() +cSocket cSocket::CreateSocket(eFamily a_Family) { - return socket(AF_INET,SOCK_STREAM,0); + return socket((int)a_Family, SOCK_STREAM, 0); } @@ -207,23 +207,40 @@ unsigned long cSocket::INTERNET_ADDRESS_LOCALHOST(void) -int cSocket::BindToAny(unsigned short a_Port) +bool cSocket::BindToAnyIPv4(unsigned short a_Port) { sockaddr_in local; memset(&local, 0, sizeof(local)); local.sin_family = AF_INET; - local.sin_addr.s_addr = 0; local.sin_port = htons((u_short)a_Port); - return bind(m_Socket, (sockaddr*)&local, sizeof(local)); + return (bind(m_Socket, (sockaddr *)&local, sizeof(local)) == 0); +} + + + + + +bool cSocket::BindToAnyIPv6(unsigned short a_Port) +{ + // Cannot use socckaddr_in6, because it is not defined in the default VS2008 SDK + // Must jump through hoops here + + sockaddr_in6 local; + memset(&local, 0, sizeof(local)); + + local.sin6_family = AF_INET6; + local.sin6_port = htons((u_short)a_Port); + + return (bind(m_Socket, (sockaddr *)&local, sizeof(local)) == 0); } -int cSocket::BindToLocalhost(unsigned short a_Port) +bool cSocket::BindToLocalhostIPv4(unsigned short a_Port) { sockaddr_in local; memset(&local, 0, sizeof(local)); @@ -232,16 +249,16 @@ int cSocket::BindToLocalhost(unsigned short a_Port) local.sin_addr.s_addr = INTERNET_ADDRESS_LOCALHOST(); local.sin_port = htons((u_short)a_Port); - return bind(m_Socket, (sockaddr*)&local, sizeof(local)); + return (bind(m_Socket, (sockaddr*)&local, sizeof(local)) == 0); } -int cSocket::Listen(int a_Backlog) +bool cSocket::Listen(int a_Backlog) { - return listen(m_Socket, a_Backlog); + return (listen(m_Socket, a_Backlog) == 0); } @@ -267,6 +284,7 @@ cSocket cSocket::Accept() +/* int cSocket::Connect(SockAddr_In & a_Address) { sockaddr_in local; @@ -277,12 +295,26 @@ int cSocket::Connect(SockAddr_In & a_Address) return connect(m_Socket, (sockaddr *)&local, sizeof(local)); } +*/ + + + + + +bool cSocket::ConnectToLocalhostIPv4(unsigned short a_Port) +{ + sockaddr_in server; + server.sin_family = AF_INET; + server.sin_addr.s_addr = INTERNET_ADDRESS_LOCALHOST(); + server.sin_port = htons(a_Port); + return (connect(m_Socket, (sockaddr *)&server, sizeof(server)) == 0); +} -int cSocket::Connect(const AString & a_HostNameOrAddr, unsigned short a_Port) +bool cSocket::ConnectIPv4(const AString & a_HostNameOrAddr, unsigned short a_Port) { // First try IP Address string to hostent conversion, because it's faster unsigned long addr = inet_addr(a_HostNameOrAddr.c_str()); @@ -303,7 +335,7 @@ int cSocket::Connect(const AString & a_HostNameOrAddr, unsigned short a_Port) server.sin_addr.s_addr = *((unsigned long*)hp->h_addr); server.sin_family = AF_INET; server.sin_port = htons( (unsigned short)a_Port ); - return connect(m_Socket, (sockaddr *)&server, sizeof(server)); + return (connect(m_Socket, (sockaddr *)&server, sizeof(server)) == 0); } diff --git a/source/OSSupport/Socket.h b/source/OSSupport/Socket.h index c1e510387..7c051d229 100644 --- a/source/OSSupport/Socket.h +++ b/source/OSSupport/Socket.h @@ -8,6 +8,12 @@ class cSocket { public: + enum eFamily + { + IPv4 = AF_INET, + IPv6 = AF_INET6, + } ; + #ifdef _WIN32 typedef SOCKET xSocket; #else @@ -20,28 +26,31 @@ public: ~cSocket(); bool IsValid(void) const { return IsValidSocket(m_Socket); } - void CloseSocket(); + void CloseSocket(void); - operator xSocket() const; - xSocket GetSocket() const; + operator xSocket(void) const; + xSocket GetSocket(void) const; bool operator == (const cSocket & a_Other) {return m_Socket == a_Other.m_Socket; } - void SetSocket( xSocket a_Socket ); + void SetSocket(xSocket a_Socket); - int SetReuseAddress(); - static int WSAStartup(); + /// Sets the address-reuse socket flag; returns true on success + bool SetReuseAddress(void); + + static int WSAStartup(void); - static AString GetErrorString( int a_ErrNo ); + static AString GetErrorString(int a_ErrNo); static int GetLastError(); static AString GetLastErrorString(void) { return GetErrorString(GetLastError()); } - static cSocket CreateSocket(); + /// Creates a new socket of the specified address family + static cSocket CreateSocket(eFamily a_Family); - inline static bool IsSocketError( int a_ReturnedValue ) + inline static bool IsSocketError(int a_ReturnedValue) { #ifdef _WIN32 return (a_ReturnedValue == SOCKET_ERROR || a_ReturnedValue == 0); @@ -52,37 +61,31 @@ public: static bool IsValidSocket(xSocket a_Socket); - struct SockAddr_In - { - short Family; - unsigned short Port; - unsigned long Address; - }; - - static const short ADDRESS_FAMILY_INTERNET = 2; - static const unsigned long INTERNET_ADDRESS_ANY = 0; static unsigned long INTERNET_ADDRESS_LOCALHOST(void); // 127.0.0.1 represented in network byteorder; must be a function due to GCC :( static const unsigned short ANY_PORT = 0; // When given to Bind() functions, they will find a free port static const int DEFAULT_BACKLOG = 10; - /// Binds to the specified port on "any" interface (0.0.0.0) - int BindToAny(unsigned short a_Port); + /// Binds to the specified port on "any" interface (0.0.0.0). Returns true if successful. + bool BindToAnyIPv4(unsigned short a_Port); + + /// Binds to the specified port on "any" interface (::/128). Returns true if successful. + bool BindToAnyIPv6(unsigned short a_Port); - /* - // TODO: - /// Binds to the specified port - int BindToAny6(unsigned short a_Port); - */ + /// Binds to the specified port on localhost interface (127.0.0.1) through IPv4. Returns true if successful. + bool BindToLocalhostIPv4(unsigned short a_Port); - /// Binds to the specified port on localhost interface (127.0.0.1) through IPv4 - int BindToLocalhost(unsigned short a_Port); + /// Sets the socket to listen for incoming connections. Returns true if successful. + bool Listen(int a_Backlog = DEFAULT_BACKLOG); - int Listen(int a_Backlog = DEFAULT_BACKLOG); + /// Accepts an incoming connection. Blocks if none available. cSocket Accept(); - int Connect(SockAddr_In & a_Address); // Returns 0 on success, !0 on failure + /// Connects to a localhost socket on the specified port using IPv4; returns true if successful. + bool ConnectToLocalhostIPv4(unsigned short a_Port); + + /// Connects to the specified host or string IP address and port, using IPv4. Returns true if successful. + bool ConnectIPv4(const AString & a_HostNameOrAddr, unsigned short a_Port); - int Connect(const AString & a_HostNameOrAddr, unsigned short a_Port); // Returns 0 on success, !0 on failure int Receive(char * a_Buffer, unsigned int a_Length, unsigned int a_Flags); int Send (const char * a_Buffer, unsigned int a_Length); diff --git a/source/OSSupport/SocketThreads.cpp b/source/OSSupport/SocketThreads.cpp index 943293f5c..e7061ed31 100644 --- a/source/OSSupport/SocketThreads.cpp +++ b/source/OSSupport/SocketThreads.cpp @@ -427,13 +427,13 @@ bool cSocketThreads::cSocketThread::QueueClose(const cCallback * a_Client) bool cSocketThreads::cSocketThread::Start(void) { // Create the control socket listener - m_ControlSocket2 = cSocket::CreateSocket(); + m_ControlSocket2 = cSocket::CreateSocket(cSocket::IPv4); if (!m_ControlSocket2.IsValid()) { LOGERROR("Cannot create a Control socket for a cSocketThread (\"%s\"); continuing, but server may be unreachable from now on.", cSocket::GetLastErrorString().c_str()); return false; } - if (m_ControlSocket2.BindToLocalhost(cSocket::ANY_PORT) != 0) + if (m_ControlSocket2.BindToLocalhostIPv4(cSocket::ANY_PORT) != 0) { LOGERROR("Cannot bind a Control socket for a cSocketThread (\"%s\"); continuing, but server may be unreachable from now on.", cSocket::GetLastErrorString().c_str()); m_ControlSocket2.CloseSocket(); @@ -481,13 +481,9 @@ bool cSocketThreads::cSocketThread::Start(void) void cSocketThreads::cSocketThread::Execute(void) { // Connect the "client" part of the Control socket: - m_ControlSocket1 = cSocket::CreateSocket(); - cSocket::SockAddr_In Addr; - Addr.Family = cSocket::ADDRESS_FAMILY_INTERNET; - Addr.Address = cSocket::INTERNET_ADDRESS_LOCALHOST(); - Addr.Port = m_ControlSocket2.GetPort(); - ASSERT(Addr.Port != 0); // We checked in the Start() method, but let's be sure - if (m_ControlSocket1.Connect(Addr) != 0) + m_ControlSocket1 = cSocket::CreateSocket(cSocket::IPv4); + ASSERT(m_ControlSocket2.GetPort() != 0); // We checked in the Start() method, but let's be sure + if (!m_ControlSocket1.ConnectToLocalhostIPv4(m_ControlSocket2.GetPort())) { LOGERROR("Cannot connect Control sockets for a cSocketThread (\"%s\"); continuing, but the server may be unreachable from now on.", cSocket::GetLastErrorString().c_str()); m_ControlSocket2.CloseSocket(); diff --git a/source/OSSupport/TCPLink.cpp b/source/OSSupport/TCPLink.cpp deleted file mode 100644 index d4c423b94..000000000 --- a/source/OSSupport/TCPLink.cpp +++ /dev/null @@ -1,128 +0,0 @@ - -#include "Globals.h" // NOTE: MSVC stupidness requires this to be the same across all modules - -#include "TCPLink.h" - - - - - -#ifdef _WIN32 - #define MSG_NOSIGNAL (0) -#endif -#ifdef __MACH__ - #define MSG_NOSIGNAL (0) -#endif - - - - - -cTCPLink::cTCPLink() - : m_Socket( 0 ) - , m_StopEvent( new cEvent() ) -{ -} - -cTCPLink::~cTCPLink() -{ - if( m_Socket ) - { - CloseSocket(); - m_StopEvent->Wait(); - } - delete m_StopEvent; -} - -void cTCPLink::CloseSocket() -{ - if( m_Socket ) - { - m_Socket.CloseSocket(); - m_Socket = 0; - } -} - -bool cTCPLink::Connect( const AString & a_Address, unsigned int a_Port ) -{ - if( m_Socket ) - { - LOGWARN("WARNING: cTCPLink Connect() called while still connected. ALWAYS disconnect before re-connecting!"); - } - - m_Socket = cSocket::CreateSocket(); - if( !m_Socket.IsValid() ) - { - LOGERROR("cTCPLink: Failed to create socket"); - return false; - } - - if (m_Socket.Connect(a_Address, a_Port) != 0) - { - LOGWARN("cTCPLink: Cannot connect to server \"%s\" (%s)", m_Socket.GetLastErrorString().c_str()); - m_Socket.CloseSocket(); - return false; - } - - cThread( ReceiveThread, this ); - - return true; -} - - - - - -int cTCPLink::Send(const char * a_Data, unsigned int a_Size, int a_Flags /* = 0 */ ) -{ - (void)a_Flags; - if (!m_Socket.IsValid()) - { - LOGWARN("cTCPLink: Trying to send data without a valid connection!"); - return -1; - } - return m_Socket.Send(a_Data, a_Size); -} - - - - - -int cTCPLink::SendMessage(const char * a_Message, int a_Flags /* = 0 */ ) -{ - (void)a_Flags; - if (!m_Socket.IsValid()) - { - LOGWARN("cTCPLink: Trying to send message without a valid connection!"); - return -1; - } - return m_Socket.Send(a_Message, strlen(a_Message)); -} - - - - - -void cTCPLink::ReceiveThread( void* a_Param) -{ - cTCPLink* self = (cTCPLink*)a_Param; - cSocket Socket = self->m_Socket; - int Received = 0; - do - { - char Data[256]; - Received = Socket.Receive(Data, sizeof(Data), 0); - self->ReceivedData( Data, ((Received > 0) ? Received : -1) ); - } while ( Received > 0 ); - - LOGINFO("cTCPLink Disconnected (%i)", Received ); - - if (Socket == self->m_Socket) - { - self->m_StopEvent->Set(); - } -} - - - - diff --git a/source/OSSupport/TCPLink.h b/source/OSSupport/TCPLink.h deleted file mode 100644 index ce7abcef0..000000000 --- a/source/OSSupport/TCPLink.h +++ /dev/null @@ -1,22 +0,0 @@ -#pragma once - -#include "Socket.h" - -class cTCPLink // tolua_export -{ // tolua_export -public: // tolua_export - cTCPLink(); // tolua_export - ~cTCPLink(); // tolua_export - - bool Connect (const AString & a_Address, unsigned int a_Port ); // tolua_export - int Send (const char * a_Data, unsigned int a_Size, int a_Flags = 0 ); // tolua_export - int SendMessage(const char * a_Message, int a_Flags = 0 ); // tolua_export - void CloseSocket(); // tolua_export -protected: // tolua_export - virtual void ReceivedData( char a_Data[256], int a_Size ) = 0; // tolua_export - - static void ReceiveThread( void* a_Param ); - - cSocket m_Socket; - cEvent* m_StopEvent; -}; // tolua_export -- cgit v1.2.3