<PackageReference Include="BouncyCastle.Cryptography" Version="2.6.2" />

DtlsTransport

using System; using System.IO; using System.Net.Sockets; namespace Org.BouncyCastle.Tls { public class DtlsTransport : DatagramTransport, DatagramReceiver, DatagramSender, TlsCloseable { private readonly DtlsRecordLayer m_recordLayer; private readonly bool m_ignoreCorruptRecords; internal DtlsTransport(DtlsRecordLayer recordLayer, bool ignoreCorruptRecords) { m_recordLayer = recordLayer; m_ignoreCorruptRecords = ignoreCorruptRecords; } public virtual int GetReceiveLimit() { return m_recordLayer.GetReceiveLimit(); } public virtual int GetSendLimit() { return m_recordLayer.GetSendLimit(); } public virtual int Receive(byte[] buf, int off, int len, int waitMillis) { return Receive(buf, off, len, waitMillis, null); } public virtual int Receive(byte[] buf, int off, int len, int waitMillis, DtlsRecordCallback recordCallback) { if (buf == null) throw new ArgumentNullException("buf"); if (off < 0 || off >= buf.Length) throw new ArgumentException("invalid offset: " + off.ToString(), "off"); if (len < 0 || len > buf.Length - off) throw new ArgumentException("invalid length: " + len.ToString(), "len"); return Receive(buf.AsSpan(off, len), waitMillis, recordCallback); } public virtual int ReceivePending(byte[] buf, int off, int len, DtlsRecordCallback recordCallback = null) { if (buf == null) throw new ArgumentNullException("buf"); if (off < 0 || off >= buf.Length) throw new ArgumentException("invalid offset: " + off.ToString(), "off"); if (len < 0 || len > buf.Length - off) throw new ArgumentException("invalid length: " + len.ToString(), "len"); return ReceivePending(buf.AsSpan(off, len), recordCallback); } public virtual int Receive(Span<byte> buffer, int waitMillis) { return Receive(buffer, waitMillis, null); } public virtual int Receive(Span<byte> buffer, int waitMillis, DtlsRecordCallback recordCallback) { if (waitMillis >= 0) try { return m_recordLayer.Receive(buffer, waitMillis, recordCallback); } catch (TlsFatalAlert tlsFatalAlert) { if (!m_ignoreCorruptRecords || 20 != tlsFatalAlert.AlertDescription) { m_recordLayer.Fail(tlsFatalAlert.AlertDescription); throw; } return -1; } catch (TlsTimeoutException) { throw; } catch (SocketException ex2) { if (TlsUtilities.IsTimeout(ex2)) throw; m_recordLayer.Fail(80); throw new TlsFatalAlert(80, ex2); } catch (IOException) { m_recordLayer.Fail(80); throw; } catch (Exception alertCause) { m_recordLayer.Fail(80); throw new TlsFatalAlert(80, alertCause); } throw new ArgumentException("cannot be negative", "waitMillis"); } public virtual int ReceivePending(Span<byte> buffer, DtlsRecordCallback recordCallback = null) { try { return m_recordLayer.ReceivePending(buffer, recordCallback); } catch (TlsFatalAlert tlsFatalAlert) { if (!m_ignoreCorruptRecords || 20 != tlsFatalAlert.AlertDescription) { m_recordLayer.Fail(tlsFatalAlert.AlertDescription); throw; } return -1; } catch (TlsTimeoutException) { throw; } catch (SocketException ex2) { if (TlsUtilities.IsTimeout(ex2)) throw; m_recordLayer.Fail(80); throw new TlsFatalAlert(80, ex2); } catch (IOException) { m_recordLayer.Fail(80); throw; } catch (Exception alertCause) { m_recordLayer.Fail(80); throw new TlsFatalAlert(80, alertCause); } } public virtual void Send(byte[] buf, int off, int len) { if (buf == null) throw new ArgumentNullException("buf"); if (off < 0 || off >= buf.Length) throw new ArgumentException("invalid offset: " + off.ToString(), "off"); if (len < 0 || len > buf.Length - off) throw new ArgumentException("invalid length: " + len.ToString(), "len"); Send(buf.AsSpan(off, len)); } public virtual void Send(ReadOnlySpan<byte> buffer) { try { m_recordLayer.Send(buffer); } catch (TlsFatalAlert tlsFatalAlert) { m_recordLayer.Fail(tlsFatalAlert.AlertDescription); throw; } catch (TlsTimeoutException) { throw; } catch (SocketException ex2) { if (TlsUtilities.IsTimeout(ex2)) throw; m_recordLayer.Fail(80); throw new TlsFatalAlert(80, ex2); } catch (IOException) { m_recordLayer.Fail(80); throw; } catch (Exception alertCause) { m_recordLayer.Fail(80); throw new TlsFatalAlert(80, alertCause); } } public virtual void Close() { m_recordLayer.Close(); } } }