1
0
mirror of https://github.com/lidgren/lidgren-network-gen3.git synced 2026-05-15 14:46:29 +09:00

Merge pull request #123 from CallumDev/master

Implement IPv6 Dual Mode Mk. 2
This commit is contained in:
Michael Lidgren
2019-06-09 21:54:09 +02:00
committed by GitHub
5 changed files with 80 additions and 29 deletions

View File

@@ -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(m_configuration.LocalAddress.AddressFamily, SocketType.Dgram, ProtocolType.Udp);
if (reBind)
m_socket.SetSocketOption(SocketOptionLevel.Socket, SocketOptionName.ReuseAddress, (int)1);
@@ -132,7 +132,10 @@ namespace Lidgren.Network
m_socket.SendBufferSize = m_configuration.SendBufferSize;
m_socket.Blocking = false;
var ep = (EndPoint)new NetEndPoint(m_configuration.LocalAddress, reBind ? m_listenPort : m_configuration.Port);
if(m_configuration.DualStack && m_configuration.LocalAddress.AddressFamily == AddressFamily.InterNetworkV6)
m_socket.DualMode = true;
var ep = (EndPoint)new NetEndPoint(m_configuration.LocalAddress.MapToIPv6(), reBind ? m_listenPort : m_configuration.Port);
m_socket.Bind(ep);
try

View File

@@ -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 if(m_configuration.DualStack && m_configuration.LocalAddress.AddressFamily == AddressFamily.InterNetworkV6)
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;

View File

@@ -121,7 +121,7 @@ namespace Lidgren.Network
m_connections = new List<NetConnection>();
m_connectionLookup = new Dictionary<NetEndPoint, NetConnection>();
m_handshakes = new Dictionary<NetEndPoint, NetConnection>();
m_senderRemote = (EndPoint)new NetEndPoint(IPAddress.Any, 0);
m_senderRemote = (EndPoint)new NetEndPoint(IPAddress.IPv6Any, 0);
m_status = NetPeerStatus.NotRunning;
m_receivedFragmentGroups = new Dictionary<NetConnection, Dictionary<int, ReceivedFragmentGroup>>();
}
@@ -303,6 +303,8 @@ namespace Lidgren.Network
{
if (remoteEndPoint == null)
throw new ArgumentNullException("remoteEndPoint");
if(m_configuration.DualStack)
remoteEndPoint = NetUtility.MapToIPv6(remoteEndPoint);
lock (m_connections)
{

View File

@@ -48,6 +48,8 @@ namespace Lidgren.Network
private string m_networkThreadName;
private IPAddress m_localAddress;
private IPAddress m_broadcastAddress;
private bool m_dualStack;
internal bool m_acceptIncomingConnections;
internal int m_maximumConnections;
internal int m_defaultOutgoingMessageCapacity;
@@ -93,7 +95,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 +330,7 @@ namespace Lidgren.Network
}
/// <summary>
/// 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.
/// </summary>
public IPAddress LocalAddress
{
@@ -341,10 +343,24 @@ namespace Lidgren.Network
}
}
/// <summary>
/// Gets or sets the local broadcast address to use when broadcasting
/// </summary>
public IPAddress BroadcastAddress
/// <summary>
/// Gets or sets a value indicating whether the library should use IPv6 dual stack mode
/// </summary>
public bool DualStack
{
get { return m_dualStack; }
set
{
if (m_isLocked)
throw new NetException(c_isLockedMessage);
m_dualStack = value;
}
}
/// <summary>
/// Gets or sets the local broadcast address to use when broadcasting
/// </summary>
public IPAddress BroadcastAddress
{
get { return m_broadcastAddress; }
set

View File

@@ -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);
}
}
/// <summary>
/// Copies from <paramref name="src"/> to <paramref name="dst"/>. Maps to an IPv6 address
/// </summary>
/// <param name="src">Source.</param>
/// <param name="dst">Destination.</param>
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;
}
/// <summary>
/// Maps the IPEndPoint object to an IPv6 address. Has allocation
/// </summary>
internal static IPEndPoint MapToIPv6(IPEndPoint endPoint)
{
if (endPoint.AddressFamily == AddressFamily.InterNetwork)
return new IPEndPoint(endPoint.Address.MapToIPv6(), endPoint.Port);
return endPoint;
}
}
}