1
Vote

DiscoverDnsServerAddresses double-checked locking bug

description

See http://confluence.jetbrains.net/display/ReSharper/Read+access+in+double+checked+locking
 
Fixes:
  • set field to volatile
     
    private static volatile List<IPAddress> dnsServerAddresses;
     
  • use a non checked variable for initialization.
     
     
    public static List<IPAddress> DiscoverDnsServerAddresses()
    {
        if (dnsServerAddresses == null)
        {
            lock (syncRoot)
            {
                if (dnsServerAddresses == null)
                {
                    var addresses = new List<IPAddress>();
     
                    NetworkInterface[] arrNetworkInterfaces = NetworkInterface.GetAllNetworkInterfaces();
                    foreach (NetworkInterface objNetworkInterface in arrNetworkInterfaces)
                    {
                        if ( objNetworkInterface.OperationalStatus == OperationalStatus.Up &&
                             objNetworkInterface.Speed > 0 &&
                             objNetworkInterface.NetworkInterfaceType != NetworkInterfaceType.Loopback &&
                             objNetworkInterface.NetworkInterfaceType != NetworkInterfaceType.Tunnel
                            )
                        {
                            foreach (var ip in objNetworkInterface.GetIPProperties().DnsAddresses)
                            {
                                //IPv4 only
                                if (ip.AddressFamily != AddressFamily.InterNetwork)
                                    continue;
     
                                if (addresses.FirstOrDefault(existingIp => ip.Equals(existingIp) ) == null)
                                    addresses.Add(ip);
                            }
                        }
                    }
     
                    //Correct double-check locking requires the use of an intermediate variable "addresses"
                    //See http://confluence.jetbrains.net/display/ReSharper/Read+access+in+double+checked+locking
                    dnsServerAddresses = addresses;
                }
            }
        }
     
        return dnsServerAddresses;
    }

comments