Skip to content

Commit

Permalink
Added NettyDiscoveryBaseHandler and packet size validation
Browse files Browse the repository at this point in the history
  • Loading branch information
alexb5dh committed Aug 5, 2024
1 parent 1adf764 commit ae96529
Show file tree
Hide file tree
Showing 5 changed files with 58 additions and 11 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@
using DotNetty.Transport.Channels.Sockets;
using FluentAssertions;
using Microsoft.Extensions.Logging;
using Nethermind.Logging;
using Nethermind.Serialization.Rlp;
using NSubstitute;
using NUnit.Framework;
Expand All @@ -29,7 +30,7 @@ public class NettyDiscoveryV5HandlerTests
public void Initialize()
{
_channel = new();
_handler = new(new LoggerFactory());
_handler = new(new TestLogManager());
_handler.InitializeChannel(_channel);
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -91,7 +91,11 @@ .. _discoveryDb.GetAllValues().Select(enr => enrFactory.CreateFromBytes(enr, ide
.WithTableOptions(new TableOptions(bootstrapEnrs.Select(enr => enr.ToString()).ToArray()))
.WithEnrBuilder(enrBuilder)
.WithLoggerFactory(new NethermindLoggerFactory(logManager, true))
.WithServices(NettyDiscoveryV5Handler.Register);
.WithServices(s =>
{
s.AddSingleton(logManager);
NettyDiscoveryV5Handler.Register(s);
});

_discv5Protocol = discv5Builder.Build();
_discv5Protocol.NodeAdded += (e) => NodeAddedByDiscovery(e.Record);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9,24 +9,24 @@
using DotNetty.Transport.Channels.Sockets;
using Lantern.Discv5.WireProtocol.Connection;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Logging;
using Nethermind.Logging;
using Nethermind.Serialization.Rlp;

namespace Nethermind.Network.Discovery;

/// <summary>
/// Adapter, integrating DotNetty externally-managed <see cref="IChannel"/> with Lantern.Discv5
/// </summary>
public class NettyDiscoveryV5Handler : SimpleChannelInboundHandler<DatagramPacket>, IUdpConnection
public class NettyDiscoveryV5Handler : NettyDiscoveryBaseHandler, IUdpConnection
{
private readonly ILogger<NettyDiscoveryV5Handler> _logger;
private readonly ILogger _logger;
private readonly Channel<UdpReceiveResult> _inboundQueue;

private IChannel? _nettyChannel;

public NettyDiscoveryV5Handler(ILoggerFactory loggerFactory)
public NettyDiscoveryV5Handler(ILogManager loggerManager) : base(loggerManager)
{
_logger = loggerFactory.CreateLogger<NettyDiscoveryV5Handler>();
_logger = loggerManager.GetClassLogger<NettyDiscoveryV5Handler>();
_inboundQueue = Channel.CreateUnbounded<UdpReceiveResult>();
}

Expand All @@ -50,7 +50,7 @@ public async Task SendAsync(byte[] data, IPEndPoint destination)
}
catch (SocketException exception)
{
_logger.LogError(exception, "Error sending data");
if (_logger.IsError) _logger.Error($"Error sending data", exception);
throw;
}
}
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
// SPDX-FileCopyrightText: 2024 Demerzel Solutions Limited
// SPDX-License-Identifier: LGPL-3.0-only

using DotNetty.Transport.Channels;
using DotNetty.Transport.Channels.Sockets;
using Nethermind.Logging;

namespace Nethermind.Network.Discovery;

public abstract class NettyDiscoveryBaseHandler : SimpleChannelInboundHandler<DatagramPacket>
{
private readonly ILogger _logger;

// https://github.com/ethereum/devp2p/blob/master/discv4.md#wire-protocol
// https://github.com/ethereum/devp2p/blob/master/discv5/discv5-wire.md#udp-communication
protected const int MaxPacketSize = 1280;

protected NettyDiscoveryBaseHandler(ILogManager? logManager)
{
_logger = logManager?.GetClassLogger<NettyDiscoveryBaseHandler>() ?? throw new ArgumentNullException(nameof(logManager));
}

public override void ChannelRead(IChannelHandlerContext ctx, object msg)
{
if (msg is DatagramPacket packet && AcceptInboundMessage(packet) && !ValidatePacket(packet))
return;

base.ChannelRead(ctx, msg);
}

protected bool ValidatePacket(DatagramPacket packet)
{
if (packet.Content.ReadableBytes is 0 or > MaxPacketSize)
{
if (_logger.IsWarn) _logger.Warn($"Skipping discovery packet of invalid size: {packet.Content.ReadableBytes}");
return false;
}

return true;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -11,10 +11,11 @@
using Nethermind.Core.Extensions;
using Nethermind.Logging;
using Nethermind.Network.Discovery.Messages;
using ILogger = Nethermind.Logging.ILogger;

namespace Nethermind.Network.Discovery;

public class NettyDiscoveryHandler : SimpleChannelInboundHandler<DatagramPacket>, IMsgSender
public class NettyDiscoveryHandler : NettyDiscoveryBaseHandler, IMsgSender
{
private readonly ILogger _logger;
private readonly IDiscoveryManager _discoveryManager;
Expand All @@ -27,7 +28,7 @@ public NettyDiscoveryHandler(
IChannel? channel,
IMessageSerializationService? msgSerializationService,
ITimestamper? timestamper,
ILogManager? logManager)
ILogManager? logManager) : base(logManager)
{
_logger = logManager?.GetClassLogger<NettyDiscoveryHandler>() ?? throw new ArgumentNullException(nameof(logManager));
_discoveryManager = discoveryManager ?? throw new ArgumentNullException(nameof(discoveryManager));
Expand Down Expand Up @@ -80,7 +81,7 @@ public async Task SendMsg(DiscoveryMsg discoveryMsg)
}

int size = msgBuffer.ReadableBytes;
if (size > 1280)
if (size > MaxPacketSize)
{
if (_logger.IsWarn) _logger.Warn($"Attempting to send message larger than 1280 bytes. This is out of spec and may not work for all client. Msg: ${discoveryMsg}");
}
Expand Down

0 comments on commit ae96529

Please sign in to comment.