Exemplo n.º 1
0
/*!
  Sends to connected \a socket any packet writes still in buffer. This method
  is usually called prior to disconnection to ensure all data, including error
  messages have been sent.
*/
void cAsyncNetIO::flush( QSocketDevice* socket )
{
	iterator it = buffers.find( socket );

	if ( it != buffers.end() )
		flushWriteBuffer( it.data() );
}
Exemplo n.º 2
0
//****************************************************************************************************
void writebuffer_t::issueWrites(){
  //We issue writes from the WB only if the MSHR does NOT contain any LD entries - MSHR LDs
  //   have priority over us (note that the MSHR does NOT count Ifetch entries!)
  if(m_use_write_buffer){
    ASSERT(m_id < system_t::inst->m_numSMTProcs);
    int mshr_entry_count = system_t::inst->m_seq[m_id]->getRubyCache()->getMSHRcount();
    if(mshr_entry_count == 0){
      flushWriteBuffer();
    }
  }
}
Exemplo n.º 3
0
//***************************************************************************************************
void writebuffer_t::Wakeup( void )
{
  #ifdef DEBUG_WRITE_BUFFER
      DEBUG_OUT("\n****writebuffer_t: Wakeup CALLED cycle[%d]!\n",m_event_queue->getCycle());
      print();
  #endif

  //reset is scheduled flag
  m_is_scheduled = false;
  //  DEBUG_OUT("***Wakeup called cycle[%d]\n",m_event_queue->getCycle());
  flushWriteBuffer();
  return;  
}
Exemplo n.º 4
0
/*!
  \internal
  The thread's execution loop for AsyncNetIO
*/
void cAsyncNetIO::run() throw()
{
	while ( !canceled() )
	{
		mapsMutex.lock(); // do not disturb me here.
		for ( const_iterator it( buffers.begin() ); it != buffers.end(); ++it )
		{
			// Read all avaliable data.
			char buf[4096];
			cAsyncNetIOPrivate* d = it.data();

			// Check if the socket is valid
			if ( !d->socket->isValid() )
				continue; // Let it in the queue until it's taken out by the closed-collector

			// Try to get the UO Header somehow
			if ( !d->skippedUOHeader )
			{
				int nread = d->socket->readBlock( buf, 4 - d->rsize );

				if ( nread > 0 )
				{
					QByteArray* a = new QByteArray( nread );
					memcpy( a->data(), buf, nread );
					d->rba.append( a );
					d->rsize += nread;

					if ( d->rsize == 4 )
					{
						char temp[4];
						d->consumeReadBuf( 4, temp );
						d->skippedUOHeader = true;

						d->seed = ( ( temp[0] & 0xFF ) << 24 ) | ( ( temp[1] & 0xFF ) << 16 ) | ( ( temp[2] & 0xFF ) << 8 ) | ( ( temp[3] & 0xFF ) );

						// Only 0xFFFFFFFF seed allowed for !d->login
						if ( !d->login && d->seed != 0xFFFFFFFF )
						{
							d->writeBlock( "\x82\x04", 2 );
							flushWriteBuffer( d );
							d->socket->close();
							continue;
						}
					}
				}
				else if ( nread == 0 )
				{
					d->socket->close();
				}
			}
			else
			{
				int nread = d->socket->readBlock( buf, sizeof( buf ) );

				if ( nread > 0 )
				{
					// If we have an encryption object already
					// then decrypt the buffer before storing it
					if ( d->encryption )
						d->encryption->clientDecrypt( &buf[0], nread );

					QByteArray* a = new QByteArray( nread );
					memcpy( a->data(), buf, nread );
					d->rba.append( a );
					d->rsize += nread;

					// We need to use the read buffer as a temporary buffer
					// for encrypted data if we didn't receive all we need
					if ( !d->encryption )
					{
						// Gameserver Encryption
						if ( !d->login && d->rsize >= 65 )
						{
							// The 0x91 packet is 65 byte
							nread = d->rsize;
							d->consumeReadBuf( d->rsize, &buf[0] );

							// This should be no encryption
							if ( buf[0] == '\x91' && buf[1] == '\xFF' && buf[2] == '\xFF' && buf[3] == '\xFF' && buf[4] == '\xFF' )
							{
								// Is no Encryption allowed?
								if ( !Config::instance()->allowUnencryptedClients() )
								{
									// Send a communication problem message to this socket
									d->writeBlock( "\x82\x04", 2 );
									flushWriteBuffer( d );
									d->socket->close();
									continue;
								}

								d->encryption = new cNoEncryption;
							}
							else
							{
								cGameEncryption* crypt = new cGameEncryption;
								crypt->init( 0xFFFFFFFF ); // Seed is fixed anyway
								d->encryption = crypt;
							}
						} // LoginServer Encryption
						else if ( d->login && d->rsize >= 62 )
						{
							// The 0x80 packet is 62 byte, but we want to have everything
							nread = d->rsize;
							d->consumeReadBuf( d->rsize, &buf[0] );

							// Check if it could be *not* encrypted
							if ( buf[0] == '\x80' && buf[30] == '\x00' && buf[60] == '\x00' )
							{
								// Is no Encryption allowed?
								if ( !Config::instance()->allowUnencryptedClients() )
								{
									// Send a communication problem message to this socket
									d->writeBlock( "\x82\x04", 2 );
									flushWriteBuffer( d );
									d->socket->close();
									continue;
								}

								d->encryption = new cNoEncryption;
							}
							else
							{
								cLoginEncryption* crypt = new cLoginEncryption;
								if ( !crypt->init( d->seed, &buf[0], nread ) )
								{
									delete crypt;

									// Send a communication problem message to this socket
									d->writeBlock( "\x82\x04", 2 );
									flushWriteBuffer( d );
									d->socket->close();
									continue;
								}

								d->encryption = crypt;
							}

							// It gets a bit tricky now, try to decode it with all
							// possible keys
						}

						// If we found an encryption let's decrypt what we got in our buffer
						if ( d->encryption )
						{
							d->encryption->clientDecrypt( &buf[0], nread );

							QByteArray* a = new QByteArray( nread );
							memcpy( a->data(), buf, nread );
							d->rba.append( a );
							d->rsize += nread;
						}
					}
				}
				else if ( nread == 0 )
				{
					d->socket->close();
				}

				buildUOPackets( d );
			}

			// Write data to socket
			flushWriteBuffer( d );
		}
		mapsMutex.unlock();
		//if( buffers.empty() )
		// Disconnecting doesnt work for now
		waitCondition.wait( 40 ); // let's rest for a while
	}
}