Skip to content

Commit 4afd648

Browse files
Removal of IPv6 config option (#876)
* Fix for incorrect reporting of a type mismatch when object mapping fails and a Vector type is involved. Before the fix the error reported when trying to map from, for example, a Vector<float> to a Vector<double> was: System.InvalidOperationException: The expected value `Neo4j.Driver.Vector`1[System.Single]` is different from the actual value `System.Collections.Generic.List`1[System.Single]` This was occurring because the ValueExtensions As method did not contain a clause for IVector, this caused the logic to fall through to the IEnumerable clause (which a vector implements) which converted the vector into a list, and then failed the type conversion on that list. Now that a clause for IVector is added you get the correct error. e.g. For the Vector<float> -> Vector<double> example: System.InvalidOperationException: The expected value `Neo4j.Driver.Vector`1[System.Single]` is different from the actual value `Neo4j.Driver.Vector`1[System.Double]` * Added tests to check on vector conversions in the valueExtensions class. Vectors should not be able to be converted to any other type, or between mismatched vectors. * Removal of IPV6 config option. The driver will support IPv6 and IPv4 by default going forward. The driver always runs it's sockets in dual mode now. Note: Several tests were removed that focused on address ordering during resolution. Preferring either IPv4 or IPv6 addresses depending on config. This ordering is not changed now. * Updated IDriver reference comments to reflect best practises when the object is disposed.
1 parent 2d16a39 commit 4afd648

File tree

9 files changed

+50
-210
lines changed

9 files changed

+50
-210
lines changed

Neo4j.Driver/Neo4j.Driver.Tests.Integration/Direct/DriverIT.cs

Lines changed: 2 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -55,8 +55,7 @@ public async Task ShouldConnectIPv6AddressIfEnabled()
5555
{
5656
await using var driver = GraphDatabase.Driver(
5757
DefaultInstallation.BoltUri,
58-
AuthToken,
59-
o => o.WithIpv6Enabled(true));
58+
AuthToken);
6059

6160
await using var session = driver.AsyncSession();
6261
var cursor = await session.RunAsync("RETURN 1");
@@ -65,22 +64,6 @@ public async Task ShouldConnectIPv6AddressIfEnabled()
6564
result.Should().Be(1);
6665
}
6766

68-
[RequireServerFact("3.1.0", VersionComparison.GreaterThanOrEqualTo)]
69-
public async Task ShouldNotConnectIPv6AddressIfDisabled()
70-
{
71-
await using var driver = GraphDatabase.Driver(
72-
"bolt://[::1]:7687",
73-
AuthToken,
74-
o => o.WithIpv6Enabled(false));
75-
76-
await using var session = driver.AsyncSession();
77-
var exc = await Record.ExceptionAsync(() => session.RunAsync("RETURN 1"));
78-
79-
exc.Should().NotBeNull();
80-
exc!.GetBaseException().Should().BeOfType<NotSupportedException>();
81-
exc.GetBaseException().Message.Should().Contain("This protocol version is not supported");
82-
}
83-
8467
[RequireServerFact]
8568
public async Task ShouldConnectIPv4AddressIfIpv6Disabled()
8669
{
@@ -96,8 +79,7 @@ public async Task ShouldConnectIPv4AddressIfIpv6Enabled()
9679
{
9780
await using var driver = GraphDatabase.Driver(
9881
DefaultInstallation.BoltUri,
99-
AuthToken,
100-
o => o.WithIpv6Enabled(true));
82+
AuthToken);
10183

10284
await using var session = driver.AsyncSession();
10385
var cursor = await session.RunAsync("RETURN 1");

Neo4j.Driver/Neo4j.Driver.Tests.TestBackend/Protocol/Driver/NewDriver.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -67,7 +67,7 @@ public override string Respond()
6767

6868
private void DriverConfig(ConfigBuilder configBuilder)
6969
{
70-
configBuilder.WithMetricsEnabled(true).WithIpv6Enabled(true);
70+
configBuilder.WithMetricsEnabled(true);
7171

7272
if (!string.IsNullOrEmpty(data.userAgent))
7373
{

Neo4j.Driver/Neo4j.Driver.Tests/Connector/DefaultResolverTests.cs

Lines changed: 30 additions & 150 deletions
Original file line numberDiff line numberDiff line change
@@ -26,38 +26,32 @@ namespace Neo4j.Driver.Tests.Connector;
2626

2727
public class DefaultResolverTests
2828
{
29-
[Theory]
30-
[InlineData(true)]
31-
[InlineData(false)]
32-
public void ShouldResolve(bool ipv6Preferred)
29+
[Fact]
30+
public void ShouldResolve()
3331
{
3432
var resolverMock = new Mock<IHostResolver>();
35-
var resolver = new DefaultHostResolver(resolverMock.Object, ipv6Preferred);
33+
var resolver = new DefaultHostResolver(resolverMock.Object);
3634

3735
resolver.Resolve("some_host");
3836

3937
resolverMock.Verify(r => r.Resolve("some_host"));
4038
}
4139

42-
[Theory]
43-
[InlineData(true)]
44-
[InlineData(false)]
45-
public async void ShouldResolveAsync(bool ipv6Preferred)
40+
[Fact]
41+
public async void ShouldResolveAsync()
4642
{
4743
var resolverMock = new Mock<IHostResolver>();
48-
var resolver = new DefaultHostResolver(resolverMock.Object, ipv6Preferred);
44+
var resolver = new DefaultHostResolver(resolverMock.Object);
4945

5046
await resolver.ResolveAsync("some_host");
5147

5248
resolverMock.Verify(r => r.ResolveAsync("some_host"));
5349
}
5450

55-
[Theory]
56-
[InlineData(true)]
57-
[InlineData(false)]
58-
public void ShouldParseLocalhost(bool ipv6Preferred)
51+
[Fact]
52+
public void ShouldParseLocalhost()
5953
{
60-
var resolver = new DefaultHostResolver(ipv6Preferred);
54+
var resolver = new DefaultHostResolver();
6155
var ipAddresses = resolver.Resolve("LocALhOsT");
6256

6357
#if NET452
@@ -68,12 +62,10 @@ public void ShouldParseLocalhost(bool ipv6Preferred)
6862
ipAddresses.Should().Contain(IPAddress.Parse("127.0.0.1"));
6963
}
7064

71-
[Theory]
72-
[InlineData(true)]
73-
[InlineData(false)]
74-
public async void ShouldParseLocalhostAsync(bool ipv6Preferred)
65+
[Fact]
66+
public async void ShouldParseLocalhostAsync()
7567
{
76-
var resolver = new DefaultHostResolver(ipv6Preferred);
68+
var resolver = new DefaultHostResolver();
7769
var ipAddresses = await resolver.ResolveAsync("LocALhOsT");
7870

7971
#if NET452
@@ -83,169 +75,57 @@ public async void ShouldParseLocalhostAsync(bool ipv6Preferred)
8375
#endif
8476
ipAddresses.Should().Contain(IPAddress.Parse("127.0.0.1"));
8577
}
86-
78+
8779
[Fact]
8880
public void ShouldParseLoopback()
8981
{
90-
var resolver = new DefaultHostResolver(false);
91-
var ipAddresses = resolver.Resolve("127.0.0.1");
92-
93-
ipAddresses.Should().HaveCount(1).And.Contain(IPAddress.Loopback);
94-
}
95-
96-
[Fact]
97-
public void ShouldParseLoopbackWhenIPv6Preferred()
98-
{
99-
var resolver = new DefaultHostResolver(true);
82+
var resolver = new DefaultHostResolver();
10083
var ipAddresses = resolver.Resolve("127.0.0.1");
10184

10285
ipAddresses.Should().HaveCount(2).And.ContainInOrder(IPAddress.IPv6Loopback, IPAddress.Loopback);
10386
}
104-
87+
10588
[Fact]
10689
public async void ShouldParseLoopbackAsync()
10790
{
108-
var resolver = new DefaultHostResolver(false);
109-
var ipAddresses = await resolver.ResolveAsync("127.0.0.1");
110-
111-
ipAddresses.Should().HaveCount(1).And.Contain(IPAddress.Loopback);
112-
}
113-
114-
[Fact]
115-
public async void ShouldParseLoopbackWhenIPv6PreferredAsync()
116-
{
117-
var resolver = new DefaultHostResolver(true);
91+
var resolver = new DefaultHostResolver();
11892
var ipAddresses = await resolver.ResolveAsync("127.0.0.1");
11993

12094
ipAddresses.Should().HaveCount(2).And.ContainInOrder(IPAddress.IPv6Loopback, IPAddress.Loopback);
12195
}
12296

123-
[Theory]
124-
[InlineData(true)]
125-
[InlineData(false)]
126-
public void ShouldParseIPv6Loopback(bool ipv6Preferred)
97+
[Fact]
98+
public void ShouldParseIPv6Loopback()
12799
{
128-
var resolver = new DefaultHostResolver(ipv6Preferred);
100+
var resolver = new DefaultHostResolver();
129101
var ipAddresses = resolver.Resolve("[::1]");
130102

131103
ipAddresses.Should().HaveCount(1).And.Contain(IPAddress.IPv6Loopback);
132104
}
133105

134-
[Theory]
135-
[InlineData(true)]
136-
[InlineData(false)]
137-
public async void ShouldParseIPv6LoopbackAsync(bool ipv6Preferred)
106+
[Fact]
107+
public async void ShouldParseIPv6LoopbackAsync()
138108
{
139-
var resolver = new DefaultHostResolver(ipv6Preferred);
109+
var resolver = new DefaultHostResolver();
140110
var ipAddresses = await resolver.ResolveAsync("[::1]");
141111

142112
ipAddresses.Should().HaveCount(1).And.Contain(IPAddress.IPv6Loopback);
143-
}
144-
145-
[Fact]
146-
public void ShouldOrderIPv4First()
147-
{
148-
var resolverMock = new Mock<IHostResolver>();
149-
resolverMock.Setup(x => x.Resolve(It.IsAny<string>()))
150-
.Returns(
151-
new[]
152-
{ IPAddress.Parse("[::1]"), IPAddress.Parse("10.0.0.1"), IPAddress.Parse("192.168.0.11") });
153-
154-
var resolver = new DefaultHostResolver(resolverMock.Object, false);
155-
var ipAddresses = resolver.Resolve("some_host");
156-
157-
ipAddresses.Should()
158-
.HaveCount(3)
159-
.And.ContainInOrder(
160-
IPAddress.Parse("10.0.0.1"),
161-
IPAddress.Parse("192.168.0.11"),
162-
IPAddress.Parse("[::1]"));
163-
}
164-
165-
[Fact]
166-
public async void ShouldOrderIPv4FirstAsync()
167-
{
168-
var resolverMock = new Mock<IHostResolver>();
169-
resolverMock.Setup(x => x.ResolveAsync(It.IsAny<string>()))
170-
.Returns(
171-
Task.FromResult(
172-
new[]
173-
{
174-
IPAddress.Parse("[::1]"), IPAddress.Parse("10.0.0.1"), IPAddress.Parse("192.168.0.11")
175-
}));
176-
177-
var resolver = new DefaultHostResolver(resolverMock.Object, false);
178-
var ipAddresses = await resolver.ResolveAsync("some_host");
179-
180-
ipAddresses.Should()
181-
.HaveCount(3)
182-
.And.ContainInOrder(
183-
IPAddress.Parse("10.0.0.1"),
184-
IPAddress.Parse("192.168.0.11"),
185-
IPAddress.Parse("[::1]"));
186-
}
187-
188-
[Fact]
189-
public void ShouldOrderIPv6FirstWhenIPv6Preferred()
190-
{
191-
var resolverMock = new Mock<IHostResolver>();
192-
resolverMock.Setup(x => x.Resolve(It.IsAny<string>()))
193-
.Returns(
194-
new[]
195-
{ IPAddress.Parse("10.0.0.1"), IPAddress.Parse("[::1]"), IPAddress.Parse("192.168.0.11") });
196-
197-
var resolver = new DefaultHostResolver(resolverMock.Object, true);
198-
var ipAddresses = resolver.Resolve("some_host");
199-
200-
ipAddresses.Should()
201-
.HaveCount(3)
202-
.And.ContainInOrder(
203-
IPAddress.Parse("[::1]"),
204-
IPAddress.Parse("10.0.0.1"),
205-
IPAddress.Parse("192.168.0.11"));
206-
}
207-
208-
[Fact]
209-
public async void ShouldOrderIPv6FirstWhenIPv6PreferredAsync()
210-
{
211-
var resolverMock = new Mock<IHostResolver>();
212-
resolverMock.Setup(x => x.ResolveAsync(It.IsAny<string>()))
213-
.Returns(
214-
Task.FromResult(
215-
new[]
216-
{
217-
IPAddress.Parse("10.0.0.1"), IPAddress.Parse("[::1]"), IPAddress.Parse("192.168.0.11")
218-
}));
219-
220-
var resolver = new DefaultHostResolver(resolverMock.Object, true);
221-
var ipAddresses = await resolver.ResolveAsync("some_host");
222-
223-
ipAddresses.Should()
224-
.HaveCount(3)
225-
.And.ContainInOrder(
226-
IPAddress.Parse("[::1]"),
227-
IPAddress.Parse("10.0.0.1"),
228-
IPAddress.Parse("192.168.0.11"));
229-
}
230-
231-
[MonoTheory]
232-
[InlineData(true)]
233-
[InlineData(false)]
234-
public void ShouldNotResolveLocalhostOnMono(bool ipv6Preferred)
113+
}
114+
115+
[MonoFact]
116+
public void ShouldNotResolveLocalhostOnMono()
235117
{
236118
var resolverMock = new Mock<IHostResolver>(MockBehavior.Strict);
237-
var resolver = new DefaultHostResolver(resolverMock.Object, ipv6Preferred);
119+
var resolver = new DefaultHostResolver(resolverMock.Object);
238120

239121
resolver.Resolve("localhost");
240122
}
241123

242-
[MonoTheory]
243-
[InlineData(true)]
244-
[InlineData(false)]
245-
public async void ShouldNotResolveLocalhostOnMonoAsync(bool ipv6Preferred)
124+
[MonoFact]
125+
public async void ShouldNotResolveLocalhostOnMonoAsync()
246126
{
247127
var resolverMock = new Mock<IHostResolver>(MockBehavior.Strict);
248-
var resolver = new DefaultHostResolver(resolverMock.Object, ipv6Preferred);
128+
var resolver = new DefaultHostResolver(resolverMock.Object);
249129

250130
await resolver.ResolveAsync("localhost");
251131
}

Neo4j.Driver/Neo4j.Driver/Internal/Connector/Resolvers/DefaultHostResolver.cs

Lines changed: 6 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -26,28 +26,26 @@ internal class DefaultHostResolver : IHostResolver
2626
{
2727
private static readonly bool OnMono = Type.GetType("Mono.Runtime") != null;
2828
private readonly IComparer<IPAddress> _addressComparer;
29-
private readonly bool _ipv6Preferred;
3029
private readonly IHostResolver _resolver;
3130

32-
public DefaultHostResolver(bool ipv6Preferred)
33-
: this(new SystemHostResolver(), ipv6Preferred)
31+
public DefaultHostResolver()
32+
: this(new SystemHostResolver())
3433
{
3534
}
3635

37-
public DefaultHostResolver(IHostResolver resolver, bool ipv6Preferred)
36+
37+
public DefaultHostResolver(IHostResolver resolver)
3838
{
3939
_resolver = resolver;
40-
_ipv6Preferred = ipv6Preferred;
4140
_addressComparer =
42-
new AddressComparer(_ipv6Preferred ? AddressFamily.InterNetworkV6 : AddressFamily.InterNetwork);
41+
new AddressComparer(AddressFamily.InterNetworkV6 );
4342
}
4443

4544
public IPAddress[] Resolve(string hostname)
4645
{
4746
if (TryParseIpAddress(hostname, out var result) == false)
4847
{
4948
result = _resolver.Resolve(hostname);
50-
result = result.OrderBy(x => x, _addressComparer).ToArray();
5149
}
5250

5351
return result;
@@ -58,7 +56,6 @@ public async Task<IPAddress[]> ResolveAsync(string hostname)
5856
if (TryParseIpAddress(hostname, out var result) == false)
5957
{
6058
result = await _resolver.ResolveAsync(hostname).ConfigureAwait(false);
61-
result = result.OrderBy(x => x, _addressComparer).ToArray();
6259
}
6360

6461
return result;
@@ -68,7 +65,7 @@ private bool TryParseIpAddress(string hostname, out IPAddress[] resolvedAddresse
6865
{
6966
if (IPAddress.TryParse(TranslateToMonoSafeHost(hostname), out var address))
7067
{
71-
if (_ipv6Preferred && address.AddressFamily == AddressFamily.InterNetwork)
68+
if (address.AddressFamily == AddressFamily.InterNetwork)
7269
{
7370
resolvedAddresses = new[]
7471
{

Neo4j.Driver/Neo4j.Driver/Internal/Connector/TcpSocketClient.cs

Lines changed: 4 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -202,20 +202,14 @@ private Task TryCleanUpAsync(IPAddress address, int port)
202202
}
203203

204204
private void InitClient()
205-
{
206-
var ipv6 = DriverContext.Config.Ipv6Enabled;
207-
var addressFamily = ipv6 ? AddressFamily.InterNetworkV6 : AddressFamily.InterNetwork;
208-
209-
_client = new Socket(addressFamily, SocketType.Stream, ProtocolType.Tcp)
205+
{
206+
_client = new Socket(AddressFamily.InterNetworkV6, SocketType.Stream, ProtocolType.Tcp)
210207
{
211208
NoDelay = true
212209
};
213210

214-
if (ipv6)
215-
{
216-
_client.DualMode = true;
217-
}
218-
211+
_client.DualMode = true;
212+
219213
_client.SetSocketOption(
220214
SocketOptionLevel.Socket,
221215
SocketOptionName.KeepAlive,

Neo4j.Driver/Neo4j.Driver/Internal/DriverContext.cs

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -48,8 +48,7 @@ internal DriverContext(
4848
(RuntimeHelper.IsDotNetCore
4949
? new SystemNetCoreHostResolver(new SystemHostResolver())
5050
: new DefaultHostResolver(
51-
new SystemHostResolver(),
52-
config.Ipv6Enabled));
51+
new SystemHostResolver()));
5352

5453
Metrics = config.MetricsEnabled ? new DefaultMetrics() : null;
5554
}

0 commit comments

Comments
 (0)