1 // Copyright 2019 The Chromium Authors. All rights reserved. 2 // Use of this source code is governed by a BSD-style license that can be 3 // found in the LICENSE file. 4 5 #ifndef DISCOVERY_MDNS_MDNS_READER_H_ 6 #define DISCOVERY_MDNS_MDNS_READER_H_ 7 8 #include <utility> 9 #include <vector> 10 11 #include "discovery/mdns/mdns_records.h" 12 #include "platform/base/error.h" 13 #include "util/big_endian.h" 14 15 namespace openscreen { 16 namespace discovery { 17 18 struct Config; 19 20 class MdnsReader : public BigEndianReader { 21 public: 22 MdnsReader(const Config& config, const uint8_t* buffer, size_t length); 23 24 using BigEndianReader::Read; 25 26 // The following methods return true if the method was able to successfully 27 // read the value to |out| and advances current() to point right past the read 28 // data. Returns false if the method failed to read the value to |out|, 29 // current() remains unchanged. 30 bool Read(TxtRecordRdata::Entry* out); 31 bool Read(DomainName* out); 32 bool Read(RawRecordRdata* out); 33 bool Read(SrvRecordRdata* out); 34 bool Read(ARecordRdata* out); 35 bool Read(AAAARecordRdata* out); 36 bool Read(PtrRecordRdata* out); 37 bool Read(TxtRecordRdata* out); 38 bool Read(NsecRecordRdata* out); 39 40 // Reads a DNS resource record with its RDATA. 41 // The correct type of RDATA to be read is determined by the type 42 // specified in the record. 43 bool Read(MdnsRecord* out); 44 bool Read(MdnsQuestion* out); 45 46 // Reads multiple mDNS questions and records that are a part of 47 // a mDNS message being read. 48 ErrorOr<MdnsMessage> Read(); 49 50 private: 51 struct NsecBitMapField { 52 uint8_t window_block; 53 uint8_t bitmap_length; 54 const uint8_t* bitmap; 55 }; 56 57 bool Read(IPAddress::Version version, IPAddress* out); 58 bool Read(DnsType type, Rdata* out); 59 bool Read(Header* out); 60 bool Read(std::vector<DnsType>* types, int remaining_length); 61 bool Read(NsecBitMapField* out); 62 63 template <class ItemType> Read(uint16_t count,std::vector<ItemType> * out)64 bool Read(uint16_t count, std::vector<ItemType>* out) { 65 Cursor cursor(this); 66 out->reserve(count); 67 for (uint16_t i = 0; i < count; ++i) { 68 ItemType entry; 69 if (!Read(&entry)) { 70 return false; 71 } 72 out->emplace_back(std::move(entry)); 73 } 74 cursor.Commit(); 75 return true; 76 } 77 78 template <class RdataType> Read(Rdata * out)79 bool Read(Rdata* out) { 80 RdataType rdata; 81 if (Read(&rdata)) { 82 *out = std::move(rdata); 83 return true; 84 } 85 return false; 86 } 87 88 // Maximum allowed size for the rdata in any received record. 89 const size_t kMaximumAllowedRdataSize; 90 }; 91 92 } // namespace discovery 93 } // namespace openscreen 94 95 #endif // DISCOVERY_MDNS_MDNS_READER_H_ 96