public static DnsClientConnection GetConnection(NameServerAddress server, NetProxy proxy)
        {
            switch (server.Protocol)
            {
            case DnsTransportProtocol.Udp:
                return(new UdpClientConnection(server, proxy));

            case DnsTransportProtocol.Tcp:
            {
                ConcurrentDictionary <NetProxy, TcpClientConnection> existingTcpConnection = _existingTcpConnections.GetOrAdd(server, delegate(NameServerAddress nameServer)
                    {
                        return(new ConcurrentDictionary <NetProxy, TcpClientConnection>());
                    });

                NetProxy proxyKey = proxy;

                if (proxyKey == null)
                {
                    proxyKey = NetProxy.NONE;
                }

                return(existingTcpConnection.GetOrAdd(proxyKey, delegate(NetProxy netProxyKey)
                    {
                        TcpClientConnection connection = new TcpClientConnection(server, proxy);
                        connection.Pooled = true;
                        return connection;
                    }));
            }

            case DnsTransportProtocol.Tls:
            {
                ConcurrentDictionary <NetProxy, TlsClientConnection> existingTlsConnection = _existingTlsConnections.GetOrAdd(server, delegate(NameServerAddress nameServer)
                    {
                        return(new ConcurrentDictionary <NetProxy, TlsClientConnection>());
                    });

                NetProxy proxyKey = proxy;

                if (proxyKey == null)
                {
                    proxyKey = NetProxy.NONE;
                }

                return(existingTlsConnection.GetOrAdd(proxyKey, delegate(NetProxy netProxyKey)
                    {
                        TlsClientConnection connection = new TlsClientConnection(server, proxy);
                        connection.Pooled = true;
                        return connection;
                    }));
            }

            case DnsTransportProtocol.Https:
            {
                ConcurrentDictionary <NetProxy, HttpsClientConnection> existingHttpsConnection = _existingHttpsConnections.GetOrAdd(server, delegate(NameServerAddress nameServer)
                    {
                        return(new ConcurrentDictionary <NetProxy, HttpsClientConnection>());
                    });

                NetProxy proxyKey = proxy;

                if (proxyKey == null)
                {
                    proxyKey = NetProxy.NONE;
                }

                return(existingHttpsConnection.GetOrAdd(proxyKey, delegate(NetProxy netProxyKey)
                    {
                        HttpsClientConnection connection = new HttpsClientConnection(server, proxy);
                        connection.Pooled = true;
                        return connection;
                    }));
            }

            case DnsTransportProtocol.HttpsJson:
            {
                ConcurrentDictionary <NetProxy, HttpsJsonClientConnection> existingHttpsJsonConnection = _existingHttpsJsonConnections.GetOrAdd(server, delegate(NameServerAddress nameServer)
                    {
                        return(new ConcurrentDictionary <NetProxy, HttpsJsonClientConnection>());
                    });

                NetProxy proxyKey = proxy;

                if (proxyKey == null)
                {
                    proxyKey = NetProxy.NONE;
                }

                return(existingHttpsJsonConnection.GetOrAdd(proxyKey, delegate(NetProxy netProxyKey)
                    {
                        HttpsJsonClientConnection connection = new HttpsJsonClientConnection(server, proxy);
                        connection.Pooled = true;
                        return connection;
                    }));
            }

            default:
                throw new NotSupportedException("DnsClient protocol not supported: " + server.Protocol.ToString());
            }
        }
        static DnsClientConnection()
        {
            _maintenanceTimer = new Timer(delegate(object state)
            {
                try
                {
                    DateTime expiryTime = DateTime.UtcNow.AddMilliseconds(CONNECTION_EXPIRY * -1);

                    //cleanup unused tcp connections
                    foreach (NameServerAddress nameServer in _existingTcpConnections.Keys.ToArray())
                    {
                        ConcurrentDictionary <object, TcpClientConnection> existingTcpConnection = _existingTcpConnections[nameServer];

                        foreach (object proxy in existingTcpConnection.Keys.ToArray())
                        {
                            TcpClientConnection connection = existingTcpConnection[proxy];

                            if (connection.LastQueried < expiryTime)
                            {
                                if (existingTcpConnection.TryRemove(proxy, out TcpClientConnection removedConnection))
                                {
                                    removedConnection.Pooled = false;
                                    removedConnection.Dispose();
                                }
                            }
                        }

                        if (existingTcpConnection.IsEmpty)
                        {
                            _existingTcpConnections.TryRemove(nameServer, out _);
                        }
                    }

                    //cleanup unused tls connections
                    foreach (NameServerAddress nameServer in _existingTlsConnections.Keys.ToArray())
                    {
                        ConcurrentDictionary <object, TlsClientConnection> existingTlsConnection = _existingTlsConnections[nameServer];

                        foreach (object proxy in existingTlsConnection.Keys.ToArray())
                        {
                            TlsClientConnection connection = existingTlsConnection[proxy];

                            if (connection.LastQueried < expiryTime)
                            {
                                if (existingTlsConnection.TryRemove(proxy, out TlsClientConnection removedConnection))
                                {
                                    removedConnection.Pooled = false;
                                    removedConnection.Dispose();
                                }
                            }
                        }

                        if (existingTlsConnection.IsEmpty)
                        {
                            _existingTlsConnections.TryRemove(nameServer, out _);
                        }
                    }

                    //cleanup unused https connections
                    foreach (NameServerAddress nameServer in _existingHttpsConnections.Keys.ToArray())
                    {
                        ConcurrentDictionary <object, HttpsClientConnection> existingHttpsConnection = _existingHttpsConnections[nameServer];

                        foreach (object proxy in existingHttpsConnection.Keys.ToArray())
                        {
                            HttpsClientConnection connection = existingHttpsConnection[proxy];

                            if (connection.LastQueried < expiryTime)
                            {
                                if (existingHttpsConnection.TryRemove(proxy, out HttpsClientConnection removedConnection))
                                {
                                    removedConnection.Pooled = false;
                                    removedConnection.Dispose();
                                }
                            }
                        }

                        if (existingHttpsConnection.IsEmpty)
                        {
                            _existingHttpsConnections.TryRemove(nameServer, out _);
                        }
                    }

                    //cleanup unused https json connections
                    foreach (NameServerAddress nameServer in _existingHttpsJsonConnections.Keys.ToArray())
                    {
                        ConcurrentDictionary <object, HttpsJsonClientConnection> existingHttpsJsonConnection = _existingHttpsJsonConnections[nameServer];

                        foreach (object proxy in existingHttpsJsonConnection.Keys.ToArray())
                        {
                            HttpsJsonClientConnection connection = existingHttpsJsonConnection[proxy];

                            if (connection.LastQueried < expiryTime)
                            {
                                if (existingHttpsJsonConnection.TryRemove(proxy, out HttpsJsonClientConnection removedConnection))
                                {
                                    removedConnection.Pooled = false;
                                    removedConnection.Dispose();
                                }
                            }
                        }

                        if (existingHttpsJsonConnection.IsEmpty)
                        {
                            _existingHttpsJsonConnections.TryRemove(nameServer, out _);
                        }
                    }
                }
                catch
                { }
            });

            _maintenanceTimer.Change(MAINTENANCE_TIMER_INITIAL_INTERVAL, MAINTENANCE_TIMER_PERIODIC_INTERVAL);
        }