// Handle all our clients void CServerSocket::HandleClients( fd_set* fds ) { for(UINT i=0;i<ClientList.size( );i++) { CClientSocket* client = ClientList.at( i ); if(!client->isActive) continue; if(FD_ISSET( client->sock, fds )) { if (client->isserver == true) { //Log( MSG_INFO,"ISC PACKET"); if(!client->ISCThread()){ client->isActive = false; DisconnectClient( client );} } else if(!client->ReceiveData( ) ) { client->isActive = false; DisconnectClient( client ); } } } }
// check for a client disconnect ---------------------------------------------- // int E_ConnManager::CheckClientDisconnect( node_t* clientnode ) { ASSERT( clientnode != NULL ); // find the slot int nClientID = _FindSlotWithNode( clientnode ); // we could find the slot if( nClientID != -1 ) { // send the response ThePacketHandler->SendDisconnectResponse( DISC_OK, clientnode, nClientID ); // disconnect the client in the slot ( must be done after the packets have been sent ) DisconnectClient( nClientID ); // disconnect was OK return TRUE; } else { // client was not found ThePacketHandler->SendDisconnectResponse( DISC_NOT_CONNECTED, clientnode, PLAYERID_ANONYMOUS ); return FALSE; } }
// ensure a client is not connected ------------------------------------------- // int E_ConnManager::_EnsureClientIsDisconnected( E_ClientConnectInfo* pClientConnectInfo ) { ASSERT( pClientConnectInfo != NULL ); ASSERT( pClientConnectInfo->m_szHostName != NULL ); ASSERT( &pClientConnectInfo->m_node != NULL ); ASSERT( pClientConnectInfo->m_szName != NULL ); ASSERT( pClientConnectInfo->m_szOSLine != NULL ); // check for duplicate connects from same node for( int nSlot = 0; nSlot < MAX_NUM_CLIENTS; nSlot++ ) { E_ClientInfo* pClientInfo = &m_ClientInfos[ nSlot ]; if ( !pClientInfo->IsSlotFree() ) { if ( NODE_Compare( &pClientInfo->m_node, &pClientConnectInfo->m_node ) == NODECMP_EQUAL ) { MSGOUT( "Removing (possibly) dead client %s", NODE_Print( &pClientConnectInfo->m_node ) ); // disconnect the client DisconnectClient( nSlot ); } } } return TRUE; }
//============================================================================ // NMessageServer::SocketDidClose : A socket has been closed. //---------------------------------------------------------------------------- void NMessageServer::SocketDidClose(NSocket *theSocket, NStatus theErr) { NSocket *clientSocket; NClientInfoMapIterator theIter; // Stop the server if (theSocket == &mSocket) { // Remove the clients // // Closing the client sockets will cause them to call us back (as we are // the socket delegate), which will cause us to remove them from the client // list). do { // Get the state we need mLock.Lock(); if (mClients.empty()) clientSocket = NULL; else clientSocket = mClients.begin()->second.theSocket; mLock.Unlock(); // Remove the client if (clientSocket != NULL) clientSocket->Close(); } while (clientSocket != NULL); // Stop the server mStatus = kNServerStopped; ServerStopped(theErr); } // Remove a client // // The client may not have been accepted by the server, so we may not actually // find its socket in the client list. Clients which never reached the connected // state can just be ignored when their socket is closed. else { mLock.Lock(); for (theIter = mClients.begin(); theIter != mClients.end(); theIter++) { if (theIter->second.theSocket == theSocket) { DisconnectClient(theIter->first); break; } } mLock.Unlock(); } }
void CLearnWorldServerDlg::OnSysCommand(UINT nID, LPARAM lParam) { if (nID == SC_CLOSE) { DisconnectClient(); } CDialogEx::OnSysCommand(nID, lParam); }
void CLearnWorldServerDlg::OnBnClickedDisconnect() { // TODO: Add your control notification handler code here int check; check = MessageBox(L"Are you sure you want to disconnect Server ?\nThis will cause ALL clients lose connection to server", L"Warning", MB_YESNO); if (check == IDYES) DisconnectClient(); }
void SecureChatIOCP::NotifyWriteCompleted(ClientContext *pContext, DWORD dwIoSize, CIOCPBuffer *pOverlapBuff) { // The pOverlapBuff Buffer are Successfully sended. // If we sended an error message Kill the connection if ( pContext && pOverlapBuff->GetPackageType()== PKG_ERRORMSG ) { DisconnectClient(pContext->m_Socket); } }
void ConnectionManager::Listen() { if (!initialized_) { throw NetworkException("ConnectionManager not initialized"); } if (listen(listen_socket_, 10) == -1) { throw NetworkException("Error listening"); } fd_set read_fd = clients_; if (select(last_client_+1, &read_fd, NULL, NULL, NULL) == -1) { throw NetworkException("Error in select()"); } for (int i = 0; i <= last_client_; i++) { if (FD_ISSET(i, &read_fd)) { if (i == listen_socket_) { // new client struct sockaddr_in client_address; memset(&client_address, 0, sizeof(client_address)); socklen_t address_length = sizeof(client_address); int new_fd = accept(listen_socket_, (struct sockaddr*)&client_address, &address_length); if (new_fd != -1) { HandleNewClient(new_fd); std::cout << ", from " << inet_ntoa(client_address.sin_addr) << std::endl; } } else { // client sending data uint16_t msg_len; int rec_len = recv(i, &msg_len, sizeof(msg_len), 0); if (rec_len <= 0) { DisconnectClient(i); } else { msg_len = ntohs(msg_len); char buffer[msg_len+1]; memset(buffer, 0, sizeof(buffer)); uint16_t rec = 0; // already received length while (msg_len > 0) { // getting the whole message rec_len = recv(i, buffer+rec, msg_len, 0); rec += rec_len; msg_len -= rec_len; } std::string str_buffer(buffer); Message *msg = new Message(str_buffer); inc_msg_->push(msg); } } } } }
void SocketClass :: ShutdownServer(void) { DisconnectClient(); if(ListenSocket != Invalid_Socket) { disconnecting = true; shutdown(ListenSocket, SHUTDOWN_PARAM); CLOSE_SOCKET(ListenSocket); ListenSocket = Invalid_Socket; } }
// Fills out an FDS for the server void CServerSocket::FillFDS( fd_set* fds ) { for(UINT i=0;i<ClientList.size( );i++) { CClientSocket* client = ClientList.at( i ); if(client->isActive) { FD_SET( (unsigned)client->sock, fds ); if(client->sock>maxfd) maxfd=client->sock; } else { DisconnectClient( client ); } } }
/* * Send a "Start the file transfer package" to the remote connection. * * */ BOOL MyIOCP::BuildStartFileTransferPackageAndSend(ClientContext *pContext) { CIOCPBuffer *pOverlapBuff=AllocateBuffer(IOWrite); if(pOverlapBuff) { if(pOverlapBuff->CreatePackage(Job_StartFileTransfer)) return ASend(pContext,pOverlapBuff); }else { CString msg; msg.Format(_T("Could not allocate memory ASend: %s"),ErrorCode2Text(WSAGetLastError())); AppendLog(msg); DisconnectClient(pContext->m_Socket); return FALSE; } return TRUE; }
//============================================================================ // NMessageServer::ReceivedMessage : The server received a message. //---------------------------------------------------------------------------- void NMessageServer::ReceivedMessage(const NNetworkMessage &theMsg) { // Validate our parameters NN_ASSERT( theMsg.GetDestination() == GetID() || theMsg.GetDestination() == kNEntityEveryone); // Handle the message switch (theMsg.GetType()) { case kNMessageDisconnectedMsg: if (theMsg.GetSource() != GetID()) DisconnectClient(theMsg.GetSource()); break; default: break; } }
// check the alive counter of all connected clients and disconnect any timed out clients // int E_ConnManager::CheckAliveStatus() { for( int nClientID = 0; nClientID < MAX_NUM_CLIENTS; nClientID++ ) { E_ClientInfo* pClientInfo = &m_ClientInfos[ nClientID ]; if ( !pClientInfo->IsSlotFree() ) { // check for client timeout if ( !pClientInfo->IsAlive() ) { MSGOUT( "force-removing timed-out client %s (name: %s)\n", NODE_Print( &pClientInfo->m_node ), pClientInfo->m_szName ); // send the response ThePacketHandler->SendDisconnectResponse( DISC_OK, &pClientInfo->m_node, nClientID ); // and disconnect the client DisconnectClient( nClientID ); } } } return TRUE; }
void Messenger::Receive() { Message msg; SocketMessage m; // We start by copying the master file descriptors list to the // temporary list for readout fReadFds = fMaster; try { SelectConnections(); } catch (Exception& e) { e.Dump(); throw Exception(__PRETTY_FUNCTION__, "Impossible to select the connections!", Fatal); } // Looking for something to read! for (SocketCollection::const_iterator s=fSocketsConnected.begin(); s!=fSocketsConnected.end(); s++) { if (!FD_ISSET(s->first, &fReadFds)) continue; // First check if we need to handle new connections if (s->first==GetSocketId()) { AddClient(); return; } // Handle data from a client try { msg = FetchMessage(s->first); } catch (Exception& e) { //std::cout << "exception found..." << e.OneLine() << ", "<< e.ErrorNumber() << std::endl; e.Dump(); if (e.ErrorNumber()==11000) { DisconnectClient(s->first, THIS_CLIENT_DELETED); return; } } m = SocketMessage(msg.GetString()); // Message was successfully decoded fNumAttempts = 0; try { ProcessMessage(m, s->first); } catch (Exception& e) { if (e.ErrorNumber()==11001) break; } } }
// Build the a text message message and send it.. BOOL MyIOCP::BuildPackageAndSend(ClientContext *pContext, CString sText) { CIOCPBuffer *pOverlapBuff=AllocateBuffer(IOWrite); if(pOverlapBuff) { if(pOverlapBuff->CreatePackage(Job_SendText2Client,sText)) return ASend(pContext,pOverlapBuff); else { AppendLog(_T("CreatePackage(0,sText) Failed in BuildPackageAndSend")); ReleaseBuffer(pOverlapBuff); return FALSE; } }else { CString msg; msg.Format(_T("Could not allocate memory ASend: %s"),ErrorCode2Text(WSAGetLastError())); AppendLog(msg); DisconnectClient(pContext->m_Socket); return FALSE; } return FALSE; }
CIOCPBuffer *SecureChatIOCP::EnCryptBuffer(CIOCPBuffer *pBuff, ClientContext *pContext) { if ( pBuff==NULL || pContext==NULL ) { ReleaseBuffer(pBuff); return NULL; } if ( !pContext->m_bGotSessionKey) { ReleaseBuffer(pBuff); return NULL; } CIOCPBuffer *pCrypBuff=NULL; // // Allocate Buffer for the encrypted pkg. // pCrypBuff=AllocateBuffer(IOWrite); if ( pCrypBuff!=NULL ) { // // Compute CRC16 // unsigned short usCRC16; pContext->m_cCryptor.crc16_init(&usCRC16); pContext->m_cCryptor.crc16_update(&usCRC16,pBuff->GetBuffer(),pBuff->GetUsed()); pContext->m_cCryptor.crc16_final(&usCRC16); // // Add the CRC16 to the Buffer // if ( !pBuff->AddData(usCRC16) ) { AppendLog("Error pBuff->AddData(usCRC16) in EnCryptBuffer"); DisconnectClient(pContext->m_Socket); ReleaseBuffer(pCrypBuff); } // // Check if The Buffer size is a multiple of the blocksize, if not // add some random nr. // int iBlockSize=16; int iBufferRest=0; UINT iBufferLenght=0; iBufferLenght=pBuff->GetUsed(); iBufferRest=iBufferLenght%iBlockSize; // How Much is needed to make the buffersize to be a multible of the block size? if ( iBufferRest!=0 ) { iBufferRest=iBlockSize-iBufferRest; } // add random Numbers at the end so we will have an cryptable buffer. for ( int i=0; i<iBufferRest; i++ ) { if ( !pBuff->AddData((BYTE)(rand()%255)) ) { AppendLog("Error pBuff->AddData((BYTE)(rand()%255) in EnCryptBuffer"); DisconnectClient(pContext->m_Socket); ReleaseBuffer(pCrypBuff); } } // We have a new length. iBufferLenght=pBuff->GetUsed(); // For the package type. iBufferLenght++; // // Configure the new package. // if ( iBufferLenght+MINIMUMPACKAGESIZE>MAXIMUMPACKAGESIZE ) { AppendLog("Error package to big to fit in the buffer"); DisconnectClient(pContext->m_Socket); ReleaseBuffer(pCrypBuff); } // Add the size of the buffer to the beging.We will not crypt this part. pCrypBuff->AddData(iBufferLenght); // Add the Type. pCrypBuff->AddData((BYTE)PKG_ENCRYPTED); // // Encrypt and add to payload. // try { pContext->m_ContextLock.Lock(); pContext->m_cCryptor.ResetChain(); // Because of CBC pContext->m_cCryptor.Encrypt((char const*)pBuff->GetBuffer(),(char*)pCrypBuff->GetBuffer()+MINIMUMPACKAGESIZE+1,iBufferLenght-1,1); pContext->m_ContextLock.Unlock(); } catch(exception& roException) { AppendLog("Error Could not encrypt in EnCryptBuffer"); DisconnectClient(pContext->m_Socket); ReleaseBuffer(pCrypBuff); pContext->m_ContextLock.Unlock(); pCrypBuff=NULL; return NULL; } // add the payload. pCrypBuff->Use(pBuff->GetUsed()); ReleaseBuffer(pBuff); // // Finished... // }else { AppendLog("Error Could not allocate memory in EnCryptBuffer"); } return pCrypBuff; }
void Messenger::ProcessMessage(SocketMessage m, int sid) { if (m.GetKey()==REMOVE_CLIENT) { if (m.GetIntValue()==GetSocketId()) { std::ostringstream o; o << "Some client (id=" << sid << ") asked for this master's disconnection!" << "\n\tIgnoring this request..."; throw Exception(__PRETTY_FUNCTION__, o.str(), JustWarning); return; } const MessageKey key = (sid==m.GetIntValue()) ? THIS_CLIENT_DELETED : OTHER_CLIENT_DELETED; DisconnectClient(m.GetIntValue(), key); throw Exception(__PRETTY_FUNCTION__, "Removing socket client", Info, 11001); } else if (m.GetKey()==PING_CLIENT) { const int toping = m.GetIntValue(); Send(SocketMessage(PING_CLIENT), toping); SocketMessage msg; int i=0; do { msg = FetchMessage(toping); i++; } while (msg.GetKey()!=PING_ANSWER && i<MAX_SOCKET_ATTEMPTS); try { Send(SocketMessage(PING_ANSWER, msg.GetValue()), sid); } catch (Exception& e) { e.Dump(); } } else if (m.GetKey()==GET_CLIENTS) { int i = 0; std::ostringstream os; for (SocketCollection::const_iterator it=fSocketsConnected.begin(); it!=fSocketsConnected.end(); it++, i++) { if (i!=0) os << ";"; os << it->first << " (type " << static_cast<int>(it->second) << ")"; } try { Send(SocketMessage(CLIENTS_LIST, os.str()), sid); } catch (Exception& e) { e.Dump(); } } else if (m.GetKey()==WEB_GET_CLIENTS) { int i = 0; SocketType type; std::ostringstream os; for (SocketCollection::const_iterator it=fSocketsConnected.begin(); it!=fSocketsConnected.end(); it++, i++) { type = (it->first==GetSocketId()) ? MASTER : it->second; if (i!=0) os << ";"; os << it->first << ","; if (it->first==GetSocketId()) os << "Master,"; else os << "Client" << it->first << ","; os << static_cast<int>(type) << "\0"; } try { Send(SocketMessage(CLIENTS_LIST, os.str()), sid); } catch (Exception& e) { e.Dump(); } } else if (m.GetKey()==START_ACQUISITION) { try { StartAcquisition(); } catch (Exception& e) { e.Dump(); SendAll(DAQ, e); } } else if (m.GetKey()==STOP_ACQUISITION) { try { StopAcquisition(); } catch (Exception& e) { e.Dump(); SendAll(DAQ, e); } } else if (m.GetKey()==NEW_RUN) { try { OnlineDBHandler().NewRun(); int last_run = OnlineDBHandler().GetLastRun(); SendAll(DQM, SocketMessage(RUN_NUMBER, last_run)); SendAll(DAQ, SocketMessage(RUN_NUMBER, last_run)); } catch (Exception& e) { e.Dump(); } } else if (m.GetKey()==GET_RUN_NUMBER) { int last_run = 0; try { last_run = OnlineDBHandler().GetLastRun(); } catch (Exception& e) { last_run = -1; } try { Send(SocketMessage(RUN_NUMBER, last_run), sid); } catch (Exception& e) { e.Dump(); } } else if (m.GetKey()==SET_NEW_FILENAME) { try { std::cout << "---> " << m.GetValue() << std::endl; SendAll(DQM, SocketMessage(NEW_FILENAME, m.GetValue().c_str())); } catch (Exception& e) { e.Dump(); } } else if (m.GetKey()==NUM_TRIGGERS or m.GetKey()==HV_STATUS) { try { SendAll(DAQ, m); } catch (Exception& e) { e.Dump(); } } else if (m.GetKey()==NEW_DQM_PLOT or m.GetKey()==UPDATED_DQM_PLOT) { try { SendAll(DAQ, m); } catch (Exception& e) { e.Dump(); } } else if (m.GetKey()==EXCEPTION) { try { SendAll(DAQ, m); std::cout << "--> " << m.GetValue() << std::endl; } catch (Exception& e) { e.Dump(); } } /*else { try { Send(SocketMessage(INVALID_KEY), sid); } catch (Exception& e) { e.Dump(); } std::ostringstream o; o << "Received an invalid message: " << m.GetString(); throw Exception(__PRETTY_FUNCTION__, o.str(), JustWarning); }*/ }
void SecureChatIOCP::NotifyReceivedPackage(CIOCPBuffer *pOverlapBuff,int nSize,ClientContext *pContext) { // No Context? Why do the work ? if ( pContext==NULL ) { AppendLog("pContext==NULL) in NotifyReceivedPackage"); return; } // No Connection ?? Why do the work ? if ( pContext->m_Socket==INVALID_SOCKET ) { //AppendLog("pContext->m_Socket==INVALID_SOCKET in NotifyReceivedPackage"); return; } BYTE PackageType=pOverlapBuff->GetPackageType(); switch (PackageType) { case PKG_ERRORMSG: OnPKG_ERRORMSG(pOverlapBuff,nSize,pContext); break; case PKG_ENCRYPTED: { //pContext->m_bGotSessionKey=FALSE; if(! pContext->m_bGotSessionKey ) { SendErrorMessageTo(pContext->m_Socket,"Server> Session key Not available, you are not authorized"); CString msg; msg.Format("Client %x (%s) not Authorized",pContext->m_Socket,GetHostAddress(pContext->m_Socket)); AppendLog(msg); break; } CIOCPBuffer *pDecryptedPKG=DeCryptBuffer(pOverlapBuff,pContext); if ( !pDecryptedPKG ) { AppendLog("SECURITY RISK: Warning could not decrypt the clients message.. The remote client may be try to hack your system."); DisconnectClient(pContext->m_Socket); }else { // Process it ProcessPayload(pDecryptedPKG,pDecryptedPKG->GetUsed(),pContext); } if ( pDecryptedPKG ) ReleaseBuffer(pDecryptedPKG); break; } #ifdef _IOCPClientMode_ // Handle the package sent from server case PKG_PUBLIC_KEYA: OnPKG_PUBLIC_KEYA(pOverlapBuff,nSize,pContext); break; case PKG_SIGNATURE: OnPKG_SIGNATURE(pOverlapBuff,nSize,pContext); break; #else // Handle the package sent from clients. case PKG_PUBLIC_KEYP: OnPKG_PUBLIC_KEYP(pOverlapBuff,nSize,pContext); break; case PKG_PUBLIC_KEYB: OnPKG_PUBLIC_KEYB(pOverlapBuff,nSize,pContext); break; #endif }; }
//--------------------------------------------------------------------------------------- void tThreadClient::OnDisconnectClient(const int _handle) { emit DisconnectClient(_handle); }
inline void SecureChatIOCP::OnPKG_PUBLIC_KEYP(CIOCPBuffer *pOverlapBuff, int nSize, ClientContext *pContext) { UINT nKeySize=0; // read the public key from the buffer. DWORD* pKey=ReadPublicKeyFromBuffer(pOverlapBuff,nKeySize,pContext); if ( pKey ) { pContext->m_ContextLock.Lock(); // Make sure that the Public key P is accepted for year 2005, _MINPUBLICKEYPSIZE_ = 1024 bits. // FIXME: What if the public key P is not prime ? is the security broken ? UINT nPubKeyBitLength= pContext->m_cCryptLib.BNBitLength(pKey,nKeySize); if ( nPubKeyBitLength < _MINPUBLICKEYPSIZE_) { SendErrorMessageTo(pContext->m_Socket,"Error PKG_PUBLIC_KEYP not accepted!, Size to small Minimum 1024 bits. "); pContext->m_ContextLock.Unlock(); return; } // We must make a copy of the public key P. // FIXME: allocate data on the heap is bad (hmm change later) DWORD* pPublicKeyP=NULL; pPublicKeyP= new DWORD[nKeySize]; if ( pPublicKeyP ) { memcpy(pPublicKeyP,pKey,nKeySize*sizeof(DWORD)); }else { AppendLog("Error pPublicKeyP=NULL, not enough memory"); DisconnectClient(pContext->m_Socket); pContext->m_ContextLock.Unlock(); } // allocate data on the heap is bad (hmm change later) if ( pContext->m_pPublickey ) delete[] pContext->m_pPublickey; pContext->m_pPublickey = pPublicKeyP; // Generate private key.. (just a Random nr) pContext->m_cCryptLib.BNMakeRandomNr(pContext->m_Privatekey,_PRIVATEKEYSIZE_); pContext->m_bGotSessionKey=FALSE; pContext->m_nPublicKeySize=nKeySize; pContext->m_sUsername="******"; // Compute And Send Public Key A. // FIXME : Should post this part into the // IOCP for fair cpu clock distribution. // Takes about ~40ms.. ComputeAndSendPublicKeyA(pContext); pContext->m_ContextLock.Unlock(); } else { AppendLog("OnPKG_PUBLIC_KEYP Failed Package error"); } }