| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147 |
- //----------------------------------------------------------------------------
- // Copyright (c) Microsoft Corporation. All rights reserved.
- //----------------------------------------------------------------------------
- namespace System.ServiceModel.Channels
- {
- using System.Collections.Generic;
- using System.Diagnostics;
- using System.Net;
- using System.Net.NetworkInformation;
- using System.Net.Sockets;
- using System.Runtime;
- using System.Security.Permissions;
- using System.ServiceModel;
- using System.ServiceModel.Dispatcher;
- using System.Text;
- static class DnsCache
- {
- const int mruWatermark = 64;
- static MruCache<string, DnsCacheEntry> resolveCache = new MruCache<string, DnsCacheEntry>(mruWatermark);
- static readonly TimeSpan cacheTimeout = TimeSpan.FromSeconds(2);
- // Double-checked locking pattern requires volatile for read/write synchronization
- static volatile string machineName;
- static object ThisLock
- {
- get
- {
- return resolveCache;
- }
- }
- public static string MachineName
- {
- get
- {
- if (machineName == null)
- {
- lock (ThisLock)
- {
- if (machineName == null)
- {
- try
- {
- machineName = Dns.GetHostEntry(String.Empty).HostName;
- }
- catch (SocketException exception)
- {
- DiagnosticUtility.TraceHandledException(exception,
- TraceEventType.Information);
- // we fall back to the NetBios machine if Dns fails
- machineName = UnsafeNativeMethods.GetComputerName(ComputerNameFormat.PhysicalNetBIOS);
- }
- }
- }
- }
- return machineName;
- }
- }
- public static IPHostEntry Resolve(Uri uri)
- {
- string hostName = uri.DnsSafeHost;
- IPHostEntry hostEntry = null;
- DateTime now = DateTime.UtcNow;
- lock (ThisLock)
- {
- DnsCacheEntry cacheEntry;
- if (resolveCache.TryGetValue(hostName, out cacheEntry))
- {
- if (now.Subtract(cacheEntry.TimeStamp) > cacheTimeout)
- {
- resolveCache.Remove(hostName);
- }
- else
- {
- if (cacheEntry.HostEntry == null)
- {
- throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(
- new EndpointNotFoundException(SR.GetString(SR.DnsResolveFailed, hostName)));
- }
- hostEntry = cacheEntry.HostEntry;
- }
- }
- }
- if (hostEntry == null)
- {
- SocketException dnsException = null;
- try
- {
- hostEntry = Dns.GetHostEntry(hostName);
- }
- catch (SocketException e)
- {
- dnsException = e;
- }
- lock (ThisLock)
- {
- // MruCache doesn't have a this[] operator, so we first remove (just in case it exists already)
- resolveCache.Remove(hostName);
- resolveCache.Add(hostName, new DnsCacheEntry(hostEntry, now));
- }
- if (dnsException != null)
- {
- throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(
- new EndpointNotFoundException(SR.GetString(SR.DnsResolveFailed, hostName), dnsException));
- }
- }
- return hostEntry;
- }
- class DnsCacheEntry
- {
- IPHostEntry hostEntry;
- DateTime timeStamp;
- public DnsCacheEntry(IPHostEntry hostEntry, DateTime timeStamp)
- {
- this.hostEntry = hostEntry;
- this.timeStamp = timeStamp;
- }
- public IPHostEntry HostEntry
- {
- get
- {
- return hostEntry;
- }
- }
- public DateTime TimeStamp
- {
- get
- {
- return timeStamp;
- }
- }
- }
- }
- }
|