diff --git a/docs/README.md b/docs/README.md
index 189dff2..ba44521 100644
--- a/docs/README.md
+++ b/docs/README.md
@@ -19,6 +19,10 @@ It is important to close the `c` object explicitly, via the `Close` method, when
The class provides a number of other features explored in the following sections.
+#### Connecting using IPv6
+
+Connections default to using IPv4. Passing `IpVersionPreference` to the constructor can be used to specify whether IPv6 should be used. The DualStack option create a dual socket so both IPv4 and IPv6 will be tried on a connection, if the operating system supports it.
+
### Connecting using UDS (Unix Domain Sockets)
As an alternative to the standard TCP connection, kdb+ can use UDS. See [here](https://code.kx.com/q/basics/listening-port/#unix-domain-socket) for details.
diff --git a/kx/c.cs b/kx/c.cs
index f9fa017..d76de77 100644
--- a/kx/c.cs
+++ b/kx/c.cs
@@ -122,6 +122,43 @@ public class c : IDisposable
///
private bool _isLittleEndian;
+ ///
+ /// Specifies the IP address family preference to use when establishing a TCP connection.
+ ///
+ ///
+ /// Use this option to control whether a connection should be attempted using IPv4,
+ /// IPv6, or a dual-mode socket that can support both IPv4 and IPv6 where the
+ /// operating system and network configuration allow it.
+ ///
+ public enum IpVersionPreference
+ {
+ ///
+ /// Use IPv4 only.
+ ///
+ ///
+ /// Creates or selects a socket that uses .
+ ///
+ IPv4,
+
+ ///
+ /// Use IPv6 only.
+ ///
+ ///
+ /// Creates or selects a socket that uses
+ /// without accepting IPv4-mapped IPv6 addresses.
+ ///
+ IPv6,
+
+ ///
+ /// Use a dual-mode socket that can support both IPv4 and IPv6.
+ ///
+ ///
+ /// Creates or selects an IPv6 socket with
+ /// enabled, allowing both IPv6 addresses and IPv4-mapped IPv6 addresses where supported.
+ ///
+ DualStack
+ }
+
///
/// Initialises a new instance of with a specified host and port
/// to connect to.
@@ -139,7 +176,8 @@ private c(
string userPassword,
int maxBufferSize,
KdbTlsOptions tlsOptions,
- bool uds)
+ bool uds,
+ IpVersionPreference ipVersionPreference)
{
if (host == null)
{
@@ -166,7 +204,18 @@ private c(
}
else
{
- _socket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
+ switch (ipVersionPreference)
+ {
+ case (IpVersionPreference.IPv4):
+ _socket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
+ break;
+ case (IpVersionPreference.IPv6):
+ _socket = new Socket(AddressFamily.InterNetworkV6, SocketType.Stream, ProtocolType.Tcp);
+ break;
+ case (IpVersionPreference.DualStack):
+ _socket = new Socket(SocketType.Stream, ProtocolType.Tcp);
+ break;
+ }
_socket.Connect(host, port);
_isLoopback = _socket.RemoteEndPoint is IPEndPoint &&
IPAddress.IsLoopback((_socket.RemoteEndPoint as IPEndPoint).Address);
@@ -216,6 +265,7 @@ private c(
/// The username and passsword, as "username:password" for remote authorisation.
/// The maximum buffer size, default is 65536.
/// A boolean flag indicating whether or not TLS authentication is enabled, default is false.
+ /// The IP address family preference to use when establishing a TCP connection.
/// or was null.
/// must be between and
/// Unable to connect to KDB+ process, access denied or process unavailable.
@@ -224,8 +274,9 @@ public c(
int port,
string userPassword,
int maxBufferSize = DefaultMaxBufferSize,
- bool useTLS = false)
- : this(host, port, userPassword, maxBufferSize, useTLS ? KdbTls.Default(host) : KdbTlsOptions.Disabled, false)
+ bool useTLS = false,
+ IpVersionPreference ipVersionPreference = IpVersionPreference.IPv4)
+ : this(host, port, userPassword, maxBufferSize, useTLS ? KdbTls.Default(host) : KdbTlsOptions.Disabled, false, ipVersionPreference)
{
}
@@ -234,6 +285,7 @@ public c(
/// The username/password string used for authentication.
/// The maximum buffer size used for IPC messages.
/// The TLS options to use for the connection.
+ /// The IP address family preference to use when establishing a TCP connection.
///
/// or was null.
///
@@ -249,8 +301,9 @@ public c(
int port,
string userPassword,
int maxBufferSize,
- KdbTlsOptions tlsOptions)
- : this(host,port,userPassword,maxBufferSize,tlsOptions ?? KdbTlsOptions.Disabled,false)
+ KdbTlsOptions tlsOptions,
+ IpVersionPreference ipVersionPreference = IpVersionPreference.IPv4)
+ : this(host,port,userPassword,maxBufferSize,tlsOptions ?? KdbTlsOptions.Disabled,false,ipVersionPreference)
{
}
@@ -262,14 +315,16 @@ public c(
/// uds file e.g. "/tmp/kx.5010" is the default with kdb+ listening on port 5010
/// The username and passsword, as "username:password" for remote authorisation.
/// The maximum buffer size, default is 65536.
+ /// The IP address family preference to use when establishing a TCP connection.
/// or was null.
/// Unable to connect to KDB+ process, access denied or process unavailable.
/// The current OS does not support Unix Domain Sockets
public c(
string file,
string userPassword,
- int maxBufferSize = DefaultMaxBufferSize)
- : this(file, 0, userPassword, maxBufferSize, KdbTlsOptions.Disabled, true)
+ int maxBufferSize = DefaultMaxBufferSize,
+ IpVersionPreference ipVersionPreference = IpVersionPreference.IPv4)
+ : this(file, 0, userPassword, maxBufferSize, KdbTlsOptions.Disabled, true, ipVersionPreference)
{
}
@@ -281,6 +336,7 @@ public c(
/// The username/password string used for authentication.
/// The maximum buffer size used for IPC messages.
/// The TLS options to use for the connection.
+ /// The IP address family preference to use when establishing a TCP connection.
///
/// or was null.
///
@@ -294,8 +350,9 @@ public c(
string file,
string userPassword,
int maxBufferSize,
- KdbTlsOptions tlsOptions)
- : this(file, 0, userPassword, maxBufferSize, tlsOptions ?? KdbTlsOptions.Disabled, true)
+ KdbTlsOptions tlsOptions,
+ IpVersionPreference ipVersionPreference = IpVersionPreference.IPv4)
+ : this(file, 0, userPassword, maxBufferSize, tlsOptions ?? KdbTlsOptions.Disabled, true, ipVersionPreference)
{
}