public StubZone(DnsServer dnsServer, string name, string primaryNameServerAddresses = null) : base(name) { _dnsServer = dnsServer; DnsQuestionRecord soaQuestion = new DnsQuestionRecord(name, DnsResourceRecordType.SOA, DnsClass.IN); DnsDatagram soaResponse = null; if (primaryNameServerAddresses == null) { soaResponse = _dnsServer.DirectQuery(soaQuestion); } else { DnsClient dnsClient = new DnsClient(primaryNameServerAddresses); dnsClient.Proxy = _dnsServer.Proxy; dnsClient.PreferIPv6 = _dnsServer.PreferIPv6; dnsClient.Retries = _dnsServer.Retries; dnsClient.Timeout = _dnsServer.Timeout; soaResponse = dnsClient.Resolve(soaQuestion); } if ((soaResponse == null) || (soaResponse.Answer.Count == 0) || (soaResponse.Answer[0].Type != DnsResourceRecordType.SOA)) { throw new DnsServerException("DNS Server failed to find SOA record for: " + name); } DnsSOARecord receivedSoa = soaResponse.Answer[0].RDATA as DnsSOARecord; DnsSOARecord soa = new DnsSOARecord(receivedSoa.PrimaryNameServer, receivedSoa.ResponsiblePerson, receivedSoa.Serial - 1, receivedSoa.Refresh, receivedSoa.Retry, receivedSoa.Expire, receivedSoa.Minimum); DnsResourceRecord[] soaRR = new DnsResourceRecord[] { new DnsResourceRecord(_name, DnsResourceRecordType.SOA, DnsClass.IN, soa.Refresh, soa) }; if (!string.IsNullOrEmpty(primaryNameServerAddresses)) { soaRR[0].SetGlueRecords(primaryNameServerAddresses); } _entries[DnsResourceRecordType.SOA] = soaRR; _isExpired = true; //new stub zone is considered expired till it refreshes _refreshTimer = new Timer(RefreshTimerCallback, null, Timeout.Infinite, Timeout.Infinite); }
private IReadOnlyList <NameServerAddress> GetNameServerAddresses(DnsServer dnsServer, DnsResourceRecord record) { string nsDomain; switch (record.Type) { case DnsResourceRecordType.NS: nsDomain = (record.RDATA as DnsNSRecord).NameServer; break; case DnsResourceRecordType.SOA: nsDomain = (record.RDATA as DnsSOARecord).PrimaryNameServer; break; default: throw new InvalidOperationException(); } List <NameServerAddress> nameServers = new List <NameServerAddress>(2); IReadOnlyList <DnsResourceRecord> glueRecords = record.GetGlueRecords(); if (glueRecords.Count > 0) { foreach (DnsResourceRecord glueRecord in glueRecords) { switch (glueRecord.Type) { case DnsResourceRecordType.A: nameServers.Add(new NameServerAddress(nsDomain, (glueRecord.RDATA as DnsARecord).Address)); break; case DnsResourceRecordType.AAAA: if (dnsServer.PreferIPv6) { nameServers.Add(new NameServerAddress(nsDomain, (glueRecord.RDATA as DnsAAAARecord).Address)); } break; } } } else { //resolve addresses try { DnsDatagram response = dnsServer.DirectQuery(new DnsQuestionRecord(nsDomain, DnsResourceRecordType.A, DnsClass.IN)); if ((response != null) && (response.Answer.Count > 0)) { IReadOnlyList <IPAddress> addresses = DnsClient.ParseResponseA(response); foreach (IPAddress address in addresses) { nameServers.Add(new NameServerAddress(nsDomain, address)); } } } catch { } if (dnsServer.PreferIPv6) { try { DnsDatagram response = dnsServer.DirectQuery(new DnsQuestionRecord(nsDomain, DnsResourceRecordType.AAAA, DnsClass.IN)); if ((response != null) && (response.Answer.Count > 0)) { IReadOnlyList <IPAddress> addresses = DnsClient.ParseResponseAAAA(response); foreach (IPAddress address in addresses) { nameServers.Add(new NameServerAddress(nsDomain, address)); } } } catch { } } } return(nameServers); }