1*3f982cf4SFabien Sanglard // Copyright 2019 The Chromium Authors. All rights reserved. 2*3f982cf4SFabien Sanglard // Use of this source code is governed by a BSD-style license that can be 3*3f982cf4SFabien Sanglard // found in the LICENSE file. 4*3f982cf4SFabien Sanglard 5*3f982cf4SFabien Sanglard #ifndef DISCOVERY_MDNS_MDNS_WRITER_H_ 6*3f982cf4SFabien Sanglard #define DISCOVERY_MDNS_MDNS_WRITER_H_ 7*3f982cf4SFabien Sanglard 8*3f982cf4SFabien Sanglard #include <string> 9*3f982cf4SFabien Sanglard #include <unordered_map> 10*3f982cf4SFabien Sanglard #include <vector> 11*3f982cf4SFabien Sanglard 12*3f982cf4SFabien Sanglard #include "discovery/mdns/mdns_records.h" 13*3f982cf4SFabien Sanglard #include "util/big_endian.h" 14*3f982cf4SFabien Sanglard 15*3f982cf4SFabien Sanglard namespace openscreen { 16*3f982cf4SFabien Sanglard namespace discovery { 17*3f982cf4SFabien Sanglard 18*3f982cf4SFabien Sanglard class MdnsWriter : public BigEndianWriter { 19*3f982cf4SFabien Sanglard public: 20*3f982cf4SFabien Sanglard using BigEndianWriter::BigEndianWriter; 21*3f982cf4SFabien Sanglard using BigEndianWriter::Write; 22*3f982cf4SFabien Sanglard 23*3f982cf4SFabien Sanglard // The following methods return true if the method was able to successfully 24*3f982cf4SFabien Sanglard // write the value to the underlying buffer and advances current() to point 25*3f982cf4SFabien Sanglard // right past the written data. Returns false if the method failed to write 26*3f982cf4SFabien Sanglard // the value to the underlying buffer, current() remains unchanged. 27*3f982cf4SFabien Sanglard bool Write(absl::string_view value); 28*3f982cf4SFabien Sanglard bool Write(const std::string& value); 29*3f982cf4SFabien Sanglard bool Write(const DomainName& name); 30*3f982cf4SFabien Sanglard bool Write(const RawRecordRdata& rdata); 31*3f982cf4SFabien Sanglard bool Write(const SrvRecordRdata& rdata); 32*3f982cf4SFabien Sanglard bool Write(const ARecordRdata& rdata); 33*3f982cf4SFabien Sanglard bool Write(const AAAARecordRdata& rdata); 34*3f982cf4SFabien Sanglard bool Write(const PtrRecordRdata& rdata); 35*3f982cf4SFabien Sanglard bool Write(const TxtRecordRdata& rdata); 36*3f982cf4SFabien Sanglard bool Write(const NsecRecordRdata& rdata); 37*3f982cf4SFabien Sanglard bool Write(const OptRecordRdata& rdata); 38*3f982cf4SFabien Sanglard // Writes a DNS resource record with its RDATA. 39*3f982cf4SFabien Sanglard // The correct type of RDATA to be written is contained in the type 40*3f982cf4SFabien Sanglard // specified in the record. 41*3f982cf4SFabien Sanglard bool Write(const MdnsRecord& record); 42*3f982cf4SFabien Sanglard bool Write(const MdnsQuestion& question); 43*3f982cf4SFabien Sanglard // Writes multiple mDNS questions and records that are a part of 44*3f982cf4SFabien Sanglard // a mDNS message being read 45*3f982cf4SFabien Sanglard bool Write(const MdnsMessage& message); 46*3f982cf4SFabien Sanglard 47*3f982cf4SFabien Sanglard private: 48*3f982cf4SFabien Sanglard bool Write(const IPAddress& address); 49*3f982cf4SFabien Sanglard bool Write(const Rdata& rdata); 50*3f982cf4SFabien Sanglard bool Write(const Header& header); 51*3f982cf4SFabien Sanglard 52*3f982cf4SFabien Sanglard template <class ItemType> Write(const std::vector<ItemType> & collection)53*3f982cf4SFabien Sanglard bool Write(const std::vector<ItemType>& collection) { 54*3f982cf4SFabien Sanglard Cursor cursor(this); 55*3f982cf4SFabien Sanglard for (const ItemType& entry : collection) { 56*3f982cf4SFabien Sanglard if (!Write(entry)) { 57*3f982cf4SFabien Sanglard return false; 58*3f982cf4SFabien Sanglard } 59*3f982cf4SFabien Sanglard } 60*3f982cf4SFabien Sanglard cursor.Commit(); 61*3f982cf4SFabien Sanglard return true; 62*3f982cf4SFabien Sanglard } 63*3f982cf4SFabien Sanglard 64*3f982cf4SFabien Sanglard // Domain name compression dictionary. 65*3f982cf4SFabien Sanglard // Maps hashes of previously written domain (sub)names 66*3f982cf4SFabien Sanglard // to the label pointers of the first occurrences in the underlying buffer. 67*3f982cf4SFabien Sanglard // Compression of multiple domain names is supported on the same instance of 68*3f982cf4SFabien Sanglard // the MdnsWriter. Underlying buffer may contain other data in addition to the 69*3f982cf4SFabien Sanglard // domain names. The compression dictionary persists between calls to 70*3f982cf4SFabien Sanglard // Write. 71*3f982cf4SFabien Sanglard // Label pointer is only 16 bits in size as per RFC 1035. Only lower 14 bits 72*3f982cf4SFabien Sanglard // are allocated for storing the offset. 73*3f982cf4SFabien Sanglard std::unordered_map<uint64_t, uint16_t> dictionary_; 74*3f982cf4SFabien Sanglard }; 75*3f982cf4SFabien Sanglard 76*3f982cf4SFabien Sanglard } // namespace discovery 77*3f982cf4SFabien Sanglard } // namespace openscreen 78*3f982cf4SFabien Sanglard 79*3f982cf4SFabien Sanglard #endif // DISCOVERY_MDNS_MDNS_WRITER_H_ 80