예제 #1
0
파일: RawRecord.cs 프로젝트: DM-TOR/nhin-d
        /// <summary>
        /// Compares a Raw Record to this given resource record
        /// </summary>
        /// <param name="record"></param>
        /// <returns></returns>
        public override bool Equals(DnsResourceRecord record)
        {
            if (!base.Equals(record))
            {
                return false;
            }

            RawRecord rawRecord = record as RawRecord;
            if (rawRecord == null)
            {
                return false;
            }
            
            if (rawRecord.m_bytes.Length != m_bytes.Length)
            {
                return false;
            }
            
            for (int i = 0; i < m_bytes.Length; ++i)
            {
                if (m_bytes[i] != rawRecord.m_bytes[i])               
                {
                    return false;
                }
            }
            
            return true;
        }
예제 #2
0
 public DnsResponse(DnsResponseCode responseCode, DnsRecordType queryType, string queryName, DnsResourceRecord[] answerRecords, DnsResourceRecord[] authorityRecords, DnsResourceRecord[] additionalInformationRecords)
 {
     this.ResponseCode = responseCode;
     this.QueryType = queryType;
     this.QueryName = queryName;
     this.AnswerRecords = answerRecords;
     this.AuthorityRecords = authorityRecords;
     this.AdditionalInformationRecords = additionalInformationRecords;
 }
예제 #3
0
        /// <summary>
        /// Tests equality between this CName record and the other <paramref name="record"/>.
        /// </summary>
        /// <param name="record">The other record.</param>
        /// <returns><c>true</c> if the RRs are equal, <c>false</c> otherwise.</returns>
        public override bool Equals(DnsResourceRecord record)
        {
            if (!base.Equals(record))
            {
                return false;
            }

            CNameRecord cnameRecord = record as CNameRecord;
            if (cnameRecord == null)
            {
                return false;
            }

            return (DnsStandard.Equals(m_name, cnameRecord.CName));
        }
예제 #4
0
파일: PtrRecord.cs 프로젝트: DM-TOR/nhin-d
        /// <summary>
        /// Tests equality between this PTR record and the other <paramref name="record"/>.
        /// </summary>
        /// <param name="record">The other record.</param>
        /// <returns><c>true</c> if the RRs are equal, <c>false</c> otherwise.</returns>
        public override bool Equals(DnsResourceRecord record)
        {
            if (!base.Equals(record))
            {
                return false;
            }

            PtrRecord ptrRecord = record as PtrRecord;
            if (ptrRecord == null)
            {
                return false;
            }
            
            return (DnsStandard.Equals(this.m_domain, ptrRecord.m_domain));
        }
예제 #5
0
 /// <summary>
 /// Helper method to extract the appropriate IP address from a DNS lookup result.
 /// The query may have returned an AAAA or A record. This method checks which
 /// and extracts the IP address accordingly.
 /// </summary>
 /// <param name="addrRecord">The DNS lookup result.</param>
 /// <param name="port">The port for the IP end point.</param>
 /// <returns>An IP end point or null.</returns>
 private static IPEndPoint GetFromLookupResult(DnsResourceRecord addrRecord, int port)
 {
     if (addrRecord is AaaaRecord)
     {
         return(new IPEndPoint((addrRecord as AaaaRecord).Address, port));
     }
     else if (addrRecord is ARecord)
     {
         return(new IPEndPoint((addrRecord as ARecord).Address, port));
     }
     else
     {
         return(null);
     }
 }
예제 #6
0
 /// <summary>
 /// Helper method to extract the appropriate IP address from a DNS lookup result.
 /// The query may have returned an AAAA or A record. This method checks which
 /// and extracts the IP address accordingly.
 /// </summary>
 /// <param name="addrRecord">The DNS lookup result.</param>
 /// <param name="port">The port for the IP end point.</param>
 /// <returns>An IP end point or null.</returns>
 private static SIPEndPoint GetFromLookupResult(SIPProtocolsEnum protocol, DnsResourceRecord addrRecord, int port)
 {
     if (addrRecord is AaaaRecord)
     {
         return(new SIPEndPoint(protocol, (addrRecord as AaaaRecord).Address, port));
     }
     else if (addrRecord is ARecord)
     {
         return(new SIPEndPoint(protocol, (addrRecord as ARecord).Address, port));
     }
     else
     {
         return(null);
     }
 }
예제 #7
0
파일: NSRecord.cs 프로젝트: DM-TOR/nhin-d
 /// <summary>
 /// Tests equality between this NS record and the other <paramref name="record"/>.
 /// </summary>
 /// <param name="record">The other record.</param>
 /// <returns><c>true</c> if the RRs are equal, <c>false</c> otherwise.</returns>
 public override bool Equals(DnsResourceRecord record)
 {
     if (!base.Equals(record))
     {
         return false;
     }
     
     NSRecord nsRecord = record as NSRecord;
     if (nsRecord == null)
     {
         return false;
     }
     
     return (DnsStandard.Equals(m_nameserver, nsRecord.NameServer));
 }
예제 #8
0
        public override void UpdateRecord(DnsResourceRecord oldRecord, DnsResourceRecord newRecord)
        {
            switch (oldRecord.Type)
            {
            case DnsResourceRecordType.SOA:
                throw new InvalidOperationException("Cannot update record: use SetRecords() for " + oldRecord.Type.ToString() + " record");

            case DnsResourceRecordType.DNSKEY:
            case DnsResourceRecordType.RRSIG:
            case DnsResourceRecordType.NSEC:
            case DnsResourceRecordType.NSEC3PARAM:
            case DnsResourceRecordType.NSEC3:
                throw new InvalidOperationException("Cannot update DNSSEC records.");

            default:
                if (oldRecord.Type != newRecord.Type)
                {
                    throw new InvalidOperationException("Old and new record types do not match.");
                }

                if ((_primaryZone.DnssecStatus != AuthZoneDnssecStatus.Unsigned) && newRecord.IsDisabled())
                {
                    throw new DnsServerException("Cannot update record: disabling records in a signed zones is not supported.");
                }

                if (newRecord.OriginalTtlValue > _primaryZone.GetZoneSoaExpire())
                {
                    throw new DnsServerException("Failed to update record: TTL cannot be greater than SOA EXPIRE.");
                }

                if (!TryDeleteRecord(oldRecord.Type, oldRecord.RDATA, out DnsResourceRecord deletedRecord))
                {
                    throw new InvalidOperationException("Cannot update record: the record does not exists to be updated.");
                }

                base.AddRecord(newRecord);

                _primaryZone.CommitAndIncrementSerial(new DnsResourceRecord[] { deletedRecord }, new DnsResourceRecord[] { newRecord });

                if (_primaryZone.DnssecStatus != AuthZoneDnssecStatus.Unsigned)
                {
                    _primaryZone.UpdateDnssecRecordsFor(this, oldRecord.Type);
                }

                _primaryZone.TriggerNotify();
                break;
            }
        }
예제 #9
0
        public DnsDatagram Query(DnsDatagram request)
        {
            List <Uri> blockLists = IsZoneBlocked(request.Question[0].Name.ToLower());

            if (blockLists == null)
            {
                return(null); //zone not blocked
            }
            //zone is blocked
            if (_dnsServer.UseNxDomainForBlocking && (request.Question[0].Type != DnsResourceRecordType.TXT))
            {
                return(new DnsDatagram(request.Identifier, true, DnsOpcode.StandardQuery, false, false, request.RecursionDesired, true, false, false, DnsResponseCode.NxDomain, request.Question));
            }

            DnsResourceRecord[] answers   = null;
            DnsResourceRecord[] authority = null;

            switch (request.Question[0].Type)
            {
            case DnsResourceRecordType.A:
                answers = new DnsResourceRecord[] { new DnsResourceRecord(request.Question[0].Name, DnsResourceRecordType.A, request.Question[0].Class, 60, _aRecord) };
                break;

            case DnsResourceRecordType.AAAA:
                answers = new DnsResourceRecord[] { new DnsResourceRecord(request.Question[0].Name, DnsResourceRecordType.AAAA, request.Question[0].Class, 60, _aaaaRecord) };
                break;

            case DnsResourceRecordType.NS:
                answers = new DnsResourceRecord[] { new DnsResourceRecord(request.Question[0].Name, DnsResourceRecordType.NS, request.Question[0].Class, 60, _nsRecord) };
                break;

            case DnsResourceRecordType.TXT:
                answers = new DnsResourceRecord[blockLists.Count];

                for (int i = 0; i < answers.Length; i++)
                {
                    answers[i] = new DnsResourceRecord(request.Question[0].Name, DnsResourceRecordType.TXT, request.Question[0].Class, 60, new DnsTXTRecord("blockList=" + blockLists[i].AbsoluteUri + "; domain=" + request.Question[0].Name));
                }

                break;

            default:
                authority = new DnsResourceRecord[] { new DnsResourceRecord(request.Question[0].Name, DnsResourceRecordType.SOA, request.Question[0].Class, 60, _soaRecord) };
                break;
            }

            return(new DnsDatagram(request.Identifier, true, DnsOpcode.StandardQuery, false, false, request.RecursionDesired, true, false, false, DnsResponseCode.NoError, request.Question, answers, authority));
        }
예제 #10
0
        /// <summary>
        /// loads and verifies the dnsrecords from the bin associated bin files, ensuring that the types
        /// match up
        /// </summary>
        /// <typeparam name="T">Type of record that is expected</typeparam>
        /// <param name="path">path to the bin file to be loaded</param>
        /// <returns>bytes from the bin file</returns>
        protected byte[] LoadAndVerifyDnsRecordFromBin <T>(string path)
        {
            byte[] bytes = null;

            //----------------------------------------------------------------------------------------------------
            //---read the stream from the bytes
            using (FileStream fs = new FileStream(path, FileMode.Open, FileAccess.Read))
            {
                //Console.WriteLine("checking [{0}]", path);
                bytes = new BinaryReader(fs).ReadBytes((int)new FileInfo(path).Length);
                DnsBufferReader   rdr = new DnsBufferReader(bytes, 0, bytes.Length);
                DnsResourceRecord rec = DnsResourceRecord.Deserialize(ref rdr);
                Assert.Equal(rec.GetType(), typeof(T));
            }
            return(bytes);
        }
예제 #11
0
        void FixupTTL(DnsResourceRecordCollection matches)
        {
            if (matches.IsNullOrEmpty())
            {
                return;
            }

            for (int i = 0, count = matches.Count; i < count; ++i)
            {
                DnsResourceRecord match = matches[i];
                if (match.TTL <= 0)
                {
                    match.TTL = this.Settings.DefaultTTL;
                }
            }
        }
예제 #12
0
        /// <summary>
        /// Tests equality between this NS record and the other <paramref name="record"/>.
        /// </summary>
        /// <param name="record">The other record.</param>
        /// <returns><c>true</c> if the RRs are equal, <c>false</c> otherwise.</returns>
        public override bool Equals(DnsResourceRecord record)
        {
            if (!base.Equals(record))
            {
                return(false);
            }

            NSRecord nsRecord = record as NSRecord;

            if (nsRecord == null)
            {
                return(false);
            }

            return(DnsStandard.Equals(m_nameserver, nsRecord.NameServer));
        }
예제 #13
0
파일: PtrRecord.cs 프로젝트: blinds52/nhind
        /// <summary>
        /// Tests equality between this PTR record and the other <paramref name="record"/>.
        /// </summary>
        /// <param name="record">The other record.</param>
        /// <returns><c>true</c> if the RRs are equal, <c>false</c> otherwise.</returns>
        public override bool Equals(DnsResourceRecord record)
        {
            if (!base.Equals(record))
            {
                return(false);
            }

            PtrRecord ptrRecord = record as PtrRecord;

            if (ptrRecord == null)
            {
                return(false);
            }

            return(DnsStandard.Equals(this.m_domain, ptrRecord.m_domain));
        }
예제 #14
0
        /// <summary>
        /// Tests equality between this CName record and the other <paramref name="record"/>.
        /// </summary>
        /// <param name="record">The other record.</param>
        /// <returns><c>true</c> if the RRs are equal, <c>false</c> otherwise.</returns>
        public override bool Equals(DnsResourceRecord record)
        {
            if (!base.Equals(record))
            {
                return(false);
            }

            CNameRecord cnameRecord = record as CNameRecord;

            if (cnameRecord == null)
            {
                return(false);
            }

            return(DnsStandard.Equals(m_name, cnameRecord.CName));
        }
예제 #15
0
        public static void SyncGlueRecords(this DnsResourceRecord record, IReadOnlyCollection <DnsResourceRecord> deletedGlueRecords, IReadOnlyCollection <DnsResourceRecord> addedGlueRecords)
        {
            if (record.RDATA is not DnsNSRecord nsRecord)
            {
                throw new InvalidOperationException();
            }

            bool updated = false;

            List <DnsResourceRecord>          updatedGlueRecords  = new List <DnsResourceRecord>();
            IReadOnlyList <DnsResourceRecord> existingGlueRecords = GetGlueRecords(record);

            foreach (DnsResourceRecord existingGlueRecord in existingGlueRecords)
            {
                if (deletedGlueRecords.Contains(existingGlueRecord))
                {
                    updated = true; //skipped to delete existing glue record
                }
                else
                {
                    updatedGlueRecords.Add(existingGlueRecord);
                }
            }

            string domain = nsRecord.NameServer;

            foreach (DnsResourceRecord addedGlueRecord in addedGlueRecords)
            {
                switch (addedGlueRecord.Type)
                {
                case DnsResourceRecordType.A:
                case DnsResourceRecordType.AAAA:
                    if (addedGlueRecord.Name.Equals(domain, StringComparison.OrdinalIgnoreCase))
                    {
                        updatedGlueRecords.Add(addedGlueRecord);
                        updated = true;
                    }
                    break;
                }
            }

            if (updated)
            {
                SetGlueRecords(record, updatedGlueRecords);
            }
        }
예제 #16
0
        public static void GetMatches(this RecordRetrievalServiceClient client, string domain, DnsResourceRecordCollection resourceRecords, DnsStandard.RecordType recordType)
        {
            DnsRecord[] matches = client.GetMatchingDnsRecords(domain, recordType);
            if (matches.IsNullOrEmpty())
            {
                return;
            }

            foreach (DnsRecord record in matches)
            {
                DnsResourceRecord responseRecord = record.Deserialize();
                if (responseRecord != null && responseRecord.Type == recordType)
                {
                    resourceRecords.Add(responseRecord);
                }
            }
        }
예제 #17
0
        public int RemoveExpiredRecords(bool serveStale)
        {
            int removedEntries = 0;

            foreach (KeyValuePair <DnsResourceRecordType, IReadOnlyList <DnsResourceRecord> > entry in _entries)
            {
                if (DnsResourceRecord.IsRRSetExpired(entry.Value, serveStale))
                {
                    if (_entries.TryRemove(entry.Key, out _)) //RR Set is expired; remove entry
                    {
                        removedEntries++;
                    }
                }
            }

            return(removedEntries);
        }
예제 #18
0
        public static async Task <StubZone> CreateAsync(DnsServer dnsServer, string name, string primaryNameServerAddresses = null)
        {
            StubZone stubZone = new StubZone(name);

            stubZone._dnsServer = dnsServer;

            DnsQuestionRecord soaQuestion = new DnsQuestionRecord(name, DnsResourceRecordType.SOA, DnsClass.IN);
            DnsDatagram       soaResponse = null;

            if (primaryNameServerAddresses == null)
            {
                soaResponse = await stubZone._dnsServer.DirectQueryAsync(soaQuestion);
            }
            else
            {
                DnsClient dnsClient = new DnsClient(primaryNameServerAddresses);

                dnsClient.Proxy      = stubZone._dnsServer.Proxy;
                dnsClient.PreferIPv6 = stubZone._dnsServer.PreferIPv6;

                soaResponse = await dnsClient.ResolveAsync(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(stubZone._name, DnsResourceRecordType.SOA, DnsClass.IN, soa.Refresh, soa) };

            if (!string.IsNullOrEmpty(primaryNameServerAddresses))
            {
                soaRR[0].SetGlueRecords(primaryNameServerAddresses);
            }

            stubZone._entries[DnsResourceRecordType.SOA] = soaRR;

            stubZone._isExpired    = true; //new stub zone is considered expired till it refreshes
            stubZone._refreshTimer = new Timer(stubZone.RefreshTimerCallback, null, Timeout.Infinite, Timeout.Infinite);

            return(stubZone);
        }
예제 #19
0
        public void Add(DnsResourceRecord record)
        {
            if (record == null)
            {
                throw new ArgumentNullException();
            }

            DnsResourceRecordCollection recordList;

            if (!m_records.TryGetValue(record.Name, out recordList))
            {
                recordList = new DnsResourceRecordCollection();
                m_records.Add(record.Name, recordList);
            }

            recordList.Add(record);
        }
예제 #20
0
        public SecondaryZone(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 secondary zone is considered expired till it refreshes
            _refreshTimer = new Timer(RefreshTimerCallback, null, Timeout.Infinite, Timeout.Infinite);
        }
예제 #21
0
        public override void UpdateRecord(DnsResourceRecord oldRecord, DnsResourceRecord newRecord)
        {
            if (oldRecord.Type == DnsResourceRecordType.SOA)
            {
                throw new InvalidOperationException("Cannot update record: use SetRecords() for " + oldRecord.Type.ToString() + " record");
            }

            if (oldRecord.Type != newRecord.Type)
            {
                throw new InvalidOperationException("Old and new record types do not match.");
            }

            DeleteRecord(oldRecord.Type, oldRecord.RDATA, out DnsResourceRecord deletedRecord);
            base.AddRecord(newRecord);

            _primaryZone.CommitAndIncrementSerial(new DnsResourceRecord[] { deletedRecord }, new DnsResourceRecord[] { newRecord });
            _primaryZone.TriggerNotify();
        }
예제 #22
0
        /// <summary>
        /// loads and verifies the dnsrecords from the bin associated bin files, ensuring that the types
        /// match up
        /// </summary>
        /// <typeparam name="T">Type of record that is expected</typeparam>
        /// <param name="path">path to the bin file to be loaded</param>
        /// <returns>bytes from the bin file</returns>
        protected T LoadAndVerifyDnsRecordFromBin <T>(string path) where T : DnsResourceRecord
        {
            T record;

            //----------------------------------------------------------------------------------------------------
            //---read the stream from the bytes
            using (FileStream fs = new FileStream(path, FileMode.Open, FileAccess.Read))
            {
                byte[]          bytes = new BinaryReader(fs).ReadBytes((int)new FileInfo(path).Length);
                DnsBufferReader rdr   = new DnsBufferReader(bytes, 0, bytes.Length);
                record = DnsResourceRecord.Deserialize(ref rdr) as T;
                if (record == null)
                {
                    throw new TypeLoadException("unexpected type encountered in file");
                }
            }
            return(record);
        }
예제 #23
0
        public void SetRecords(string domain, DnsResourceRecordType type, uint ttl, DnsResourceRecordData[] records)
        {
            DnsResourceRecord[] resourceRecords = new DnsResourceRecord[records.Length];

            for (int i = 0; i < records.Length; i++)
            {
                resourceRecords[i] = new DnsResourceRecord(domain, type, DnsClass.IN, ttl, records[i]);
            }

            AuthZone zone = GetOrAddSubDomainZone(domain);

            zone.SetRecords(type, resourceRecords);

            if (zone is SubDomainZone)
            {
                (zone as SubDomainZone).AutoUpdateState();
            }
        }
예제 #24
0
        public static IReadOnlyList <DnsResourceRecord> GetGlueRecords(this DnsResourceRecord record)
        {
            DnsResourceRecordInfo rrInfo = record.Tag as DnsResourceRecordInfo;

            if (rrInfo == null)
            {
                return(Array.Empty <DnsResourceRecord>());
            }

            IReadOnlyList <DnsResourceRecord> glueRecords = rrInfo.GlueRecords;

            if (glueRecords == null)
            {
                return(Array.Empty <DnsResourceRecord>());
            }

            return(glueRecords);
        }
예제 #25
0
        private void ResolveAdditionalRecords(DnsResourceRecord refRecord, string domain, bool serveStale, List <DnsResourceRecord> additionalRecords)
        {
            IReadOnlyList <DnsResourceRecord> glueRecords = refRecord.GetGlueRecords();

            if (glueRecords.Count > 0)
            {
                bool added = false;

                foreach (DnsResourceRecord glueRecord in glueRecords)
                {
                    if (!glueRecord.IsStale)
                    {
                        added = true;
                        additionalRecords.Add(glueRecord);
                    }
                }

                if (added)
                {
                    return;
                }
            }

            CacheZone cacheZone = _root.FindZone(domain, out _, out _, out _);

            if (cacheZone != null)
            {
                {
                    IReadOnlyList <DnsResourceRecord> records = cacheZone.QueryRecords(DnsResourceRecordType.A, serveStale, true);
                    if ((records.Count > 0) && (records[0].RDATA is DnsARecord))
                    {
                        additionalRecords.AddRange(records);
                    }
                }

                {
                    IReadOnlyList <DnsResourceRecord> records = cacheZone.QueryRecords(DnsResourceRecordType.AAAA, serveStale, true);
                    if ((records.Count > 0) && (records[0].RDATA is DnsAAAARecord))
                    {
                        additionalRecords.AddRange(records);
                    }
                }
            }
        }
예제 #26
0
        public Task <DnsDatagram> ProcessRequestAsync(DnsDatagram request, IPEndPoint remoteEP, string zoneName, uint appRecordTtl, string appRecordData, bool isRecursionAllowed, IDnsServer dnsServer)
        {
            dynamic jsonAppRecordData = JsonConvert.DeserializeObject(appRecordData);
            dynamic jsonCountry;

            if (_mmCountryReader.TryCountry(remoteEP.Address, out CountryResponse response))
            {
                jsonCountry = jsonAppRecordData[response.Country.IsoCode];
                if (jsonCountry == null)
                {
                    jsonCountry = jsonAppRecordData["default"];
                }
            }
            else
            {
                jsonCountry = jsonAppRecordData["default"];
            }

            if (jsonCountry == null)
            {
                return(Task.FromResult <DnsDatagram>(null));
            }

            string cname = jsonCountry.Value;

            if (string.IsNullOrEmpty(cname))
            {
                return(Task.FromResult <DnsDatagram>(null));
            }

            IReadOnlyList <DnsResourceRecord> answers;

            if (request.Question[0].Name.Equals(zoneName, StringComparison.OrdinalIgnoreCase)) //check for zone apex
            {
                answers = new DnsResourceRecord[] { new DnsResourceRecord(request.Question[0].Name, DnsResourceRecordType.ANAME, DnsClass.IN, appRecordTtl, new DnsANAMERecord(cname)) }
            }
            ;                                                                                                                                                                             //use ANAME
            else
            {
                answers = new DnsResourceRecord[] { new DnsResourceRecord(request.Question[0].Name, DnsResourceRecordType.CNAME, DnsClass.IN, appRecordTtl, new DnsCNAMERecord(cname)) }
            };

            return(Task.FromResult(new DnsDatagram(request.Identifier, true, request.OPCODE, true, false, request.RecursionDesired, isRecursionAllowed, false, false, DnsResponseCode.NoError, request.Question, answers)));
        }
예제 #27
0
        /// <summary>
        /// Tests equality between this TXT record and the other <paramref name="record"/>.
        /// </summary>
        /// <param name="record">The other record.</param>
        /// <returns><c>true</c> if the RRs are equal, <c>false</c> otherwise.</returns>
        public override bool Equals(DnsResourceRecord record)
        {
            if (!base.Equals(record))
            {
                return(false);
            }

            MXRecord mxRecord = record as MXRecord;

            if (mxRecord == null)
            {
                return(false);
            }

            return(
                DnsStandard.Equals(m_exchange, mxRecord.m_exchange) &&
                this.Preference == mxRecord.Preference
                );
        }
예제 #28
0
        public override void SetRecords(DnsResourceRecordType type, IReadOnlyList <DnsResourceRecord> records)
        {
            switch (type)
            {
            case DnsResourceRecordType.SOA:
                if ((records.Count != 1) || !records[0].Name.Equals(_name, StringComparison.OrdinalIgnoreCase))
                {
                    throw new InvalidOperationException("Invalid SOA record.");
                }

                DnsResourceRecord existingSoaRecord = _entries[DnsResourceRecordType.SOA][0];
                DnsResourceRecord newSoaRecord      = records[0];

                existingSoaRecord.CopyRecordInfoFrom(newSoaRecord);
                break;

            default:
                throw new InvalidOperationException("Cannot set records in stub zone.");
            }
        }
예제 #29
0
        public override void SetRecords(DnsResourceRecordType type, IReadOnlyList <DnsResourceRecord> records)
        {
            switch (type)
            {
            case DnsResourceRecordType.SOA:
                if ((records.Count != 1) || !records[0].Name.Equals(_name, StringComparison.OrdinalIgnoreCase))
                {
                    throw new InvalidOperationException("Invalid SOA record.");
                }

                DnsResourceRecord existingSoaRR = _entries[DnsResourceRecordType.SOA][0];

                existingSoaRR.SetGlueRecords(records.GetGlueRecords());
                existingSoaRR.SetComments(records[0].GetComments());
                break;

            default:
                throw new InvalidOperationException("Cannot set records in secondary zone.");
            }
        }
예제 #30
0
        private static Task ResolveNameServerAddressesAsync(DnsServer dnsServer, DnsResourceRecord nsRecord, List <NameServerAddress> outNameServers)
        {
            switch (nsRecord.Type)
            {
            case DnsResourceRecordType.NS:
            {
                string nsDomain = (nsRecord.RDATA as DnsNSRecord).NameServer;

                IReadOnlyList <DnsResourceRecord> glueRecords = nsRecord.GetGlueRecords();
                if (glueRecords.Count > 0)
                {
                    foreach (DnsResourceRecord glueRecord in glueRecords)
                    {
                        switch (glueRecord.Type)
                        {
                        case DnsResourceRecordType.A:
                            outNameServers.Add(new NameServerAddress(nsDomain, (glueRecord.RDATA as DnsARecord).Address));
                            break;

                        case DnsResourceRecordType.AAAA:
                            if (dnsServer.PreferIPv6)
                            {
                                outNameServers.Add(new NameServerAddress(nsDomain, (glueRecord.RDATA as DnsAAAARecord).Address));
                            }

                            break;
                        }
                    }

                    return(Task.CompletedTask);
                }
                else
                {
                    return(ResolveNameServerAddressesAsync(dnsServer, nsDomain, 53, DnsTransportProtocol.Udp, outNameServers));
                }
            }

            default:
                throw new InvalidOperationException();
            }
        }
예제 #31
0
        DnsRecord Find(DnsRecord record)
        {
            DnsRecord[] existingRecords = Client.GetMatchingDnsRecordsByType(record.DomainName, record.RecordType);
            if (existingRecords.IsNullOrEmpty())
            {
                return(null);
            }

            DnsResourceRecord testRecord = record.Deserialize();

            foreach (DnsRecord existingRecord in existingRecords)
            {
                DnsResourceRecord rr = existingRecord.Deserialize();
                if (rr.Equals(testRecord))
                {
                    return(existingRecord);
                }
            }

            return(null);
        }
예제 #32
0
        public static void SyncGlueRecords(this DnsResourceRecord record, IReadOnlyList <DnsResourceRecord> allGlueRecords)
        {
            string domain;

            switch (record.Type)
            {
            case DnsResourceRecordType.NS:
                domain = (record.RDATA as DnsNSRecord).NameServer;
                break;

            case DnsResourceRecordType.SOA:
                domain = (record.RDATA as DnsSOARecord).PrimaryNameServer;
                break;

            default:
                throw new NotSupportedException();
            }

            List <DnsResourceRecord> foundGlueRecords = new List <DnsResourceRecord>(2);

            foreach (DnsResourceRecord glueRecord in allGlueRecords)
            {
                switch (glueRecord.Type)
                {
                case DnsResourceRecordType.A:
                case DnsResourceRecordType.AAAA:
                    if (glueRecord.Name.Equals(domain, StringComparison.OrdinalIgnoreCase))
                    {
                        foundGlueRecords.Add(glueRecord);
                    }

                    break;
                }
            }

            if (foundGlueRecords.Count > 0)
            {
                SetGlueRecords(record, foundGlueRecords);
            }
        }
예제 #33
0
        public Task <DnsDatagram> ProcessRequestAsync(DnsDatagram request, IPEndPoint remoteEP, string zoneName, uint appRecordTtl, string appRecordData, bool isRecursionAllowed, IDnsServer dnsServer)
        {
            DnsResourceRecord answer;

            switch (request.Question[0].Type)
            {
            case DnsResourceRecordType.A:
                if (remoteEP.AddressFamily == AddressFamily.InterNetwork)
                {
                    answer = new DnsResourceRecord(request.Question[0].Name, DnsResourceRecordType.A, DnsClass.IN, appRecordTtl, new DnsARecord(remoteEP.Address));
                }
                else
                {
                    return(Task.FromResult <DnsDatagram>(null));
                }

                break;

            case DnsResourceRecordType.AAAA:
                if (remoteEP.AddressFamily == AddressFamily.InterNetworkV6)
                {
                    answer = new DnsResourceRecord(request.Question[0].Name, DnsResourceRecordType.AAAA, DnsClass.IN, appRecordTtl, new DnsAAAARecord(remoteEP.Address));
                }
                else
                {
                    return(Task.FromResult <DnsDatagram>(null));
                }

                break;

            case DnsResourceRecordType.TXT:
                answer = new DnsResourceRecord(request.Question[0].Name, DnsResourceRecordType.TXT, DnsClass.IN, appRecordTtl, new DnsTXTRecord(remoteEP.Address.ToString()));
                break;

            default:
                return(Task.FromResult <DnsDatagram>(null));
            }

            return(Task.FromResult(new DnsDatagram(request.Identifier, true, request.OPCODE, true, false, request.RecursionDesired, isRecursionAllowed, false, false, DnsResponseCode.NoError, request.Question, new DnsResourceRecord[] { answer })));
        }
예제 #34
0
        public DnsResourceRecordInfo(BinaryReader bR)
        {
            byte version = bR.ReadByte();

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

            case 2:
            case 3:
                _disabled = bR.ReadBoolean();

                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();
                }

                break;

            default:
                throw new InvalidDataException("DnsResourceRecordInfo format version not supported.");
            }
        }
예제 #35
0
        public void IncrementSoaSerial()
        {
            DnsResourceRecord record = _entries[DnsResourceRecordType.SOA][0];
            DnsSOARecord      soa    = record.RDATA as DnsSOARecord;

            uint serial = soa.Serial;

            if (serial < uint.MaxValue)
            {
                serial++;
            }
            else
            {
                serial = 0;
            }

            DnsResourceRecord newRecord = new DnsResourceRecord(record.Name, record.Type, record.Class, record.TtlValue, new DnsSOARecord(soa.PrimaryNameServer, soa.ResponsiblePerson, serial, soa.Refresh, soa.Retry, soa.Expire, soa.Minimum))
            {
                Tag = record.Tag
            };

            _entries[DnsResourceRecordType.SOA] = new DnsResourceRecord[] { newRecord };
        }
예제 #36
0
        bool RetrieveDnsResponse(UdpSocket socket, UInt16 transactionID, out DnsResponse dnsResponse, Int64 timeoutInMachineTicks)
        {
            byte[] dnsFrameBuffer = new byte[DNS_FRAME_BUFFER_LENGTH];
            while (timeoutInMachineTicks > Microsoft.SPOT.Hardware.Utility.GetMachineTime().Ticks)
            {
                Int32 bytesReceived = socket.Receive(dnsFrameBuffer, 0, dnsFrameBuffer.Length, 0, timeoutInMachineTicks);

                if (bytesReceived == 0) // timeout
                {
                    break;
                }

                /* parse our DNS response */
                Int32 bufferIndex = 0;
                // verify that the transaction ID matches
                UInt16 verifyTransactionID = (UInt16)(
                    (UInt16)(dnsFrameBuffer[bufferIndex++] << 8) +
                    (UInt16)(dnsFrameBuffer[bufferIndex++])
                    );
                if (transactionID != verifyTransactionID)
                    continue; /* filter out this DHCP frame */
                // Flags
                UInt16 flags = (UInt16)(
                    (UInt16)(dnsFrameBuffer[bufferIndex++] << 8) +
                    (UInt16)(dnsFrameBuffer[bufferIndex++])
                    );
                DnsResponseCode responseCode = (DnsResponseCode)(flags & 0x0F);
                // Query Count
                UInt16 queryCount = (UInt16)(
                    (UInt16)(dnsFrameBuffer[bufferIndex++] << 8) +
                    (UInt16)(dnsFrameBuffer[bufferIndex++])
                    );
                // Answer Record Count
                UInt16 answerRecordCount = (UInt16)(
                    (UInt16)(dnsFrameBuffer[bufferIndex++] << 8) +
                    (UInt16)(dnsFrameBuffer[bufferIndex++])
                    );
                // Authority Record Count
                UInt16 authorityRecordCount = (UInt16)(
                    (UInt16)(dnsFrameBuffer[bufferIndex++] << 8) +
                    (UInt16)(dnsFrameBuffer[bufferIndex++])
                    );
                // Additional Information Record Count
                UInt16 additionalInformationRecordCount = (UInt16)(
                    (UInt16)(dnsFrameBuffer[bufferIndex++] << 8) +
                    (UInt16)(dnsFrameBuffer[bufferIndex++])
                    );

                /* parse our query records */
                string queryName = "";
                DnsRecordType queryType = (DnsRecordType)0;
                for (int iRecord = 0; iRecord < queryCount; iRecord++)
                {
                    // Query Name
                    bufferIndex += ParseDnsName(dnsFrameBuffer, bufferIndex, out queryName);
                    queryType = (DnsRecordType)(
                        (UInt16)(dnsFrameBuffer[bufferIndex++] << 8) +
                        (UInt16)(dnsFrameBuffer[bufferIndex++])
                        );
                    UInt16 queryClass = (UInt16)(
                        (UInt16)(dnsFrameBuffer[bufferIndex++] << 8) +
                        (UInt16)(dnsFrameBuffer[bufferIndex++])
                        );
                    if (queryClass != DNS_RECORD_CLASS_INTERNET)
                        continue; /* filter out the current query */
                }

                /* parse our answer records */
                DnsResourceRecord[] answerRecords = new DnsResourceRecord[answerRecordCount];
                for (int iRecord = 0; iRecord < answerRecordCount; iRecord++)
                {
                    // store answer record
                    bufferIndex += ParseResourceRecord(dnsFrameBuffer, bufferIndex, out answerRecords[iRecord]);
                }

                /* parse our authority records */
                DnsResourceRecord[] authorityRecords = new DnsResourceRecord[authorityRecordCount];
                for (int iRecord = 0; iRecord < authorityRecordCount; iRecord++)
                {
                    // store authority record
                    bufferIndex += ParseResourceRecord(dnsFrameBuffer, bufferIndex, out authorityRecords[iRecord]);
                }

                /* parse our authority records */
                DnsResourceRecord[] additionalInformationRecords = new DnsResourceRecord[additionalInformationRecordCount];
                for (int iRecord = 0; iRecord < additionalInformationRecordCount; iRecord++)
                {
                    // store authority record
                    bufferIndex += ParseResourceRecord(dnsFrameBuffer, bufferIndex, out additionalInformationRecords[iRecord]);
                }

                dnsResponse = new DnsResponse(responseCode, queryType, queryName, answerRecords, authorityRecords, additionalInformationRecords);
                return true;
            }

            // if we did not receive a message before timeout, return false.
            dnsResponse = null;
            return false;
        }
예제 #37
0
        /* this function returns the number of bytes processed */
        Int32 ParseResourceRecord(byte[] buffer, Int32 offset, out DnsResourceRecord resourceRecord)
        {
            Int32 bytesProcessed = 0;
            // Name
            string name;
            int dnsNameBytesProcessed = ParseDnsName(buffer, offset, out name);
            bytesProcessed += dnsNameBytesProcessed;
            offset += bytesProcessed;
            // Type
            DnsRecordType recordType = (DnsRecordType)(
                (UInt16)(buffer[offset++] << 8) +
                (UInt16)(buffer[offset++])
                );
            bytesProcessed += 2;
            // Class
            UInt16 recordClass = (UInt16)(
                (UInt16)(buffer[offset++] << 8) +
                (UInt16)(buffer[offset++])
                );
            bytesProcessed += 2;
            // TTL
            UInt32 timeToLive = (
                (UInt32)(buffer[offset++] << 24) +
                (UInt32)(buffer[offset++] << 16) +
                (UInt32)(buffer[offset++] << 8) +
                (UInt32)(buffer[offset++])
                );
            bytesProcessed += 4;
            // RDLENGTH
            UInt16 dataLength = (UInt16)(
                (UInt16)(buffer[offset++] << 8) +
                (UInt16)(buffer[offset++])
                );
            bytesProcessed += 2;
            // RDATA
            byte[] data = new byte[dataLength];
            Array.Copy(buffer, offset, data, 0, dataLength);
            offset += dataLength;
            bytesProcessed += dataLength;

            if (recordClass == DNS_RECORD_CLASS_INTERNET)
            {
                resourceRecord = new DnsResourceRecord(name, recordType, timeToLive, data);
            }
            else
            {
                /* filter out the current query */
                resourceRecord = new DnsResourceRecord();
            }

            return bytesProcessed;
        }
예제 #38
0
파일: MXRecord.cs 프로젝트: DM-TOR/nhin-d
 /// <summary>
 /// Tests equality between this TXT record and the other <paramref name="record"/>.
 /// </summary>
 /// <param name="record">The other record.</param>
 /// <returns><c>true</c> if the RRs are equal, <c>false</c> otherwise.</returns>
 public override bool Equals(DnsResourceRecord record)
 {
     if (!base.Equals(record))
     {
         return false;
     }
     
     MXRecord mxRecord = record as MXRecord;
     if (mxRecord == null)
     {
         return false;
     }
     
     return (
                DnsStandard.Equals(m_exchange, mxRecord.m_exchange)
                &&  this.Preference == mxRecord.Preference
            );
 }
예제 #39
0
파일: SOARecord.cs 프로젝트: DM-TOR/nhin-d
        /// <summary>
        /// Tests equality between this SOA record and the other <paramref name="record"/>.
        /// </summary>
        /// <param name="record">The other record.</param>
        /// <returns><c>true</c> if the RRs are equal, <c>false</c> otherwise.</returns>
        public override bool Equals(DnsResourceRecord record)
        {
            if (!base.Equals(record))
            {
                return false;
            }

            SOARecord soaRecord = record as SOARecord;
            if (soaRecord == null)
            {
                return false;
            }
            
            return (
                       DnsStandard.Equals(m_mname, soaRecord.m_mname)
                       &&  DnsStandard.Equals(m_rname, soaRecord.m_rname)
                       &&  this.SerialNumber == soaRecord.SerialNumber
                       &&  this.Refresh == soaRecord.Refresh
                       &&  this.Retry == soaRecord.Retry
                       &&  this.Expire == soaRecord.Expire
                       &&  this.Minimum == soaRecord.Minimum 
                   );
        }