Skip to content

Commit

Permalink
RemotingClient should handle undeserializable remote exceptions.
Browse files Browse the repository at this point in the history
  • Loading branch information
yallie committed Dec 4, 2024
1 parent 449428f commit fb8b97a
Show file tree
Hide file tree
Showing 4 changed files with 50 additions and 19 deletions.
3 changes: 0 additions & 3 deletions CoreRemoting.Tests/Tools/FailingService.cs
Original file line number Diff line number Diff line change
@@ -1,7 +1,4 @@
using System;
using System.Data;
using System.Threading.Tasks;
using CoreRemoting.Tests.ExternalTypes;

namespace CoreRemoting.Tests.Tools;

Expand Down
6 changes: 3 additions & 3 deletions CoreRemoting/Channels/Websocket/WebsocketServerChannel.cs
Original file line number Diff line number Diff line change
Expand Up @@ -14,8 +14,8 @@ public class WebsocketServerChannel : IServerChannel

private IRemotingServer Server { get; set; }

private ConcurrentDictionary<Guid, WebsocketConnection> Connections { get; } =
new ConcurrentDictionary<Guid, WebsocketConnection>();
private ConcurrentDictionary<Guid, WebsocketServerConnection> Connections { get; } =
new ConcurrentDictionary<Guid, WebsocketServerConnection>();

/// <inheritdoc/>
public bool IsListening => HttpListener.IsListening;
Expand Down Expand Up @@ -57,7 +57,7 @@ private async Task ReceiveConnection()
// accept websocket request and start a new session
var websocketContext = await context.AcceptWebSocketAsync(null);
var websocket = websocketContext.WebSocket;
var connection = new WebsocketConnection(websocketContext, websocket, Server);
var connection = new WebsocketServerConnection(websocketContext, websocket, Server);

// handle incoming websocket messages
var sessionId = connection.StartListening();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9,15 +9,15 @@ namespace CoreRemoting.Channels.Websocket;
/// <summary>
/// Websocket connection.
/// </summary>
public class WebsocketConnection : IRawMessageTransport
public class WebsocketServerConnection : IRawMessageTransport
{
// note: LOH threshold is ~85 kilobytes
private const int BufferSize = 16 * 1024;

/// <summary>
/// Initializes a new instance of the <see cref="WebsocketConnection"/> class.
/// Initializes a new instance of the <see cref="WebsocketServerConnection"/> class.
/// </summary>
public WebsocketConnection(HttpListenerWebSocketContext websocketContext, WebSocket websocket, IRemotingServer remotingServer)
public WebsocketServerConnection(HttpListenerWebSocketContext websocketContext, WebSocket websocket, IRemotingServer remotingServer)
{
WebSocketContext = websocketContext ?? throw new ArgumentNullException(nameof(websocketContext));
WebSocket = websocket ?? throw new ArgumentNullException(nameof(websocket));
Expand Down
54 changes: 44 additions & 10 deletions CoreRemoting/RemotingClient.cs
Original file line number Diff line number Diff line change
Expand Up @@ -434,7 +434,7 @@ private void Authenticate()
/// <param name="rawMessage">Raw message data</param>
private void OnMessage(byte[] rawMessage)
{
var message = Serializer.Deserialize<WireMessage>(rawMessage);
var message = TryDeserialize(rawMessage);

switch (message.MessageType.ToLower())
{
Expand All @@ -456,6 +456,29 @@ private void OnMessage(byte[] rawMessage)
case "session_closed":
Disconnect(quiet: true);
break;
default:
// TODO: how do we handle invalid wire messages received by the client?
// A wire message could have been tampered with and couldn't be deserialized
break;
}
}

private WireMessage TryDeserialize(byte[] rawMessage)
{
try
{
return Serializer.Deserialize<WireMessage>(rawMessage);
}
catch // TODO: dispatch message deserialization exception?
{
return new WireMessage
{
Data = rawMessage,
Error = true,
Iv = Array.Empty<byte>(),
MessageType = "invalid",
UniqueCallKey = Array.Empty<byte>(),
};
}
}

Expand Down Expand Up @@ -585,16 +608,27 @@ private void ProcessRpcResultMessage(WireMessage message)

if (message.Error)
{
var remoteException =
Serializer.Deserialize<RemoteInvocationException>(
MessageEncryptionManager.GetDecryptedMessageData(
message: message,
serializer: Serializer,
sharedSecret: sharedSecret,
sendersPublicKeyBlob: _serverPublicKeyBlob,
sendersPublicKeySize: _keyPair?.KeySize ?? 0));
try
{
var remoteException =
Serializer.Deserialize<RemoteInvocationException>(
MessageEncryptionManager.GetDecryptedMessageData(
message: message,
serializer: Serializer,
sharedSecret: sharedSecret,
sendersPublicKeyBlob: _serverPublicKeyBlob,
sendersPublicKeySize: _keyPair?.KeySize ?? 0));

clientRpcContext.RemoteException = remoteException;
}
catch (Exception deserializationException)
{
var remoteException = new RemoteInvocationException(
"Remote exception couldn't be deserialized",
deserializationException);

clientRpcContext.RemoteException = remoteException;
clientRpcContext.RemoteException = remoteException;
}
}
else
{
Expand Down

0 comments on commit fb8b97a

Please sign in to comment.