diff --git a/crypto/src/tls/DtlsRecordLayer.cs b/crypto/src/tls/DtlsRecordLayer.cs
index 82fc3db64..a61688cb0 100644
--- a/crypto/src/tls/DtlsRecordLayer.cs
+++ b/crypto/src/tls/DtlsRecordLayer.cs
@@ -278,7 +278,7 @@ namespace Org.BouncyCastle.Tls
}
/// <exception cref="IOException"/>
- internal int Receive(byte[] buf, int off, int len, int waitMillis, Action recordCallback)
+ internal int Receive(byte[] buf, int off, int len, int waitMillis, DtlsRecordCallback recordCallback)
{
#if NETCOREAPP2_1_OR_GREATER || NETSTANDARD2_1_OR_GREATER
return Receive(buf.AsSpan(off, len), waitMillis, recordCallback);
@@ -348,7 +348,7 @@ namespace Org.BouncyCastle.Tls
}
/// <exception cref="IOException"/>
- internal int ReceivePending(byte[] buf, int off, int len, Action recordCallback)
+ internal int ReceivePending(byte[] buf, int off, int len, DtlsRecordCallback recordCallback)
{
#if NETCOREAPP2_1_OR_GREATER || NETSTANDARD2_1_OR_GREATER
return ReceivePending(buf.AsSpan(off, len), recordCallback);
@@ -380,7 +380,7 @@ namespace Org.BouncyCastle.Tls
}
/// <exception cref="IOException"/>
- internal int Receive(Span<byte> buffer, int waitMillis, Action recordCallback)
+ internal int Receive(Span<byte> buffer, int waitMillis, DtlsRecordCallback recordCallback)
{
long currentTimeMillis = DateTimeUtilities.CurrentUnixMs();
@@ -446,7 +446,7 @@ namespace Org.BouncyCastle.Tls
}
/// <exception cref="IOException"/>
- internal int ReceivePending(Span<byte> buffer, Action recordCallback)
+ internal int ReceivePending(Span<byte> buffer, DtlsRecordCallback recordCallback)
{
if (m_recordQueue.Available > 0)
{
@@ -677,9 +677,10 @@ namespace Org.BouncyCastle.Tls
// TODO Include 'currentTimeMillis' as an argument, use with Timeout, resetHeartbeat
/// <exception cref="IOException"/>
#if NETCOREAPP2_1_OR_GREATER || NETSTANDARD2_1_OR_GREATER
- private int ProcessRecord(int received, byte[] record, Span<byte> buffer, Action recordCallback)
+ private int ProcessRecord(int received, byte[] record, Span<byte> buffer, DtlsRecordCallback recordCallback)
#else
- private int ProcessRecord(int received, byte[] record, byte[] buf, int off, int len, Action recordCallback)
+ private int ProcessRecord(int received, byte[] record, byte[] buf, int off, int len,
+ DtlsRecordCallback recordCallback)
#endif
{
// NOTE: received < 0 (timeout) is covered by this first case
@@ -823,13 +824,19 @@ namespace Org.BouncyCastle.Tls
*/
if (recordCallback != null)
{
- // TODO Make the callback more general than just peer address update
- if (ContentType.tls12_cid == recordType &&
- isLatestConfirmed &&
- recordEpoch == m_readEpoch)
+ var flags = DtlsRecordFlags.None;
+
+ if (recordEpoch == m_readEpoch && isLatestConfirmed)
+ {
+ flags |= DtlsRecordFlags.IsNewest;
+ }
+
+ if (ContentType.tls12_cid == recordType)
{
- recordCallback();
+ flags |= DtlsRecordFlags.UsesConnectionID;
}
+
+ recordCallback(flags);
}
switch (decoded.contentType)
diff --git a/crypto/src/tls/DtlsTransport.cs b/crypto/src/tls/DtlsTransport.cs
index b452b8c89..2e928e761 100644
--- a/crypto/src/tls/DtlsTransport.cs
+++ b/crypto/src/tls/DtlsTransport.cs
@@ -4,6 +4,20 @@ using System.Net.Sockets;
namespace Org.BouncyCastle.Tls
{
+ [Flags]
+ public enum DtlsRecordFlags
+ {
+ None = 0,
+
+ /// <summary>The record is newer (by epoch and sequence number) than any record received previously.</summary>
+ IsNewest = 1,
+
+ /// <summary>The record includes the (valid) connection ID (RFC 9146) for this connection.</summary>
+ UsesConnectionID = 2,
+ }
+
+ public delegate void DtlsRecordCallback(DtlsRecordFlags flags);
+
public class DtlsTransport
: DatagramTransport
{
@@ -34,8 +48,9 @@ namespace Org.BouncyCastle.Tls
return Receive(buf, off, len, waitMillis, null);
}
+ // TODO[api] Add to DatagramTransport (with a default null parameter)
/// <exception cref="IOException"/>
- public virtual int Receive(byte[] buf, int off, int len, int waitMillis, Action recordCallback)
+ public virtual int Receive(byte[] buf, int off, int len, int waitMillis, DtlsRecordCallback recordCallback)
{
if (null == buf)
throw new ArgumentNullException("buf");
@@ -92,8 +107,9 @@ namespace Org.BouncyCastle.Tls
#endif
}
+ // TODO[api] Add to DatagramTransport
/// <exception cref="IOException"/>
- public virtual int ReceivePending(byte[] buf, int off, int len, Action recordCallback = null)
+ public virtual int ReceivePending(byte[] buf, int off, int len, DtlsRecordCallback recordCallback = null)
{
if (null == buf)
throw new ArgumentNullException("buf");
@@ -154,8 +170,9 @@ namespace Org.BouncyCastle.Tls
return Receive(buffer, waitMillis, null);
}
+ // TODO[api] Add to DatagramTransport (with a default null parameter)
/// <exception cref="IOException"/>
- public virtual int Receive(Span<byte> buffer, int waitMillis, Action recordCallback)
+ public virtual int Receive(Span<byte> buffer, int waitMillis, DtlsRecordCallback recordCallback)
{
if (waitMillis < 0)
throw new ArgumentException("cannot be negative", nameof(waitMillis));
@@ -201,8 +218,9 @@ namespace Org.BouncyCastle.Tls
}
}
+ // TODO[api] Add to DatagramTransport
/// <exception cref="IOException"/>
- public virtual int ReceivePending(Span<byte> buffer, Action recordCallback = null)
+ public virtual int ReceivePending(Span<byte> buffer, DtlsRecordCallback recordCallback = null)
{
try
{
|