Skip to content

Commit

Permalink
Merge pull request #616 from alanmcgovern/fix-ipv6-non-compact-responses
Browse files Browse the repository at this point in the history
[ipv6] Use the correct prefix for IPv6 non-compact peers
  • Loading branch information
alanmcgovern authored Jan 31, 2023
2 parents 0030a5b + 168c8ac commit 629ddcf
Show file tree
Hide file tree
Showing 2 changed files with 49 additions and 3 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,7 @@

using System;
using System.Collections.Generic;
using System.Net;
using System.Net.Sockets;

using MonoTorrent.BEncoding;
Expand Down Expand Up @@ -71,7 +72,9 @@ static PeerInfo DecodeFromDict (BEncodedDictionary dict)
else
peerId = BEncodedString.Empty;

var connectionUri = new Uri ($"ipv4://{dict[IPKey]}:{dict[PortKey]}");
var ipAddress = IPAddress.Parse (((BEncodedString)dict[IPKey]).Text);
int port = (int)((BEncodedNumber) dict[PortKey]).Number;
var connectionUri = new Uri ($"{(ipAddress.AddressFamily == AddressFamily.InterNetwork ? "ipv4" : "ipv6")}://{new IPEndPoint (ipAddress, port)}");
return new PeerInfo (connectionUri, peerId);
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -125,6 +125,42 @@ public void DecodeDictionary ()
VerifyDecodedPeers (PeerDecoder.Decode (list, AddressFamily.InterNetwork));
}

[Test]
public void DecodeDictionaryIPv6_WithCorruptEntry ()
{
List<PeerInfo> actual = new List<PeerInfo> {
new PeerInfo (new Uri ("ipv6://[::1]:1234")),
new PeerInfo (new Uri ("ipv6://[::1234:2345:3456]:5451")),
new PeerInfo (new Uri ("ipv6://[fe80::08ef]:5555")),
};

var list = new BEncodedList ();
foreach (PeerInfo p in actual) {
list.Add (new BEncodedDictionary {
{"ip", (BEncodedString) p.ConnectionUri.Host},
{"port", (BEncodedNumber) p.ConnectionUri.Port},
{"peer id", p.PeerId}
});
}

// Add a corrupt port and ip
list.Add (new BEncodedDictionary {
{"ip", (BEncodedString) "fake"},
{"port", (BEncodedNumber) 1234},
{"peer id", (BEncodedString) "bad ip"}
});

list.Add (new BEncodedDictionary {
{"ip", (BEncodedString) "::1"},
{"port", (BEncodedNumber) 12345678},
{"peer id", (BEncodedString) "bad port"}
});

// non-compact responses do not need the AddressFamily hint, and ipv6 address will parse correctly regardless of the value of the hint flag.
VerifyDecodedPeers (PeerDecoder.Decode (list, AddressFamily.InterNetwork), actual);
VerifyDecodedPeers (PeerDecoder.Decode (list, AddressFamily.InterNetworkV6), actual);
}

[Test]
public void DecodeCompact ()
{
Expand All @@ -141,7 +177,7 @@ public void DecodePeerId ()
{
var peerId = new BEncodedString (Enumerable.Repeat ((byte) 255, 20).ToArray ());
var dict = new BEncodedDictionary {
{"ip", (BEncodedString) "1237.1.2.3"},
{"ip", (BEncodedString) "127.1.2.3"},
{"port", (BEncodedNumber) 12345}
};
dict["peer id"] = peerId;
Expand Down Expand Up @@ -206,11 +242,18 @@ public void Equality_SamePeerId_SameIP ()
Assert.AreEqual (one.GetHashCode (), otherOne.GetHashCode (), "#2");
}

private void VerifyDecodedPeers (IList<PeerInfo> decoded)
void VerifyDecodedPeers (IList<PeerInfo> decoded)
{
Assert.AreEqual (peers.Count, decoded.Count, "#1");
foreach (PeerInfo dec in decoded)
Assert.IsTrue (peers.Exists (p => p.ConnectionUri.Equals (dec.ConnectionUri)));
}

static void VerifyDecodedPeers (IList<PeerInfo> decoded, List<PeerInfo> actual)
{
Assert.AreEqual (actual.Count, decoded.Count, "#1");
foreach (PeerInfo dec in decoded)
Assert.IsTrue (actual.Exists (p => p.ConnectionUri.Equals (dec.ConnectionUri)));
}
}
}

0 comments on commit 629ddcf

Please sign in to comment.