Esempio n. 1
0
        protected override byte[] QueryByTcp(IPAddress nameServer, int port, byte[] messageData, int messageLength, ref TcpClient tcpClient, ref System.IO.Stream tlsStream, out IPAddress responderAddress, out int responderPort)
        {
            responderAddress = nameServer;
            responderPort    = port == 0 ? _port : port;

            if (!IsTcpEnabled)
            {
                return(null);
            }

            IPEndPoint endPoint = new IPEndPoint(nameServer, port == 0 ? _port : port);

            IPAddress         unferResponderAddress = responderAddress;
            int               unferResponderPort    = responderPort;
            TlsUpstreamServer tlsServer             = _tlsservers.Where(t => t.IPAddress == unferResponderAddress && t.Port == unferResponderPort).FirstOrDefault();

            if (tlsServer == null)
            {
                Trace.TraceError("Error on dns query: invalid TLS upstream server");
                return(null);
            }

            try
            {
                if (tcpClient == null || (this.IsReuseTcpEnabled && !tcpClient.IsConnected()))
                {
                    tcpClient = new TcpClient(nameServer.AddressFamily)
                    {
                        ReceiveTimeout = QueryTimeout,
                        SendTimeout    = QueryTimeout
                    };

                    if (!tcpClient.TryConnect(endPoint, QueryTimeout))
                    {
                        return(null);
                    }

                    SslStream sslStream = new SslStream(tcpClient.GetStream(), true, new RemoteCertificateValidationCallback(tlsServer.ValidateRemoteCertificate));
                    tlsStream = sslStream;
                    try
                    {
                        sslStream.AuthenticateAsClient(tlsServer.AuthName ?? string.Empty, new X509CertificateCollection(), tlsServer.SslProtocols, false);
                    }
                    catch (Exception)
                    {
                    }

                    if (!sslStream.IsAuthenticated)
                    {
                        Trace.TraceError("Error on dns query: invalid TLS upstream server certificate");
                        if (this.IsReuseTcpEnabled)
                        {
                            try
                            {
                                tlsStream.Dispose();
                                tcpClient.Close();
                            }
                            catch (Exception)
                            {
                            }
                        }

                        return(null);
                    }
                }

                int    tmp          = 0;
                byte[] lengthBuffer = new byte[2];

                if (messageLength > 0)
                {
                    DnsMessageBase.EncodeUShort(lengthBuffer, ref tmp, (ushort)messageLength);

                    tlsStream.Write(lengthBuffer, 0, 2);
                    tlsStream.Write(messageData, 0, messageLength);
                }

                if (!TryRead(tcpClient, tlsStream, lengthBuffer, 2))
                {
                    return(null);
                }

                tmp = 0;
                int length = DnsMessageBase.ParseUShort(lengthBuffer, ref tmp);

                byte[] resultData = new byte[length];

                return(TryRead(tcpClient, tlsStream, resultData, length) ? resultData : null);
            }
            catch (Exception e)
            {
                Trace.TraceError("Error on dns query: " + e);
                return(null);
            }
        }
 /// <summary>
 ///   Provides a new instance with custom dns server and query timeout
 /// </summary>
 /// <param name="dnsServer"> The IPAddress of the dns server to use </param>
 /// <param name="queryTimeout"> Query timeout in milliseconds </param>
 /// <param name="port"> Server port </param>
 public DnsOverTlsClient(TlsUpstreamServer dnsServer, int queryTimeout, int port = 853)
     : this(new List <TlsUpstreamServer> {
     dnsServer
 }, queryTimeout, port)
 {
 }
Esempio n. 3
0
        protected async override Task <QueryResponse> QueryByTcpAsync(IPAddress nameServer, int port, byte[] messageData, int messageLength, TcpClient tcpClient, System.IO.Stream tlsStream, CancellationToken token)
        {
            if (!IsTcpEnabled)
            {
                return(null);
            }
            int responderPort = port == 0 ? _port : port;

            TlsUpstreamServer tlsServer = _tlsservers.Where(t => t.IPAddress == nameServer && t.Port == responderPort).FirstOrDefault();

            if (tlsServer == null)
            {
                Trace.TraceError("Error on dns query: invalid TLS upstream server");
                return(null);
            }

            string reusableMapKey = string.Concat(nameServer, port);

            if (tcpClient == null && this.IsReuseTcpEnabled)
            {
                if (!this.reusableTcp.ContainsKey(reusableMapKey))
                {
                    this.reusableTcp[reusableMapKey] = new ReusableTcpConnection();
                }

                ReusableTcpConnection reuse = this.reusableTcp[reusableMapKey];
                tcpClient = reuse.Client;
                tlsStream = reuse.Stream;
                this.reusableTcp[reusableMapKey].LastUsed = DateTime.UtcNow;
            }

            try
            {
                if (tcpClient == null || (this.IsReuseTcpEnabled && !tcpClient.IsConnected()))
                {
                    tcpClient = new TcpClient(nameServer.AddressFamily)
                    {
                        ReceiveTimeout = QueryTimeout,
                        SendTimeout    = QueryTimeout
                    };

                    if (!await tcpClient.TryConnectAsync(nameServer, responderPort, QueryTimeout, token))
                    {
                        return(null);
                    }

                    SslStream sslStream = new SslStream(tcpClient.GetStream(), true, new RemoteCertificateValidationCallback(tlsServer.ValidateRemoteCertificate));
                    tlsStream = sslStream;
                    try
                    {
                        sslStream.AuthenticateAsClient(tlsServer.AuthName ?? string.Empty, new X509CertificateCollection(), tlsServer.SslProtocols, false);
                    }
                    catch (Exception)
                    {
                    }

                    if (!sslStream.IsAuthenticated)
                    {
                        Trace.TraceError("Error on dns query: invalid TLS upstream server certificate");
                        if (this.IsReuseTcpEnabled)
                        {
                            try
                            {
                                tlsStream.Dispose();
                                tcpClient.Close();
                            }
                            catch (Exception)
                            {
                            }
                        }

                        return(null);
                    }
                }

                int    tmp          = 0;
                byte[] lengthBuffer = new byte[2];

                if (messageLength > 0)
                {
                    DnsMessageBase.EncodeUShort(lengthBuffer, ref tmp, (ushort)messageLength);

                    await tlsStream.WriteAsync(lengthBuffer, 0, 2, token);

                    await tlsStream.WriteAsync(messageData, 0, messageLength, token);
                }

                if (!await TryReadAsync(tcpClient, tlsStream, lengthBuffer, 2, token))
                {
                    return(null);
                }

                tmp = 0;
                int length = DnsMessageBase.ParseUShort(lengthBuffer, ref tmp);

                byte[] resultData = new byte[length];

                return(await TryReadAsync(tcpClient, tlsStream, resultData, length, token) ? new QueryResponse(resultData, nameServer, tcpClient, tlsStream, responderPort) : null);
            }
            catch (Exception e)
            {
                Trace.TraceError("Error on dns query: " + e);
                return(null);
            }
        }