b1525 - Added IPv6 support

This commit is contained in:
Saty 2024-01-01 21:23:01 +01:00
parent 256e2370a3
commit fdd4c7bac7
8 changed files with 275 additions and 197 deletions

View file

@ -70,7 +70,8 @@ namespace SRMultiplayer
!assembly.GetName().Name.Contains("Logger") && !assembly.GetName().Name.Contains("Mono.") && !assembly.GetName().Name.Contains("Harmony") && !assembly.GetName().Name.Contains("Logger") && !assembly.GetName().Name.Contains("Mono.") && !assembly.GetName().Name.Contains("Harmony") &&
!assembly.GetName().Name.Equals("SRML") && !assembly.GetName().Name.Equals("SRML.Editor") && !assembly.GetName().Name.Equals("Newtonsoft.Json") && !assembly.GetName().Name.Equals("SRML") && !assembly.GetName().Name.Equals("SRML.Editor") && !assembly.GetName().Name.Equals("Newtonsoft.Json") &&
!assembly.GetName().Name.Equals("INIFileParser") && !assembly.GetName().Name.Equals("SRMultiplayer") && !assembly.GetName().Name.Contains("Microsoft.") && !assembly.GetName().Name.Equals("INIFileParser") && !assembly.GetName().Name.Equals("SRMultiplayer") && !assembly.GetName().Name.Contains("Microsoft.") &&
!assembly.GetName().Name.Equals("SRMP") && !assembly.GetName().Name.Equals("XGamingRuntime") && !Globals.UserData.IgnoredMods.Contains(assembly.GetName().Name)) !assembly.GetName().Name.Equals("SRMP") && !assembly.GetName().Name.Equals("XGamingRuntime") && !assembly.GetName().Name.Contains("MonoMod.Utils.")
&& !Globals.UserData.IgnoredMods.Contains(assembly.GetName().Name))
{ {
mods.Add(assembly.GetName().Name); mods.Add(assembly.GetName().Name);
} }

View file

@ -123,7 +123,7 @@ namespace Lidgren.Network
mutex.WaitOne(); mutex.WaitOne();
if (m_socket == null) 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) if (reBind)
m_socket.SetSocketOption(SocketOptionLevel.Socket, SocketOptionName.ReuseAddress, (int)1); m_socket.SetSocketOption(SocketOptionLevel.Socket, SocketOptionName.ReuseAddress, (int)1);
@ -132,6 +132,18 @@ namespace Lidgren.Network
m_socket.SendBufferSize = m_configuration.SendBufferSize; m_socket.SendBufferSize = m_configuration.SendBufferSize;
m_socket.Blocking = false; m_socket.Blocking = false;
if (m_configuration.DualStack)
{
if (m_configuration.LocalAddress.AddressFamily != AddressFamily.InterNetworkV6)
{
LogWarning("Configuration specifies Dual Stack but does not use IPv6 local address; Dual stack will not work.");
}
else
{
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, reBind ? m_listenPort : m_configuration.Port);
m_socket.Bind(ep); m_socket.Bind(ep);
@ -412,12 +424,12 @@ namespace Lidgren.Network
// update now // update now
now = NetTime.Now; now = NetTime.Now;
do
{
int bytesReceived = 0;
try try
{ {
bytesReceived = m_socket.ReceiveFrom(m_receiveBuffer, 0, m_receiveBuffer.Length, SocketFlags.None, ref m_senderRemote); do
{
ReceiveSocketData(now);
} while (m_socket.Available > 0);
} }
catch (SocketException sx) catch (SocketException sx)
{ {
@ -440,6 +452,11 @@ namespace Lidgren.Network
return; return;
} }
} }
}
private void ReceiveSocketData(double now)
{
int bytesReceived = m_socket.ReceiveFrom(m_receiveBuffer, 0, m_receiveBuffer.Length, SocketFlags.None, ref m_senderRemote);
if (bytesReceived < NetConstants.HeaderByteSize) if (bytesReceived < NetConstants.HeaderByteSize)
return; return;
@ -573,8 +590,6 @@ namespace Lidgren.Network
m_statistics.PacketReceived(bytesReceived, numMessages, numFragments); m_statistics.PacketReceived(bytesReceived, numMessages, numFragments);
if (sender != null) if (sender != null)
sender.m_statistics.PacketReceived(bytesReceived, numMessages, numFragments); sender.m_statistics.PacketReceived(bytesReceived, numMessages, numFragments);
} while (m_socket.Available > 0);
} }
/// <summary> /// <summary>
@ -686,7 +701,7 @@ namespace Lidgren.Network
case NetMessageType.Connect: case NetMessageType.Connect:
if (m_configuration.AcceptIncomingConnections == false) if (m_configuration.AcceptIncomingConnections == false)
{ {
LogWarning(m_configuration.AppIdentifier + " Received Connect, but we're not accepting incoming connections!"); LogWarning("Received Connect, but we're not accepting incoming connections!");
return; return;
} }
// handle connect // handle connect

View file

@ -132,6 +132,9 @@ namespace Lidgren.Network
catch { } 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) internal bool ActuallySendPacket(byte[] data, int numBytes, NetEndPoint target, out bool connectionReset)
{ {
connectionReset = false; connectionReset = false;
@ -146,11 +149,19 @@ namespace Lidgren.Network
// Some networks do not allow // Some networks do not allow
// a global broadcast so we use the BroadcastAddress from the configuration // 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 // this can be resolved to a local broadcast addresss e.g 192.168.x.255
target.Address = m_configuration.BroadcastAddress; targetCopy.Address = m_configuration.BroadcastAddress;
targetCopy.Port = target.Port;
m_socket.SetSocketOption(SocketOptionLevel.Socket, SocketOptionName.Broadcast, true); 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
else
{
targetCopy.Port = target.Port;
targetCopy.Address = target.Address;
}
int bytesSent = m_socket.SendTo(data, 0, numBytes, SocketFlags.None, target); int bytesSent = m_socket.SendTo(data, 0, numBytes, SocketFlags.None, targetCopy);
if (numBytes != bytesSent) if (numBytes != bytesSent)
LogWarning("Failed to send the full " + numBytes + "; only " + bytesSent + " bytes sent in packet!"); LogWarning("Failed to send the full " + numBytes + "; only " + bytesSent + " bytes sent in packet!");
@ -178,7 +189,7 @@ namespace Lidgren.Network
} }
finally finally
{ {
if (target.Address == ba) if (target.Address.Equals(ba))
m_socket.SetSocketOption(SocketOptionLevel.Socket, SocketOptionName.Broadcast, false); m_socket.SetSocketOption(SocketOptionLevel.Socket, SocketOptionName.Broadcast, false);
} }
return true; return true;

View file

@ -2,7 +2,7 @@
using System.Threading; using System.Threading;
using System.Collections.Generic; using System.Collections.Generic;
using System.Net; using System.Net;
using System.Net.Sockets;
#if !__NOIPENDPOINT__ #if !__NOIPENDPOINT__
using NetEndPoint = System.Net.IPEndPoint; using NetEndPoint = System.Net.IPEndPoint;
#endif #endif
@ -121,7 +121,14 @@ namespace Lidgren.Network
m_connections = new List<NetConnection>(); m_connections = new List<NetConnection>();
m_connectionLookup = new Dictionary<NetEndPoint, NetConnection>(); m_connectionLookup = new Dictionary<NetEndPoint, NetConnection>();
m_handshakes = new Dictionary<NetEndPoint, NetConnection>(); m_handshakes = new Dictionary<NetEndPoint, NetConnection>();
m_senderRemote = (EndPoint)new NetEndPoint(IPAddress.Any, 0); if (m_configuration.LocalAddress.AddressFamily == AddressFamily.InterNetworkV6)
{
m_senderRemote = (EndPoint)new IPEndPoint(IPAddress.IPv6Any, 0);
}
else
{
m_senderRemote = (EndPoint)new IPEndPoint(IPAddress.Any, 0);
}
m_status = NetPeerStatus.NotRunning; m_status = NetPeerStatus.NotRunning;
m_receivedFragmentGroups = new Dictionary<NetConnection, Dictionary<int, ReceivedFragmentGroup>>(); m_receivedFragmentGroups = new Dictionary<NetConnection, Dictionary<int, ReceivedFragmentGroup>>();
} }
@ -303,6 +310,8 @@ namespace Lidgren.Network
{ {
if (remoteEndPoint == null) if (remoteEndPoint == null)
throw new ArgumentNullException("remoteEndPoint"); throw new ArgumentNullException("remoteEndPoint");
if(m_configuration.DualStack)
remoteEndPoint = NetUtility.MapToIPv6(remoteEndPoint);
lock (m_connections) lock (m_connections)
{ {

View file

@ -48,6 +48,8 @@ namespace Lidgren.Network
private string m_networkThreadName; private string m_networkThreadName;
private IPAddress m_localAddress; private IPAddress m_localAddress;
private IPAddress m_broadcastAddress; private IPAddress m_broadcastAddress;
private bool m_dualStack;
internal bool m_acceptIncomingConnections; internal bool m_acceptIncomingConnections;
internal int m_maximumConnections; internal int m_maximumConnections;
internal int m_defaultOutgoingMessageCapacity; internal int m_defaultOutgoingMessageCapacity;
@ -341,6 +343,22 @@ namespace Lidgren.Network
} }
} }
/// <summary>
/// Gets or sets a value indicating whether the library should use IPv6 dual stack mode.
/// If you enable this you should make sure that the <see cref="LocalAddress"/> is an IPv6 address.
/// Cannot be changed once NetPeer is initialized.
/// </summary>
public bool DualStack
{
get { return m_dualStack; }
set
{
if (m_isLocked)
throw new NetException(c_isLockedMessage);
m_dualStack = value;
}
}
/// <summary> /// <summary>
/// Gets or sets the local broadcast address to use when broadcasting /// Gets or sets the local broadcast address to use when broadcasting
/// </summary> /// </summary>

View file

@ -98,7 +98,7 @@ namespace Lidgren.Network
NetAddress ipAddress = null; NetAddress ipAddress = null;
if (NetAddress.TryParse(ipOrHost, out ipAddress)) if (NetAddress.TryParse(ipOrHost, out ipAddress))
{ {
if (ipAddress.AddressFamily == AddressFamily.InterNetwork) if (ipAddress.AddressFamily == AddressFamily.InterNetwork || ipAddress.AddressFamily == AddressFamily.InterNetworkV6)
{ {
callback(ipAddress); callback(ipAddress);
return; return;
@ -139,7 +139,7 @@ namespace Lidgren.Network
// check each entry for a valid IP address // check each entry for a valid IP address
foreach (var ipCurrent in entry.AddressList) foreach (var ipCurrent in entry.AddressList)
{ {
if (ipCurrent.AddressFamily == AddressFamily.InterNetwork) if (ipCurrent.AddressFamily == AddressFamily.InterNetwork || ipCurrent.AddressFamily == AddressFamily.InterNetworkV6)
{ {
callback(ipCurrent); callback(ipCurrent);
return; return;
@ -176,9 +176,9 @@ namespace Lidgren.Network
NetAddress ipAddress = null; NetAddress ipAddress = null;
if (NetAddress.TryParse(ipOrHost, out ipAddress)) if (NetAddress.TryParse(ipOrHost, out ipAddress))
{ {
if (ipAddress.AddressFamily == AddressFamily.InterNetwork) if (ipAddress.AddressFamily == AddressFamily.InterNetwork || ipAddress.AddressFamily == AddressFamily.InterNetworkV6)
return ipAddress; 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 // ok must be a host name
@ -189,7 +189,7 @@ namespace Lidgren.Network
return null; return null;
foreach (var address in addresses) foreach (var address in addresses)
{ {
if (address.AddressFamily == AddressFamily.InterNetwork) if (address.AddressFamily == AddressFamily.InterNetwork || address.AddressFamily == AddressFamily.InterNetworkV6)
return address; return address;
} }
return null; return null;
@ -465,5 +465,29 @@ namespace Lidgren.Network
// this is defined in the platform specific files // this is defined in the platform specific files
return ComputeSHAHash(bytes, 0, bytes.Length); 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;
}
} }
} }

View file

@ -15,7 +15,7 @@ using System.Resources;
[assembly: AssemblyCulture("")] [assembly: AssemblyCulture("")]
// Version informationr( // Version informationr(
[assembly: AssemblyVersion("0.0.0.1524")] [assembly: AssemblyVersion("0.0.0.1525")]
[assembly: AssemblyFileVersion("0.0.0.1524")] [assembly: AssemblyFileVersion("0.0.0.1525")]
[assembly: NeutralResourcesLanguageAttribute( "en-US" )] [assembly: NeutralResourcesLanguageAttribute( "en-US" )]

View file

@ -1,7 +1,7 @@
{ {
"id": "srmp", "id": "srmp",
"name": "Slime Rancher Multiplayer", "name": "Slime Rancher Multiplayer",
"version": "0.0.1524", "version": "0.0.1525",
"author": "SatyPardus", "author": "SatyPardus",
"dependencies": [ "dependencies": [