Esempio n. 1
0
	protected bool Send( int connectionId, byte[] key, InternalMessage message, ChannelIndex channel, BitWriter writer, bool sendImmediately, out string error )
	{
		MessageSecurity security = AlpacaConstant.GetSecurity( channel );
		if( !WrapMessage( message, security, writer, key, out error ) )
		{
			return false;
		}

		//_profiler.StartEvent(TickType.Send, (uint)stream.Length, channelName, AlpacaConstant.INTERNAL_MESSAGE_NAME[messageType]);
		DataStream s = writer.GetStream();		
		byte errorAsByte;
		if( sendImmediately )
		{
			NetworkTransport.Send                  ( 0, connectionId, channel.GetIndex(), s.GetBuffer(), s.GetByteLength(), out errorAsByte);
		}
		else
		{
			NetworkTransport.QueueMessageForSending( 0, connectionId, channel.GetIndex(), s.GetBuffer(), s.GetByteLength(), out errorAsByte);
		}
		//_profiler.EndEvent();

		if( (NetworkError)errorAsByte != NetworkError.Ok )
		{
			error = $"Send {AlpacaConstant.GetName(message)} to node {connectionId} failed with error{StringFromError(errorAsByte)}";
			return false;
		}

		return true;
	}
Esempio n. 2
0
	protected bool WrapMessage( InternalMessage message, MessageSecurity security, BitWriter writer, byte[] key, out string error )
	{
		if( !_commonSettings.enableEncryption && security != MessageSecurity.None )
		{
			error = "Attempted to send encrypted and/or authenticated message but encryption was not enabled";
			return false;
		}

		bool authenticated = ((security & MessageSecurity.Authenticated) != 0);
		bool encrypted     = ((security & MessageSecurity.Encrypted    ) != 0);
		
		if( authenticated || encrypted )
		{
			Debug.Assert( false );
			// TODO: handle encryption and authentication here
			error = "WrapMessage: tried to apply encryption, but it was not enabled.";
			return false;
		}

		DataStream writerStream = writer.GetStream();
		int lastBytePos = writerStream.GetBytePosition();
		
		
		// reset write head to write authentication and encryption bits
		writer.Normal(authenticated);
		writer.Normal(encrypted);
		writerStream.SetBytePosition( lastBytePos );
		byte messageByte = (byte)(((int)message) << 2);
		writer.Normal<byte>( messageByte );
		error = null;
		return true;
	}
	bool Send( NodeIndex client, InternalMessage message, ChannelIndex channel, BitWriter writer, bool sendImmediately, out string error )
	{
		int clientIndex = client.GetClientIndex();	
		byte[] key = _connection.GetAt(clientIndex-1).GetSharedSecretKey();
		// for the server, connectionId == clientIndex
		return base.Send( clientIndex, key, message, channel, writer, sendImmediately, out error );
	}
Esempio n. 4
0
	// Extracts body of message, which could include decrypting and/or authentication.
	protected InternalMessage UnwrapMessage( BitReader reader, NodeIndex client )
	{
		DataStream readerStream = reader.GetStream();
		int byteLength = readerStream.GetByteLength();
		Log.Info( $"Unwrapping incoming message from {client} : {byteLength} bytes" );

		if( byteLength < 1 )
		{
			Log.Error( $"The incoming message from {client} was too small" );
			return InternalMessage.INVALID;
		}

		// The last byte of the wrapped message is:
		// 2 bits indicating encryption and authentication, followed by
		// 6 bits containing the packed message type byte.
		// TODO: Security: This means the message type is outside encryption,
		//       which enables an attacker to get some info. Does this matter enough?
		int messageBodyStart = readerStream.GetBytePosition();
		readerStream.SetBytePosition( byteLength - 1 );
		bool isAuthenticated = reader.Normal<bool>(); 
		bool isEncrypted     = reader.Normal<bool>();
		// reset the read head so that we can read the message byte
		readerStream.SetBytePosition( byteLength - 1 ); 
		byte messageByte = reader.Normal<byte>();
		InternalMessage message = (InternalMessage)((int)messageByte >> 2);
		readerStream.SetBytePosition( messageBodyStart );
	
		if( isEncrypted || isAuthenticated )
		{
			if( !_commonSettings.enableEncryption )
			{
				Log.Error( "Got a encrypted and/or authenticated message but encryption was not enabled" );
				return InternalMessage.INVALID;
			}

			if( isAuthenticated )
			{
				if( !CheckAuthentication( reader, client ) )
				{
					return InternalMessage.INVALID;
				}
			}

			if( isEncrypted )
			{
				if( !PerformDecryption( reader, client ) )
				{
					return InternalMessage.INVALID;
				}
			}
		}
		
		return message;
	}
Esempio n. 5
0
	void HandleMessage( BitReader reader, ChannelIndex channel )
	{
		InternalMessage messageType = UnwrapMessage( reader, NodeIndex.SERVER_NODE_INDEX );
		if( messageType == InternalMessage.INVALID ) { return; }

		//_profiler.StartEvent(TickType.Receive, size, channelId, messageType);

		Log.Info( $"Handling message {AlpacaConstant.GetName(messageType)} from server" );

		if( (_status == Status.WaitingForChallenge) && (messageType != InternalMessage.ConnectionChallenge) )
		{
			Log.Error( $"We are waiting for challenge, but server sent message {AlpacaConstant.GetName(messageType)} instead." );
			return;
		}

		if( (_status == Status.WaitingForConnectionApproval) && (messageType != InternalMessage.ConnectionApproved ) )
		{
			Log.Error( $"We are waiting for connection approval, but server sent message {AlpacaConstant.GetName(messageType)} instead." );
			return;
		}

		switch( messageType )
		{
			case InternalMessage.ConnectionChallenge:
				// TODO: cozeroff crypto implementation
				Log.Error( "Crypto not implemented yet!" );
				break;
			case InternalMessage.ConnectionApproved:
				OnMessageConnectionApproved( reader );
				break;

			// TODO: cozeroff handle sibling connect/disconnect

			case InternalMessage.EntityCreate:
				OnEntityCreate( reader );
				break;
			
			case InternalMessage.CustomClient:
				OnMessageCustomClient( reader );
				break;
			default:
				Log.Error( $"Read unrecognized messageType{AlpacaConstant.GetName(messageType)}" );
				break;
		}

		//_profiler.EndEvent();
	}
	void HandleMessage( BitReader reader, NodeIndex client, ChannelIndex channel )
	{
		InternalMessage messageType = UnwrapMessage( reader, client );
		if( messageType == InternalMessage.INVALID ) { return; }

		//_profiler.StartEvent(TickType.Receive, size, channelId, messageType);

		Log.Info( $"Handling message {AlpacaConstant.GetName(messageType)} from client {client.GetClientIndex()}" );

		ClientConnection connection = _connection.GetAt( client.GetClientIndex() - 1 );
		ClientConnection.Status state = connection.GetState();
		
		if( (state == ClientConnection.Status.PendingConnectionChallengeResponse) && (messageType != InternalMessage.ConnectionResponse ) )
		{
			Log.Error( $"Client {client.GetClientIndex()} is pending connection response, but client sent message {AlpacaConstant.GetName(messageType)} instead." );
			return;
		}

		if( (state == ClientConnection.Status.PendingConnectionRequest) && (messageType != InternalMessage.ConnectionRequest) )
		{
			Log.Error( $"Client {client.GetClientIndex()} is pending connection request, but client sent message {AlpacaConstant.GetName(messageType)} instead." );
			return;
		}

		switch( messageType )
		{
			case InternalMessage.ConnectionRequest:
				OnMessageConnectionRequest( client, reader );
				break;
			case InternalMessage.ConnectionResponse:
				// TODO: cozeroff crypto implementation
				Log.Error( "Crypto not implemented yet!" );
				break;
			case InternalMessage.CustomServer:
				OnMessageCustomServer( client, reader );
				break;
			default:
				Log.Error( $"Read unrecognized messageType{AlpacaConstant.GetName(messageType)}" );
				break;
		}

		//_profiler.EndEvent();
	}
Esempio n. 7
0
 public void Read(BitReader reader)
 {
     _byteCount = reader.Packed <UInt32>();
     _channel.Read(reader);
     _message = (InternalMessage)reader.Packed <UInt32>();
 }
Esempio n. 8
0
 public TickEvent(UInt32 byteCount, ChannelIndex channel, InternalMessage message)
 {
     _byteCount = byteCount;
     _channel   = channel;
     _message   = message;
 }
Esempio n. 9
0
 public void RecordEvent(UInt32 byteCount, ChannelIndex channel, InternalMessage message)
 {
     _events.Add(new TickEvent(byteCount, channel, message));
     _totalByteCount += byteCount;
 }
Esempio n. 10
0
	bool Send( InternalMessage message, ChannelIndex channel, BitWriter writer, bool sendImmediately, out string error )
	{
		// for the client, connectionId == 1 always (server)
		return base.Send( 1, _serverKey, message, channel, writer, sendImmediately, out error );
	}
Esempio n. 11
0
	// PRIVATE

	// sends an internal message to the server (Alpaca layer)
	bool SendInternal( InternalMessage message, InternalChannel channel, BitWriter writer, bool sendImmediately, out string error )
	{
		return Send( message, ChannelIndex.CreateInternal(channel), writer, sendImmediately, out error );
	}