Files
Ryujinx-greemdev/src/Ryujinx.HLE/HOS/Services/Sockets/Bsd/Proxy/DefaultSocket.cs
Vudjun 6d8738c048 TESTERS WANTED: RyuLDN implementation (#65)
These changes allow players to matchmake for local wireless using a LDN
server. The network implementation originates from Berry's public TCP
RyuLDN fork. Logo and unrelated changes have been removed.

Additionally displays LDN game status in the game selection window when
RyuLDN is enabled.

Functionality is only enabled while network mode is set to "RyuLDN" in
the settings.
2024-11-11 16:06:50 -06:00

179 lines
5.1 KiB
C#

using Ryujinx.Common.Utilities;
using System;
using System.Net;
using System.Net.NetworkInformation;
using System.Net.Sockets;
namespace Ryujinx.HLE.HOS.Services.Sockets.Bsd.Proxy
{
class DefaultSocket : ISocketImpl
{
public Socket BaseSocket { get; }
public EndPoint RemoteEndPoint => BaseSocket.RemoteEndPoint;
public EndPoint LocalEndPoint => BaseSocket.LocalEndPoint;
public bool Connected => BaseSocket.Connected;
public bool IsBound => BaseSocket.IsBound;
public AddressFamily AddressFamily => BaseSocket.AddressFamily;
public SocketType SocketType => BaseSocket.SocketType;
public ProtocolType ProtocolType => BaseSocket.ProtocolType;
public bool Blocking { get => BaseSocket.Blocking; set => BaseSocket.Blocking = value; }
public int Available => BaseSocket.Available;
private readonly string _lanInterfaceId;
public DefaultSocket(Socket baseSocket, string lanInterfaceId)
{
_lanInterfaceId = lanInterfaceId;
BaseSocket = baseSocket;
}
public DefaultSocket(AddressFamily domain, SocketType type, ProtocolType protocol, string lanInterfaceId)
{
_lanInterfaceId = lanInterfaceId;
BaseSocket = new Socket(domain, type, protocol);
}
private void EnsureNetworkInterfaceBound()
{
if (_lanInterfaceId != "0" && !BaseSocket.IsBound)
{
(_, UnicastIPAddressInformation ipInfo) = NetworkHelpers.GetLocalInterface(_lanInterfaceId);
BaseSocket.Bind(new IPEndPoint(ipInfo.Address, 0));
}
}
public ISocketImpl Accept()
{
return new DefaultSocket(BaseSocket.Accept(), _lanInterfaceId);
}
public void Bind(EndPoint localEP)
{
// NOTE: The guest is able to receive on 0.0.0.0 without it being limited to the chosen network interface.
// This is because it must get loopback traffic as well. This could allow other network traffic to leak in.
BaseSocket.Bind(localEP);
}
public void Close()
{
BaseSocket.Close();
}
public void Connect(EndPoint remoteEP)
{
EnsureNetworkInterfaceBound();
BaseSocket.Connect(remoteEP);
}
public void Disconnect(bool reuseSocket)
{
BaseSocket.Disconnect(reuseSocket);
}
public void GetSocketOption(SocketOptionLevel optionLevel, SocketOptionName optionName, byte[] optionValue)
{
BaseSocket.GetSocketOption(optionLevel, optionName, optionValue);
}
public void Listen(int backlog)
{
BaseSocket.Listen(backlog);
}
public int Receive(Span<byte> buffer)
{
EnsureNetworkInterfaceBound();
return BaseSocket.Receive(buffer);
}
public int Receive(Span<byte> buffer, SocketFlags flags)
{
EnsureNetworkInterfaceBound();
return BaseSocket.Receive(buffer, flags);
}
public int Receive(Span<byte> buffer, SocketFlags flags, out SocketError socketError)
{
EnsureNetworkInterfaceBound();
return BaseSocket.Receive(buffer, flags, out socketError);
}
public int ReceiveFrom(Span<byte> buffer, SocketFlags flags, ref EndPoint remoteEP)
{
EnsureNetworkInterfaceBound();
return BaseSocket.ReceiveFrom(buffer, flags, ref remoteEP);
}
public int Send(ReadOnlySpan<byte> buffer)
{
EnsureNetworkInterfaceBound();
return BaseSocket.Send(buffer);
}
public int Send(ReadOnlySpan<byte> buffer, SocketFlags flags)
{
EnsureNetworkInterfaceBound();
return BaseSocket.Send(buffer, flags);
}
public int Send(ReadOnlySpan<byte> buffer, SocketFlags flags, out SocketError socketError)
{
EnsureNetworkInterfaceBound();
return BaseSocket.Send(buffer, flags, out socketError);
}
public int SendTo(ReadOnlySpan<byte> buffer, SocketFlags flags, EndPoint remoteEP)
{
EnsureNetworkInterfaceBound();
return BaseSocket.SendTo(buffer, flags, remoteEP);
}
public bool Poll(int microSeconds, SelectMode mode)
{
return BaseSocket.Poll(microSeconds, mode);
}
public void SetSocketOption(SocketOptionLevel optionLevel, SocketOptionName optionName, int optionValue)
{
BaseSocket.SetSocketOption(optionLevel, optionName, optionValue);
}
public void SetSocketOption(SocketOptionLevel optionLevel, SocketOptionName optionName, object optionValue)
{
BaseSocket.SetSocketOption(optionLevel, optionName, optionValue);
}
public void Shutdown(SocketShutdown how)
{
BaseSocket.Shutdown(how);
}
public void Dispose()
{
BaseSocket.Dispose();
}
}
}