00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015 #include "gloox.h"
00016
00017 #include "connectiontcpserver.h"
00018 #include "connectiontcpclient.h"
00019 #include "connectionhandler.h"
00020 #include "dns.h"
00021 #include "logsink.h"
00022 #include "mutex.h"
00023 #include "mutexguard.h"
00024
00025 #ifdef __MINGW32__
00026 # include <winsock.h>
00027 #endif
00028
00029 #if !defined( _WIN32 ) && !defined( _WIN32_WCE )
00030 # include <netinet/in.h>
00031 # include <arpa/nameser.h>
00032 # include <resolv.h>
00033 # include <netdb.h>
00034 # include <arpa/inet.h>
00035 # include <sys/socket.h>
00036 # include <sys/un.h>
00037 # include <sys/select.h>
00038 # include <unistd.h>
00039 #endif
00040
00041 #ifdef _WIN32
00042 # include <winsock.h>
00043 #elif defined( _WIN32_WCE )
00044 # include <winsock2.h>
00045 #endif
00046
00047 #include <cstdlib>
00048 #include <string>
00049
00050 #ifndef _WIN32_WCE
00051 # include <sys/types.h>
00052 # include <sstream>
00053 #endif
00054
00055 namespace gloox
00056 {
00057
00058 ConnectionTCPServer::ConnectionTCPServer( ConnectionHandler *ch, const LogSink& logInstance,
00059 const std::string& ip, int port )
00060 : ConnectionTCPBase( 0, logInstance, ip, port ),
00061 m_connectionHandler( ch )
00062 {
00063 }
00064
00065 ConnectionTCPServer::~ConnectionTCPServer()
00066 {
00067 }
00068
00069 ConnectionBase* ConnectionTCPServer::newInstance() const
00070 {
00071 return new ConnectionTCPServer( m_connectionHandler, m_logInstance, m_server, m_port );
00072 }
00073
00074 ConnectionError ConnectionTCPServer::connect()
00075 {
00076 MutexGuard mg( &m_sendMutex );
00077
00078 if( m_socket >= 0 || m_state > StateDisconnected )
00079 return ConnNoError;
00080
00081 m_state = StateConnecting;
00082
00083 if( m_socket < 0 )
00084 m_socket = DNS::getSocket();
00085
00086 if( m_socket < 0 )
00087 return ConnIoError;
00088
00089 struct sockaddr_in local;
00090 local.sin_family = AF_INET;
00091 local.sin_port = htons( m_port );
00092 local.sin_addr.s_addr = m_server.empty() ? INADDR_ANY : inet_addr( m_server.c_str() );
00093 memset( &(local.sin_zero), '\0', 8 );
00094
00095 if( bind( m_socket, (struct sockaddr*)&local, sizeof( struct sockaddr ) ) < 0 )
00096 return ConnIoError;
00097
00098 if( listen( m_socket, 10 ) < 0 )
00099 return ConnIoError;
00100
00101 m_cancel = false;
00102 return ConnNoError;
00103 }
00104
00105 ConnectionError ConnectionTCPServer::recv( int timeout )
00106 {
00107 m_recvMutex.lock();
00108
00109 if( m_cancel || m_socket < 0 || !m_connectionHandler )
00110 {
00111 m_recvMutex.unlock();
00112 return ConnNotConnected;
00113 }
00114
00115 if( !dataAvailable( timeout ) )
00116 {
00117 m_recvMutex.unlock();
00118 return ConnNoError;
00119 }
00120
00121 struct sockaddr_in they;
00122 int sin_size = sizeof( struct sockaddr_in );
00123 #ifdef _WIN32
00124 int newfd = accept( m_socket, (struct sockaddr*)&they, &sin_size );
00125 #else
00126 int newfd = accept( m_socket, (struct sockaddr*)&they, (socklen_t*)&sin_size );
00127 #endif
00128
00129 m_recvMutex.unlock();
00130
00131 ConnectionTCPClient* conn = new ConnectionTCPClient( m_logInstance, inet_ntoa( they.sin_addr ),
00132 ntohs( they.sin_port ) );
00133 conn->setSocket( newfd );
00134 m_connectionHandler->handleIncomingConnection( conn );
00135
00136 return ConnNoError;
00137 }
00138
00139 }