• Main Page
  • Related Pages
  • Modules
  • Namespaces
  • Classes
  • Files
  • File List
  • File Members

TCPInterface.cpp

Go to the documentation of this file.
00001 #include "NativeFeatureIncludes.h"
00002 #if _RAKNET_SUPPORT_TCPInterface==1
00003 
00010 
00011 
00012 #include "TCPInterface.h"
00013 #ifdef _WIN32
00014 typedef int socklen_t;
00015 #else
00016 #include <sys/time.h>
00017 #include <unistd.h>
00018 #include <pthread.h>
00019 #endif
00020 #include <string.h>
00021 #include "RakAssert.h"
00022 #include <stdio.h>
00023 #include "RakAssert.h"
00024 #include "RakSleep.h"
00025 #include "StringCompressor.h"
00026 #include "StringTable.h"
00027 
00028 #ifdef _DO_PRINTF
00029 #endif
00030 
00031 #ifdef _WIN32
00032 #include "WSAStartupSingleton.h"
00033 #endif
00034 
00035 RAK_THREAD_DECLARATION(UpdateTCPInterfaceLoop);
00036 RAK_THREAD_DECLARATION(ConnectionAttemptLoop);
00037 
00038 #ifdef _MSC_VER
00039 #pragma warning( push )
00040 #endif
00041 
00042 TCPInterface::TCPInterface()
00043 {
00044         isStarted=false;
00045         threadRunning=false;
00046         listenSocket=(SOCKET) -1;
00047         remoteClients=0;
00048         remoteClientsLength=0;
00049 
00050         StringCompressor::AddReference();
00051         RakNet::StringTable::AddReference();
00052 
00053 #if defined(OPEN_SSL_CLIENT_SUPPORT)
00054         ctx=0;
00055         meth=0;
00056 #endif
00057 
00058 #ifdef _WIN32
00059         WSAStartupSingleton::AddRef();
00060 #endif
00061 }
00062 TCPInterface::~TCPInterface()
00063 {
00064         Stop();
00065 #ifdef _WIN32
00066         WSAStartupSingleton::Deref();
00067 #endif
00068 
00069         RakNet::OP_DELETE_ARRAY(remoteClients,__FILE__,__LINE__);
00070 
00071         StringCompressor::RemoveReference();
00072         RakNet::StringTable::RemoveReference();
00073 }
00074 bool TCPInterface::Start(unsigned short port, unsigned short maxIncomingConnections, unsigned short maxConnections, int _threadPriority)
00075 {
00076         if (isStarted)
00077                 return false;
00078 
00079         threadPriority=_threadPriority;
00080 
00081         if (threadPriority==-99999)
00082         {
00083 #if defined(_XBOX) || defined(X360)
00084                    
00085 #elif defined(_WIN32)
00086                 threadPriority=0;
00087 #elif defined(_PS3) || defined(__PS3__) || defined(SN_TARGET_PS3)
00088                       
00089 #else
00090                 threadPriority=1000;
00091 #endif
00092         }
00093 
00094         isStarted=true;
00095         if (maxConnections==0)
00096                 maxConnections=maxIncomingConnections;
00097         if (maxConnections==0)
00098                 maxConnections=1;
00099         remoteClientsLength=maxConnections;
00100         remoteClients=RakNet::OP_NEW_ARRAY<RemoteClient>(maxConnections,__FILE__,__LINE__);
00101 
00102         if (maxIncomingConnections>0)
00103         {
00104                 listenSocket = socket(AF_INET, SOCK_STREAM, 0);
00105                 if ((int)listenSocket ==-1)
00106                         return false;
00107 
00108                 struct sockaddr_in serverAddress;
00109                 serverAddress.sin_family = AF_INET;
00110                 serverAddress.sin_addr.s_addr = htonl(INADDR_ANY);
00111                 serverAddress.sin_port = htons(port);
00112 
00113                 if (bind(listenSocket,(struct sockaddr *) &serverAddress,sizeof(serverAddress)) < 0)
00114                         return false;
00115 
00116                 listen(listenSocket, maxIncomingConnections);
00117         }
00118 
00119         // Start the update thread
00120         int errorCode = RakNet::RakThread::Create(UpdateTCPInterfaceLoop, this, threadPriority);
00121         if (errorCode!=0)
00122                 return false;
00123 
00124         while (threadRunning==false)
00125                 RakSleep(0);
00126 
00127         return true;
00128 }
00129 void TCPInterface::Stop(void)
00130 {
00131         if (isStarted==false)
00132                 return;
00133 
00134         unsigned i;
00135 #if defined(OPEN_SSL_CLIENT_SUPPORT)
00136         for (i=0; i < remoteClientsLength; i++)
00137                 remoteClients[i].DisconnectSSL();
00138 #endif
00139 
00140         isStarted=false;
00141 
00142         if (listenSocket!=(SOCKET) -1)
00143         {
00144 #ifdef _WIN32
00145                 shutdown(listenSocket, SD_BOTH);
00146 #else           
00147                 shutdown(listenSocket, SHUT_RDWR);
00148 #endif
00149                 closesocket(listenSocket);
00150                 listenSocket=(SOCKET) -1;
00151         }
00152 
00153         // Abort waiting connect calls
00154         blockingSocketListMutex.Lock();
00155         for (i=0; i < blockingSocketList.Size(); i++)
00156         {
00157                 closesocket(blockingSocketList[i]);
00158         }
00159         blockingSocketListMutex.Unlock();
00160 
00161         // Wait for the thread to stop
00162         while ( threadRunning )
00163                 RakSleep(15);
00164 
00165         RakSleep(100);
00166 
00167         // Stuff from here on to the end of the function is not threadsafe
00168         for (i=0; i < (unsigned int) remoteClientsLength; i++)
00169         {
00170                 closesocket(remoteClients[i].socket);
00171 #if defined(OPEN_SSL_CLIENT_SUPPORT)
00172                 remoteClients[i].FreeSSL();
00173 #endif
00174         }
00175         remoteClientsLength=0;
00176         RakNet::OP_DELETE_ARRAY(remoteClients,__FILE__,__LINE__);
00177         remoteClients=0;
00178 
00179         incomingMessages.Clear(__FILE__, __LINE__);
00180         newIncomingConnections.Clear(__FILE__, __LINE__);
00181         newRemoteClients.Clear(__FILE__, __LINE__);
00182         lostConnections.Clear(__FILE__, __LINE__);
00183         requestedCloseConnections.Clear(__FILE__, __LINE__);
00184         failedConnectionAttempts.Clear(__FILE__, __LINE__);
00185         completedConnectionAttempts.Clear(__FILE__, __LINE__);
00186         failedConnectionAttempts.Clear(__FILE__, __LINE__);
00187         for (i=0; i < headPush.Size(); i++)
00188                 DeallocatePacket(headPush[i]);
00189         headPush.Clear(__FILE__, __LINE__);
00190         for (i=0; i < tailPush.Size(); i++)
00191                 DeallocatePacket(tailPush[i]);
00192         tailPush.Clear(__FILE__, __LINE__);
00193 
00194 #if defined(OPEN_SSL_CLIENT_SUPPORT)
00195         SSL_CTX_free (ctx);
00196         startSSL.Clear(__FILE__, __LINE__);
00197         activeSSLConnections.Clear(false, __FILE__, __LINE__);
00198 #endif
00199 }
00200 SystemAddress TCPInterface::Connect(const char* host, unsigned short remotePort, bool block)
00201 {
00202         if (threadRunning==false)
00203                 return UNASSIGNED_SYSTEM_ADDRESS;
00204 
00205         int newRemoteClientIndex=-1;
00206         for (newRemoteClientIndex=0; newRemoteClientIndex < remoteClientsLength; newRemoteClientIndex++)
00207         {
00208                 remoteClients[newRemoteClientIndex].isActiveMutex.Lock();
00209                 if (remoteClients[newRemoteClientIndex].isActive==false)
00210                 {
00211                         remoteClients[newRemoteClientIndex].SetActive(true);
00212                         remoteClients[newRemoteClientIndex].isActiveMutex.Unlock();
00213                         break;
00214                 }
00215                 remoteClients[newRemoteClientIndex].isActiveMutex.Unlock();
00216         }
00217         if (newRemoteClientIndex==-1)
00218                 return UNASSIGNED_SYSTEM_ADDRESS;
00219 
00220         if (block)
00221         {
00222                 SystemAddress systemAddress;
00223                 systemAddress.binaryAddress=inet_addr(host);
00224                 systemAddress.port=remotePort;
00225                 systemAddress.systemIndex=(SystemIndex) newRemoteClientIndex;
00226 
00227                 SOCKET sockfd = SocketConnect(host, remotePort);
00228                 if (sockfd==(SOCKET)-1)
00229                 {
00230                         remoteClients[newRemoteClientIndex].isActiveMutex.Lock();
00231                         remoteClients[newRemoteClientIndex].SetActive(false);
00232                         remoteClients[newRemoteClientIndex].isActiveMutex.Unlock();
00233 
00234                         failedConnectionAttemptMutex.Lock();
00235                         failedConnectionAttempts.Push(systemAddress, __FILE__, __LINE__ );
00236                         failedConnectionAttemptMutex.Unlock();
00237 
00238                         return UNASSIGNED_SYSTEM_ADDRESS;
00239                 }
00240 
00241                 remoteClients[newRemoteClientIndex].socket=sockfd;
00242                 remoteClients[newRemoteClientIndex].systemAddress=systemAddress;
00243 
00244                 completedConnectionAttemptMutex.Lock();
00245                 completedConnectionAttempts.Push(remoteClients[newRemoteClientIndex].systemAddress, __FILE__, __LINE__ );
00246                 completedConnectionAttemptMutex.Unlock();
00247 
00248                 return remoteClients[newRemoteClientIndex].systemAddress;
00249         }
00250         else
00251         {
00252                 ThisPtrPlusSysAddr *s = RakNet::OP_NEW<ThisPtrPlusSysAddr>( __FILE__, __LINE__ );
00253                 s->systemAddress.SetBinaryAddress(host);
00254                 s->systemAddress.port=remotePort;
00255                 s->systemAddress.systemIndex=(SystemIndex) newRemoteClientIndex;
00256                 s->tcpInterface=this;
00257 
00258                 // Start the connection thread
00259                 int errorCode = RakNet::RakThread::Create(ConnectionAttemptLoop, s, threadPriority);
00260                 if (errorCode!=0)
00261                 {
00262                         RakNet::OP_DELETE(s, __FILE__, __LINE__);
00263                         failedConnectionAttempts.Push(s->systemAddress, __FILE__, __LINE__ );
00264                 }
00265                 return UNASSIGNED_SYSTEM_ADDRESS;
00266         }       
00267 }
00268 #if defined(OPEN_SSL_CLIENT_SUPPORT)
00269 void TCPInterface::StartSSLClient(SystemAddress systemAddress)
00270 {
00271         if (ctx==0)
00272         {
00273                 SSLeay_add_ssl_algorithms();
00274                 meth = SSLv2_client_method();
00275                 SSL_load_error_strings();
00276                 ctx = SSL_CTX_new (meth);
00277                 RakAssert(ctx!=0);
00278         }
00279 
00280         SystemAddress *id = startSSL.Allocate( __FILE__, __LINE__ );
00281         *id=systemAddress;
00282         startSSL.Push(id);
00283         unsigned index = activeSSLConnections.GetIndexOf(systemAddress);
00284         if (index==(unsigned)-1)
00285                 activeSSLConnections.Insert(systemAddress,__FILE__,__LINE__);
00286 }
00287 bool TCPInterface::IsSSLActive(SystemAddress systemAddress)
00288 {
00289         return activeSSLConnections.GetIndexOf(systemAddress)!=-1;
00290 }
00291 #endif
00292 void TCPInterface::Send( const char *data, unsigned length, SystemAddress systemAddress, bool broadcast )
00293 {
00294         SendList( &data, &length, 1, systemAddress,broadcast );
00295 }
00296 bool TCPInterface::SendList( const char **data, const unsigned int *lengths, const int numParameters, SystemAddress systemAddress, bool broadcast )
00297 {
00298         if (isStarted==false)
00299                 return false;
00300         if (data==0)
00301                 return false;
00302         if (systemAddress==UNASSIGNED_SYSTEM_ADDRESS && broadcast==false)
00303                 return false;
00304         unsigned int totalLength=0;
00305         int i;
00306         for (i=0; i < numParameters; i++)
00307         {
00308                 if (lengths[i]>0)
00309                         totalLength+=lengths[i];
00310         }
00311         if (totalLength==0)
00312                 return false;
00313 
00314         if (broadcast)
00315         {
00316                 // Send to all, possible exception system
00317                 for (i=0; i < remoteClientsLength; i++)
00318                 {
00319                         if (remoteClients[i].systemAddress!=systemAddress)
00320                         {
00321                                 remoteClients[i].SendOrBuffer(data, lengths, numParameters);
00322                         }
00323                 }
00324         }
00325         else
00326         {
00327                 // Send to this player
00328                 if (systemAddress.systemIndex<remoteClientsLength &&
00329                         remoteClients[systemAddress.systemIndex].systemAddress==systemAddress)
00330                 {
00331                         remoteClients[systemAddress.systemIndex].SendOrBuffer(data, lengths, numParameters);
00332                 }
00333                 else
00334                 {
00335                         for (i=0; i < remoteClientsLength; i++)
00336                         {
00337                                 if (remoteClients[i].systemAddress==systemAddress )
00338                                 {
00339                                         remoteClients[i].SendOrBuffer(data, lengths, numParameters);
00340                                 }
00341                         }
00342                 }
00343         }
00344 
00345 
00346         return true;
00347 }
00348 bool TCPInterface::ReceiveHasPackets( void )
00349 {
00350         return headPush.IsEmpty()==false || incomingMessages.IsEmpty()==false || tailPush.IsEmpty()==false;
00351 }
00352 Packet* TCPInterface::Receive( void )
00353 {
00354         if (isStarted==false)
00355                 return 0;
00356         if (headPush.IsEmpty()==false)
00357                 return headPush.Pop();
00358         Packet *p = incomingMessages.PopInaccurate();
00359         if (p)
00360                 return p;
00361         if (tailPush.IsEmpty()==false)
00362                 return tailPush.Pop();
00363         return 0;
00364 }
00365 void TCPInterface::CloseConnection( SystemAddress systemAddress )
00366 {
00367         if (isStarted==false)
00368                 return;
00369         if (systemAddress==UNASSIGNED_SYSTEM_ADDRESS)
00370                 return;
00371         
00372         if (systemAddress.systemIndex<remoteClientsLength && remoteClients[systemAddress.systemIndex].systemAddress==systemAddress)
00373         {
00374                 remoteClients[systemAddress.systemIndex].SetActive(false);
00375         }
00376         else
00377         {
00378                 for (int i=0; i < remoteClientsLength; i++)
00379                 {
00380                         remoteClients[i].isActiveMutex.Lock();
00381                         if (remoteClients[i].isActive && remoteClients[i].systemAddress==systemAddress)
00382                         {
00383                                 remoteClients[systemAddress.systemIndex].SetActive(false);
00384                                 remoteClients[i].isActiveMutex.Unlock();
00385                                 break;
00386                         }
00387                         remoteClients[i].isActiveMutex.Unlock();
00388                 }
00389         }
00390 
00391 
00392 #if defined(OPEN_SSL_CLIENT_SUPPORT)
00393         unsigned index = activeSSLConnections.GetIndexOf(systemAddress);
00394         if (index!=(unsigned)-1)
00395                 activeSSLConnections.RemoveAtIndex(index);
00396 #endif
00397 }
00398 void TCPInterface::DeallocatePacket( Packet *packet )
00399 {
00400         if (packet==0)
00401                 return;
00402         if (packet->deleteData)
00403         {
00404                 rakFree_Ex(packet->data, __FILE__, __LINE__ );
00405                 incomingMessages.Deallocate(packet, __FILE__,__LINE__);
00406         }
00407         else
00408         {
00409                 // Came from userspace AllocatePacket
00410                 rakFree_Ex(packet->data, __FILE__, __LINE__ );
00411                 RakNet::OP_DELETE(packet, __FILE__, __LINE__);
00412         }
00413 }
00414 Packet* TCPInterface::AllocatePacket(unsigned dataSize)
00415 {
00416         Packet*p = RakNet::OP_NEW<Packet>(__FILE__,__LINE__);
00417         p->data=(unsigned char*) rakMalloc_Ex(dataSize,__FILE__,__LINE__);
00418         p->length=dataSize;
00419         p->bitSize=BYTES_TO_BITS(dataSize);
00420         p->deleteData=false;
00421         p->guid=UNASSIGNED_RAKNET_GUID;
00422         p->systemAddress=UNASSIGNED_SYSTEM_ADDRESS;
00423         p->systemAddress.systemIndex=(SystemIndex)-1;
00424         return p;
00425 }
00426 void TCPInterface::PushBackPacket( Packet *packet, bool pushAtHead )
00427 {
00428         if (pushAtHead)
00429                 headPush.Push(packet, __FILE__, __LINE__ );
00430         else
00431                 tailPush.Push(packet, __FILE__, __LINE__ );
00432 }
00433 SystemAddress TCPInterface::HasCompletedConnectionAttempt(void)
00434 {
00435         SystemAddress sysAddr=UNASSIGNED_SYSTEM_ADDRESS;
00436         completedConnectionAttemptMutex.Lock();
00437         if (completedConnectionAttempts.IsEmpty()==false)
00438                 sysAddr=completedConnectionAttempts.Pop();
00439         completedConnectionAttemptMutex.Unlock();
00440         return sysAddr;
00441 }
00442 SystemAddress TCPInterface::HasFailedConnectionAttempt(void)
00443 {
00444         SystemAddress sysAddr=UNASSIGNED_SYSTEM_ADDRESS;
00445         failedConnectionAttemptMutex.Lock();
00446         if (failedConnectionAttempts.IsEmpty()==false)
00447                 sysAddr=failedConnectionAttempts.Pop();
00448         failedConnectionAttemptMutex.Unlock();
00449         return sysAddr;
00450 }
00451 SystemAddress TCPInterface::HasNewIncomingConnection(void)
00452 {
00453         SystemAddress *out, out2;
00454         out = newIncomingConnections.PopInaccurate();
00455         if (out)
00456         {
00457                 out2=*out;
00458                 newIncomingConnections.Deallocate(out, __FILE__,__LINE__);
00459                 return *out;
00460         }
00461         else
00462         {
00463                 return UNASSIGNED_SYSTEM_ADDRESS;
00464         }
00465 }
00466 SystemAddress TCPInterface::HasLostConnection(void)
00467 {
00468         SystemAddress *out, out2;
00469         out = lostConnections.PopInaccurate();
00470         if (out)
00471         {
00472                 out2=*out;
00473                 lostConnections.Deallocate(out, __FILE__,__LINE__);
00474                 return *out;
00475         }
00476         else
00477         {
00478                 return UNASSIGNED_SYSTEM_ADDRESS;
00479         }
00480 }
00481 void TCPInterface::GetConnectionList( SystemAddress *remoteSystems, unsigned short *numberOfSystems ) const
00482 {
00483         unsigned short systemCount=0;
00484         unsigned short maxToWrite=*numberOfSystems;
00485         for (int i=0; i < remoteClientsLength; i++)
00486         {
00487                 if (remoteClients[i].isActive)
00488                 {
00489                         if (systemCount < maxToWrite)
00490                                 remoteSystems[systemCount]=remoteClients[i].systemAddress;
00491                         systemCount++;
00492                 }
00493         }
00494         *numberOfSystems=systemCount;
00495 }
00496 unsigned short TCPInterface::GetConnectionCount(void) const
00497 {
00498         unsigned short systemCount=0;
00499         for (int i=0; i < remoteClientsLength; i++)
00500         {
00501                 if (remoteClients[i].isActive)
00502                         systemCount++;
00503         }
00504         return systemCount;
00505 }
00506 
00507 unsigned int TCPInterface::GetOutgoingDataBufferSize(SystemAddress systemAddress) const
00508 {
00509         unsigned bytesWritten=0;
00510         if (systemAddress.systemIndex<remoteClientsLength &&
00511                 remoteClients[systemAddress.systemIndex].isActive &&
00512                 remoteClients[systemAddress.systemIndex].systemAddress==systemAddress)
00513         {
00514                 remoteClients[systemAddress.systemIndex].outgoingDataMutex.Lock();
00515                 bytesWritten=remoteClients[systemAddress.systemIndex].outgoingData.GetBytesWritten();
00516                 remoteClients[systemAddress.systemIndex].outgoingDataMutex.Unlock();
00517                 return bytesWritten;
00518         }
00519 
00520         for (int i=0; i < remoteClientsLength; i++)
00521         {
00522                 if (remoteClients[i].isActive && remoteClients[i].systemAddress==systemAddress)
00523                 {
00524                         remoteClients[i].outgoingDataMutex.Lock();
00525                         bytesWritten+=remoteClients[i].outgoingData.GetBytesWritten();
00526                         remoteClients[i].outgoingDataMutex.Unlock();
00527                 }
00528         }
00529         return bytesWritten;
00530 }
00531 SOCKET TCPInterface::SocketConnect(const char* host, unsigned short remotePort)
00532 {
00533         sockaddr_in serverAddress;
00534 
00535 #if !defined(_XBOX) && !defined(_X360)
00536         struct hostent * server;
00537         server = gethostbyname(host);
00538         if (server == NULL)
00539                 return (SOCKET) -1;
00540 #endif
00541 
00542         SOCKET sockfd = socket(AF_INET, SOCK_STREAM, 0);
00543         if (sockfd < 0) 
00544                 return (SOCKET) -1;
00545 
00546         memset(&serverAddress, 0, sizeof(serverAddress));
00547         serverAddress.sin_family = AF_INET;
00548         serverAddress.sin_port = htons( remotePort );
00549 
00550         /*
00551 #ifdef _WIN32
00552         unsigned long nonblocking = 1;
00553         ioctlsocket( sockfd, FIONBIO, &nonblocking );
00554 #elif defined(_PS3) || defined(__PS3__) || defined(SN_TARGET_PS3)
00555                                                                                                         
00556 #else
00557         fcntl( sockfd, F_SETFL, O_NONBLOCK );
00558 #endif
00559         */
00560 
00561         int sock_opt=1024*256;
00562         setsockopt(sockfd, SOL_SOCKET, SO_RCVBUF, ( char * ) & sock_opt, sizeof ( sock_opt ) );
00563 
00564 
00565 #if !defined(_XBOX) && !defined(_X360)
00566         memcpy((char *)&serverAddress.sin_addr.s_addr, (char *)server->h_addr, server->h_length);
00567 #else
00568         serverAddress.sin_addr.s_addr = inet_addr( host );
00569 #endif
00570 
00571         blockingSocketListMutex.Lock();
00572         blockingSocketList.Insert(sockfd, __FILE__, __LINE__);
00573         blockingSocketListMutex.Unlock();
00574 
00575         // This is blocking
00576         int connectResult = connect( sockfd, ( struct sockaddr * ) &serverAddress, sizeof( struct sockaddr ) );
00577 
00578         unsigned sockfdIndex;
00579         blockingSocketListMutex.Lock();
00580         sockfdIndex=blockingSocketList.GetIndexOf(sockfd);
00581         if (sockfdIndex!=(unsigned)-1)
00582                 blockingSocketList.RemoveAtIndexFast(sockfdIndex);
00583         blockingSocketListMutex.Unlock();
00584 
00585         if (connectResult==-1)
00586         {
00587                 closesocket(sockfd);
00588                 return (SOCKET) -1;
00589         }
00590 
00591         return sockfd;
00592 }
00593 RAK_THREAD_DECLARATION(ConnectionAttemptLoop)
00594 {
00595         TCPInterface::ThisPtrPlusSysAddr *s = (TCPInterface::ThisPtrPlusSysAddr *) arguments;
00596         SystemAddress systemAddress = s->systemAddress;
00597         TCPInterface *tcpInterface = s->tcpInterface;
00598         int newRemoteClientIndex=systemAddress.systemIndex;
00599         RakNet::OP_DELETE(s, __FILE__, __LINE__);
00600 
00601         char str1[64];
00602         systemAddress.ToString(false, str1);
00603         SOCKET sockfd = tcpInterface->SocketConnect(str1, systemAddress.port);
00604         if (sockfd==(SOCKET)-1)
00605         {
00606                 tcpInterface->remoteClients[newRemoteClientIndex].isActiveMutex.Lock();
00607                 tcpInterface->remoteClients[newRemoteClientIndex].SetActive(false);
00608                 tcpInterface->remoteClients[newRemoteClientIndex].isActiveMutex.Unlock();
00609 
00610                 tcpInterface->failedConnectionAttemptMutex.Lock();
00611                 tcpInterface->failedConnectionAttempts.Push(systemAddress, __FILE__, __LINE__ );
00612                 tcpInterface->failedConnectionAttemptMutex.Unlock();
00613                 return 0;
00614         }
00615 
00616         tcpInterface->remoteClients[newRemoteClientIndex].socket=sockfd;
00617         tcpInterface->remoteClients[newRemoteClientIndex].systemAddress=systemAddress;
00618 
00619         // Notify user that the connection attempt has completed.
00620         if (tcpInterface->threadRunning)
00621         {
00622                 tcpInterface->completedConnectionAttemptMutex.Lock();
00623                 tcpInterface->completedConnectionAttempts.Push(systemAddress, __FILE__, __LINE__ );
00624                 tcpInterface->completedConnectionAttemptMutex.Unlock();
00625         }       
00626 
00627         return 0;
00628 }
00629 
00630 RAK_THREAD_DECLARATION(UpdateTCPInterfaceLoop)
00631 {
00632         TCPInterface * sts = ( TCPInterface * ) arguments;
00633 //      const int BUFF_SIZE=8096;
00634         const int BUFF_SIZE=1048576;
00635         //char data[ BUFF_SIZE ];
00636         char * data = (char*) rakMalloc_Ex(BUFF_SIZE,__FILE__,__LINE__);
00637         Packet *incomingMessage;
00638         fd_set      readFD, exceptionFD, writeFD;
00639         sts->threadRunning=true;
00640 
00641         sockaddr_in sockAddr;
00642         int sockAddrSize = sizeof(sockAddr);
00643 
00644         int len;
00645         SOCKET newSock;
00646         timeval tv;
00647         int selectResult;
00648         tv.tv_sec=0;
00649         tv.tv_usec=50000;
00650 
00651         while (sts->isStarted)
00652         {
00653 #if defined(OPEN_SSL_CLIENT_SUPPORT)
00654                 SystemAddress *sslSystemAddress;
00655                 sslSystemAddress = sts->startSSL.PopInaccurate();
00656                 if (sslSystemAddress)
00657                 {
00658                         if (sslSystemAddress->systemIndex>=0 &&
00659                                 sslSystemAddress->systemIndex<sts->remoteClientsLength &&
00660                                 sts->remoteClients[sslSystemAddress->systemIndex].systemAddress==*sslSystemAddress)
00661                         {
00662                                 sts->remoteClients[sslSystemAddress->systemIndex].InitSSL(sts->ctx,sts->meth);
00663                         }
00664                         else
00665                         {
00666                                 for (int i=0; i < sts->remoteClientsLength; i++)
00667                                 {
00668                                         sts->remoteClients[i].isActiveMutex.Lock();
00669                                         if (sts->remoteClients[i].isActive && sts->remoteClients[i].systemAddress==*sslSystemAddress)
00670                                         {
00671                                                 if (sts->remoteClients[i].ssl==0)
00672                                                         sts->remoteClients[i].InitSSL(sts->ctx,sts->meth);
00673                                         }
00674                                         sts->remoteClients[i].isActiveMutex.Unlock();
00675                                 }
00676                         }
00677                         sts->startSSL.Deallocate(sslSystemAddress,__FILE__,__LINE__);
00678                 }
00679 #endif
00680 
00681 
00682                 SOCKET largestDescriptor=0; // see select()'s first parameter's documentation under linux
00683 
00684 
00685                 // Linux' select() implementation changes the timeout
00686                 tv.tv_sec=0;
00687                 tv.tv_usec=500000;
00688 
00689                 while (1)
00690                 {
00691                         // Reset readFD, writeFD, and exceptionFD since select seems to clear it
00692                         FD_ZERO(&readFD);
00693                         FD_ZERO(&exceptionFD);
00694                         FD_ZERO(&writeFD);
00695 #ifdef _MSC_VER
00696 #pragma warning( disable : 4127 ) // warning C4127: conditional expression is constant
00697 #endif
00698                         largestDescriptor=0;
00699                         if (sts->listenSocket!=(SOCKET) -1)
00700                         {
00701                                 FD_SET(sts->listenSocket, &readFD);
00702                                 FD_SET(sts->listenSocket, &exceptionFD);
00703                                 largestDescriptor = sts->listenSocket; // @see largestDescriptor def
00704                         }
00705 
00706                         unsigned i;
00707                         for (i=0; i < (unsigned int) sts->remoteClientsLength; i++)
00708                         {
00709                                 sts->remoteClients[i].isActiveMutex.Lock();
00710                                 if (sts->remoteClients[i].isActive && sts->remoteClients[i].socket!=INVALID_SOCKET)
00711                                 {
00712                                         FD_SET(sts->remoteClients[i].socket, &readFD);
00713                                         FD_SET(sts->remoteClients[i].socket, &exceptionFD);
00714                                         if (sts->remoteClients[i].outgoingData.GetBytesWritten()>0)
00715                                                 FD_SET(sts->remoteClients[i].socket, &writeFD);
00716                                         if(sts->remoteClients[i].socket > largestDescriptor) // @see largestDescriptorDef
00717                                                 largestDescriptor = sts->remoteClients[i].socket;
00718                                 }
00719                                 sts->remoteClients[i].isActiveMutex.Unlock();
00720                         }
00721 
00722 #ifdef _MSC_VER
00723 #pragma warning( disable : 4244 ) // warning C4127: conditional expression is constant
00724 #endif
00725 #if defined(_PS3) || defined(__PS3__) || defined(SN_TARGET_PS3)
00726                                                                                         
00727 #else
00728                         selectResult=(int) select(largestDescriptor+1, &readFD, &writeFD, &exceptionFD, &tv);           
00729 #endif
00730 
00731                         if (selectResult<=0)
00732                                 break;
00733 
00734                         if (sts->listenSocket!=(SOCKET) -1 && FD_ISSET(sts->listenSocket, &readFD))
00735                         {
00736                                 newSock = accept(sts->listenSocket, (sockaddr*)&sockAddr, (socklen_t*)&sockAddrSize);
00737 
00738                                 if (newSock != (SOCKET) -1)
00739                                 {
00740                                         int newRemoteClientIndex=-1;
00741                                         for (newRemoteClientIndex=0; newRemoteClientIndex < sts->remoteClientsLength; newRemoteClientIndex++)
00742                                         {
00743                                                 sts->remoteClients[newRemoteClientIndex].isActiveMutex.Lock();
00744                                                 if (sts->remoteClients[newRemoteClientIndex].isActive==false)
00745                                                 {
00746                                                         sts->remoteClients[newRemoteClientIndex].socket=newSock;
00747                                                         sts->remoteClients[newRemoteClientIndex].systemAddress.binaryAddress=sockAddr.sin_addr.s_addr;
00748                                                         sts->remoteClients[newRemoteClientIndex].systemAddress.port=ntohs( sockAddr.sin_port);
00749                                                         sts->remoteClients[newRemoteClientIndex].systemAddress.systemIndex=newRemoteClientIndex;
00750 
00751                                                         sts->remoteClients[newRemoteClientIndex].SetActive(true);
00752                                                         sts->remoteClients[newRemoteClientIndex].isActiveMutex.Unlock();
00753 
00754 
00755                                                         SystemAddress *newConnectionSystemAddress=sts->newIncomingConnections.Allocate( __FILE__, __LINE__ );
00756                                                         *newConnectionSystemAddress=sts->remoteClients[newRemoteClientIndex].systemAddress;
00757                                                         sts->newIncomingConnections.Push(newConnectionSystemAddress);
00758 
00759                                                         break;
00760                                                 }
00761                                                 sts->remoteClients[newRemoteClientIndex].isActiveMutex.Unlock();
00762                                         }
00763                                         if (newRemoteClientIndex==-1)
00764                                         {
00765                                                 closesocket(sts->listenSocket);
00766                                         }
00767                                 }
00768                                 else
00769                                 {
00770 #ifdef _DO_PRINTF
00771                                         RAKNET_DEBUG_PRINTF("Error: connection failed\n");
00772 #endif
00773                                 }
00774                         }
00775                         else if (sts->listenSocket!=(SOCKET) -1 && FD_ISSET(sts->listenSocket, &exceptionFD))
00776                         {
00777 #ifdef _DO_PRINTF
00778                                 int err;
00779                                 int errlen = sizeof(err);
00780                                 getsockopt(sts->listenSocket, SOL_SOCKET, SO_ERROR,(char*)&err, &errlen);
00781                                 RAKNET_DEBUG_PRINTF("Socket error %s on listening socket\n", err);
00782 #endif
00783                         }
00784                         
00785                         {
00786                                 i=0;
00787                                 while (i < (unsigned int) sts->remoteClientsLength)
00788                                 {
00789                                         if (sts->remoteClients[i].isActive==false)
00790                                         {
00791                                                 i++;
00792                                                 continue;
00793                                         }
00794 
00795                                         if (FD_ISSET(sts->remoteClients[i].socket, &exceptionFD))
00796                                         {
00797 #ifdef _DO_PRINTF
00798                                                 if (sts->listenSocket!=-1)
00799                                                 {
00800                                                         int err;
00801                                                         int errlen = sizeof(err);
00802                                                         getsockopt(sts->listenSocket, SOL_SOCKET, SO_ERROR,(char*)&err, &errlen);
00803                                                         in_addr in;
00804                                                         in.s_addr = sts->remoteClients[i].systemAddress.binaryAddress;
00805                                                         RAKNET_DEBUG_PRINTF("Socket error %i on %s:%i\n", err,inet_ntoa( in ), sts->remoteClients[i].systemAddress.port );
00806                                                 }
00807                                                 
00808 #endif
00809                                                 // Connection lost abruptly
00810                                                 SystemAddress *lostConnectionSystemAddress=sts->lostConnections.Allocate( __FILE__, __LINE__ );
00811                                                 *lostConnectionSystemAddress=sts->remoteClients[i].systemAddress;
00812                                                 sts->lostConnections.Push(lostConnectionSystemAddress);
00813                                                 sts->remoteClients[i].SetActive(false);
00814                                         }
00815                                         else
00816                                         {
00817                                                 if (FD_ISSET(sts->remoteClients[i].socket, &readFD))
00818                                                 {
00819                                                         // if recv returns 0 this was a graceful close
00820                                                         len = sts->remoteClients[i].Recv(data,BUFF_SIZE);
00821                                                         if (len>0)
00822                                                         {
00823                                                                 incomingMessage=sts->incomingMessages.Allocate( __FILE__, __LINE__ );
00824                                                                 incomingMessage->data = (unsigned char*) rakMalloc_Ex( len+1, __FILE__, __LINE__ );
00825                                                                 memcpy(incomingMessage->data, data, len);
00826                                                                 incomingMessage->data[len]=0; // Null terminate this so we can print it out as regular strings.  This is different from RakNet which does not do this.
00827 //                                                              printf("RECV: %s\n",incomingMessage->data);
00828                                                                 incomingMessage->length=len;
00829                                                                 incomingMessage->deleteData=true; // actually means came from SPSC, rather than AllocatePacket
00830                                                                 incomingMessage->systemAddress=sts->remoteClients[i].systemAddress;
00831                                                                 sts->incomingMessages.Push(incomingMessage);
00832                                                         }
00833                                                         else
00834                                                         {
00835                                                                 // Connection lost gracefully
00836                                                                 SystemAddress *lostConnectionSystemAddress=sts->lostConnections.Allocate( __FILE__, __LINE__ );
00837                                                                 *lostConnectionSystemAddress=sts->remoteClients[i].systemAddress;
00838                                                                 sts->lostConnections.Push(lostConnectionSystemAddress);
00839                                                                 sts->remoteClients[i].SetActive(false);
00840                                                                 continue;
00841                                                         }
00842                                                 }
00843                                                 if (FD_ISSET(sts->remoteClients[i].socket, &writeFD))
00844                                                 {
00845                                                         RemoteClient *rc = &sts->remoteClients[i];
00846                                                         unsigned int bytesInBuffer;
00847                                                         int bytesAvailable;
00848                                                         int bytesSent;
00849                                                         rc->outgoingDataMutex.Lock();
00850                                                         bytesInBuffer=rc->outgoingData.GetBytesWritten();
00851                                                         if (bytesInBuffer>0)
00852                                                         {
00853                                                                 unsigned int contiguousLength;
00854                                                                 char* contiguousBytesPointer = rc->outgoingData.PeekContiguousBytes(&contiguousLength);
00855                                                                 if (contiguousLength < BUFF_SIZE && contiguousLength<bytesInBuffer)
00856                                                                 {
00857                                                                         if (bytesInBuffer > BUFF_SIZE)
00858                                                                                 bytesAvailable=BUFF_SIZE;
00859                                                                         else
00860                                                                                 bytesAvailable=bytesInBuffer;
00861                                                                         rc->outgoingData.ReadBytes(data,bytesAvailable,true);
00862                                                                         bytesSent=rc->Send(data,bytesAvailable);
00863                                                                 }
00864                                                                 else
00865                                                                 {
00866                                                                         bytesSent=rc->Send(contiguousBytesPointer,contiguousLength);
00867                                                                 }
00868 
00869                                                                 rc->outgoingData.IncrementReadOffset(bytesSent);
00870                                                                 bytesInBuffer=rc->outgoingData.GetBytesWritten();
00871                                                         }
00872                                                         rc->outgoingDataMutex.Unlock();
00873                                                 }
00874                                                         
00875                                                 i++; // Nothing deleted so increment the index
00876                                         }
00877                                 }
00878                         }
00879                 }
00880 
00881                 // Sleep 0 on Linux monopolizes the CPU
00882                 RakSleep(30);
00883         }
00884         sts->threadRunning=false;
00885 
00886         rakFree_Ex(data,__FILE__,__LINE__);
00887 
00888         return 0;
00889 }
00890 void RemoteClient::SetActive(bool a)
00891 {
00892         isActive=a;
00893         Reset();
00894         if (isActive==false && socket!=INVALID_SOCKET)
00895         {
00896                 closesocket(socket);
00897                 socket=INVALID_SOCKET;
00898         }
00899 }
00900 void RemoteClient::SendOrBuffer(const char **data, const unsigned int *lengths, const int numParameters)
00901 {
00902         // True can save memory and buffer copies, but gives worse performance overall
00903         // Do not use true for the XBOX, as it just locks up
00904         const bool ALLOW_SEND_FROM_USER_THREAD=false;
00905 
00906         int parameterIndex;
00907         if (isActive==false)
00908                 return;
00909         parameterIndex=0;
00910         for (; parameterIndex < numParameters; parameterIndex++)
00911         {
00912                 outgoingDataMutex.Lock();
00913                 if (ALLOW_SEND_FROM_USER_THREAD && outgoingData.GetBytesWritten()==0)
00914                 {
00915                         outgoingDataMutex.Unlock();
00916                         int bytesSent = Send(data[parameterIndex],lengths[parameterIndex]);
00917                         if (bytesSent<(int) lengths[parameterIndex])
00918                         {
00919                                 // Push remainder
00920                                 outgoingDataMutex.Lock();
00921                                 outgoingData.WriteBytes(data[parameterIndex]+bytesSent,lengths[parameterIndex]-bytesSent,__FILE__,__LINE__);
00922                                 outgoingDataMutex.Unlock();
00923                         }
00924                 }
00925                 else
00926                 {
00927                         outgoingData.WriteBytes(data[parameterIndex],lengths[parameterIndex],__FILE__,__LINE__);
00928                         outgoingDataMutex.Unlock();
00929                 }
00930         }
00931 }
00932 #if defined(OPEN_SSL_CLIENT_SUPPORT)
00933 void RemoteClient::InitSSL(SSL_CTX* ctx, SSL_METHOD *meth)
00934 {
00935         (void) meth;
00936 
00937         ssl = SSL_new (ctx);                         
00938         RakAssert(ssl);    
00939         SSL_set_fd (ssl, socket);
00940         SSL_connect (ssl);
00941 }
00942 void RemoteClient::DisconnectSSL(void)
00943 {
00944         if (ssl)
00945                 SSL_shutdown (ssl);  /* send SSL/TLS close_notify */
00946 }
00947 void RemoteClient::FreeSSL(void)
00948 {
00949         if (ssl)
00950                 SSL_free (ssl);
00951 }
00952 int RemoteClient::Send(const char *data, unsigned int length)
00953 {
00954         int err;
00955         if (ssl)
00956         {
00957                 err = SSL_write (ssl, data, length);
00958                 RakAssert(err>0);
00959                 return 0;
00960         }
00961         else
00962                 return send(socket, data, length, 0);
00963 }
00964 int RemoteClient::Recv(char *data, const int dataSize)
00965 {
00966         if (ssl)
00967                 return SSL_read (ssl, data, dataSize);
00968         else
00969                 return recv(socket, data, dataSize, 0);
00970 }
00971 #else
00972 int RemoteClient::Send(const char *data, unsigned int length)
00973 {
00974         return send(socket, data, length, 0);
00975 }
00976 int RemoteClient::Recv(char *data, const int dataSize)
00977 {
00978         return recv(socket, data, dataSize, 0);
00979 }
00980 #endif
00981 
00982 #ifdef _MSC_VER
00983 #pragma warning( pop )
00984 #endif
00985 
00986 #endif // _RAKNET_SUPPORT_*

Generated on Thu Sep 30 2010 01:27:28 for RakNet by  doxygen 1.7.1