Example #1
0
            public void SetResponse(DnsDatagram response, NameServerAddress server, DnsTransportProtocol protocol)
            {
                if (_isZoneTransferRequest)
                {
                    if (_firstResponse is null)
                    {
                        _firstResponse = response;
                    }
                    else
                    {
                        _lastResponse.NextDatagram = response;
                    }

                    _lastResponse = response;

                    if ((_lastResponse.Answer.Count == 0) || (_lastResponse.Answer[_lastResponse.Answer.Count - 1].Type == DnsResourceRecordType.SOA))
                    {
                        //found last response
                        _stopwatch.Stop();

                        _firstResponse.SetMetadata(server, protocol, _stopwatch.Elapsed.TotalMilliseconds);

                        _responseTask.TrySetResult(_firstResponse);
                    }
                }
                else
                {
                    _stopwatch.Stop();

                    response.SetMetadata(server, protocol, _stopwatch.Elapsed.TotalMilliseconds);

                    _responseTask.TrySetResult(response);
                }
            }
Example #2
0
        public DnsForwarderRecord(DnsTransportProtocol protocol, string forwarder)
        {
            _protocol  = protocol;
            _forwarder = forwarder;

            _nameServer = new NameServerAddress(_forwarder, _protocol);
        }
Example #3
0
        public Startup(IConfiguration configuration)
        {
            Configuration = configuration;

            DnsTransportProtocol protocol = (DnsTransportProtocol)Enum.Parse(typeof(DnsTransportProtocol), Configuration.GetValue <string>("dnsServerProtocol"), true);

            _dnsServer = new NameServerAddress(Configuration.GetValue <string>("dnsServer"), protocol);
            _timeout   = Configuration.GetValue <int>("dnsTimeout");
            _debug     = Configuration.GetValue <bool>("debug");
        }
Example #4
0
        private async Task NotifyNameServerAsync(NameServerAddress nameServer)
        {
            try
            {
                DnsClient client = new DnsClient(nameServer);

                client.Timeout = NOTIFY_TIMEOUT;
                client.Retries = NOTIFY_RETRIES;

                DnsDatagram notifyRequest = new DnsDatagram(0, false, DnsOpcode.Notify, true, false, false, false, false, false, DnsResponseCode.NoError, new DnsQuestionRecord[] { new DnsQuestionRecord(_name, DnsResourceRecordType.SOA, DnsClass.IN) }, _entries[DnsResourceRecordType.SOA]);
                DnsDatagram response      = await client.ResolveAsync(notifyRequest);

                switch (response.RCODE)
                {
                case DnsResponseCode.NoError:
                case DnsResponseCode.NotImplemented:
                {
                    //transaction complete
                    LogManager log = _dnsServer.LogManager;
                    if (log != null)
                    {
                        log.Write("DNS Server successfully notified name server for '" + _name + "' zone changes: " + nameServer.ToString());
                    }
                }
                break;

                default:
                {
                    //transaction failed
                    LogManager log = _dnsServer.LogManager;
                    if (log != null)
                    {
                        log.Write("DNS Server received RCODE=" + response.RCODE.ToString() + " from name server for '" + _name + "' zone notification: " + nameServer.ToString());
                    }
                }
                break;
                }
            }
            catch (Exception ex)
            {
                LogManager log = _dnsServer.LogManager;
                if (log != null)
                {
                    log.Write("DNS Server failed to notify name server for '" + _name + "' zone changes: " + nameServer.ToString());
                    log.Write(ex);
                }
            }
            finally
            {
                lock (_notifyList)
                {
                    _notifyList.Remove(nameServer);
                }
            }
        }
Example #5
0
        public UdpClientConnection(NameServerAddress server, NetProxy proxy)
            : base(DnsTransportProtocol.Udp, server, proxy)
        {
            if (proxy != null)
            {
                if (proxy.Type == NetProxyType.Http)
                {
                    throw new NotSupportedException("DnsClient cannot use HTTP proxy with UDP protocol.");
                }
            }

            _timeout = 2000;
        }
Example #6
0
        private void NotifyNameServer(NameServerAddress nameServer)
        {
            //use notify list to prevent multiple threads from notifying the same name server
            lock (_notifyList)
            {
                if (_notifyList.Contains(nameServer))
                {
                    return; //already notifying the name server in another thread
                }
                _notifyList.Add(nameServer);
            }

            _ = NotifyNameServerAsync(nameServer);
        }
        public HttpsClientConnection(NameServerAddress server, NetProxy proxy)
            : base(DnsTransportProtocol.Https, server, proxy)
        {
            if (proxy == null)
            {
                _httpClient = new HttpClient();
            }
            else
            {
                SocketsHttpHandler handler = new SocketsHttpHandler();
                handler.Proxy = proxy;

                _httpClient = new HttpClient(handler);
            }

            _httpClient.DefaultRequestHeaders.Add("accept", "application/dns-message");
            _httpClient.DefaultRequestHeaders.Add("host", _server.DnsOverHttpEndPoint.Host + ":" + _server.DnsOverHttpEndPoint.Port);
            _httpClient.DefaultRequestHeaders.Add("user-agent", "DoH client");
        }
Example #8
0
        /// <summary>开始</summary>
        /// <returns></returns>
        public virtual Boolean Start()
        {
            if (Active)
            {
                return(true);
            }

            if (NameServerAddress.IsNullOrEmpty())
            {
                // 获取阿里云ONS的名称服务器地址
                var addr = Server;
                if (!addr.IsNullOrEmpty() && addr.StartsWithIgnoreCase("http"))
                {
                    var http = new TinyHttpClient();
                    var html = http.GetStringAsync(addr).Result;

                    if (!html.IsNullOrWhiteSpace())
                    {
                        NameServerAddress = html.Trim();
                    }
                }
            }

            var client = new NameClient(ClientId, this)
            {
                Name = "Name", Log = Log
            };

            client.Start();

            var rs = client.GetRouteInfo(Topic);

            foreach (var item in rs)
            {
                XTrace.WriteLine("发现Broker[{0}]: {1}", item.Name, item.Addresses.Join());
            }

            _NameServer = client;

            return(Active = true);
        }
Example #9
0
        protected override void Parse(Stream s)
        {
            int b = s.ReadByte();

            if (b < 0)
            {
                throw new EndOfStreamException();
            }

            _protocol = (DnsTransportProtocol)b;

            b = s.ReadByte();
            if (b < 0)
            {
                throw new EndOfStreamException();
            }

            _forwarder = Encoding.ASCII.GetString(s.ReadBytes(b));

            _nameServer = new NameServerAddress(_forwarder, _protocol);
        }
        public DnsResourceRecordInfo(BinaryReader bR, bool isSoa)
        {
            byte version = bR.ReadByte();

            switch (version)
            {
            case 1:
                _disabled = bR.ReadBoolean();
                break;

            case 2:
            case 3:
            case 4:
            case 5:
            case 6:
            case 7:
                _disabled = bR.ReadBoolean();

                if ((version < 5) && isSoa)
                {
                    //read old glue records as NameServerAddress in case of SOA record
                    int count = bR.ReadByte();
                    if (count > 0)
                    {
                        NameServerAddress[] primaryNameServers = new NameServerAddress[count];

                        for (int i = 0; i < primaryNameServers.Length; i++)
                        {
                            DnsResourceRecord glueRecord = new DnsResourceRecord(bR.BaseStream);

                            IPAddress address;

                            switch (glueRecord.Type)
                            {
                            case DnsResourceRecordType.A:
                                address = (glueRecord.RDATA as DnsARecordData).Address;
                                break;

                            case DnsResourceRecordType.AAAA:
                                address = (glueRecord.RDATA as DnsAAAARecordData).Address;
                                break;

                            default:
                                continue;
                            }

                            primaryNameServers[i] = new NameServerAddress(address);
                        }

                        _primaryNameServers = primaryNameServers;
                    }
                }
                else
                {
                    int count = bR.ReadByte();
                    if (count > 0)
                    {
                        DnsResourceRecord[] glueRecords = new DnsResourceRecord[count];

                        for (int i = 0; i < glueRecords.Length; i++)
                        {
                            glueRecords[i] = new DnsResourceRecord(bR.BaseStream);
                        }

                        _glueRecords = glueRecords;
                    }
                }

                if (version >= 3)
                {
                    _comments = bR.ReadShortString();
                }

                if (version >= 4)
                {
                    _deletedOn = bR.ReadDateTime();
                }

                if (version >= 5)
                {
                    int count = bR.ReadByte();
                    if (count > 0)
                    {
                        NameServerAddress[] primaryNameServers = new NameServerAddress[count];

                        for (int i = 0; i < primaryNameServers.Length; i++)
                        {
                            primaryNameServers[i] = new NameServerAddress(bR);
                        }

                        _primaryNameServers = primaryNameServers;
                    }
                }

                if (version >= 7)
                {
                    _zoneTransferProtocol = (DnsTransportProtocol)bR.ReadByte();

                    _tsigKeyName = bR.ReadShortString();
                }
                else if (version >= 6)
                {
                    _zoneTransferProtocol = (DnsTransportProtocol)bR.ReadByte();

                    _tsigKeyName = bR.ReadShortString();
                    _            = bR.ReadShortString(); //_tsigSharedSecret (obsolete)
                    _            = bR.ReadShortString(); //_tsigAlgorithm (obsolete)
                }

                break;

            default:
                throw new InvalidDataException("DnsResourceRecordInfo format version not supported.");
            }
        }
Example #11
0
        public Startup(IConfiguration configuration)
        {
            Configuration = configuration;

            _dnsServer = new NameServerAddress(Configuration.GetValue <string>("DnsServer"));
        }
 protected TcpClientConnection(DnsTransportProtocol protocol, NameServerAddress server, NetProxy proxy)
     : base(protocol, server, proxy)
 {
 }
 public TcpClientConnection(NameServerAddress server, NetProxy proxy)
     : base(DnsTransportProtocol.Tcp, server, proxy)
 {
     _timeout = 2000;
 }
Example #14
0
        private void NotifyNameServer(NameServerAddress nameServer)
        {
            //use notify list to prevent multiple threads from notifying the same name server
            lock (_notifyList)
            {
                if (_notifyList.Contains(nameServer))
                {
                    return; //already notifying the name server in another thread
                }
                _notifyList.Add(nameServer);
            }

            ThreadPool.QueueUserWorkItem(delegate(object state)
            {
                try
                {
                    DnsClient client = new DnsClient(nameServer);

                    client.Timeout = NOTIFY_TIMEOUT;
                    client.Retries = NOTIFY_RETRIES;

                    DnsDatagram notifyRequest = new DnsDatagram(0, false, DnsOpcode.Notify, true, false, false, false, false, false, DnsResponseCode.NoError, new DnsQuestionRecord[] { new DnsQuestionRecord(_name, DnsResourceRecordType.SOA, DnsClass.IN) }, _entries[DnsResourceRecordType.SOA]);
                    DnsDatagram response      = client.Resolve(notifyRequest);

                    switch (response.RCODE)
                    {
                    case DnsResponseCode.NoError:
                    case DnsResponseCode.NotImplemented:
                        {
                            //transaction complete
                            LogManager log = _dnsServer.LogManager;
                            if (log != null)
                            {
                                log.Write("DNS Server successfully notified name server for '" + _name + "' zone changes: " + nameServer.ToString());
                            }
                        }
                        break;

                    default:
                        {
                            //transaction failed
                            LogManager log = _dnsServer.LogManager;
                            if (log != null)
                            {
                                log.Write("DNS Server received RCODE=" + response.RCODE.ToString() + " from name server for '" + _name + "' zone notification: " + nameServer.ToString());
                            }
                        }
                        break;
                    }
                }
                catch (Exception ex)
                {
                    LogManager log = _dnsServer.LogManager;
                    if (log != null)
                    {
                        log.Write("DNS Server failed to notify name server for '" + _name + "' zone changes: " + nameServer.ToString());
                        log.Write(ex);
                    }
                }
                finally
                {
                    lock (_notifyList)
                    {
                        _notifyList.Remove(nameServer);
                    }
                }
            });
        }
Example #15
0
        public void Configure(IApplicationBuilder app, IHostEnvironment env)
        {
            int staticFilesCachePeriod;

            if (env.IsDevelopment())
            {
                staticFilesCachePeriod = 60;
                app.UseDeveloperExceptionPage();
            }
            else
            {
                staticFilesCachePeriod = 14400;
            }

            app.UseDefaultFiles();
            app.UseStaticFiles(new StaticFileOptions()
            {
                OnPrepareResponse = delegate(StaticFileResponseContext ctx)
                {
                    ctx.Context.Response.Headers.Append("Cache-Control", $"public, max-age={staticFilesCachePeriod}");
                }
            });

            app.Run(async(context) =>
            {
                HttpRequest request   = context.Request;
                HttpResponse response = context.Response;

                if (request.Path == "/api/dnsclient/")
                {
                    try
                    {
                        string server = request.Query["server"];
                        string domain = request.Query["domain"];
                        DnsResourceRecordType type = (DnsResourceRecordType)Enum.Parse(typeof(DnsResourceRecordType), request.Query["type"], true);

                        domain = domain.Trim();

                        if (domain.EndsWith("."))
                        {
                            domain = domain.Substring(0, domain.Length - 1);
                        }

                        bool preferIpv6        = Configuration.GetValue <bool>("PreferIpv6");
                        bool randomizeName     = false;
                        bool qnameMinimization = false;
                        int retries            = Configuration.GetValue <int>("Retries");
                        int timeout            = Configuration.GetValue <int>("Timeout");

                        DnsDatagram dnsResponse;

                        if (server == "recursive-resolver")
                        {
                            DnsQuestionRecord question;

                            if ((type == DnsResourceRecordType.PTR) && IPAddress.TryParse(domain, out IPAddress address))
                            {
                                question = new DnsQuestionRecord(address, DnsClass.IN);
                            }
                            else
                            {
                                question = new DnsQuestionRecord(domain, type, DnsClass.IN);
                            }

                            dnsResponse = await DnsClient.RecursiveResolveAsync(question, null, null, preferIpv6, randomizeName, qnameMinimization, retries, timeout);
                        }
                        else
                        {
                            DnsTransportProtocol protocol = (DnsTransportProtocol)Enum.Parse(typeof(DnsTransportProtocol), request.Query["protocol"], true);

                            if ((protocol == DnsTransportProtocol.Tls) && !server.Contains(":853"))
                            {
                                server += ":853";
                            }

                            NameServerAddress nameServer = new NameServerAddress(server, protocol);

                            if (nameServer.IPEndPoint == null)
                            {
                                await nameServer.ResolveIPAddressAsync(null, null, preferIpv6);
                            }
                            else if (nameServer.DomainEndPoint == null)
                            {
                                try
                                {
                                    await nameServer.ResolveDomainNameAsync(null, null, preferIpv6);
                                }
                                catch
                                { }
                            }

                            DnsClient dnsClient = new DnsClient(nameServer);

                            dnsClient.PreferIPv6    = preferIpv6;
                            dnsClient.RandomizeName = randomizeName;
                            dnsClient.Retries       = retries;
                            dnsClient.Timeout       = timeout;

                            dnsResponse = await dnsClient.ResolveAsync(domain, type);
                        }

                        string jsonResponse = JsonConvert.SerializeObject(dnsResponse, new StringEnumConverter());

                        response.Headers.Add("Content-Type", "application/json; charset=utf-8");
                        await response.WriteAsync("{\"status\":\"ok\", \"response\":" + jsonResponse + "}");
                    }
                    catch (Exception ex)
                    {
                        string jsonResponse = JsonConvert.SerializeObject(ex);

                        response.Headers.Add("Content-Type", "application/json; charset=utf-8");
                        await response.WriteAsync("{\"status\":\"error\", \"response\":" + jsonResponse + "}");
                    }
                }
            });
        }
Example #16
0
        protected void Page_Load(object sender, EventArgs e)
        {
            try
            {
                string server = Request.QueryString["server"];
                string domain = Request.QueryString["domain"];
                DnsResourceRecordType type = (DnsResourceRecordType)Enum.Parse(typeof(DnsResourceRecordType), Request.QueryString["type"]);

                DnsDatagram dnsResponse;

                if (server == "root-servers")
                {
                    dnsResponse = DnsClient.ResolveViaRootNameServers(domain, type, new SimpleDnsCache(), null, PREFER_IPv6, TCP, RETRIES, MAX_STACK_COUNT);
                }
                else
                {
                    NameServerAddress[] nameServers;

                    if (IPAddress.TryParse(server, out IPAddress serverIP))
                    {
                        string serverDomain = null;

                        try
                        {
                            serverDomain = (new DnsClient()
                            {
                                PreferIPv6 = PREFER_IPv6, Tcp = TCP, Retries = RETRIES
                            }).ResolvePTR(serverIP);
                        }
                        catch
                        { }

                        nameServers = new NameServerAddress[] { new NameServerAddress(serverDomain, serverIP) };
                    }
                    else
                    {
                        IPAddress[] serverIPs = (new DnsClient()
                        {
                            PreferIPv6 = PREFER_IPv6, Tcp = TCP, Retries = RETRIES
                        }).ResolveIP(server, PREFER_IPv6);

                        nameServers = new NameServerAddress[serverIPs.Length];

                        for (int i = 0; i < serverIPs.Length; i++)
                        {
                            nameServers[i] = new NameServerAddress(server, serverIPs[i]);
                        }
                    }

                    dnsResponse = (new DnsClient(nameServers)
                    {
                        PreferIPv6 = PREFER_IPv6, Tcp = TCP, Retries = RETRIES
                    }).Resolve(domain, type);
                }

                string jsonResponse = JsonConvert.SerializeObject(dnsResponse, new StringEnumConverter());

                Response.AddHeader("Content-Type", "application/json; charset=utf-8");
                Response.Write("{\"status\":\"ok\", \"response\":" + jsonResponse + "}");
            }
            catch (Exception ex)
            {
                string jsonResponse = JsonConvert.SerializeObject(ex);

                Response.AddHeader("Content-Type", "application/json; charset=utf-8");
                Response.Write("{\"status\":\"error\", \"response\":" + jsonResponse + "}");
            }
        }
 public HttpsJsonClientConnection(NameServerAddress server, NetProxy proxy)
     : base(DnsTransportProtocol.HttpsJson, server, proxy)
 {
     _timeout = 5000;
 }
Example #18
0
        public void Configure(IApplicationBuilder app, IHostingEnvironment env)
        {
            int staticFilesCachePeriod;

            if (env.IsDevelopment())
            {
                staticFilesCachePeriod = 60;
                app.UseDeveloperExceptionPage();
            }
            else
            {
                staticFilesCachePeriod = 14400;
            }

            app.UseDefaultFiles();
            app.UseStaticFiles(new StaticFileOptions()
            {
                OnPrepareResponse = delegate(StaticFileResponseContext ctx)
                {
                    ctx.Context.Response.Headers.Append("Cache-Control", $"public, max-age={staticFilesCachePeriod}");
                }
            });

            app.Run(async(context) =>
            {
                await Task.Run(() =>
                {
                    HttpRequest Request   = context.Request;
                    HttpResponse Response = context.Response;

                    if (Request.Path == "/api/dnsclient/")
                    {
                        try
                        {
                            string server = Request.Query["server"];
                            string domain = Request.Query["domain"];
                            DnsResourceRecordType type = (DnsResourceRecordType)Enum.Parse(typeof(DnsResourceRecordType), Request.Query["type"], true);

                            if (domain.EndsWith("."))
                            {
                                domain = domain.Substring(0, domain.Length - 1);
                            }

                            bool preferIpv6 = Configuration.GetValue <bool>("PreferIpv6");
                            int retries     = Configuration.GetValue <int>("Retries");
                            int timeout     = Configuration.GetValue <int>("Timeout");

                            DnsDatagram dnsResponse;

                            if (server == "recursive-resolver")
                            {
                                bool useTcp = Configuration.GetValue <bool>("UseTcpForRecursion");
                                DnsQuestionRecord question;

                                if (type == DnsResourceRecordType.PTR)
                                {
                                    question = new DnsQuestionRecord(IPAddress.Parse(domain), DnsClass.IN);
                                }
                                else
                                {
                                    question = new DnsQuestionRecord(domain, type, DnsClass.IN);
                                }

                                dnsResponse = DnsClient.RecursiveResolve(question, null, null, null, preferIpv6, retries, timeout, useTcp);
                            }
                            else
                            {
                                DnsTransportProtocol protocol = (DnsTransportProtocol)Enum.Parse(typeof(DnsTransportProtocol), Request.Query["protocol"], true);
                                NameServerAddress nameServer  = new NameServerAddress(server);

                                if (nameServer.IPEndPoint == null)
                                {
                                    nameServer.ResolveIPAddress(null, null, preferIpv6);
                                }
                                else if (nameServer.DomainEndPoint == null)
                                {
                                    try
                                    {
                                        nameServer.ResolveDomainName(null, null, preferIpv6);
                                    }
                                    catch
                                    { }
                                }

                                DnsClient dnsClient = new DnsClient(nameServer);

                                dnsClient.PreferIPv6 = preferIpv6;
                                dnsClient.Protocol   = protocol;
                                dnsClient.Retries    = retries;
                                dnsClient.Timeout    = timeout;

                                dnsResponse = dnsClient.Resolve(domain, type);

                                if (dnsResponse.Header.Truncation && (dnsClient.Protocol == DnsTransportProtocol.Udp))
                                {
                                    dnsClient.Protocol = DnsTransportProtocol.Tcp;
                                    dnsResponse        = dnsClient.Resolve(domain, type);
                                }
                            }

                            string jsonResponse = JsonConvert.SerializeObject(dnsResponse, new StringEnumConverter());

                            Response.Headers.Add("Content-Type", "application/json; charset=utf-8");
                            Response.WriteAsync("{\"status\":\"ok\", \"response\":" + jsonResponse + "}");
                        }
                        catch (Exception ex)
                        {
                            string jsonResponse = JsonConvert.SerializeObject(ex);

                            Response.Headers.Add("Content-Type", "application/json; charset=utf-8");
                            Response.WriteAsync("{\"status\":\"error\", \"response\":" + jsonResponse + "}");
                        }
                    }
                });
            });
        }
 protected DnsClientConnection(DnsTransportProtocol protocol, NameServerAddress server, NetProxy proxy)
 {
     _protocol = protocol;
     _server   = server;
     _proxy    = proxy;
 }
        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());
            }
        }
 public UdpClientConnection(NameServerAddress server, NetProxy proxy)
     : base(DnsTransportProtocol.Udp, server, proxy)
 {
 }
Example #22
0
        private DnsDatagram ProcessAuthoritativeQuery(DnsDatagram request, bool isRecursionAllowed)
        {
            DnsDatagram response = _authoritativeZoneRoot.Query(request);

            if (response.Header.RCODE == DnsResponseCode.NoError)
            {
                if (response.Answer.Length > 0)
                {
                    DnsResourceRecordType questionType = request.Question[0].Type;
                    DnsResourceRecord     lastRR       = response.Answer[response.Answer.Length - 1];

                    if ((lastRR.Type != questionType) && (lastRR.Type == DnsResourceRecordType.CNAME) && (questionType != DnsResourceRecordType.ANY))
                    {
                        List <DnsResourceRecord> responseAnswer = new List <DnsResourceRecord>();
                        responseAnswer.AddRange(response.Answer);

                        DnsDatagram lastResponse;

                        while (true)
                        {
                            DnsDatagram cnameRequest = new DnsDatagram(new DnsHeader(0, false, DnsOpcode.StandardQuery, false, false, request.Header.RecursionDesired, false, false, false, DnsResponseCode.NoError, 1, 0, 0, 0), new DnsQuestionRecord[] { new DnsQuestionRecord((lastRR.RDATA as DnsCNAMERecord).CNAMEDomainName, questionType, DnsClass.IN) }, null, null, null);

                            lastResponse = _authoritativeZoneRoot.Query(cnameRequest);

                            if (lastResponse.Header.RCODE == DnsResponseCode.Refused)
                            {
                                if (!cnameRequest.Header.RecursionDesired || !isRecursionAllowed)
                                {
                                    break;
                                }

                                lastResponse = ProcessRecursiveQuery(cnameRequest);
                            }

                            if ((lastResponse.Header.RCODE != DnsResponseCode.NoError) || (lastResponse.Answer.Length == 0))
                            {
                                break;
                            }

                            responseAnswer.AddRange(lastResponse.Answer);

                            lastRR = lastResponse.Answer[lastResponse.Answer.Length - 1];

                            if (lastRR.Type != DnsResourceRecordType.CNAME)
                            {
                                break;
                            }
                        }

                        DnsResponseCode     rcode;
                        DnsResourceRecord[] authority;
                        DnsResourceRecord[] additional;

                        if (lastResponse.Header.RCODE == DnsResponseCode.Refused)
                        {
                            rcode      = DnsResponseCode.NoError;
                            authority  = new DnsResourceRecord[] { };
                            additional = new DnsResourceRecord[] { };
                        }
                        else
                        {
                            rcode = lastResponse.Header.RCODE;

                            if (lastResponse.Header.AuthoritativeAnswer)
                            {
                                authority  = lastResponse.Authority;
                                additional = lastResponse.Additional;
                            }
                            else
                            {
                                if ((lastResponse.Authority.Length > 0) && (lastResponse.Authority[0].Type == DnsResourceRecordType.SOA))
                                {
                                    authority = lastResponse.Authority;
                                }
                                else
                                {
                                    authority = new DnsResourceRecord[] { }
                                };

                                additional = new DnsResourceRecord[] { };
                            }
                        }

                        return(new DnsDatagram(new DnsHeader(request.Header.Identifier, true, DnsOpcode.StandardQuery, lastResponse.Header.AuthoritativeAnswer, false, request.Header.RecursionDesired, isRecursionAllowed, false, false, rcode, 1, (ushort)responseAnswer.Count, (ushort)authority.Length, (ushort)additional.Length), request.Question, responseAnswer.ToArray(), authority, additional));
                    }
                }
                else if ((response.Authority.Length > 0) && (response.Authority[0].Type == DnsResourceRecordType.NS) && isRecursionAllowed)
                {
                    if (_forwarders != null)
                    {
                        return(ProcessRecursiveQuery(request)); //do recursive resolution using forwarders
                    }
                    //do recursive resolution using response authority name servers
                    NameServerAddress[] nameServers = NameServerAddress.GetNameServersFromResponse(response, _preferIPv6, false);

                    return(ProcessRecursiveQuery(request, nameServers));
                }
            }

            return(response);
        }
        public void Init(HttpApplication context)
        {
            _dnsServer = new NameServerAddress(Properties.Settings.Default.DnsServer);

            context.BeginRequest += delegate(object sender, EventArgs e)
            {
                HttpRequest  Request  = context.Request;
                HttpResponse Response = context.Response;

                if (Request.Path == "/dns-query")
                {
                    if (!Request.AcceptTypes.Contains("application/dns-message"))
                    {
                        throw new NotSupportedException("DoH request type not supported.");
                    }

                    try
                    {
                        DnsDatagram request;

                        switch (Request.HttpMethod)
                        {
                        case "GET":
                            string strRequest = Request.QueryString["dns"];
                            if (string.IsNullOrEmpty(strRequest))
                            {
                                throw new ArgumentNullException("dns");
                            }

                            //convert from base64url to base64
                            strRequest = strRequest.Replace('-', '+');
                            strRequest = strRequest.Replace('_', '/');

                            //add padding
                            int x = strRequest.Length % 4;
                            if (x > 0)
                            {
                                strRequest = strRequest.PadRight(strRequest.Length - x + 4, '=');
                            }

                            request = new DnsDatagram(new MemoryStream(Convert.FromBase64String(strRequest)));
                            break;

                        case "POST":
                            if (Request.ContentType != "application/dns-message")
                            {
                                throw new NotSupportedException("DNS request type not supported: " + Request.ContentType);
                            }

                            request = new DnsDatagram(Request.InputStream);
                            break;

                        default:
                            throw new NotSupportedException("DoH request type not supported.");;
                        }

                        DnsClientConnection connection = DnsClientConnection.GetConnection((DnsTransportProtocol)Enum.Parse(typeof(DnsTransportProtocol), Properties.Settings.Default.DnsServerProtocol, true), _dnsServer, null);
                        connection.Timeout = Properties.Settings.Default.DnsTimeout;

                        ushort originalRequestId = request.Header.Identifier;

                        DnsDatagram response = connection.Query(request);
                        if (response == null)
                        {
                            Response.StatusCode = (int)HttpStatusCode.GatewayTimeout;
                            Response.Write("<p>DNS query timed out.</p>");
                        }
                        else
                        {
                            response.Header.SetIdentifier(originalRequestId); //set id since dns connection may change it if 2 clients have same id

                            Response.ContentType = "application/dns-message";

                            using (MemoryStream mS = new MemoryStream())
                            {
                                response.WriteTo(mS);
                                mS.WriteTo(Response.OutputStream);
                            }
                        }
                    }
                    catch (Exception ex)
                    {
                        Response.Clear();
                        Response.StatusCode = (int)HttpStatusCode.InternalServerError;
                        Response.Write("<p>" + ex.ToString() + "</p>");
                    }
                }
                else
                {
                    Response.StatusCode = (int)HttpStatusCode.NotFound;
                    Response.Write("<h1>404 Not Found</h1>");
                }

                Response.End();
            };
        }