Skip to content

Commit

Permalink
Improve QUIC and tcp/ip IP and port resolution
Browse files Browse the repository at this point in the history
  • Loading branch information
flcl42 committed Oct 6, 2023
1 parent 4161470 commit c7caeac
Show file tree
Hide file tree
Showing 3 changed files with 41 additions and 42 deletions.
62 changes: 22 additions & 40 deletions src/libp2p/Libp2p.Protocols.IpTcp/IpTcpProtocol.cs
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@
using System.Net.Sockets;
using Nethermind.Libp2p.Core;
using Microsoft.Extensions.Logging;
using MultiaddrEnum = Nethermind.Libp2p.Core.Enums.Multiaddr;

namespace Nethermind.Libp2p.Protocols;

Expand All @@ -27,32 +28,26 @@ public async Task ListenAsync(IChannel channel, IChannelFactory? channelFactory,

Socket srv = new(SocketType.Stream, ProtocolType.Tcp);
Multiaddr addr = context.LocalPeer.Address;
Core.Enums.Multiaddr ipProtocol = addr.Has(Core.Enums.Multiaddr.Ip4) ? Core.Enums.Multiaddr.Ip4 : Core.Enums.Multiaddr.Ip6;
MultiaddrEnum ipProtocol = addr.Has(MultiaddrEnum.Ip4) ? MultiaddrEnum.Ip4 : MultiaddrEnum.Ip6;
IPAddress ipAddress = IPAddress.Parse(addr.At(ipProtocol)!);
int tcpPort = int.Parse(addr.At(Core.Enums.Multiaddr.Tcp)!);
int tcpPort = int.Parse(addr.At(MultiaddrEnum.Tcp)!);
srv.Bind(new IPEndPoint(ipAddress, tcpPort));
srv.Listen(32767);
srv.Listen(tcpPort);

IPEndPoint localIpEndpoint = (IPEndPoint)srv.LocalEndPoint!;
channel.OnClose(() =>
{
srv.Close();
return Task.CompletedTask;
});
Core.Enums.Multiaddr newIpProtocol = localIpEndpoint.AddressFamily == AddressFamily.InterNetwork
? Core.Enums.Multiaddr.Ip4
: Core.Enums.Multiaddr.Ip6;

context.LocalEndpoint = Core.Multiaddr.From(newIpProtocol, localIpEndpoint.Address.ToString(),
Core.Enums.Multiaddr.Tcp,
localIpEndpoint.Port);
context.LocalEndpoint = Multiaddr.From(
ipProtocol, localIpEndpoint.Address.ToString(),
MultiaddrEnum.Tcp, localIpEndpoint.Port);

context.LocalPeer.Address = context.LocalPeer.Address.Replace(
context.LocalEndpoint.Has(Core.Enums.Multiaddr.Ip4) ? Core.Enums.Multiaddr.Ip4 : Core.Enums.Multiaddr.Ip6, newIpProtocol,
localIpEndpoint.Address.ToString())
.Replace(
Core.Enums.Multiaddr.Tcp,
localIpEndpoint.Port.ToString());
context.LocalPeer.Address = context.LocalPeer.Address
.Replace(ipProtocol, localIpEndpoint.Address.ToString())
.Replace(MultiaddrEnum.Tcp, localIpEndpoint.Port.ToString());

await Task.Run(async () =>
{
Expand All @@ -62,22 +57,9 @@ await Task.Run(async () =>
IPeerContext clientContext = context.Fork();
IPEndPoint remoteIpEndpoint = (IPEndPoint)client.RemoteEndPoint!;

clientContext.RemoteEndpoint = Core.Multiaddr.From(
remoteIpEndpoint.AddressFamily == AddressFamily.InterNetwork
? Core.Enums.Multiaddr.Ip4
: Core.Enums.Multiaddr.Ip6, remoteIpEndpoint.Address.ToString(), Core.Enums.Multiaddr.Tcp,
remoteIpEndpoint.Port);
clientContext.LocalPeer.Address = context.LocalPeer.Address.Replace(
context.LocalEndpoint.Has(Core.Enums.Multiaddr.Ip4) ? Core.Enums.Multiaddr.Ip4 : Core.Enums.Multiaddr.Ip6, newIpProtocol,
localIpEndpoint.Address.ToString())
.Replace(
Core.Enums.Multiaddr.Tcp,
remoteIpEndpoint.Port.ToString());
clientContext.RemotePeer.Address = new Multiaddr()
.Append(remoteIpEndpoint.AddressFamily == AddressFamily.InterNetwork
? Core.Enums.Multiaddr.Ip4
: Core.Enums.Multiaddr.Ip6, remoteIpEndpoint.Address.ToString())
.Append(Core.Enums.Multiaddr.Tcp, remoteIpEndpoint.Port.ToString());
clientContext.RemoteEndpoint = clientContext.RemotePeer.Address = Multiaddr.From(
ipProtocol, remoteIpEndpoint.Address.ToString(),
MultiaddrEnum.Tcp, remoteIpEndpoint.Port);

IChannel chan = channelFactory.SubListen(clientContext);

Expand Down Expand Up @@ -131,9 +113,9 @@ public async Task DialAsync(IChannel channel, IChannelFactory channelFactory, IP
TaskCompletionSource<bool?> waitForStop = new(TaskCreationOptions.RunContinuationsAsynchronously);
Socket client = new(SocketType.Stream, ProtocolType.Tcp);
Multiaddr addr = context.RemotePeer.Address;
Core.Enums.Multiaddr ipProtocol = addr.Has(Core.Enums.Multiaddr.Ip4) ? Core.Enums.Multiaddr.Ip4 : Core.Enums.Multiaddr.Ip6;
Core.Enums.Multiaddr ipProtocol = addr.Has(MultiaddrEnum.Ip4) ? MultiaddrEnum.Ip4 : MultiaddrEnum.Ip6;
IPAddress ipAddress = IPAddress.Parse(addr.At(ipProtocol)!);
int tcpPort = int.Parse(addr.At(Core.Enums.Multiaddr.Tcp)!);
int tcpPort = int.Parse(addr.At(MultiaddrEnum.Tcp)!);
try
{
await client.ConnectAsync(new IPEndPoint(ipAddress, tcpPort), channel.Token);
Expand All @@ -148,15 +130,15 @@ public async Task DialAsync(IChannel channel, IChannelFactory channelFactory, IP
IPEndPoint localEndpoint = (IPEndPoint)client.LocalEndPoint!;
IPEndPoint remoteEndpoint = (IPEndPoint)client.RemoteEndPoint!;

context.RemoteEndpoint = Core.Multiaddr.From(
context.RemoteEndpoint = Multiaddr.From(
ipProtocol,
ipProtocol == Core.Enums.Multiaddr.Ip4 ? remoteEndpoint.Address.MapToIPv4() : remoteEndpoint.Address.MapToIPv6(),
Core.Enums.Multiaddr.Tcp, remoteEndpoint.Port);
context.LocalEndpoint = Core.Multiaddr.From(
ipProtocol == MultiaddrEnum.Ip4 ? remoteEndpoint.Address.MapToIPv4() : remoteEndpoint.Address.MapToIPv6(),
MultiaddrEnum.Tcp, remoteEndpoint.Port);
context.LocalEndpoint = Multiaddr.From(
ipProtocol,
ipProtocol == Core.Enums.Multiaddr.Ip4 ? localEndpoint.Address.MapToIPv4() : localEndpoint.Address.MapToIPv6(),
Core.Enums.Multiaddr.Tcp, localEndpoint.Port);
context.LocalPeer.Address = context.LocalEndpoint.Append(Core.Enums.Multiaddr.P2p, context.LocalPeer.Identity.PeerId.ToString());
ipProtocol == MultiaddrEnum.Ip4 ? localEndpoint.Address.MapToIPv4() : localEndpoint.Address.MapToIPv6(),
MultiaddrEnum.Tcp, localEndpoint.Port);
context.LocalPeer.Address = context.LocalEndpoint.Append(MultiaddrEnum.P2p, context.LocalPeer.Identity.PeerId.ToString());

IChannel upChannel = channelFactory.SubDial(context);
channel.Token.Register(() => upChannel.CloseAsync());
Expand Down
8 changes: 8 additions & 0 deletions src/libp2p/Libp2p.Protocols.Quic/QuicProtocol.cs
Original file line number Diff line number Diff line change
Expand Up @@ -75,6 +75,14 @@ public async Task ListenAsync(IChannel channel, IChannelFactory? channelFactory,
ConnectionOptionsCallback = (_, _, _) => ValueTask.FromResult(serverConnectionOptions)
});

context.LocalEndpoint = Multiaddr.From(
ipProtocol, listener.LocalEndPoint.Address.ToString(),
MultiaddrEnum.Udp, listener.LocalEndPoint.Port);

context.LocalPeer.Address = context.LocalPeer.Address
.Replace(ipProtocol, listener.LocalEndPoint.Address.ToString())
.Replace(MultiaddrEnum.Udp, listener.LocalEndPoint.Port.ToString());

channel.OnClose(async () =>
{
await listener.DisposeAsync();
Expand Down
13 changes: 11 additions & 2 deletions src/samples/chat/Program.cs
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,12 @@
if (args.Length > 0 && args[0] == "-d")
{
Multiaddr remoteAddr = args[1];
ILocalPeer localPeer = peerFactory.Create();

string addrTemplate = remoteAddr.Has(Nethermind.Libp2p.Core.Enums.Multiaddr.Quic) ?
"/ip4/0.0.0.0/udp/0/quic-v1" :
"/ip4/0.0.0.0/tcp/0";

ILocalPeer localPeer = peerFactory.Create(localAddr: addrTemplate);

logger.LogInformation("Dialing {0}", remoteAddr);
IRemotePeer remotePeer = await localPeer.DialAsync(remoteAddr, ts.Token);
Expand All @@ -38,8 +43,12 @@
Identity optionalFixedIdentity = new(Enumerable.Repeat((byte)42, 32).ToArray());
ILocalPeer peer = peerFactory.Create(optionalFixedIdentity);

string addrTemplate = args.Contains("quic") ?
"/ip4/0.0.0.0/udp/{0}/quic-v1/p2p/{1}" :
"/ip4/0.0.0.0/tcp/{0}/p2p/{1}";

IListener listener = await peer.ListenAsync(
$"/ip4/0.0.0.0/udp/{(args.Length > 0 && args[0] == "-sp" ? args[1] : "0")}/quic-v1/p2p/{peer.Identity.PeerId}",
string.Format(addrTemplate, args.Length > 0 && args[0] == "-sp" ? args[1] : "0", peer.Identity.PeerId),
ts.Token);
logger.LogInformation($"Listener started at {listener.Address}");
listener.OnConnection += async remotePeer => logger.LogInformation($"A peer connected {remotePeer.Address}");
Expand Down

0 comments on commit c7caeac

Please sign in to comment.