summary refs log tree commit diff
path: root/crypto/src
diff options
context:
space:
mode:
authorPeter Dettman <peter.dettman@bouncycastle.org>2020-07-29 23:42:20 +0700
committerPeter Dettman <peter.dettman@bouncycastle.org>2020-07-29 23:42:20 +0700
commitff428e2e8066781e328f29236e696ac74fd257f8 (patch)
tree0324fce1274fdf3d222d7deeb8deb148123c62ef /crypto/src
parentSupport RSASSA-PSS as keypair generator alg (diff)
downloadBouncyCastle.NET-ed25519-ff428e2e8066781e328f29236e696ac74fd257f8.tar.xz
Add Timeout class for DTLS from bc-java
Diffstat (limited to 'crypto/src')
-rw-r--r--crypto/src/crypto/tls/Timeout.cs121
1 files changed, 121 insertions, 0 deletions
diff --git a/crypto/src/crypto/tls/Timeout.cs b/crypto/src/crypto/tls/Timeout.cs
new file mode 100644
index 000000000..924073c4f
--- /dev/null
+++ b/crypto/src/crypto/tls/Timeout.cs
@@ -0,0 +1,121 @@
+using System;
+
+using Org.BouncyCastle.Utilities.Date;
+
+namespace Org.BouncyCastle.Crypto.Tls
+{
+    internal class Timeout
+    {
+        private long durationMillis;
+        private long startMillis;
+
+        internal Timeout(long durationMillis)
+            : this(durationMillis, DateTimeUtilities.CurrentUnixMs())
+        {
+        }
+
+        internal Timeout(long durationMillis, long currentTimeMillis)
+        {
+            this.durationMillis = System.Math.Max(0, durationMillis);
+            this.startMillis = System.Math.Max(0, currentTimeMillis);
+        }
+
+        //internal long RemainingMillis()
+        //{
+        //    return RemainingMillis(DateTimeUtilities.CurrentUnixMs());
+        //}
+
+        internal long RemainingMillis(long currentTimeMillis)
+        {
+            lock (this)
+            {
+                // If clock jumped backwards, reset start time 
+                if (startMillis > currentTimeMillis)
+                {
+                    startMillis = currentTimeMillis;
+                    return durationMillis;
+                }
+
+                long elapsed = currentTimeMillis - startMillis;
+                long remaining = durationMillis - elapsed;
+
+                // Once timeout reached, lock it in
+                if (remaining <= 0)
+                {
+                    return durationMillis = 0L;
+                }
+
+                return remaining;
+            }
+        }
+
+        //internal static int ConstrainWaitMillis(int waitMillis, Timeout timeout)
+        //{
+        //    return ConstrainWaitMillis(waitMillis, timeout, DateTimeUtilities.CurrentUnixMs());
+        //}
+
+        internal static int ConstrainWaitMillis(int waitMillis, Timeout timeout, long currentTimeMillis)
+        {
+            if (waitMillis < 0)
+                return -1;
+
+            int timeoutMillis = GetWaitMillis(timeout, currentTimeMillis);
+            if (timeoutMillis < 0)
+                return -1;
+
+            if (waitMillis == 0)
+                return timeoutMillis;
+
+            if (timeoutMillis == 0)
+                return waitMillis;
+
+            return System.Math.Min(waitMillis, timeoutMillis);
+        }
+
+        internal static Timeout ForWaitMillis(int waitMillis)
+        {
+            return ForWaitMillis(waitMillis, DateTimeUtilities.CurrentUnixMs());
+        }
+
+        internal static Timeout ForWaitMillis(int waitMillis, long currentTimeMillis)
+        {
+            if (waitMillis < 0)
+                throw new ArgumentException("cannot be negative", "waitMillis");
+
+            if (waitMillis > 0)
+                return new Timeout(waitMillis, currentTimeMillis);
+
+            return null;
+        }
+
+        //internal static int GetWaitMillis(Timeout timeout)
+        //{
+        //    return GetWaitMillis(timeout, DateTimeUtilities.CurrentUnixMs());
+        //}
+
+        internal static int GetWaitMillis(Timeout timeout, long currentTimeMillis)
+        {
+            if (null == timeout)
+                return 0;
+
+            long remainingMillis = timeout.RemainingMillis(currentTimeMillis);
+            if (remainingMillis < 1L)
+                return -1;
+
+            if (remainingMillis > int.MaxValue)
+                return int.MaxValue;
+
+            return (int)remainingMillis;
+        }
+
+        //internal static bool HasExpired(Timeout timeout)
+        //{
+        //    return HasExpired(timeout, DateTimeUtilities.CurrentUnixMs());
+        //}
+
+        internal static bool HasExpired(Timeout timeout, long currentTimeMillis)
+        {
+            return null != timeout && timeout.RemainingMillis(currentTimeMillis) < 1L;
+        }
+    }
+}