private static NetworkMessageDelegate MessageHandler <T>(Action <INetworkConnection, T> handler) where T : IMessageBase, new() { void AdapterFunction(INetworkConnection conn, NetworkReader reader, int channelId) { // protect against DOS attacks if attackers try to send invalid // data packets to crash the server/client. there are a thousand // ways to cause an exception in data handling: // - invalid headers // - invalid message ids // - invalid data causing exceptions // - negative ReadBytesAndSize prefixes // - invalid utf8 strings // - etc. // // let's catch them all and then disconnect that connection to avoid // further attacks. T message = default(T) != null ? default : new T(); try { message.Deserialize(reader); } finally { NetworkDiagnostics.OnReceive(message, channelId, reader.Length); } handler(conn, message); } return(AdapterFunction); }
internal static NetworkMessageDelegate MessageHandler <T>(Action <NetworkConnection, T> handler) where T : IMessageBase, new() => networkMessage => { // protect against DOS attacks if attackers try to send invalid // data packets to crash the server/client. there are a thousand // ways to cause an exception in data handling: // - invalid headers // - invalid message ids // - invalid data causing exceptions // - negative ReadBytesAndSize prefixes // - invalid utf8 strings // - etc. // // let's catch them all and then disconnect that connection to avoid // further attacks. T message = default; try { message = networkMessage.ReadMessage <T>(); } catch (Exception exception) { Debug.LogError("Closed connection: " + networkMessage.conn.connectionId + ". This can happen if the other side accidentally (or an attacker intentionally) sent invalid data. Reason: " + exception); networkMessage.conn.Disconnect(); return; } finally { // TODO: Figure out the correct channel NetworkDiagnostics.OnReceive(message, -1, networkMessage.reader.Length); } handler(networkMessage.conn, message); };
internal static NetworkMessageDelegate WrapHandler <T, C>(Action <C, T> handler, bool requireAuthentication) where T : struct, NetworkMessage where C : NetworkConnection => (conn, reader, channelId) => { // protect against DOS attacks if attackers try to send invalid // data packets to crash the server/client. there are a thousand // ways to cause an exception in data handling: // - invalid headers // - invalid message ids // - invalid data causing exceptions // - negative ReadBytesAndSize prefixes // - invalid utf8 strings // - etc. // // let's catch them all and then disconnect that connection to avoid // further attacks. T message = default; try { if (requireAuthentication && !conn.isAuthenticated) { // message requires authentication, but the connection was not authenticated Debug.LogWarning($"Closing connection: {conn}. Received message {typeof(T)} that required authentication, but the user has not authenticated yet"); conn.Disconnect(); return; } //Debug.Log($"ConnectionRecv {conn} msgType:{typeof(T)} content:{BitConverter.ToString(reader.buffer.Array, reader.buffer.Offset, reader.buffer.Count)}"); // if it is a value type, just use default(T) // otherwise allocate a new instance message = reader.Read <T>(); } catch (Exception exception) { Debug.LogError($"Closed connection: {conn}. This can happen if the other side accidentally (or an attacker intentionally) sent invalid data. Reason: {exception}"); conn.Disconnect(); return; } finally { // TODO: Figure out the correct channel NetworkDiagnostics.OnReceive(message, channelId, reader.Length); } // user handler exception should not stop the whole server try { // user implemented handler handler((C)conn, message); } catch (Exception e) { Debug.LogError($"Exception in MessageHandler: {e.GetType().Name} {e.Message}\n{e.StackTrace}"); conn.Disconnect(); } };
internal static NetworkMessageDelegate MessageHandler <T, C>(Action <C, T> handler, bool requireAuthenication) where T : IMessageBase, new() where C : NetworkConnection => (conn, reader, channelId) => { // protect against DOS attacks if attackers try to send invalid // data packets to crash the server/client. there are a thousand // ways to cause an exception in data handling: // - invalid headers // - invalid message ids // - invalid data causing exceptions // - negative ReadBytesAndSize prefixes // - invalid utf8 strings // - etc. // // let's catch them all and then disconnect that connection to avoid // further attacks. T message = default; try { if (requireAuthenication && !conn.isAuthenticated) { // message requires authentication, but the connection was not authenticated Debug.LogWarning($"Closing connection: {conn}. Received message {typeof(T)} that required authentication, but the user has not authenticated yet"); conn.Disconnect(); return; } // if it is a value type, just use defult(T) // otherwise allocate a new instance message = default(T) != null ? default(T) : new T(); message.Deserialize(reader); } catch (Exception exception) { Debug.LogError("Closed connection: " + conn + ". This can happen if the other side accidentally (or an attacker intentionally) sent invalid data. Reason: " + exception); conn.Disconnect(); return; } finally { // TODO: Figure out the correct channel NetworkDiagnostics.OnReceive(message, channelId, reader.Length); } handler((C)conn, message); };
private static NetworkMessageDelegate MessageHandler <T, C>(Action <C, T> handler, bool requireAuthenication) where T : IMessageBase, new() where C : NetworkConnection { void AdapterFunction(NetworkConnection conn, NetworkReader reader, int channelId) { // protect against DOS attacks if attackers try to send invalid // data packets to crash the server/client. there are a thousand // ways to cause an exception in data handling: // - invalid headers // - invalid message ids // - invalid data causing exceptions // - negative ReadBytesAndSize prefixes // - invalid utf8 strings // - etc. // // let's catch them all and then disconnect that connection to avoid // further attacks. T message = default; try { if (requireAuthenication && !conn.isAuthenticated) { // message requires authentication, but the connection was not authenticated Debug.LogWarning($"Closing connection: {conn}. Received message {typeof(T)} that required authentication, but the user has not authenticated yet"); conn.Disconnect(); return; } message = default(T) != null ? default(T) : new T(); message.Deserialize(reader); } finally { NetworkDiagnostics.OnReceive(message, channelId, reader.Length); } handler((C)conn, message); } return(AdapterFunction); }