-
-
Notifications
You must be signed in to change notification settings - Fork 40
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Initial work for DTLS for connections
- Loading branch information
1 parent
3d21be4
commit 0647a58
Showing
15 changed files
with
624 additions
and
143 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,49 @@ | ||
using System.Net.Sockets; | ||
using Hkmp.Logging; | ||
using Org.BouncyCastle.Tls; | ||
|
||
namespace Hkmp.Networking.Client; | ||
|
||
internal class ClientDatagramTransport : DatagramTransport { | ||
private readonly Socket _socket; | ||
|
||
public ClientDatagramTransport(Socket socket) { | ||
_socket = socket; | ||
} | ||
|
||
public int GetReceiveLimit() { | ||
// TODO: change to const defined somewhere | ||
return 1400; | ||
} | ||
|
||
public int GetSendLimit() { | ||
// TODO: change to const defined somewhere | ||
return 1400; | ||
} | ||
|
||
public int Receive(byte[] buf, int off, int len, int waitMillis) { | ||
try { | ||
// _socket.ReceiveTimeout = waitMillis; | ||
var numReceived = _socket.Receive( | ||
buf, | ||
off, | ||
len, | ||
SocketFlags.None | ||
); | ||
Logger.Debug($"Client socket receive: {numReceived}"); | ||
return numReceived; | ||
} catch (SocketException e) { | ||
Logger.Error($"UDP Socket exception:\n{e}"); | ||
} | ||
|
||
return -1; | ||
} | ||
|
||
public void Send(byte[] buf, int off, int len) { | ||
Logger.Debug($"Client sending {len} bytes of data"); | ||
_socket.Send(buf, off, len, SocketFlags.None); | ||
} | ||
|
||
public void Close() { | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,37 @@ | ||
using Org.BouncyCastle.Tls; | ||
using Org.BouncyCastle.Tls.Crypto; | ||
|
||
namespace Hkmp.Networking.Client; | ||
|
||
internal class ClientTlsClient(TlsCrypto crypto) : AbstractTlsClient(crypto) { | ||
private static readonly int[] SupportedCipherSuites = [ | ||
CipherSuite.TLS_AES_128_GCM_SHA256, | ||
CipherSuite.TLS_AES_256_GCM_SHA384, | ||
CipherSuite.TLS_CHACHA20_POLY1305_SHA256, | ||
CipherSuite.TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384, | ||
CipherSuite.TLS_ECDHE_ECDSA_WITH_CHACHA20_POLY1305_SHA256 | ||
]; | ||
|
||
protected override ProtocolVersion[] GetSupportedVersions() { | ||
return ProtocolVersion.DTLSv12.Only(); | ||
} | ||
|
||
protected override int[] GetSupportedCipherSuites() { | ||
return SupportedCipherSuites; | ||
} | ||
|
||
public override TlsAuthentication GetAuthentication() { | ||
return new TlsAuthenticationImpl(); | ||
} | ||
|
||
private class TlsAuthenticationImpl : TlsAuthentication { | ||
public void NotifyServerCertificate(TlsServerCertificate serverCertificate) { | ||
// TODO: check server certificate, throw error in case of invalid cert | ||
} | ||
|
||
public TlsCredentials GetClientCredentials(CertificateRequest certificateRequest) { | ||
// TODO: provide means for a client to have certificate and return it in this method | ||
return null; | ||
} | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,104 @@ | ||
using System; | ||
using System.IO; | ||
using System.Net.Sockets; | ||
using System.Threading; | ||
using Hkmp.Logging; | ||
using Org.BouncyCastle.Tls; | ||
using Org.BouncyCastle.Tls.Crypto.Impl.BC; | ||
|
||
namespace Hkmp.Networking.Client; | ||
|
||
internal class DtlsClient { | ||
private Socket _socket; | ||
private ClientTlsClient _tlsClient; | ||
private ClientDatagramTransport _clientDatagramTransport; | ||
|
||
private CancellationTokenSource _updateTaskTokenSource; | ||
|
||
public DtlsTransport DtlsTransport { get; set; } | ||
public event Action<byte[], int> DataReceivedEvent; | ||
|
||
public void Connect(string address, int port) { | ||
if (_socket != null || | ||
_tlsClient != null || | ||
_clientDatagramTransport != null || | ||
DtlsTransport != null || | ||
_updateTaskTokenSource != null | ||
) { | ||
Disconnect(); | ||
} | ||
|
||
_socket = new Socket(AddressFamily.InterNetwork, SocketType.Dgram, ProtocolType.Udp); | ||
// _socket.DualMode = true; | ||
|
||
try { | ||
_socket.Connect(address, port); | ||
} catch (SocketException e) { | ||
Logger.Error($"Socket exception when connecting UDP socket:\n{e}"); | ||
|
||
_socket.Close(); | ||
|
||
throw; | ||
} | ||
|
||
var clientProtocol = new DtlsClientProtocol(); | ||
_tlsClient = new ClientTlsClient(new BcTlsCrypto()); | ||
_clientDatagramTransport = new ClientDatagramTransport(_socket); | ||
|
||
try { | ||
DtlsTransport = clientProtocol.Connect(_tlsClient, _clientDatagramTransport); | ||
} catch (IOException e) { | ||
Logger.Error($"IO exception when connecting DTLS client:\n{e}"); | ||
|
||
_clientDatagramTransport.Close(); | ||
|
||
throw; | ||
} | ||
|
||
Logger.Debug($"Successfully connected DTLS client to endpoint: {address}:{port}"); | ||
|
||
_updateTaskTokenSource = new CancellationTokenSource(); | ||
var cancellationToken = _updateTaskTokenSource.Token; | ||
new Thread(() => ReceiveLoop(cancellationToken)).Start(); | ||
} | ||
|
||
public void Disconnect() { | ||
_updateTaskTokenSource?.Cancel(); | ||
_updateTaskTokenSource?.Dispose(); | ||
_updateTaskTokenSource = null; | ||
|
||
DtlsTransport?.Close(); | ||
DtlsTransport = null; | ||
|
||
_clientDatagramTransport?.Close(); | ||
_clientDatagramTransport = null; | ||
|
||
_tlsClient?.Cancel(); | ||
_tlsClient = null; | ||
|
||
_socket?.Close(); | ||
_socket = null; | ||
} | ||
|
||
public void SendPacket(Packet.Packet packet) { | ||
if (DtlsTransport == null) { | ||
Logger.Error("DTLS transport instance is null, cannot send packet"); | ||
return; | ||
} | ||
|
||
var buffer = packet.ToArray(); | ||
|
||
DtlsTransport.Send(buffer, 0, buffer.Length); | ||
} | ||
|
||
private void ReceiveLoop(CancellationToken cancellationToken) { | ||
while (!cancellationToken.IsCancellationRequested && DtlsTransport != null) { | ||
// TODO: change to const define somewhere central | ||
var buffer = new byte[1400]; | ||
var length = DtlsTransport.Receive(buffer, 0, buffer.Length, 5); | ||
if (length >= 0) { | ||
DataReceivedEvent?.Invoke(buffer, length); | ||
} | ||
} | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.