123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242 |
- #if !BESTHTTP_DISABLE_ALTERNATE_SSL && (!UNITY_WEBGL || UNITY_EDITOR)
- #pragma warning disable
- using System;
- using System.IO;
- using System.Net.Sockets;
- namespace Best.HTTP.SecureProtocol.Org.BouncyCastle.Tls
- {
- public class DtlsTransport
- : DatagramTransport
- {
- private readonly DtlsRecordLayer m_recordLayer;
- private readonly bool m_ignoreCorruptRecords;
- internal DtlsTransport(DtlsRecordLayer recordLayer, bool ignoreCorruptRecords)
- {
- m_recordLayer = recordLayer;
- m_ignoreCorruptRecords = ignoreCorruptRecords;
- }
- /// <exception cref="IOException"/>
- public virtual int GetReceiveLimit()
- {
- return m_recordLayer.GetReceiveLimit();
- }
- /// <exception cref="IOException"/>
- public virtual int GetSendLimit()
- {
- return m_recordLayer.GetSendLimit();
- }
- /// <exception cref="IOException"/>
- public virtual int Receive(byte[] buf, int off, int len, int waitMillis)
- {
- if (null == buf)
- throw new ArgumentNullException("buf");
- if (off < 0 || off >= buf.Length)
- throw new ArgumentException("invalid offset: " + off, "off");
- if (len < 0 || len > buf.Length - off)
- throw new ArgumentException("invalid length: " + len, "len");
- #if NETCOREAPP2_1_OR_GREATER || NETSTANDARD2_1_OR_GREATER || UNITY_2021_2_OR_NEWER
- return Receive(buf.AsSpan(off, len), waitMillis);
- #else
- if (waitMillis < 0)
- throw new ArgumentException("cannot be negative", "waitMillis");
- try
- {
- return m_recordLayer.Receive(buf, off, len, waitMillis);
- }
- catch (TlsFatalAlert fatalAlert)
- {
- if (m_ignoreCorruptRecords && AlertDescription.bad_record_mac == fatalAlert.AlertDescription)
- return -1;
- m_recordLayer.Fail(fatalAlert.AlertDescription);
- throw fatalAlert;
- }
- catch (TlsTimeoutException e)
- {
- throw e;
- }
- catch (SocketException e)
- {
- if (TlsUtilities.IsTimeout(e))
- throw e;
- m_recordLayer.Fail(AlertDescription.internal_error);
- throw new TlsFatalAlert(AlertDescription.internal_error, e);
- }
- // TODO[tls-port] Can we support interrupted IO on .NET?
- //catch (InterruptedIOException e)
- //{
- // throw e;
- //}
- catch (IOException e)
- {
- m_recordLayer.Fail(AlertDescription.internal_error);
- throw e;
- }
- catch (Exception e)
- {
- m_recordLayer.Fail(AlertDescription.internal_error);
- throw new TlsFatalAlert(AlertDescription.internal_error, e);
- }
- #endif
- }
- #if NETCOREAPP2_1_OR_GREATER || NETSTANDARD2_1_OR_GREATER || UNITY_2021_2_OR_NEWER
- /// <exception cref="IOException"/>
- public virtual int Receive(Span<byte> buffer, int waitMillis)
- {
- if (waitMillis < 0)
- throw new ArgumentException("cannot be negative", nameof(waitMillis));
- try
- {
- return m_recordLayer.Receive(buffer, waitMillis);
- }
- catch (TlsFatalAlert fatalAlert)
- {
- if (m_ignoreCorruptRecords && AlertDescription.bad_record_mac == fatalAlert.AlertDescription)
- return -1;
- m_recordLayer.Fail(fatalAlert.AlertDescription);
- throw fatalAlert;
- }
- catch (TlsTimeoutException e)
- {
- throw e;
- }
- catch (SocketException e)
- {
- if (TlsUtilities.IsTimeout(e))
- throw e;
- m_recordLayer.Fail(AlertDescription.internal_error);
- throw new TlsFatalAlert(AlertDescription.internal_error, e);
- }
- // TODO[tls-port] Can we support interrupted IO on .NET?
- //catch (InterruptedIOException e)
- //{
- // throw e;
- //}
- catch (IOException e)
- {
- m_recordLayer.Fail(AlertDescription.internal_error);
- throw e;
- }
- catch (Exception e)
- {
- m_recordLayer.Fail(AlertDescription.internal_error);
- throw new TlsFatalAlert(AlertDescription.internal_error, e);
- }
- }
- #endif
- /// <exception cref="IOException"/>
- public virtual void Send(byte[] buf, int off, int len)
- {
- if (null == buf)
- throw new ArgumentNullException("buf");
- if (off < 0 || off >= buf.Length)
- throw new ArgumentException("invalid offset: " + off, "off");
- if (len < 0 || len > buf.Length - off)
- throw new ArgumentException("invalid length: " + len, "len");
- #if NETCOREAPP2_1_OR_GREATER || NETSTANDARD2_1_OR_GREATER || UNITY_2021_2_OR_NEWER
- Send(buf.AsSpan(off, len));
- #else
- try
- {
- m_recordLayer.Send(buf, off, len);
- }
- catch (TlsFatalAlert fatalAlert)
- {
- m_recordLayer.Fail(fatalAlert.AlertDescription);
- throw fatalAlert;
- }
- catch (TlsTimeoutException e)
- {
- throw e;
- }
- catch (SocketException e)
- {
- if (TlsUtilities.IsTimeout(e))
- throw e;
- m_recordLayer.Fail(AlertDescription.internal_error);
- throw new TlsFatalAlert(AlertDescription.internal_error, e);
- }
- // TODO[tls-port] Can we support interrupted IO on .NET?
- //catch (InterruptedIOException e)
- //{
- // throw e;
- //}
- catch (IOException e)
- {
- m_recordLayer.Fail(AlertDescription.internal_error);
- throw e;
- }
- catch (Exception e)
- {
- m_recordLayer.Fail(AlertDescription.internal_error);
- throw new TlsFatalAlert(AlertDescription.internal_error, e);
- }
- #endif
- }
- #if NETCOREAPP2_1_OR_GREATER || NETSTANDARD2_1_OR_GREATER || UNITY_2021_2_OR_NEWER
- public virtual void Send(ReadOnlySpan<byte> buffer)
- {
- try
- {
- m_recordLayer.Send(buffer);
- }
- catch (TlsFatalAlert fatalAlert)
- {
- m_recordLayer.Fail(fatalAlert.AlertDescription);
- throw fatalAlert;
- }
- catch (TlsTimeoutException e)
- {
- throw e;
- }
- catch (SocketException e)
- {
- if (TlsUtilities.IsTimeout(e))
- throw e;
- m_recordLayer.Fail(AlertDescription.internal_error);
- throw new TlsFatalAlert(AlertDescription.internal_error, e);
- }
- // TODO[tls-port] Can we support interrupted IO on .NET?
- //catch (InterruptedIOException e)
- //{
- // throw e;
- //}
- catch (IOException e)
- {
- m_recordLayer.Fail(AlertDescription.internal_error);
- throw e;
- }
- catch (Exception e)
- {
- m_recordLayer.Fail(AlertDescription.internal_error);
- throw new TlsFatalAlert(AlertDescription.internal_error, e);
- }
- }
- #endif
- /// <exception cref="IOException"/>
- public virtual void Close()
- {
- m_recordLayer.Close();
- }
- }
- }
- #pragma warning restore
- #endif
|