public DnsDatagram(Stream s, NameServerAddress server = null, ProtocolType protocol = ProtocolType.Udp, double rtt = 0) { _server = server; _protocol = protocol; _size = s.Length; _rtt = rtt; _header = new DnsHeader(s); _question = new DnsQuestionRecord[_header.QDCOUNT]; for (int i = 0; i < _header.QDCOUNT; i++) { _question[i] = new DnsQuestionRecord(s); } _answer = new DnsResourceRecord[_header.ANCOUNT]; for (int i = 0; i < _header.ANCOUNT; i++) { _answer[i] = new DnsResourceRecord(s); } _authority = new DnsResourceRecord[_header.NSCOUNT]; for (int i = 0; i < _header.NSCOUNT; i++) { _authority[i] = new DnsResourceRecord(s); } _additional = new DnsResourceRecord[_header.ARCOUNT]; for (int i = 0; i < _header.ARCOUNT; i++) { _additional[i] = new DnsResourceRecord(s); } }
public DnsDatagramMetadata(NameServerAddress server, DnsTransportProtocol protocol, int size, double rtt) { _server = server; _protocol = protocol; _size = size; _rtt = rtt; if (_rtt < 0.1) { _rtt = 0.1; } }
public DnsClient(IPAddress[] servers) { if (servers.Length == 0) { throw new DnsClientException("Atleast one name server must be available for DnsClient."); } _servers = new NameServerAddress[servers.Length]; for (int i = 0; i < servers.Length; i++) { _servers[i] = new NameServerAddress(servers[i]); } }
public DnsClient(bool preferIPv6 = false) { _preferIPv6 = preferIPv6; NetworkInfo defaultNetworkInfo; if (_preferIPv6) { defaultNetworkInfo = NetUtilities.GetDefaultIPv6NetworkInfo(); if ((defaultNetworkInfo == null) || (defaultNetworkInfo.Interface.GetIPProperties().DnsAddresses.Count == 0)) { defaultNetworkInfo = NetUtilities.GetDefaultIPv4NetworkInfo(); } } else { defaultNetworkInfo = NetUtilities.GetDefaultIPv4NetworkInfo(); } if (defaultNetworkInfo == null) { throw new DnsClientException("No default network connection was found on this computer."); } IPAddressCollection servers = defaultNetworkInfo.Interface.GetIPProperties().DnsAddresses; if (servers.Count == 0) { throw new DnsClientException("Default network does not have any DNS server configured."); } _servers = new NameServerAddress[servers.Count]; for (int i = 0; i < servers.Count; i++) { _servers[i] = new NameServerAddress(servers[i]); } }
public static DnsDatagram ResolveViaNameServers(DnsQuestionRecord question, NameServerAddress[] nameServers = null, IDnsCache cache = null, NetProxy proxy = null, bool preferIPv6 = false, bool tcp = false, int retries = 2, int maxStackCount = 10) { if ((nameServers != null) && (nameServers.Length > 0)) { //create copy of name servers array so that the values in original array are not messed due to shuffling feature NameServerAddress[] nameServersCopy = new NameServerAddress[nameServers.Length]; Array.Copy(nameServers, nameServersCopy, nameServers.Length); nameServers = nameServersCopy; } Stack <ResolverData> resolverStack = new Stack <ResolverData>(); int stackNameServerIndex = 0; while (true) //stack loop { if (resolverStack.Count > maxStackCount) { while (resolverStack.Count > 0) { ResolverData data = resolverStack.Pop(); question = data.Question; } throw new DnsClientException("DnsClient exceeded the maximum stack count to resolve the domain: " + question.Name); } if (cache != null) { DnsDatagram request = new DnsDatagram(new DnsHeader(0, false, DnsOpcode.StandardQuery, false, false, true, false, false, false, DnsResponseCode.NoError, 1, 0, 0, 0), new DnsQuestionRecord[] { question }, null, null, null); DnsDatagram cacheResponse = cache.Query(request); switch (cacheResponse.Header.RCODE) { case DnsResponseCode.NoError: if (cacheResponse.Answer.Length > 0) { if (resolverStack.Count == 0) { return(cacheResponse); } else { ResolverData data = resolverStack.Pop(); question = data.Question; nameServers = data.NameServers; stackNameServerIndex = data.NameServerIndex; switch (cacheResponse.Answer[0].Type) { case DnsResourceRecordType.AAAA: nameServers[stackNameServerIndex] = new NameServerAddress(nameServers[stackNameServerIndex].Domain, (cacheResponse.Answer[0].RDATA as DnsAAAARecord).Address); break; case DnsResourceRecordType.A: nameServers[stackNameServerIndex] = new NameServerAddress(nameServers[stackNameServerIndex].Domain, (cacheResponse.Answer[0].RDATA as DnsARecord).Address); break; default: //didnt find IP for current name server stackNameServerIndex++; //increment to skip current name server break; } continue; //stack loop } } if (cacheResponse.Authority.Length > 0) { if (cacheResponse.Authority[0].Type == DnsResourceRecordType.SOA) { if (resolverStack.Count == 0) { return(cacheResponse); } else { if (question.Type == DnsResourceRecordType.AAAA) { question = new DnsQuestionRecord(question.Name, DnsResourceRecordType.A, question.Class); } else { //didnt find IP for current name server //pop and try next name server ResolverData data = resolverStack.Pop(); question = data.Question; nameServers = data.NameServers; stackNameServerIndex = data.NameServerIndex + 1; //increment to skip current name server } continue; //to stack loop } } if ((nameServers == null) || (nameServers.Length == 0)) { NameServerAddress[] cacheNameServers = NameServerAddress.GetNameServersFromResponse(cacheResponse, preferIPv6, true); if (cacheNameServers.Length > 0) { nameServers = cacheNameServers; } } } break; case DnsResponseCode.NameError: if (resolverStack.Count == 0) { return(cacheResponse); } else { //current name server domain doesnt exists //pop and try next name server ResolverData data = resolverStack.Pop(); question = data.Question; nameServers = data.NameServers; stackNameServerIndex = data.NameServerIndex + 1; //increment to skip current name server continue; //stack loop } } } if ((nameServers == null) || (nameServers.Length == 0)) { //create copy of root name servers array so that the values in original array are not messed due to shuffling feature if (preferIPv6) { nameServers = new NameServerAddress[ROOT_NAME_SERVERS_IPv6.Length]; Array.Copy(ROOT_NAME_SERVERS_IPv6, nameServers, ROOT_NAME_SERVERS_IPv6.Length); } else { nameServers = new NameServerAddress[ROOT_NAME_SERVERS_IPv4.Length]; Array.Copy(ROOT_NAME_SERVERS_IPv4, nameServers, ROOT_NAME_SERVERS_IPv4.Length); } } NameServerAddress.Shuffle(nameServers); int hopCount = 0; while ((hopCount++) < MAX_HOPS) //resolver loop { //copy and reset stack name server index since its one time use only after stack pop int i = stackNameServerIndex; stackNameServerIndex = 0; //query name servers one by one for (; i < nameServers.Length; i++) //retry next server loop { NameServerAddress currentNameServer = nameServers[i]; if (question.Name == currentNameServer.Domain) { continue; //obvious! } if (currentNameServer.EndPoint == null) { resolverStack.Push(new ResolverData(question, nameServers, i)); if (preferIPv6) { question = new DnsQuestionRecord(currentNameServer.Domain, DnsResourceRecordType.AAAA, question.Class); } else { question = new DnsQuestionRecord(currentNameServer.Domain, DnsResourceRecordType.A, question.Class); } nameServers = null; goto stackLoop; } DnsClient client = new DnsClient(currentNameServer); client._proxy = proxy; client._preferIPv6 = preferIPv6; client._tcp = tcp; client._retries = retries; DnsDatagram request = new DnsDatagram(new DnsHeader(0, false, DnsOpcode.StandardQuery, false, false, true, false, false, false, DnsResponseCode.NoError, 1, 0, 0, 0), new DnsQuestionRecord[] { question }, null, null, null); DnsDatagram response; try { response = client.Resolve(request); } catch (DnsClientException) { continue; //resolver loop } if (response.Header.Truncation) { if (tcp) { return(response); } client._tcp = true; response = client.Resolve(request); } if (cache != null) { cache.CacheResponse(response); } switch (response.Header.RCODE) { case DnsResponseCode.NoError: if (response.Answer.Length > 0) { if (!response.Answer[0].Name.Equals(question.Name, StringComparison.CurrentCultureIgnoreCase)) { continue; //continue to next name server since current name server may be misconfigured } if (resolverStack.Count == 0) { return(response); } else { ResolverData data = resolverStack.Pop(); question = data.Question; nameServers = data.NameServers; stackNameServerIndex = data.NameServerIndex; switch (response.Answer[0].Type) { case DnsResourceRecordType.AAAA: nameServers[stackNameServerIndex] = new NameServerAddress(nameServers[stackNameServerIndex].Domain, (response.Answer[0].RDATA as DnsAAAARecord).Address); break; case DnsResourceRecordType.A: nameServers[stackNameServerIndex] = new NameServerAddress(nameServers[stackNameServerIndex].Domain, (response.Answer[0].RDATA as DnsARecord).Address); break; default: //didnt find IP for current name server stackNameServerIndex++; //increment to skip current name server break; } goto resolverLoop; } } if (response.Authority.Length == 0) { continue; //continue to next name server since current name server may be misconfigured } if (response.Authority[0].Type == DnsResourceRecordType.SOA) { //no entry for given type if (resolverStack.Count == 0) { return(response); } else { if (question.Type == DnsResourceRecordType.AAAA) { question = new DnsQuestionRecord(question.Name, DnsResourceRecordType.A, question.Class); } else { //didnt find IP for current name server //pop and try next name server ResolverData data = resolverStack.Pop(); question = data.Question; nameServers = data.NameServers; stackNameServerIndex = data.NameServerIndex + 1; //increment to skip current name server } goto stackLoop; //goto stack loop } } nameServers = NameServerAddress.GetNameServersFromResponse(response, preferIPv6, false); if (nameServers.Length == 0) { continue; //continue to next name server since current name server may be misconfigured } goto resolverLoop; case DnsResponseCode.NameError: if (resolverStack.Count == 0) { return(response); } else { //current name server domain doesnt exists //pop and try next name server ResolverData data = resolverStack.Pop(); question = data.Question; nameServers = data.NameServers; stackNameServerIndex = data.NameServerIndex + 1; //increment to skip current name server goto stackLoop; //goto stack loop } default: continue; //continue to next name server since current name server may be misconfigured } } if (resolverStack.Count == 0) { throw new DnsClientException("DnsClient failed to resolve the request: no response from name servers."); } else { //didnt find IP for current name server //pop and try next name server ResolverData data = resolverStack.Pop(); question = data.Question; nameServers = data.NameServers; stackNameServerIndex = data.NameServerIndex + 1; //increment to skip current name server break; //to stack loop } resolverLoop :; } stackLoop :; } }
public DnsClient(NameServerAddress server) { _servers = new NameServerAddress[] { server }; }