diff --git a/Lidgren.Network/NetPeer.Internal.cs b/Lidgren.Network/NetPeer.Internal.cs index 162e681..c80afc3 100644 --- a/Lidgren.Network/NetPeer.Internal.cs +++ b/Lidgren.Network/NetPeer.Internal.cs @@ -123,7 +123,7 @@ namespace Lidgren.Network mutex.WaitOne(); if (m_socket == null) - m_socket = new Socket(AddressFamily.InterNetwork, SocketType.Dgram, ProtocolType.Udp); + m_socket = new Socket(AddressFamily.InterNetworkV6, SocketType.Dgram, ProtocolType.Udp); if (reBind) m_socket.SetSocketOption(SocketOptionLevel.Socket, SocketOptionName.ReuseAddress, (int)1); @@ -131,8 +131,9 @@ namespace Lidgren.Network m_socket.ReceiveBufferSize = m_configuration.ReceiveBufferSize; m_socket.SendBufferSize = m_configuration.SendBufferSize; m_socket.Blocking = false; + m_socket.DualMode = true; - var ep = (EndPoint)new NetEndPoint(m_configuration.LocalAddress, reBind ? m_listenPort : m_configuration.Port); + var ep = (EndPoint)new NetEndPoint(m_configuration.LocalAddress.MapToIPv6(), reBind ? m_listenPort : m_configuration.Port); m_socket.Bind(ep); try diff --git a/Lidgren.Network/NetPeer.LatencySimulation.cs b/Lidgren.Network/NetPeer.LatencySimulation.cs index 49b11b4..c221975 100644 --- a/Lidgren.Network/NetPeer.LatencySimulation.cs +++ b/Lidgren.Network/NetPeer.LatencySimulation.cs @@ -132,25 +132,31 @@ namespace Lidgren.Network catch { } } + //Avoids allocation on mapping to IPv6 + private IPEndPoint targetCopy = new IPEndPoint(IPAddress.Any, 0); + internal bool ActuallySendPacket(byte[] data, int numBytes, NetEndPoint target, out bool connectionReset) { connectionReset = false; IPAddress ba = default(IPAddress); try { - ba = NetUtility.GetCachedBroadcastAddress(); - - // TODO: refactor this check outta here - if (target.Address.Equals(ba)) - { - // Some networks do not allow - // a global broadcast so we use the BroadcastAddress from the configuration - // this can be resolved to a local broadcast addresss e.g 192.168.x.255 - target.Address = m_configuration.BroadcastAddress; - m_socket.SetSocketOption(SocketOptionLevel.Socket, SocketOptionName.Broadcast, true); - } - - int bytesSent = m_socket.SendTo(data, 0, numBytes, SocketFlags.None, target); + ba = NetUtility.GetCachedBroadcastAddress(); + + // TODO: refactor this check outta here + if (target.Address.Equals(ba)) + { + // Some networks do not allow + // a global broadcast so we use the BroadcastAddress from the configuration + // this can be resolved to a local broadcast addresss e.g 192.168.x.255 + targetCopy.Address = m_configuration.BroadcastAddress; + targetCopy.Port = target.Port; + m_socket.SetSocketOption(SocketOptionLevel.Socket, SocketOptionName.Broadcast, true); + } + else + NetUtility.CopyEndpoint(target, targetCopy); //Maps to IPv6 for Dual Mode + + int bytesSent = m_socket.SendTo(data, 0, numBytes, SocketFlags.None, targetCopy); if (numBytes != bytesSent) LogWarning("Failed to send the full " + numBytes + "; only " + bytesSent + " bytes sent in packet!"); @@ -178,7 +184,7 @@ namespace Lidgren.Network } finally { - if (target.Address == ba) + if (target.Address.Equals(ba)) m_socket.SetSocketOption(SocketOptionLevel.Socket, SocketOptionName.Broadcast, false); } return true; diff --git a/Lidgren.Network/NetPeer.cs b/Lidgren.Network/NetPeer.cs index 737015c..459e091 100644 --- a/Lidgren.Network/NetPeer.cs +++ b/Lidgren.Network/NetPeer.cs @@ -121,7 +121,7 @@ namespace Lidgren.Network m_connections = new List(); m_connectionLookup = new Dictionary(); m_handshakes = new Dictionary(); - m_senderRemote = (EndPoint)new NetEndPoint(IPAddress.Any, 0); + m_senderRemote = (EndPoint)new NetEndPoint(IPAddress.IPv6Any, 0); m_status = NetPeerStatus.NotRunning; m_receivedFragmentGroups = new Dictionary>(); } @@ -303,6 +303,7 @@ namespace Lidgren.Network { if (remoteEndPoint == null) throw new ArgumentNullException("remoteEndPoint"); + remoteEndPoint = NetUtility.MapToIPv6(remoteEndPoint); lock (m_connections) { diff --git a/Lidgren.Network/NetPeerConfiguration.cs b/Lidgren.Network/NetPeerConfiguration.cs index cbcf34c..4e9f460 100644 --- a/Lidgren.Network/NetPeerConfiguration.cs +++ b/Lidgren.Network/NetPeerConfiguration.cs @@ -93,7 +93,7 @@ namespace Lidgren.Network // m_disabledTypes = NetIncomingMessageType.ConnectionApproval | NetIncomingMessageType.UnconnectedData | NetIncomingMessageType.VerboseDebugMessage | NetIncomingMessageType.ConnectionLatencyUpdated | NetIncomingMessageType.NatIntroductionSuccess; m_networkThreadName = "Lidgren network thread"; - m_localAddress = IPAddress.Any; + m_localAddress = IPAddress.IPv6Any; m_broadcastAddress = IPAddress.Broadcast; var ip = NetUtility.GetBroadcastAddress(); if (ip != null) @@ -328,7 +328,7 @@ namespace Lidgren.Network } /// - /// Gets or sets the local ip address to bind to. Defaults to IPAddress.Any. Cannot be changed once NetPeer is initialized. + /// Gets or sets the local ip address to bind to. Defaults to IPAddress.IPv6Any. Cannot be changed once NetPeer is initialized. /// public IPAddress LocalAddress { diff --git a/Lidgren.Network/NetUtility.cs b/Lidgren.Network/NetUtility.cs index 20ac1e6..a7798fb 100644 --- a/Lidgren.Network/NetUtility.cs +++ b/Lidgren.Network/NetUtility.cs @@ -98,7 +98,7 @@ namespace Lidgren.Network NetAddress ipAddress = null; if (NetAddress.TryParse(ipOrHost, out ipAddress)) { - if (ipAddress.AddressFamily == AddressFamily.InterNetwork) + if (ipAddress.AddressFamily == AddressFamily.InterNetwork || ipAddress.AddressFamily == AddressFamily.InterNetworkV6) { callback(ipAddress); return; @@ -139,7 +139,7 @@ namespace Lidgren.Network // check each entry for a valid IP address foreach (var ipCurrent in entry.AddressList) { - if (ipCurrent.AddressFamily == AddressFamily.InterNetwork) + if (ipCurrent.AddressFamily == AddressFamily.InterNetwork || ipCurrent.AddressFamily == AddressFamily.InterNetworkV6) { callback(ipCurrent); return; @@ -176,9 +176,9 @@ namespace Lidgren.Network NetAddress ipAddress = null; if (NetAddress.TryParse(ipOrHost, out ipAddress)) { - if (ipAddress.AddressFamily == AddressFamily.InterNetwork) + if (ipAddress.AddressFamily == AddressFamily.InterNetwork || ipAddress.AddressFamily == AddressFamily.InterNetworkV6) return ipAddress; - throw new ArgumentException("This method will not currently resolve other than ipv4 addresses"); + throw new ArgumentException("This method will not currently resolve other than IPv4 or IPv6 addresses"); } // ok must be a host name @@ -189,7 +189,7 @@ namespace Lidgren.Network return null; foreach (var address in addresses) { - if (address.AddressFamily == AddressFamily.InterNetwork) + if (address.AddressFamily == AddressFamily.InterNetwork || ipAddress.AddressFamily == AddressFamily.InterNetworkV6) return address; } return null; @@ -465,5 +465,29 @@ namespace Lidgren.Network // this is defined in the platform specific files return ComputeSHAHash(bytes, 0, bytes.Length); } - } + + /// + /// Copies from to . Maps to an IPv6 address + /// + /// Source. + /// Destination. + internal static void CopyEndpoint(IPEndPoint src, IPEndPoint dst) + { + dst.Port = src.Port; + if (src.AddressFamily == AddressFamily.InterNetwork) + dst.Address = src.Address.MapToIPv6(); + else + dst.Address = src.Address; + } + + /// + /// Maps the IPEndPoint object to an IPv6 address. Has allocation + /// + internal static IPEndPoint MapToIPv6(IPEndPoint endPoint) + { + if (endPoint.AddressFamily == AddressFamily.InterNetwork) + return new IPEndPoint(endPoint.Address.MapToIPv6(), endPoint.Port); + return endPoint; + } + } } \ No newline at end of file