/******************************************************************************* * Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved. * Licensed under the Apache License, Version 2.0 (the "License"). You may not use * this file except in compliance with the License. A copy of the License is located at * * http://aws.amazon.com/apache2.0 * * or in the "license" file accompanying this file. * This file is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR * CONDITIONS OF ANY KIND, either express or implied. See the License for the * specific language governing permissions and limitations under the License. * ***************************************************************************** * __ _ _ ___ * ( )( \/\/ )/ __) * /__\ \ / \__ \ * (_)(_) \/\/ (___/ * * AWS SDK for .NET * API Version: 2006-03-01 * */ using System; using System.Collections.Generic; using Amazon.Util.Internal; using System.Threading; namespace Amazon.Runtime { /// /// Utility class that stores clock skew information. /// public static class CorrectClockSkew { private static TimeSpan? manualClockCorrection; private static ReaderWriterLockSlim manualClockCorrectionLock = new ReaderWriterLockSlim(); /// /// GlobalClockCorrection should be only set by AWSConfigs.ManualClockCorrection property /// and is only available to maintain backward compatibilty. This should override any /// endpoint specific clockskew correction. /// internal static TimeSpan? GlobalClockCorrection { get { TimeSpan? value; manualClockCorrectionLock.EnterReadLock(); { value = manualClockCorrection; } manualClockCorrectionLock.ExitReadLock(); return value; } set { manualClockCorrectionLock.EnterWriteLock(); { manualClockCorrection = value; } manualClockCorrectionLock.ExitWriteLock(); } } private static IDictionary clockCorrectionDictionary = new Dictionary(); private static ReaderWriterLockSlim clockCorrectionDictionaryLock = new ReaderWriterLockSlim(); /// /// Return clock skew correction value for an endpoint if there is one. /// /// AWSConfigs.ManualClockCorrection overrides globally any calculated service endpoint specific /// clock correction value. /// /// Endpoint should in a form such as "https://s3" /// Clock correction value for an endpoint in TimeSpan. TimeSpan.Zero if no such clock correction is set. public static TimeSpan GetClockCorrectionForEndpoint(string endpoint) { TimeSpan span; bool hasValue = false; clockCorrectionDictionaryLock.EnterReadLock(); try { hasValue = clockCorrectionDictionary.TryGetValue(endpoint, out span); } finally { clockCorrectionDictionaryLock.ExitReadLock(); } return hasValue ? span : TimeSpan.Zero; } /// /// Get clock skew corrected UTC now value. If ManualClockCorrection is set, /// use ManualClockCorrection instead of endpoint specific clock correction value. /// /// /// public static DateTime GetCorrectedUtcNowForEndpoint(string endpoint) { TimeSpan adjustment = TimeSpan.Zero; manualClockCorrectionLock.EnterReadLock(); try { if (manualClockCorrection != null) adjustment = manualClockCorrection.Value; } finally { manualClockCorrectionLock.ExitReadLock(); } if (AWSConfigs.CorrectForClockSkew && (adjustment == TimeSpan.Zero)) { adjustment = GetClockCorrectionForEndpoint(endpoint); } return AWSConfigs.utcNowSource() + adjustment; } internal static void SetClockCorrectionForEndpoint(string endpoint, TimeSpan correction) { clockCorrectionDictionaryLock.EnterWriteLock(); try { clockCorrectionDictionary[endpoint] = correction; #pragma warning disable CS0618 // Type or member is obsolete AWSConfigs.ClockOffset = correction; #pragma warning restore CS0618 // Type or member is obsolete } finally { clockCorrectionDictionaryLock.ExitWriteLock(); } } } }