1 // Copyright 2020 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_COMMON_CONFIG_H_
6 #define DISCOVERY_COMMON_CONFIG_H_
7 
8 #include <vector>
9 
10 #include "platform/base/interface_info.h"
11 
12 namespace openscreen {
13 namespace discovery {
14 
15 // This struct provides parameters needed to initialize the discovery pipeline.
16 struct Config {
17   struct NetworkInfo {
18     enum AddressFamilies : uint8_t {
19       kNoAddressFamily = 0,
20       kUseIpV4 = 0x01 << 0,
21       kUseIpV6 = 0x01 << 1
22     };
23 
24     // Network Interface on which discovery should be run.
25     InterfaceInfo interface;
26 
27     // IP Address Families supported by this network interface and on which the
28     // mDNS Service should listen for and/or publish records.
29     AddressFamilies supported_address_families;
30   };
31 
32   /*****************************************
33    * Common Settings
34    *****************************************/
35 
36   // Interfaces on which services should be published, and on which discovery
37   // should listen for announced service instances.
38   std::vector<NetworkInfo> network_info;
39 
40   // Maximum allowed size in bytes for the rdata in an incoming record. All
41   // received records with rdata size exceeding this size will be dropped.
42   // The default value is taken from RFC 6763 section 6.2.
43   int maximum_valid_rdata_size = 1300;
44 
45   /*****************************************
46    * Publisher Settings
47    *****************************************/
48 
49   // Determines whether publishing of services is enabled.
50   bool enable_publication = true;
51 
52   // Number of times new mDNS records should be announced, using an exponential
53   // back off. See RFC 6762 section 8.3 for further details. Per RFC, this value
54   // is expected to be in the range of 2 to 8.
55   int new_record_announcement_count = 8;
56 
57   // Maximum number of truncated messages that the receiver may receive for a
58   // single query from any given host.
59   // The supported record type with the largest expected data size is a TXT
60   // record. RFC 6763 section 6.1 states that the "maximum sensible size" for
61   // one such record is "a few hundred bytes". Given that an mDNS Message's size
62   // is bounded by 9000 bytes, each message can be expected to hold at least 30
63   // records, meaning that the default value of 8 allows for 240 records, or
64   // more in the case of non-TXT records.
65   int maximum_truncated_messages_per_query = 8;
66 
67   // Maximum number of concurrent truncated queries that may be tracked by a
68   // single network interface.
69   // By the same logic stated in the above config value, truncated queries
70   // should be relatively rare. Each truncated query lives for at most one
71   // second after the last truncated packet is received, so receiving 64 such
72   // queries in a short timespan is unlinkely.
73   int maximum_concurrent_truncated_queries_per_interface = 64;
74 
75   // Maximum number of known answers allowed for a given truncated query.
76   // A default value of 256 is used because this is the maximum number of
77   // devices on a LAN.
78   int maximum_known_answer_records_per_query = 256;
79 
80   /*****************************************
81    * Querier Settings
82    *****************************************/
83 
84   // Determines whether querying is enabled.
85   bool enable_querying = true;
86 
87   // Number of times new mDNS records should be announced, using an exponential
88   // back off. -1 signifies that there should be no maximum.
89   int new_query_announcement_count = -1;
90 
91   // Limit on the size to which the mDNS Querier Cache may grow. This is used to
92   // prevent a malicious or misbehaving mDNS client from causing the memory
93   // used by mDNS to grow in an unbounded fashion.
94   int querier_max_records_cached = 1024;
95 
96   // Sets the querier to ignore all NSEC negative response records received as
97   // responses to outgoing queries.
98   bool ignore_nsec_responses = false;
99 };
100 
101 inline Config::NetworkInfo::AddressFamilies operator&(
102     Config::NetworkInfo::AddressFamilies lhs,
103     Config::NetworkInfo::AddressFamilies rhs) {
104   return static_cast<Config::NetworkInfo::AddressFamilies>(
105       static_cast<uint8_t>(lhs) & static_cast<uint8_t>(rhs));
106 }
107 
108 inline Config::NetworkInfo::AddressFamilies operator|(
109     Config::NetworkInfo::AddressFamilies lhs,
110     Config::NetworkInfo::AddressFamilies rhs) {
111   return static_cast<Config::NetworkInfo::AddressFamilies>(
112       static_cast<uint8_t>(lhs) | static_cast<uint8_t>(rhs));
113 }
114 
115 inline Config::NetworkInfo::AddressFamilies operator|=(
116     Config::NetworkInfo::AddressFamilies& lhs,
117     Config::NetworkInfo::AddressFamilies rhs) {
118   return lhs = lhs | rhs;
119 }
120 
121 inline Config::NetworkInfo::AddressFamilies operator&=(
122     Config::NetworkInfo::AddressFamilies& lhs,
123     Config::NetworkInfo::AddressFamilies rhs) {
124   return lhs = lhs & rhs;
125 }
126 
127 }  // namespace discovery
128 }  // namespace openscreen
129 
130 #endif  // DISCOVERY_COMMON_CONFIG_H_
131