Skip to content

Commit

Permalink
feat: port checker prototype (#1938)
Browse files Browse the repository at this point in the history
* feat: port checker prototype

* fix: automatically unmap IPv6-mapped IPv4 on error

* feat: port checker service behind proxy

* chore: additional log line

* chore: cleaned up server api KnownProxies impl
  • Loading branch information
lodicolo authored Oct 11, 2023
1 parent e83f25f commit 69e37aa
Show file tree
Hide file tree
Showing 31 changed files with 867 additions and 98 deletions.
25 changes: 25 additions & 0 deletions .dockerignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
**/.dockerignore
**/.env
**/.git
**/.gitignore
**/.project
**/.settings
**/.toolstarget
**/.vs
**/.vscode
**/.idea
**/*.*proj.user
**/*.dbmdl
**/*.jfm
**/azds.yaml
**/bin
**/charts
**/docker-compose*
**/Dockerfile*
**/node_modules
**/npm-debug.log
**/obj
**/secrets.dev.yaml
**/values.dev.yaml
LICENSE
README.md
4 changes: 2 additions & 2 deletions .editorconfig
Original file line number Diff line number Diff line change
Expand Up @@ -96,7 +96,7 @@ csharp_style_pattern_matching_over_as_with_null_check = true:suggestion
csharp_style_throw_expression = true:suggestion
csharp_style_conditional_delegate_call = true:suggestion
# Modifier preferences
csharp_preferred_modifier_order = public,private,protected,internal,static,extern,new,virtual,abstract,sealed,override,readonly,unsafe,volatile,async:suggestion
csharp_preferred_modifier_order = public, private, protected, internal, static, extern, new, virtual, abstract, sealed, override, readonly, unsafe, volatile, async:suggestion
# Expression-level preferences
csharp_prefer_braces = true:silent
csharp_style_deconstructed_variable_declaration = true:suggestion
Expand Down Expand Up @@ -143,4 +143,4 @@ resharper_trailing_comma_in_multiline_lists = true
###############################
[*.vb]
# Modifier preferences
visual_basic_preferred_modifier_order = Partial,Default,Private,Protected,Public,Friend,NotOverridable,Overridable,MustOverride,Overloads,Overrides,MustInherit,NotInheritable,Static,Shared,Shadows,ReadOnly,WriteOnly,Dim,Const,WithEvents,Widening,Narrowing,Custom,Async:suggestion
visual_basic_preferred_modifier_order = Partial, Default, Private, Protected, Public, Friend, NotOverridable, Overridable, MustOverride, Overloads, Overrides, MustInherit, NotInheritable, Static, Shared, Shadows, ReadOnly, WriteOnly, Dim, Const, WithEvents, Widening, Narrowing, Custom, Async:suggestion
2 changes: 1 addition & 1 deletion Directory.Build.props
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@
<IntersectRepoPath Condition="'$(IntersectRepoPath)' == ''">$(MSBuildProjectDirectory)\..</IntersectRepoPath>
</PropertyGroup>

<Import Project=".\Intersect.props" />
<Import Project=".\Intersect.props"/>

<PropertyGroup>
<IntersectProjectName>$(MSBuildProjectName.Substring(10))</IntersectProjectName>
Expand Down
3 changes: 3 additions & 0 deletions Intersect (Core)/Config/Options.cs
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,9 @@ public partial class Options
[JsonProperty("OpenPortChecker", Order = 0)]
protected bool _portChecker = true;

[JsonProperty(NullValueHandling = NullValueHandling.Include)]
public string? PortCheckerUrl { get; set; }

[JsonProperty("MaxClientConnections")]
public int MaxClientConnections { get; set; }= 100;

Expand Down
2 changes: 2 additions & 0 deletions Intersect (Core)/Network/INetworkLayerInterface.cs
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,8 @@ bool SendPacket(
TransmissionMode transmissionMode = TransmissionMode.All
);

bool SendUnconnectedPacket(IPEndPoint target, ReadOnlySpan<byte> data);

bool SendUnconnectedPacket(IPEndPoint target, UnconnectedPacket packet);

void Start();
Expand Down
2 changes: 2 additions & 0 deletions Intersect (Core)/Network/UnconnectedMessageSender.cs
Original file line number Diff line number Diff line change
Expand Up @@ -8,5 +8,7 @@ public sealed record UnconnectedMessageSender(
object? InterfaceMetadata
)
{
public void Reply(ReadOnlySpan<byte> data) => NetworkInterface.SendUnconnectedPacket(RemoteEndPoint, data);

public void Reply(UnconnectedPacket packet) => NetworkInterface.SendUnconnectedPacket(RemoteEndPoint, packet);
}
5 changes: 5 additions & 0 deletions Intersect.Network/Lidgren/LidgrenInterface.cs
Original file line number Diff line number Diff line change
Expand Up @@ -149,6 +149,11 @@ public LidgrenInterface(INetwork network, Type peerType, RSAParameters rsaParame

public bool IsDisposed { get; private set; }

public bool SendUnconnectedPacket(IPEndPoint target, ReadOnlySpan<byte> data)
{
throw new NotImplementedException();
}

public bool SendUnconnectedPacket(IPEndPoint target, UnconnectedPacket packet)
{
throw new NotImplementedException();
Expand Down
48 changes: 46 additions & 2 deletions Intersect.Network/LiteNetLib/LiteNetLibInterface.cs
Original file line number Diff line number Diff line change
Expand Up @@ -304,6 +304,9 @@ DeliveryMethod deliveryMethod
OnPacketAvailable?.Invoke(this);
}

public bool SendUnconnectedPacket(IPEndPoint target, ReadOnlySpan<byte> data) =>
_manager.SendUnconnectedMessage(data.ToArray(), target);

public bool SendUnconnectedPacket(IPEndPoint target, UnconnectedPacket packet)
{
using var tempAsymmetric = RSA.Create(_asymmetricServer.ExportParameters(false));
Expand Down Expand Up @@ -332,11 +335,17 @@ public bool SendUnconnectedPacket(IPEndPoint target, UnconnectedPacket packet)
Log.Debug($"{nameof(SendUnconnectedPacket)} {nameof(encryptedPacketData)}({encryptedPacketData.Length})={Convert.ToHexString(encryptedPacketData)}");
#endif

var data = NetDataWriter.FromBytes(encryptedPacketData, false);
NetDataWriter data = new(false, encryptedPacketData.Length + 1);
data.Put((byte)UnconnectedPacketType.AsymmetricEncrypted);
data.Put(encryptedPacketData);
return _manager.SendUnconnectedMessage(data, target);
}

public void OnNetworkReceiveUnconnected(IPEndPoint remoteEndPoint, NetPacketReader reader, UnconnectedMessageType messageType)
private void HandleAsymmetricEncryptedUnconnectedPacket(
IPEndPoint remoteEndPoint,
NetDataReader reader,
UnconnectedMessageType messageType
)
{
try
{
Expand Down Expand Up @@ -379,6 +388,41 @@ public void OnNetworkReceiveUnconnected(IPEndPoint remoteEndPoint, NetPacketRead
}
}

public void OnNetworkReceiveUnconnected(IPEndPoint remoteEndPoint, NetPacketReader reader, UnconnectedMessageType messageType)
{
try
{
if (!reader.TryGetByte(out var unconnectedPacketTypeAsByte))
{
return;
}

var unconnectedPacketType = (UnconnectedPacketType)unconnectedPacketTypeAsByte;
if (!Enum.IsDefined(typeof(UnconnectedPacketType), unconnectedPacketTypeAsByte))
{
unconnectedPacketType = UnconnectedPacketType.AsymmetricEncrypted;
}

switch (unconnectedPacketType)
{
case UnconnectedPacketType.Plaintext:
OnUnconnectedMessage?.Invoke(
new UnconnectedMessageSender(this, remoteEndPoint, default),
new LiteNetLibInboundBuffer(reader)
);
break;
case UnconnectedPacketType.AsymmetricEncrypted:
HandleAsymmetricEncryptedUnconnectedPacket(remoteEndPoint, reader, messageType);
break;
default: throw new UnreachableException();
}
}
catch (Exception exception)
{
Log.Debug(exception);
}
}

public void OnNetworkLatencyUpdate(NetPeer peer, int latency)
{
Log.Verbose($"LTNC {peer.EndPoint} {latency}ms");
Expand Down
7 changes: 7 additions & 0 deletions Intersect.Network/LiteNetLib/UnconnectedPacketType.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
namespace Intersect.Network.LiteNetLib;

public enum UnconnectedPacketType : byte
{
Plaintext = 0,
AsymmetricEncrypted,
}
2 changes: 1 addition & 1 deletion Intersect.Server/Core/Bootstrapper.cs
Original file line number Diff line number Diff line change
Expand Up @@ -168,7 +168,7 @@ internal static void CheckNetwork()
return;
}

if (Options.UPnP)
if (Options.UPnP && !Context.StartupOptions.NoNatPunchthrough)
{
Log.Pretty.Info(Strings.Portchecking.PortNotOpenTryingUPnP.ToString(Options.ServerPort));
Console.WriteLine();
Expand Down
5 changes: 0 additions & 5 deletions Intersect.Server/Core/ServerContext.cs
Original file line number Diff line number Diff line change
Expand Up @@ -272,11 +272,6 @@ private void InternalStartNetworking()
Console.WriteLine();
#endif

if (!Options.UPnP || Instance.StartupOptions.NoNatPunchthrough)
{
return;
}

Bootstrapper.CheckNetwork();

Console.WriteLine();
Expand Down
16 changes: 16 additions & 0 deletions Intersect.Server/Networking/Helpers/PortCheckResult.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
namespace Intersect.Server.Networking.Helpers;

public enum PortCheckResult
{
Unknown,
Open,
PossiblyOpen,
IntersectResponseNoPlayerCount,
IntersectResponseInvalidPlayerCount,
InvalidPortCheckerRequest,
InvalidPortCheckerResponse,
PortCheckerServerError,
PortCheckerServerDown,
PortCheckerServerUnexpectedResponse,
Inaccessible,
}
Loading

0 comments on commit 69e37aa

Please sign in to comment.